diff options
Diffstat (limited to 'gnu/java/security/key/KeyPairCodecFactory.java')
| -rw-r--r-- | gnu/java/security/key/KeyPairCodecFactory.java | 400 |
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; + } } |
