diff options
Diffstat (limited to 'luni/src/main/java/java/security/KeyRep.java')
-rw-r--r-- | luni/src/main/java/java/security/KeyRep.java | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/luni/src/main/java/java/security/KeyRep.java b/luni/src/main/java/java/security/KeyRep.java new file mode 100644 index 0000000..29ccd22 --- /dev/null +++ b/luni/src/main/java/java/security/KeyRep.java @@ -0,0 +1,183 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.security; + +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.security.spec.X509EncodedKeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.InvalidKeySpecException; + +import javax.crypto.spec.SecretKeySpec; + +import org.apache.harmony.security.internal.nls.Messages; + +/** + * {@code KeyRep} is a standardized representation for serialized {@link Key} + * objects. + */ +public class KeyRep implements Serializable { + + private static final long serialVersionUID = -4757683898830641853L; + // Key type + private final Type type; + // Key algorithm name + private final String algorithm; + // Key encoding format + private final String format; + // Key encoding + private byte[] encoded; + + /** + * Constructs a new instance of {@code KeyRep} with the specified arguments. + * The arguments should be obtained from the {@code Key} object that has to + * be serialized. + * + * @param type + * the type of the key. + * @param algorithm + * the algorithm (obtained by {@link Key#getAlgorithm()}). + * @param format + * the format of the key (obtained by {@link Key#getFormat()}). + * @param encoded + * the encoded {@code byte[]} (obtained by + * {@link Key#getEncoded()}). + * @throws NullPointerException + * if {@code type, algorithm, format or encoded} is {@code null} + * . + */ + public KeyRep(Type type, + String algorithm, String format, byte[] encoded) { + this.type = type; + this.algorithm = algorithm; + this.format = format; + this.encoded = encoded; + if(this.type == null) { + throw new NullPointerException(Messages.getString("security.07")); //$NON-NLS-1$ + } + if(this.algorithm == null) { + throw new NullPointerException(Messages.getString("security.08")); //$NON-NLS-1$ + } + if(this.format == null) { + throw new NullPointerException(Messages.getString("security.09")); //$NON-NLS-1$ + } + if(this.encoded == null) { + throw new NullPointerException(Messages.getString("security.0A")); //$NON-NLS-1$ + } + } + + /** + * Resolves and returns the {@code Key} object. Three {@link Type}|format + * combinations are supported: + * <ul> + * <li> {@code Type.PRIVATE} | "PKCS#8" : returns a {@link PrivateKey} + * instance, generated from a key factory (suitable for the algorithm) that + * is initialized with a {@link PKCS8EncodedKeySpec} using the encoded key + * bytes. + * <li> {@code Type.SECRET} | "RAW" : returns a {@link SecretKeySpec} + * instance, created with the encoded key bytes and the algorithm. + * <li> {@code Type.PUBLIC} | "X.509": returns a {@link PublicKey} instance, + * generated from a key factory (suitable for the algorithm) that is + * initialized with a {@link X509EncodedKeySpec} using the encoded key + * bytes. + * </ul> + * + * @return the resolved {@code Key} object. + * @throws ObjectStreamException + * if the {@code Type}|format combination is not recognized, or + * the resolution of any key parameter fails. + */ + protected Object readResolve() throws ObjectStreamException { + switch (type) { + case SECRET: + if ("RAW".equals(format)) { //$NON-NLS-1$ + try { + return new SecretKeySpec(encoded, algorithm); + } catch (IllegalArgumentException e) { + throw new NotSerializableException( + Messages.getString("security.0B", e)); //$NON-NLS-1$ + } + } + throw new NotSerializableException( + Messages.getString("security.0C", type, format)); //$NON-NLS-1$ + case PUBLIC: + if ("X.509".equals(format)) { //$NON-NLS-1$ + try { + KeyFactory kf = KeyFactory.getInstance(algorithm); + return kf.generatePublic(new X509EncodedKeySpec(encoded)); + } catch (NoSuchAlgorithmException e) { + throw new NotSerializableException( + Messages.getString("security.0D", e)); //$NON-NLS-1$ + } + catch (InvalidKeySpecException e) { + throw new NotSerializableException( + Messages.getString("security.0D", e)); //$NON-NLS-1$ + } + } + throw new NotSerializableException( + Messages.getString("security.0C", type, format)); //$NON-NLS-1$ + case PRIVATE: + if ("PKCS#8".equals(format)) { //$NON-NLS-1$ + try { + KeyFactory kf = KeyFactory.getInstance(algorithm); + return kf.generatePrivate(new PKCS8EncodedKeySpec(encoded)); + } catch (NoSuchAlgorithmException e) { + throw new NotSerializableException( + Messages.getString("security.0D", e)); //$NON-NLS-1$ + } + catch (InvalidKeySpecException e) { + throw new NotSerializableException( + Messages.getString("security.0D", e)); //$NON-NLS-1$ + } + } + throw new NotSerializableException( + Messages.getString("security.0C", type, format)); //$NON-NLS-1$ + } + throw new NotSerializableException(Messages.getString("security.0E", type)); //$NON-NLS-1$ + } + + // Makes defensive copy of key encoding + private void readObject(ObjectInputStream is) + throws IOException, ClassNotFoundException { + is.defaultReadObject(); + byte[] new_encoded = new byte[encoded.length]; + System.arraycopy(encoded, 0, new_encoded, 0, new_encoded.length); + encoded = new_encoded; + } + + /** + * {@code Type} enumerates the supported key types. + */ + public static enum Type { + /** + * Type for secret keys. + */ + SECRET, + /** + * Type for public keys. + */ + PUBLIC, + /** + * Type for private keys. + */ + PRIVATE + } +} |