Home | History | Annotate | Download | only in x509
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 package sun.security.x509;
     28 
     29 import java.io.*;
     30 import java.util.*;
     31 import java.security.*;
     32 
     33 import sun.security.util.*;
     34 
     35 
     36 /**
     37  * This class identifies algorithms, such as cryptographic transforms, each
     38  * of which may be associated with parameters.  Instances of this base class
     39  * are used when this runtime environment has no special knowledge of the
     40  * algorithm type, and may also be used in other cases.  Equivalence is
     41  * defined according to OID and (where relevant) parameters.
     42  *
     43  * <P>Subclasses may be used, for example when when the algorithm ID has
     44  * associated parameters which some code (e.g. code using public keys) needs
     45  * to have parsed.  Two examples of such algorithms are Diffie-Hellman key
     46  * exchange, and the Digital Signature Standard Algorithm (DSS/DSA).
     47  *
     48  * <P>The OID constants defined in this class correspond to some widely
     49  * used algorithms, for which conventional string names have been defined.
     50  * This class is not a general repository for OIDs, or for such string names.
     51  * Note that the mappings between algorithm IDs and algorithm names is
     52  * not one-to-one.
     53  *
     54  *
     55  * @author David Brownell
     56  * @author Amit Kapoor
     57  * @author Hemma Prafullchandra
     58  */
     59 public class AlgorithmId implements Serializable, DerEncoder {
     60 
     61     /** use serialVersionUID from JDK 1.1. for interoperability */
     62     private static final long serialVersionUID = 7205873507486557157L;
     63 
     64     /**
     65      * The object identitifer being used for this algorithm.
     66      */
     67     private ObjectIdentifier algid;
     68 
     69     // The (parsed) parameters
     70     private AlgorithmParameters algParams;
     71     private boolean constructedFromDer = true;
     72 
     73     /**
     74      * Parameters for this algorithm.  These are stored in unparsed
     75      * DER-encoded form; subclasses can be made to automaticaly parse
     76      * them so there is fast access to these parameters.
     77      */
     78     protected DerValue          params;
     79 
     80 
     81     /**
     82      * Constructs an algorithm ID which will be initialized
     83      * separately, for example by deserialization.
     84      * @deprecated use one of the other constructors.
     85      */
     86     @Deprecated
     87     public AlgorithmId() { }
     88 
     89     /**
     90      * Constructs a parameterless algorithm ID.
     91      *
     92      * @param oid the identifier for the algorithm
     93      */
     94     public AlgorithmId(ObjectIdentifier oid) {
     95         algid = oid;
     96     }
     97 
     98     /**
     99      * Constructs an algorithm ID with algorithm parameters.
    100      *
    101      * @param oid the identifier for the algorithm.
    102      * @param algparams the associated algorithm parameters.
    103      */
    104     public AlgorithmId(ObjectIdentifier oid, AlgorithmParameters algparams) {
    105         algid = oid;
    106         algParams = algparams;
    107         constructedFromDer = false;
    108     }
    109 
    110     private AlgorithmId(ObjectIdentifier oid, DerValue params)
    111             throws IOException {
    112         this.algid = oid;
    113         this.params = params;
    114         if (this.params != null) {
    115             decodeParams();
    116         }
    117     }
    118 
    119     protected void decodeParams() throws IOException {
    120         String algidString = algid.toString();
    121         try {
    122             algParams = AlgorithmParameters.getInstance(algidString);
    123         } catch (NoSuchAlgorithmException e) {
    124             try {
    125                 // Try the internal EC code so that we can fully parse EC
    126                 // keys even if the provider is not registered.
    127                 // This code can go away once we have EC in the SUN provider.
    128                 algParams = AlgorithmParameters.getInstance(algidString,
    129                                 sun.security.ec.ECKeyFactory.ecInternalProvider);
    130             } catch (NoSuchAlgorithmException ee) {
    131                 /*
    132                  * This algorithm parameter type is not supported, so we cannot
    133                  * parse the parameters.
    134                  */
    135                 algParams = null;
    136                 return;
    137             }
    138         }
    139         // Decode (parse) the parameters
    140         algParams.init(params.toByteArray());
    141     }
    142 
    143     /**
    144      * Marshal a DER-encoded "AlgorithmID" sequence on the DER stream.
    145      */
    146     public final void encode(DerOutputStream out) throws IOException {
    147         derEncode(out);
    148     }
    149 
    150     /**
    151      * DER encode this object onto an output stream.
    152      * Implements the <code>DerEncoder</code> interface.
    153      *
    154      * @param out
    155      * the output stream on which to write the DER encoding.
    156      *
    157      * @exception IOException on encoding error.
    158      */
    159     public void derEncode (OutputStream out) throws IOException {
    160         DerOutputStream bytes = new DerOutputStream();
    161         DerOutputStream tmp = new DerOutputStream();
    162 
    163         bytes.putOID(algid);
    164         // Setup params from algParams since no DER encoding is given
    165         if (constructedFromDer == false) {
    166             if (algParams != null) {
    167                 params = new DerValue(algParams.getEncoded());
    168             } else {
    169                 params = null;
    170             }
    171         }
    172         if (params == null) {
    173             // Changes backed out for compatibility with Solaris
    174 
    175             // Several AlgorithmId should omit the whole parameter part when
    176             // it's NULL. They are ---
    177             // rfc3370 2.1: Implementations SHOULD generate SHA-1
    178             // AlgorithmIdentifiers with absent parameters.
    179             // rfc3447 C1: When id-sha1, id-sha256, id-sha384 and id-sha512
    180             // are used in an AlgorithmIdentifier the parameters (which are
    181             // optional) SHOULD be omitted.
    182             // rfc3279 2.3.2: The id-dsa algorithm syntax includes optional
    183             // domain parameters... When omitted, the parameters component
    184             // MUST be omitted entirely
    185             // rfc3370 3.1: When the id-dsa-with-sha1 algorithm identifier
    186             // is used, the AlgorithmIdentifier parameters field MUST be absent.
    187             /*if (
    188                 algid.equals((Object)SHA_oid) ||
    189                 algid.equals((Object)SHA256_oid) ||
    190                 algid.equals((Object)SHA384_oid) ||
    191                 algid.equals((Object)SHA512_oid) ||
    192                 algid.equals((Object)DSA_oid) ||
    193                 algid.equals((Object)sha1WithDSA_oid)) {
    194                 ; // no parameter part encoded
    195             } else {
    196                 bytes.putNull();
    197             }*/
    198             bytes.putNull();
    199         } else {
    200             bytes.putDerValue(params);
    201         }
    202         tmp.write(DerValue.tag_Sequence, bytes);
    203         out.write(tmp.toByteArray());
    204     }
    205 
    206 
    207     /**
    208      * Returns the DER-encoded X.509 AlgorithmId as a byte array.
    209      */
    210     public final byte[] encode() throws IOException {
    211         DerOutputStream out = new DerOutputStream();
    212         derEncode(out);
    213         return out.toByteArray();
    214     }
    215 
    216     /**
    217      * Returns the ISO OID for this algorithm.  This is usually converted
    218      * to a string and used as part of an algorithm name, for example
    219      * "OID.1.3.14.3.2.13" style notation.  Use the <code>getName</code>
    220      * call when you do not need to ensure cross-system portability
    221      * of algorithm names, or need a user friendly name.
    222      */
    223     public final ObjectIdentifier getOID () {
    224         return algid;
    225     }
    226 
    227     /**
    228      * Returns a name for the algorithm which may be more intelligible
    229      * to humans than the algorithm's OID, but which won't necessarily
    230      * be comprehensible on other systems.  For example, this might
    231      * return a name such as "MD5withRSA" for a signature algorithm on
    232      * some systems.  It also returns names like "OID.1.2.3.4", when
    233      * no particular name for the algorithm is known.
    234      */
    235     public String getName() {
    236         String algName = nameTable.get(algid);
    237         if (algName != null) {
    238             return algName;
    239         }
    240         if ((params != null) && algid.equals(specifiedWithECDSA_oid)) {
    241             try {
    242                 AlgorithmId paramsId =
    243                         AlgorithmId.parse(new DerValue(getEncodedParams()));
    244                 String paramsName = paramsId.getName();
    245                 if (paramsName.equals("SHA")) {
    246                     paramsName = "SHA1";
    247                 }
    248                 algName = paramsName + "withECDSA";
    249             } catch (IOException e) {
    250                 // ignore
    251             }
    252         }
    253 
    254         // Try to update the name <-> OID mapping table.
    255         synchronized (oidTable) {
    256             reinitializeMappingTableLocked();
    257             algName = nameTable.get(algid);
    258         }
    259 
    260         return (algName == null) ? algid.toString() : algName;
    261     }
    262 
    263     public AlgorithmParameters getParameters() {
    264         return algParams;
    265     }
    266 
    267     /**
    268      * Returns the DER encoded parameter, which can then be
    269      * used to initialize java.security.AlgorithmParamters.
    270      *
    271      * @return DER encoded parameters, or null not present.
    272      */
    273     public byte[] getEncodedParams() throws IOException {
    274         return (params == null) ? null : params.toByteArray();
    275     }
    276 
    277     /**
    278      * Returns true iff the argument indicates the same algorithm
    279      * with the same parameters.
    280      */
    281     public boolean equals(AlgorithmId other) {
    282         boolean paramsEqual =
    283           (params == null ? other.params == null : params.equals(other.params));
    284         return (algid.equals(other.algid) && paramsEqual);
    285     }
    286 
    287     /**
    288      * Compares this AlgorithmID to another.  If algorithm parameters are
    289      * available, they are compared.  Otherwise, just the object IDs
    290      * for the algorithm are compared.
    291      *
    292      * @param other preferably an AlgorithmId, else an ObjectIdentifier
    293      */
    294     public boolean equals(Object other) {
    295         if (this == other) {
    296             return true;
    297         }
    298         if (other instanceof AlgorithmId) {
    299             return equals((AlgorithmId) other);
    300         } else if (other instanceof ObjectIdentifier) {
    301             return equals((ObjectIdentifier) other);
    302         } else {
    303             return false;
    304         }
    305     }
    306 
    307     /**
    308      * Compares two algorithm IDs for equality.  Returns true iff
    309      * they are the same algorithm, ignoring algorithm parameters.
    310      */
    311     public final boolean equals(ObjectIdentifier id) {
    312         return algid.equals(id);
    313     }
    314 
    315     /**
    316      * Returns a hashcode for this AlgorithmId.
    317      *
    318      * @return a hashcode for this AlgorithmId.
    319      */
    320     public int hashCode() {
    321         StringBuilder sbuf = new StringBuilder();
    322         sbuf.append(algid.toString());
    323         sbuf.append(paramsToString());
    324         return sbuf.toString().hashCode();
    325     }
    326 
    327     /**
    328      * Provides a human-readable description of the algorithm parameters.
    329      * This may be redefined by subclasses which parse those parameters.
    330      */
    331     protected String paramsToString() {
    332         if (params == null) {
    333             return "";
    334         } else if (algParams != null) {
    335             return algParams.toString();
    336         } else {
    337             return ", params unparsed";
    338         }
    339     }
    340 
    341     /**
    342      * Returns a string describing the algorithm and its parameters.
    343      */
    344     public String toString() {
    345         return getName() + paramsToString();
    346     }
    347 
    348     /**
    349      * Parse (unmarshal) an ID from a DER sequence input value.  This form
    350      * parsing might be used when expanding a value which has already been
    351      * partially unmarshaled as a set or sequence member.
    352      *
    353      * @exception IOException on error.
    354      * @param val the input value, which contains the algid and, if
    355      *          there are any parameters, those parameters.
    356      * @return an ID for the algorithm.  If the system is configured
    357      *          appropriately, this may be an instance of a class
    358      *          with some kind of special support for this algorithm.
    359      *          In that case, you may "narrow" the type of the ID.
    360      */
    361     public static AlgorithmId parse(DerValue val) throws IOException {
    362         if (val.tag != DerValue.tag_Sequence) {
    363             throw new IOException("algid parse error, not a sequence");
    364         }
    365 
    366         /*
    367          * Get the algorithm ID and any parameters.
    368          */
    369         ObjectIdentifier        algid;
    370         DerValue                params;
    371         DerInputStream          in = val.toDerInputStream();
    372 
    373         algid = in.getOID();
    374         if (in.available() == 0) {
    375             params = null;
    376         } else {
    377             params = in.getDerValue();
    378             if (params.tag == DerValue.tag_Null) {
    379                 if (params.length() != 0) {
    380                     throw new IOException("invalid NULL");
    381                 }
    382                 params = null;
    383             }
    384             if (in.available() != 0) {
    385                 throw new IOException("Invalid AlgorithmIdentifier: extra data");
    386             }
    387         }
    388 
    389         return new AlgorithmId(algid, params);
    390     }
    391 
    392     /**
    393      * Returns one of the algorithm IDs most commonly associated
    394      * with this algorithm name.
    395      *
    396      * @param algname the name being used
    397      * @deprecated use the short get form of this method.
    398      * @exception NoSuchAlgorithmException on error.
    399      */
    400     @Deprecated
    401     public static AlgorithmId getAlgorithmId(String algname)
    402             throws NoSuchAlgorithmException {
    403         return get(algname);
    404     }
    405 
    406     /**
    407      * Returns one of the algorithm IDs most commonly associated
    408      * with this algorithm name.
    409      *
    410      * @param algname the name being used
    411      * @exception NoSuchAlgorithmException on error.
    412      */
    413     public static AlgorithmId get(String algname)
    414             throws NoSuchAlgorithmException {
    415         ObjectIdentifier oid;
    416         try {
    417             oid = algOID(algname);
    418         } catch (IOException ioe) {
    419             throw new NoSuchAlgorithmException
    420                 ("Invalid ObjectIdentifier " + algname);
    421         }
    422 
    423         if (oid == null) {
    424             throw new NoSuchAlgorithmException
    425                 ("unrecognized algorithm name: " + algname);
    426         }
    427         return new AlgorithmId(oid);
    428     }
    429 
    430     /**
    431      * Returns one of the algorithm IDs most commonly associated
    432      * with this algorithm parameters.
    433      *
    434      * @param algparams the associated algorithm parameters.
    435      * @exception NoSuchAlgorithmException on error.
    436      */
    437     public static AlgorithmId get(AlgorithmParameters algparams)
    438             throws NoSuchAlgorithmException {
    439         ObjectIdentifier oid;
    440         String algname = algparams.getAlgorithm();
    441         try {
    442             oid = algOID(algname);
    443         } catch (IOException ioe) {
    444             throw new NoSuchAlgorithmException
    445                 ("Invalid ObjectIdentifier " + algname);
    446         }
    447         if (oid == null) {
    448             throw new NoSuchAlgorithmException
    449                 ("unrecognized algorithm name: " + algname);
    450         }
    451         return new AlgorithmId(oid, algparams);
    452     }
    453 
    454     /*
    455      * Translates from some common algorithm names to the
    456      * OID with which they're usually associated ... this mapping
    457      * is the reverse of the one below, except in those cases
    458      * where synonyms are supported or where a given algorithm
    459      * is commonly associated with multiple OIDs.
    460      *
    461      * XXX This method needs to be enhanced so that we can also pass the
    462      * scope of the algorithm name to it, e.g., the algorithm name "DSA"
    463      * may have a different OID when used as a "Signature" algorithm than when
    464      * used as a "KeyPairGenerator" algorithm.
    465      */
    466     private static ObjectIdentifier algOID(String name) throws IOException {
    467         // See if algname is in printable OID ("dot-dot") notation
    468         if (name.indexOf('.') != -1) {
    469             if (name.startsWith("OID.")) {
    470                 return new ObjectIdentifier(name.substring("OID.".length()));
    471             } else {
    472                 return new ObjectIdentifier(name);
    473             }
    474         }
    475 
    476         // Digesting algorithms
    477         if (name.equalsIgnoreCase("MD5")) {
    478             return AlgorithmId.MD5_oid;
    479         }
    480         if (name.equalsIgnoreCase("MD2")) {
    481             return AlgorithmId.MD2_oid;
    482         }
    483         if (name.equalsIgnoreCase("SHA") || name.equalsIgnoreCase("SHA1")
    484             || name.equalsIgnoreCase("SHA-1")) {
    485             return AlgorithmId.SHA_oid;
    486         }
    487         if (name.equalsIgnoreCase("SHA-256") ||
    488             name.equalsIgnoreCase("SHA256")) {
    489             return AlgorithmId.SHA256_oid;
    490         }
    491         if (name.equalsIgnoreCase("SHA-384") ||
    492             name.equalsIgnoreCase("SHA384")) {
    493             return AlgorithmId.SHA384_oid;
    494         }
    495         if (name.equalsIgnoreCase("SHA-512") ||
    496             name.equalsIgnoreCase("SHA512")) {
    497             return AlgorithmId.SHA512_oid;
    498         }
    499 
    500 
    501         // Various public key algorithms
    502         if (name.equalsIgnoreCase("RSA")) {
    503             return AlgorithmId.RSAEncryption_oid;
    504         }
    505         if (name.equalsIgnoreCase("Diffie-Hellman")
    506             || name.equalsIgnoreCase("DH")) {
    507             return AlgorithmId.DH_oid;
    508         }
    509         if (name.equalsIgnoreCase("DSA")) {
    510             return AlgorithmId.DSA_oid;
    511         }
    512         if (name.equalsIgnoreCase("EC")) {
    513             return EC_oid;
    514         }
    515 
    516         // Common signature types
    517         if (name.equalsIgnoreCase("MD5withRSA")
    518             || name.equalsIgnoreCase("MD5/RSA")) {
    519             return AlgorithmId.md5WithRSAEncryption_oid;
    520         }
    521         if (name.equalsIgnoreCase("MD2withRSA")
    522             || name.equalsIgnoreCase("MD2/RSA")) {
    523             return AlgorithmId.md2WithRSAEncryption_oid;
    524         }
    525         if (name.equalsIgnoreCase("SHAwithDSA")
    526             || name.equalsIgnoreCase("SHA1withDSA")
    527             || name.equalsIgnoreCase("SHA/DSA")
    528             || name.equalsIgnoreCase("SHA1/DSA")
    529             || name.equalsIgnoreCase("DSAWithSHA1")
    530             || name.equalsIgnoreCase("DSS")
    531             || name.equalsIgnoreCase("SHA-1/DSA")) {
    532             return AlgorithmId.sha1WithDSA_oid;
    533         }
    534         if (name.equalsIgnoreCase("SHA1WithRSA")
    535             || name.equalsIgnoreCase("SHA1/RSA")) {
    536             return AlgorithmId.sha1WithRSAEncryption_oid;
    537         }
    538         if (name.equalsIgnoreCase("SHA1withECDSA")
    539                 || name.equalsIgnoreCase("ECDSA")) {
    540             return AlgorithmId.sha1WithECDSA_oid;
    541         }
    542         if (name.equalsIgnoreCase("SHA224withECDSA")) {
    543             return AlgorithmId.sha224WithECDSA_oid;
    544         }
    545         if (name.equalsIgnoreCase("SHA256withECDSA")) {
    546             return AlgorithmId.sha256WithECDSA_oid;
    547         }
    548         if (name.equalsIgnoreCase("SHA384withECDSA")) {
    549             return AlgorithmId.sha384WithECDSA_oid;
    550         }
    551         if (name.equalsIgnoreCase("SHA512withECDSA")) {
    552             return AlgorithmId.sha512WithECDSA_oid;
    553         }
    554 
    555         // See if any of the installed providers supply a mapping from
    556         // the given algorithm name to an OID string
    557         synchronized (oidTable) {
    558             reinitializeMappingTableLocked();
    559             return oidTable.get(name.toUpperCase(Locale.ENGLISH));
    560         }
    561     }
    562 
    563     private static void reinitializeMappingTableLocked() {
    564         // Android-changed: Update the table only if the OID changed. Also synchronize
    565         // on oidTable for thread safety.
    566         int currentVersion = Security.getVersion();
    567         if (initOidTableVersion != currentVersion) {
    568             Provider[] provs = Security.getProviders();
    569             for (int i=0; i<provs.length; i++) {
    570                 for (Enumeration<Object> enum_ = provs[i].keys();
    571                      enum_.hasMoreElements(); ) {
    572                     String alias = (String)enum_.nextElement();
    573                     String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH);
    574                     int index;
    575                     if (upperCaseAlias.startsWith("ALG.ALIAS")) {
    576                         if ((index=upperCaseAlias.indexOf("OID.", 0)) != -1) {
    577                             index += "OID.".length();
    578                             if (index == alias.length()) {
    579                                 // invalid alias entry
    580                                 break;
    581                             }
    582                             String oidString = alias.substring(index);
    583                             String stdAlgName = provs[i].getProperty(alias);
    584                             if (stdAlgName != null) {
    585                                 stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH);
    586 
    587                                 ObjectIdentifier oid = null;
    588                                 try {
    589                                     oid = new ObjectIdentifier(oidString);
    590                                 } catch (IOException e) {
    591                                     // Not an OID.
    592                                 }
    593 
    594                                 if (oid != null) {
    595                                     if (!oidTable.containsKey(stdAlgName)) {
    596                                         oidTable.put(stdAlgName, oid);
    597                                     }
    598                                     if (!nameTable.containsKey(oid)) {
    599                                         nameTable.put(oid, stdAlgName);
    600                                     }
    601                                 }
    602                             }
    603                         } else {
    604                             // Android-changed: If the alias isn't specified with an explicit
    605                             // "OID." in the name, we still attempt to parse it as one.
    606                             final int sep = alias.indexOf('.', "ALG.ALIAS.".length());
    607                             String suffix = alias.substring(sep + 1);
    608 
    609                             ObjectIdentifier oid = null;
    610                             try {
    611                                 oid = new ObjectIdentifier(suffix);
    612                             } catch (IOException e) {
    613                                 // Not an OID.
    614                             }
    615 
    616                             if (oid != null) {
    617                                 String stdAlgName = provs[i].getProperty(alias);
    618                                 if (stdAlgName != null) {
    619                                     stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH);
    620                                     if (!oidTable.containsKey(stdAlgName)) {
    621                                         oidTable.put(stdAlgName, oid);
    622                                     }
    623                                     if (!nameTable.containsKey(oid)) {
    624                                         nameTable.put(oid, stdAlgName);
    625                                     }
    626                                 }
    627                             }
    628                         }
    629                     }
    630                 }
    631             }
    632 
    633             initOidTableVersion = currentVersion;
    634         }
    635     }
    636 
    637     private static ObjectIdentifier oid(int ... values) {
    638         return ObjectIdentifier.newInternal(values);
    639     }
    640 
    641     private static int initOidTableVersion = -1;
    642     private static final Map<String,ObjectIdentifier> oidTable =
    643         new HashMap<String,ObjectIdentifier>(1);
    644     private static final Map<ObjectIdentifier,String> nameTable =
    645         new HashMap<ObjectIdentifier,String>();
    646 
    647     /*****************************************************************/
    648 
    649     /*
    650      * HASHING ALGORITHMS
    651      */
    652 
    653     /**
    654      * Algorithm ID for the MD2 Message Digest Algorthm, from RFC 1319.
    655      * OID = 1.2.840.113549.2.2
    656      */
    657     public static final ObjectIdentifier MD2_oid =
    658     ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 2});
    659 
    660     /**
    661      * Algorithm ID for the MD5 Message Digest Algorthm, from RFC 1321.
    662      * OID = 1.2.840.113549.2.5
    663      */
    664     public static final ObjectIdentifier MD5_oid =
    665     ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 5});
    666 
    667     /**
    668      * Algorithm ID for the SHA1 Message Digest Algorithm, from FIPS 180-1.
    669      * This is sometimes called "SHA", though that is often confusing since
    670      * many people refer to FIPS 180 (which has an error) as defining SHA.
    671      * OID = 1.3.14.3.2.26. Old SHA-0 OID: 1.3.14.3.2.18.
    672      */
    673     public static final ObjectIdentifier SHA_oid =
    674     ObjectIdentifier.newInternal(new int[] {1, 3, 14, 3, 2, 26});
    675 
    676     public static final ObjectIdentifier SHA256_oid =
    677     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 1});
    678 
    679     public static final ObjectIdentifier SHA384_oid =
    680     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 2});
    681 
    682     public static final ObjectIdentifier SHA512_oid =
    683     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 3});
    684 
    685     /*
    686      * COMMON PUBLIC KEY TYPES
    687      */
    688     private static final int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 };
    689     private static final int DH_PKIX_data[] = { 1, 2, 840, 10046, 2, 1 };
    690     private static final int DSA_OIW_data[] = { 1, 3, 14, 3, 2, 12 };
    691     private static final int DSA_PKIX_data[] = { 1, 2, 840, 10040, 4, 1 };
    692     private static final int RSA_data[] = { 2, 5, 8, 1, 1 };
    693     private static final int RSAEncryption_data[] =
    694                                  { 1, 2, 840, 113549, 1, 1, 1 };
    695 
    696     public static final ObjectIdentifier DH_oid;
    697     public static final ObjectIdentifier DH_PKIX_oid;
    698     public static final ObjectIdentifier DSA_oid;
    699     public static final ObjectIdentifier DSA_OIW_oid;
    700     public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1);
    701     public static final ObjectIdentifier RSA_oid;
    702     public static final ObjectIdentifier RSAEncryption_oid;
    703 
    704     /*
    705      * COMMON SIGNATURE ALGORITHMS
    706      */
    707     private static final int md2WithRSAEncryption_data[] =
    708                                        { 1, 2, 840, 113549, 1, 1, 2 };
    709     private static final int md5WithRSAEncryption_data[] =
    710                                        { 1, 2, 840, 113549, 1, 1, 4 };
    711     private static final int sha1WithRSAEncryption_data[] =
    712                                        { 1, 2, 840, 113549, 1, 1, 5 };
    713     private static final int sha1WithRSAEncryption_OIW_data[] =
    714                                        { 1, 3, 14, 3, 2, 29 };
    715     private static final int sha256WithRSAEncryption_data[] =
    716                                        { 1, 2, 840, 113549, 1, 1, 11 };
    717     private static final int sha384WithRSAEncryption_data[] =
    718                                        { 1, 2, 840, 113549, 1, 1, 12 };
    719     private static final int sha512WithRSAEncryption_data[] =
    720                                        { 1, 2, 840, 113549, 1, 1, 13 };
    721     private static final int shaWithDSA_OIW_data[] =
    722                                        { 1, 3, 14, 3, 2, 13 };
    723     private static final int sha1WithDSA_OIW_data[] =
    724                                        { 1, 3, 14, 3, 2, 27 };
    725     private static final int dsaWithSHA1_PKIX_data[] =
    726                                        { 1, 2, 840, 10040, 4, 3 };
    727 
    728     public static final ObjectIdentifier md2WithRSAEncryption_oid;
    729     public static final ObjectIdentifier md5WithRSAEncryption_oid;
    730     public static final ObjectIdentifier sha1WithRSAEncryption_oid;
    731     public static final ObjectIdentifier sha1WithRSAEncryption_OIW_oid;
    732     public static final ObjectIdentifier sha256WithRSAEncryption_oid;
    733     public static final ObjectIdentifier sha384WithRSAEncryption_oid;
    734     public static final ObjectIdentifier sha512WithRSAEncryption_oid;
    735     public static final ObjectIdentifier shaWithDSA_OIW_oid;
    736     public static final ObjectIdentifier sha1WithDSA_OIW_oid;
    737     public static final ObjectIdentifier sha1WithDSA_oid;
    738 
    739     public static final ObjectIdentifier sha1WithECDSA_oid =
    740                                             oid(1, 2, 840, 10045, 4, 1);
    741     public static final ObjectIdentifier sha224WithECDSA_oid =
    742                                             oid(1, 2, 840, 10045, 4, 3, 1);
    743     public static final ObjectIdentifier sha256WithECDSA_oid =
    744                                             oid(1, 2, 840, 10045, 4, 3, 2);
    745     public static final ObjectIdentifier sha384WithECDSA_oid =
    746                                             oid(1, 2, 840, 10045, 4, 3, 3);
    747     public static final ObjectIdentifier sha512WithECDSA_oid =
    748                                             oid(1, 2, 840, 10045, 4, 3, 4);
    749     public static final ObjectIdentifier specifiedWithECDSA_oid =
    750                                             oid(1, 2, 840, 10045, 4, 3);
    751 
    752     /**
    753      * Algorithm ID for the PBE encryption algorithms from PKCS#5 and
    754      * PKCS#12.
    755      */
    756     public static final ObjectIdentifier pbeWithMD5AndDES_oid =
    757         ObjectIdentifier.newInternal(new int[]{1, 2, 840, 113549, 1, 5, 3});
    758     public static final ObjectIdentifier pbeWithMD5AndRC2_oid =
    759         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 6});
    760     public static final ObjectIdentifier pbeWithSHA1AndDES_oid =
    761         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 10});
    762     public static final ObjectIdentifier pbeWithSHA1AndRC2_oid =
    763         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 11});
    764     public static ObjectIdentifier pbeWithSHA1AndDESede_oid =
    765         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 3});
    766     public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid =
    767         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6});
    768 
    769 
    770     static {
    771     /*
    772      * Note the preferred OIDs are named simply with no "OIW" or
    773      * "PKIX" in them, even though they may point to data from these
    774      * specs; e.g. SHA_oid, DH_oid, DSA_oid, SHA1WithDSA_oid...
    775      */
    776     /**
    777      * Algorithm ID for Diffie Hellman Key agreement, from PKCS #3.
    778      * Parameters include public values P and G, and may optionally specify
    779      * the length of the private key X.  Alternatively, algorithm parameters
    780      * may be derived from another source such as a Certificate Authority's
    781      * certificate.
    782      * OID = 1.2.840.113549.1.3.1
    783      */
    784         DH_oid = ObjectIdentifier.newInternal(DH_data);
    785 
    786     /**
    787      * Algorithm ID for the Diffie Hellman Key Agreement (DH), from RFC 3279.
    788      * Parameters may include public values P and G.
    789      * OID = 1.2.840.10046.2.1
    790      */
    791         DH_PKIX_oid = ObjectIdentifier.newInternal(DH_PKIX_data);
    792 
    793     /**
    794      * Algorithm ID for the Digital Signing Algorithm (DSA), from the
    795      * NIST OIW Stable Agreements part 12.
    796      * Parameters may include public values P, Q, and G; or these may be
    797      * derived from
    798      * another source such as a Certificate Authority's certificate.
    799      * OID = 1.3.14.3.2.12
    800      */
    801         DSA_OIW_oid = ObjectIdentifier.newInternal(DSA_OIW_data);
    802 
    803     /**
    804      * Algorithm ID for the Digital Signing Algorithm (DSA), from RFC 3279.
    805      * Parameters may include public values P, Q, and G; or these may be
    806      * derived from another source such as a Certificate Authority's
    807      * certificate.
    808      * OID = 1.2.840.10040.4.1
    809      */
    810         DSA_oid = ObjectIdentifier.newInternal(DSA_PKIX_data);
    811 
    812     /**
    813      * Algorithm ID for RSA keys used for any purpose, as defined in X.509.
    814      * The algorithm parameter is a single value, the number of bits in the
    815      * public modulus.
    816      * OID = 2.5.8.1.1
    817      */
    818         RSA_oid = ObjectIdentifier.newInternal(RSA_data);
    819 
    820     /**
    821      * Algorithm ID for RSA keys used with RSA encryption, as defined
    822      * in PKCS #1.  There are no parameters associated with this algorithm.
    823      * OID = 1.2.840.113549.1.1.1
    824      */
    825         RSAEncryption_oid = ObjectIdentifier.newInternal(RSAEncryption_data);
    826 
    827     /**
    828      * Identifies a signing algorithm where an MD2 digest is encrypted
    829      * using an RSA private key; defined in PKCS #1.  Use of this
    830      * signing algorithm is discouraged due to MD2 vulnerabilities.
    831      * OID = 1.2.840.113549.1.1.2
    832      */
    833         md2WithRSAEncryption_oid =
    834             ObjectIdentifier.newInternal(md2WithRSAEncryption_data);
    835 
    836     /**
    837      * Identifies a signing algorithm where an MD5 digest is
    838      * encrypted using an RSA private key; defined in PKCS #1.
    839      * OID = 1.2.840.113549.1.1.4
    840      */
    841         md5WithRSAEncryption_oid =
    842             ObjectIdentifier.newInternal(md5WithRSAEncryption_data);
    843 
    844     /**
    845      * Identifies a signing algorithm where a SHA1 digest is
    846      * encrypted using an RSA private key; defined by RSA DSI.
    847      * OID = 1.2.840.113549.1.1.5
    848      */
    849         sha1WithRSAEncryption_oid =
    850             ObjectIdentifier.newInternal(sha1WithRSAEncryption_data);
    851 
    852     /**
    853      * Identifies a signing algorithm where a SHA1 digest is
    854      * encrypted using an RSA private key; defined in NIST OIW.
    855      * OID = 1.3.14.3.2.29
    856      */
    857         sha1WithRSAEncryption_OIW_oid =
    858             ObjectIdentifier.newInternal(sha1WithRSAEncryption_OIW_data);
    859 
    860     /**
    861      * Identifies a signing algorithm where a SHA256 digest is
    862      * encrypted using an RSA private key; defined by PKCS #1.
    863      * OID = 1.2.840.113549.1.1.11
    864      */
    865         sha256WithRSAEncryption_oid =
    866             ObjectIdentifier.newInternal(sha256WithRSAEncryption_data);
    867 
    868     /**
    869      * Identifies a signing algorithm where a SHA384 digest is
    870      * encrypted using an RSA private key; defined by PKCS #1.
    871      * OID = 1.2.840.113549.1.1.12
    872      */
    873         sha384WithRSAEncryption_oid =
    874             ObjectIdentifier.newInternal(sha384WithRSAEncryption_data);
    875 
    876     /**
    877      * Identifies a signing algorithm where a SHA512 digest is
    878      * encrypted using an RSA private key; defined by PKCS #1.
    879      * OID = 1.2.840.113549.1.1.13
    880      */
    881         sha512WithRSAEncryption_oid =
    882             ObjectIdentifier.newInternal(sha512WithRSAEncryption_data);
    883 
    884     /**
    885      * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
    886      * SHA digest is signed using the Digital Signing Algorithm (DSA).
    887      * This should not be used.
    888      * OID = 1.3.14.3.2.13
    889      */
    890         shaWithDSA_OIW_oid = ObjectIdentifier.newInternal(shaWithDSA_OIW_data);
    891 
    892     /**
    893      * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
    894      * SHA1 digest is signed using the Digital Signing Algorithm (DSA).
    895      * OID = 1.3.14.3.2.27
    896      */
    897         sha1WithDSA_OIW_oid = ObjectIdentifier.newInternal(sha1WithDSA_OIW_data);
    898 
    899     /**
    900      * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
    901      * SHA1 digest is signed using the Digital Signing Algorithm (DSA).
    902      * OID = 1.2.840.10040.4.3
    903      */
    904         sha1WithDSA_oid = ObjectIdentifier.newInternal(dsaWithSHA1_PKIX_data);
    905 
    906         nameTable.put(MD5_oid, "MD5");
    907         nameTable.put(MD2_oid, "MD2");
    908         nameTable.put(SHA_oid, "SHA");
    909         nameTable.put(SHA256_oid, "SHA256");
    910         nameTable.put(SHA384_oid, "SHA384");
    911         nameTable.put(SHA512_oid, "SHA512");
    912         nameTable.put(RSAEncryption_oid, "RSA");
    913         nameTable.put(RSA_oid, "RSA");
    914         nameTable.put(DH_oid, "Diffie-Hellman");
    915         nameTable.put(DH_PKIX_oid, "Diffie-Hellman");
    916         nameTable.put(DSA_oid, "DSA");
    917         nameTable.put(DSA_OIW_oid, "DSA");
    918         nameTable.put(EC_oid, "EC");
    919         nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA");
    920         nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA");
    921         nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA");
    922         nameTable.put(sha384WithECDSA_oid, "SHA384withECDSA");
    923         nameTable.put(sha512WithECDSA_oid, "SHA512withECDSA");
    924         nameTable.put(md5WithRSAEncryption_oid, "MD5withRSA");
    925         nameTable.put(md2WithRSAEncryption_oid, "MD2withRSA");
    926         nameTable.put(sha1WithDSA_oid, "SHA1withDSA");
    927         nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA");
    928         nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA");
    929         nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA");
    930         nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA");
    931         nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA");
    932         nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA");
    933         nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA");
    934         nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES");
    935         nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2");
    936         nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES");
    937         nameTable.put(pbeWithSHA1AndRC2_oid, "PBEWithSHA1AndRC2");
    938         nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede");
    939         nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40");
    940     }
    941 
    942     /**
    943      * Creates a signature algorithm name from a digest algorithm
    944      * name and a encryption algorithm name.
    945      */
    946     public static String makeSigAlg(String digAlg, String encAlg) {
    947         digAlg = digAlg.replace("-", "").toUpperCase(Locale.ENGLISH);
    948         if (digAlg.equalsIgnoreCase("SHA")) digAlg = "SHA1";
    949 
    950         encAlg = encAlg.toUpperCase(Locale.ENGLISH);
    951         if (encAlg.equals("EC")) encAlg = "ECDSA";
    952 
    953         return digAlg + "with" + encAlg;
    954     }
    955 
    956     /**
    957      * Extracts the encryption algorithm name from a signature
    958      * algorithm name.
    959       */
    960     public static String getEncAlgFromSigAlg(String signatureAlgorithm) {
    961         signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH);
    962         int with = signatureAlgorithm.indexOf("WITH");
    963         String keyAlgorithm = null;
    964         if (with > 0) {
    965             int and = signatureAlgorithm.indexOf("AND", with + 4);
    966             if (and > 0) {
    967                 keyAlgorithm = signatureAlgorithm.substring(with + 4, and);
    968             } else {
    969                 keyAlgorithm = signatureAlgorithm.substring(with + 4);
    970             }
    971             if (keyAlgorithm.equalsIgnoreCase("ECDSA")) {
    972                 keyAlgorithm = "EC";
    973             }
    974         }
    975         return keyAlgorithm;
    976     }
    977 
    978     /**
    979      * Extracts the digest algorithm name from a signature
    980      * algorithm name.
    981       */
    982     public static String getDigAlgFromSigAlg(String signatureAlgorithm) {
    983         signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH);
    984         int with = signatureAlgorithm.indexOf("WITH");
    985         if (with > 0) {
    986             return signatureAlgorithm.substring(0, with);
    987         }
    988         return null;
    989     }
    990 }
    991