summaryrefslogtreecommitdiff
path: root/gnu/java/security/key/KeyPairCodecFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/java/security/key/KeyPairCodecFactory.java')
-rw-r--r--gnu/java/security/key/KeyPairCodecFactory.java400
1 files changed, 220 insertions, 180 deletions
diff --git a/gnu/java/security/key/KeyPairCodecFactory.java b/gnu/java/security/key/KeyPairCodecFactory.java
index d0cb1ca17..1a8b8aa03 100644
--- a/gnu/java/security/key/KeyPairCodecFactory.java
+++ b/gnu/java/security/key/KeyPairCodecFactory.java
@@ -39,32 +39,30 @@ exception statement from your version. */
package gnu.java.security.key;
import gnu.java.security.Registry;
+import gnu.java.security.key.dss.DSSKeyPairPKCS8Codec;
import gnu.java.security.key.dss.DSSKeyPairRawCodec;
+import gnu.java.security.key.dss.DSSKeyPairX509Codec;
import gnu.java.security.key.dss.DSSPrivateKey;
import gnu.java.security.key.dss.DSSPublicKey;
import gnu.java.security.key.rsa.GnuRSAPrivateKey;
import gnu.java.security.key.rsa.GnuRSAPublicKey;
+import gnu.java.security.key.rsa.RSAKeyPairPKCS8Codec;
import gnu.java.security.key.rsa.RSAKeyPairRawCodec;
+import gnu.java.security.key.rsa.RSAKeyPairX509Codec;
+import gnu.java.security.util.FormatUtil;
import java.lang.reflect.Constructor;
-import java.util.Set;
import java.security.Key;
-import java.security.PrivateKey;
-import java.security.PublicKey;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
/**
- * <p>A <i>Factory</i> class to instantiate key encoder/decoder instances.</p>
- *
- * @version $Revision: 1.2 $
+ * A <i>Factory</i> class to instantiate key encoder/decoder instances.
*/
public class KeyPairCodecFactory
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
- // Constructor(s)
- // -------------------------------------------------------------------------
+ private static Set names;
/** Trivial constructor to enforce Singleton pattern. */
private KeyPairCodecFactory()
@@ -72,220 +70,148 @@ public class KeyPairCodecFactory
super();
}
- // Class methods
- // -------------------------------------------------------------------------
-
/**
- * <p>Returns an instance of a keypair codec given its name.</p>
- *
+ * Returns the appropriate codec given a composed key-pair generator algorithm
+ * and an encoding format. A composed name is formed by the concatenation of
+ * the canonical key-pair algorithm name, the forward slash character
+ * <code>/</code> and the canonical name of the encoding format.
+ * <p>
+ * <b>IMPORTANT</b>: For backward compatibility, when the encoding format
+ * name is missing, the Raw encoding format is assumed. When this is the case
+ * the trailing forward slash is discarded from the name.
+ *
* @param name the case-insensitive key codec name.
* @return an instance of the keypair codec, or <code>null</code> if none
- * found.
+ * found.
*/
public static IKeyPairCodec getInstance(String name)
{
if (name == null)
- {
- return null;
- }
+ return null;
name = name.trim();
- IKeyPairCodec result = null;
- if (name.equalsIgnoreCase(Registry.DSA_KPG)
- || name.equals(Registry.DSS_KPG))
- {
- result = new DSSKeyPairRawCodec();
- }
- else if (name.equalsIgnoreCase(Registry.RSA_KPG))
- {
- result = new RSAKeyPairRawCodec();
- }
- else if (name.equalsIgnoreCase(Registry.DH_KPG))
- {
- result = makeInstance ("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
- }
- else if (name.equalsIgnoreCase(Registry.SRP_KPG))
- {
- result = makeInstance ("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");
- }
+ if (name.length() == 0)
+ return null;
- return result;
+ if (name.startsWith("/"))
+ return null;
+
+ if (name.endsWith("/"))
+ return getInstance(name.substring(0, name.length() - 1),
+ Registry.RAW_ENCODING_ID);
+
+ int i = name.indexOf("/");
+ if (i == -1)
+ return getInstance(name, Registry.RAW_ENCODING_ID);
+
+ String kpgName = name.substring(0, i);
+ String formatName = name.substring(i + 1);
+ return getInstance(kpgName, formatName);
}
/**
- * <p>Returns an instance of a keypair codec given a byte array that is
- * assumed to contain a previously encoded key (public or private).</p>
- *
- * @param buffer a byte array containing a previously encoded key.
- * @return an instance of the keypair codec, or <code>null</code> if none
- * found.
+ * Returns an instance of a keypair codec given the canonical name of the
+ * key-pair algorithm, and the name of the encoding format to use when
+ * externalizing the keys.
+ *
+ * @param name the case-insensitive key-pair algorithm name.
+ * @param format the name of the encoding format to use when externalizing the
+ * keys generated by the key-pair algorithm.
+ * @return an instance of the key-pair codec, or <code>null</code> if none
+ * found.
*/
- public static IKeyPairCodec getInstance(byte[] buffer)
+ public static IKeyPairCodec getInstance(String name, String format)
{
- if (buffer == null)
- {
- return null;
- }
- // our codecs prefix the stream with a 4-byte magic
- if (buffer.length < 5)
- {
- return null;
- }
- // the first byte is always 0x47
- if (buffer[0] != 0x47)
- {
- return null;
- }
- // so far we only have RAW codecs
- if (buffer[1] != Registry.RAW_ENCODING_ID)
- {
- return null;
- }
- IKeyPairCodec result = null;
- switch (buffer[2])
- {
- case 0x44:
- result = new DSSKeyPairRawCodec();
- break;
- case 0x52:
- result = new RSAKeyPairRawCodec();
- break;
- case 0x48:
- result = makeInstance ("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
- break;
- case 0x53:
- result = makeInstance ("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");
- break;
- }
+ int formatID = FormatUtil.getFormatID(format);
+ if (formatID == 0)
+ return null;
- return result;
+ return getInstance(name, formatID);
}
/**
- * <p>Returns an instance of a keypair codec given a key.</p>
- *
- * @param key the key to encode.
- * @return an instance of the keypair codec, or <code>null</code> if none
- * found.
+ * Returns an instance of a keypair codec given the canonical name of the
+ * key-pair algorithm, and the identifier of the format to use when
+ * externalizing the keys.
+ *
+ * @param name the case-insensitive key-pair algorithm name.
+ * @param formatID the identifier of the format to use when externalizing the
+ * keys generated by the key-pair algorithm.
+ * @return an instance of the key-pair codec, or <code>null</code> if none
+ * found.
*/
- public static IKeyPairCodec getInstance(Key key)
+ public static IKeyPairCodec getInstance(String name, int formatID)
{
- if (key == null)
- {
- return null;
- }
+ if (name == null)
+ return null;
- IKeyPairCodec result = null;
- if (key instanceof PublicKey)
- {
- if (key instanceof DSSPublicKey)
- {
- result = new DSSKeyPairRawCodec();
- }
- else if (key instanceof GnuRSAPublicKey)
- {
- result = new RSAKeyPairRawCodec();
- }
- else if (matches (key, "gnu.javax.crypto.key.dh.GnuDHPublicKey"))
- {
- result = makeInstance ("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
- }
- else if (matches (key, "gnu.javax.crypto.key.srp6.SRPPublicKey"))
- {
- result = makeInstance ("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");
- }
- }
- else if (key instanceof PrivateKey)
+ name = name.trim();
+ switch (formatID)
{
- if (key instanceof DSSPrivateKey)
- {
- result = new DSSKeyPairRawCodec();
- }
- else if (key instanceof GnuRSAPrivateKey)
- {
- result = new RSAKeyPairRawCodec();
- }
- else if (matches (key, "gnu.javax.crypto.key.dh.GnuDHPrivateKey"))
- {
- result = makeInstance ("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
- }
- else if (matches (key, "gnu.javax.crypto.key.srp6.SRPPrivateKey"))
- {
- result = makeInstance ("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");
- }
+ case Registry.RAW_ENCODING_ID:
+ return getRawCodec(name);
+ case Registry.X509_ENCODING_ID:
+ return getX509Codec(name);
+ case Registry.PKCS8_ENCODING_ID:
+ return getPKCS8Codec(name);
}
- return result;
+ return null;
}
/**
- * <p>Returns a {@link Set} of keypair codec names supported by this
- * <i>Factory</i>.</p>
- *
- * @return a {@link Set} of keypair codec names (Strings).
- */
- public static final Set getNames()
- {
- return KeyPairGeneratorFactory.getNames();
- }
-
- /**
- * Returns the fully qualified name of the designated encoding ID.
+ * Returns an instance of a keypair codec given a key.
*
- * @param formatID the unique identifier of the encoding format.
- * @return the fully qualified name of the designated format. Returns
- * <code>null</code> if no such encoding format is known.
+ * @param key the key to encode.
+ * @return an instance of the keypair codec, or <code>null</code> if none
+ * found.
*/
- public static final String getEncodingName(int formatID)
+ public static IKeyPairCodec getInstance(Key key)
{
- String result = null;
+ if (key == null)
+ return null;
+
+ String format = key.getFormat();
+ int formatID = FormatUtil.getFormatID(format);
+ if (formatID == 0)
+ return null;
+
switch (formatID)
{
case Registry.RAW_ENCODING_ID:
- result = Registry.RAW_ENCODING;
- break;
+ return getRawCodec(key);
case Registry.X509_ENCODING_ID:
- result = Registry.X509_ENCODING;
- break;
+ return getX509Codec(key);
case Registry.PKCS8_ENCODING_ID:
- result = Registry.PKCS8_ENCODING;
- break;
- case Registry.ASN1_ENCODING_ID:
- result = Registry.ASN1_ENCODING;
- break;
+ return getPKCS8Codec(key);
}
- return result;
+ return null;
}
/**
- * Returns the short name of the designated encoding ID. This is used by the
- * JCE Adapters.
- *
- * @param formatID the unique identifier of the encoding format.
- * @return the short name of the designated format. Returns <code>null</code>
- * if no such encoding format is known.
+ * Returns a {@link Set} of supported key-pair codec names.
+ *
+ * @return a {@link Set} of the names of supported key-pair codec (Strings).
*/
- public static final String getEncodingShortName(int formatID)
+ public static synchronized final Set getNames()
{
- String result = null;
- switch (formatID)
+ if (names == null)
{
- case Registry.RAW_ENCODING_ID:
- result = Registry.RAW_ENCODING_SHORT_NAME;
- break;
- case Registry.X509_ENCODING_ID:
- result = Registry.X509_ENCODING_SORT_NAME;
- break;
- case Registry.PKCS8_ENCODING_ID:
- result = Registry.PKCS8_ENCODING_SHORT_NAME;
- break;
- case Registry.ASN1_ENCODING_ID:
- result = Registry.ASN1_ENCODING_SHORT_NAME;
- break;
+ HashSet hs = new HashSet();
+ hs.add(Registry.DSS_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
+ hs.add(Registry.DSS_KPG + "/" + Registry.X509_ENCODING_SORT_NAME);
+ hs.add(Registry.DSS_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME);
+ hs.add(Registry.RSA_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
+ hs.add(Registry.RSA_KPG + "/" + Registry.X509_ENCODING_SORT_NAME);
+ hs.add(Registry.RSA_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME);
+ hs.add(Registry.DH_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
+ hs.add(Registry.SRP_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
+
+ names = Collections.unmodifiableSet(hs);
}
- return result;
+ return names;
}
private static IKeyPairCodec makeInstance (String clazz)
@@ -319,4 +245,118 @@ public class KeyPairCodecFactory
return false;
}
}
+
+ /**
+ * @param name the trimmed name of a key-pair algorithm.
+ * @return a Raw format codec for the designated key-pair algorithm, or
+ * <code>null</code> if none exists.
+ */
+ private static IKeyPairCodec getRawCodec(String name)
+ {
+ IKeyPairCodec result = null;
+ if (name.equalsIgnoreCase(Registry.DSA_KPG)
+ || name.equals(Registry.DSS_KPG))
+ result = new DSSKeyPairRawCodec();
+ else if (name.equalsIgnoreCase(Registry.RSA_KPG))
+ result = new RSAKeyPairRawCodec();
+ else if (name.equalsIgnoreCase(Registry.DH_KPG))
+ result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
+ else if (name.equalsIgnoreCase(Registry.SRP_KPG))
+ result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");
+
+ return result;
+ }
+
+ /**
+ * @param name the trimmed name of a key-pair algorithm.
+ * @return a X.509 format codec for the designated key-pair algorithm, or
+ * <code>null</code> if none exists.
+ */
+ private static IKeyPairCodec getX509Codec(String name)
+ {
+ IKeyPairCodec result = null;
+ if (name.equalsIgnoreCase(Registry.DSA_KPG)
+ || name.equals(Registry.DSS_KPG))
+ result = new DSSKeyPairX509Codec();
+ else if (name.equalsIgnoreCase(Registry.RSA_KPG))
+ result = new RSAKeyPairX509Codec();
+ else if (name.equalsIgnoreCase(Registry.DH_KPG))
+ result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairX509Codec");
+
+ return result;
+ }
+
+ /**
+ * @param name the trimmed name of a key-pair algorithm.
+ * @return a PKCS#8 format codec for the designated key-pair algorithm, or
+ * <code>null</code> if none exists.
+ */
+ private static IKeyPairCodec getPKCS8Codec(String name)
+ {
+ IKeyPairCodec result = null;
+ if (name.equalsIgnoreCase(Registry.DSA_KPG)
+ || name.equals(Registry.DSS_KPG))
+ result = new DSSKeyPairPKCS8Codec();
+ else if (name.equalsIgnoreCase(Registry.RSA_KPG))
+ result = new RSAKeyPairPKCS8Codec();
+ else if (name.equalsIgnoreCase(Registry.DH_KPG))
+ result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairPKCS8Codec");
+
+ return result;
+ }
+
+ /**
+ * @param key a {@link Key} for which we want to return a Raw codec.
+ * @return the Raw codec corresponding to the key, or <code>null</code> if
+ * none exists for this key.
+ */
+ private static IKeyPairCodec getRawCodec(Key key)
+ {
+ IKeyPairCodec result = null;
+ if ((key instanceof DSSPublicKey) || (key instanceof DSSPrivateKey))
+ result = new DSSKeyPairRawCodec();
+ else if ((key instanceof GnuRSAPublicKey)
+ || (key instanceof GnuRSAPrivateKey))
+ result = new RSAKeyPairRawCodec();
+ else if (matches(key, "gnu.javax.crypto.key.dh.GnuDHPublicKey")
+ || matches(key, "gnu.javax.crypto.key.dh.GnuDHPrivateKey"))
+ result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
+ else if (matches(key, "gnu.javax.crypto.key.srp6.SRPPublicKey")
+ || matches(key, "gnu.javax.crypto.key.srp6.SRPPrivateKey"))
+ result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");
+
+ return result;
+ }
+
+ /**
+ * @param key a {@link Key} for which we want to return an X.509 codec.
+ * @return the X.509 codec corresponding to the key, or <code>null</code> if
+ * none exists for this key.
+ */
+ private static IKeyPairCodec getX509Codec(Key key)
+ {
+ IKeyPairCodec result = null;
+ if (key instanceof DSSPublicKey)
+ result = new DSSKeyPairX509Codec();
+ else if (key instanceof GnuRSAPublicKey)
+ result = new RSAKeyPairX509Codec();
+
+ return result;
+ }
+
+ /**
+ * @param key a {@link Key} for which we want to return a PKCS#8 codec.
+ * @return the PKCS#8 codec corresponding to the key, or <code>null</code> if
+ * none exists for this key.
+ */
+ private static IKeyPairCodec getPKCS8Codec(Key key)
+ {
+ IKeyPairCodec result = null;
+ if (key instanceof DSSPrivateKey)
+ result = new DSSKeyPairPKCS8Codec();
+ else if (key instanceof GnuRSAPrivateKey)
+ result = new RSAKeyPairPKCS8Codec();
+
+ return result;
+ }
}