summaryrefslogtreecommitdiffstats
path: root/luni/src/main/java/java/security/KeyRep.java
diff options
context:
space:
mode:
Diffstat (limited to 'luni/src/main/java/java/security/KeyRep.java')
-rw-r--r--luni/src/main/java/java/security/KeyRep.java183
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
+ }
+}