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