• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
60 public class AlgorithmId implements Serializable, DerEncoder {
61 
62     /** use serialVersionUID from JDK 1.1. for interoperability */
63     private static final long serialVersionUID = 7205873507486557157L;
64 
65     /**
66      * The object identitifer being used for this algorithm.
67      */
68     private ObjectIdentifier algid;
69 
70     // The (parsed) parameters
71     private AlgorithmParameters algParams;
72     private boolean constructedFromDer = true;
73 
74     /**
75      * Parameters for this algorithm.  These are stored in unparsed
76      * DER-encoded form; subclasses can be made to automaticaly parse
77      * them so there is fast access to these parameters.
78      */
79     protected DerValue          params;
80 
81 
82     /**
83      * Constructs an algorithm ID which will be initialized
84      * separately, for example by deserialization.
85      * @deprecated use one of the other constructors.
86      */
87     @Deprecated
AlgorithmId()88     public AlgorithmId() { }
89 
90     /**
91      * Constructs a parameterless algorithm ID.
92      *
93      * @param oid the identifier for the algorithm
94      */
AlgorithmId(ObjectIdentifier oid)95     public AlgorithmId(ObjectIdentifier oid) {
96         algid = oid;
97     }
98 
99     /**
100      * Constructs an algorithm ID with algorithm parameters.
101      *
102      * @param oid the identifier for the algorithm.
103      * @param algparams the associated algorithm parameters.
104      */
AlgorithmId(ObjectIdentifier oid, AlgorithmParameters algparams)105     public AlgorithmId(ObjectIdentifier oid, AlgorithmParameters algparams) {
106         algid = oid;
107         algParams = algparams;
108         constructedFromDer = false;
109     }
110 
AlgorithmId(ObjectIdentifier oid, DerValue params)111     private AlgorithmId(ObjectIdentifier oid, DerValue params)
112             throws IOException {
113         this.algid = oid;
114         this.params = params;
115         if (this.params != null) {
116             decodeParams();
117         }
118     }
119 
decodeParams()120     protected void decodeParams() throws IOException {
121         String algidString = algid.toString();
122         try {
123             algParams = AlgorithmParameters.getInstance(algidString);
124         } catch (NoSuchAlgorithmException e) {
125             /*
126              * This algorithm parameter type is not supported, so we cannot
127              * parse the parameters.
128              */
129             algParams = null;
130             return;
131         }
132 
133         // Decode (parse) the parameters
134         algParams.init(params.toByteArray());
135     }
136 
137     /**
138      * Marshal a DER-encoded "AlgorithmID" sequence on the DER stream.
139      *
140      * @param out {@link DerInputStream} to write encoded data to
141      * @throws IOException on encoding error
142      */
encode(DerOutputStream out)143     public final void encode(DerOutputStream out) throws IOException {
144         derEncode(out);
145     }
146 
147     /**
148      * DER encode this object onto an output stream.
149      * Implements the <code>DerEncoder</code> interface.
150      *
151      * @param out
152      * the output stream on which to write the DER encoding.
153      *
154      * @exception IOException on encoding error.
155      */
derEncode(OutputStream out)156     public void derEncode (OutputStream out) throws IOException {
157         DerOutputStream bytes = new DerOutputStream();
158         DerOutputStream tmp = new DerOutputStream();
159 
160         bytes.putOID(algid);
161         // Setup params from algParams since no DER encoding is given
162         if (constructedFromDer == false) {
163             if (algParams != null) {
164                 params = new DerValue(algParams.getEncoded());
165             } else {
166                 params = null;
167             }
168         }
169         if (params == null) {
170             // Changes backed out for compatibility with Solaris
171 
172             // Several AlgorithmId should omit the whole parameter part when
173             // it's NULL. They are ---
174             // rfc3370 2.1: Implementations SHOULD generate SHA-1
175             // AlgorithmIdentifiers with absent parameters.
176             // rfc3447 C1: When id-sha1, id-sha224, id-sha256, id-sha384 and
177             // id-sha512 are used in an AlgorithmIdentifier the parameters
178             // (which are optional) SHOULD be omitted.
179             // rfc3279 2.3.2: The id-dsa algorithm syntax includes optional
180             // domain parameters... When omitted, the parameters component
181             // MUST be omitted entirely
182             // rfc3370 3.1: When the id-dsa-with-sha1 algorithm identifier
183             // is used, the AlgorithmIdentifier parameters field MUST be absent.
184             /*if (
185                 algid.equals((Object)SHA_oid) ||
186                 algid.equals((Object)SHA224_oid) ||
187                 algid.equals((Object)SHA256_oid) ||
188                 algid.equals((Object)SHA384_oid) ||
189                 algid.equals((Object)SHA512_oid) ||
190                 algid.equals((Object)DSA_oid) ||
191                 algid.equals((Object)sha1WithDSA_oid)) {
192                 ; // no parameter part encoded
193             } else {
194                 bytes.putNull();
195             }*/
196             bytes.putNull();
197         } else {
198             bytes.putDerValue(params);
199         }
200         tmp.write(DerValue.tag_Sequence, bytes);
201         out.write(tmp.toByteArray());
202     }
203 
204 
205     /**
206      * Returns the DER-encoded X.509 AlgorithmId as a byte array.
207      */
encode()208     public final byte[] encode() throws IOException {
209         DerOutputStream out = new DerOutputStream();
210         derEncode(out);
211         return out.toByteArray();
212     }
213 
214     /**
215      * Returns the ISO OID for this algorithm.  This is usually converted
216      * to a string and used as part of an algorithm name, for example
217      * "OID.1.3.14.3.2.13" style notation.  Use the <code>getName</code>
218      * call when you do not need to ensure cross-system portability
219      * of algorithm names, or need a user friendly name.
220      */
getOID()221     public final ObjectIdentifier getOID () {
222         return algid;
223     }
224 
225     /**
226      * Returns a name for the algorithm which may be more intelligible
227      * to humans than the algorithm's OID, but which won't necessarily
228      * be comprehensible on other systems.  For example, this might
229      * return a name such as "MD5withRSA" for a signature algorithm on
230      * some systems.  It also returns names like "OID.1.2.3.4", when
231      * no particular name for the algorithm is known.
232      *
233      * @return name of the algorithm
234      */
235     @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
getName()236     public String getName() {
237         String algName = nameTable.get(algid);
238         if (algName != null) {
239             return algName;
240         }
241         if ((params != null) && algid.equals((Object)specifiedWithECDSA_oid)) {
242             try {
243                 AlgorithmId paramsId =
244                         AlgorithmId.parse(new DerValue(getEncodedParams()));
245                 String paramsName = paramsId.getName();
246                 algName = makeSigAlg(paramsName, "EC");
247             } catch (IOException e) {
248                 // ignore
249             }
250         }
251 
252         // BEGIN Android-added: Update algorithm mapping tables for names when OID is used
253         // Try to update the name <-> OID mapping table.
254         synchronized (oidTable) {
255             reinitializeMappingTableLocked();
256             algName = nameTable.get(algid);
257         }
258         // END Android-added: Update algorithm mapping tables for names when OID is used
259 
260         return (algName == null) ? algid.toString() : algName;
261     }
262 
getParameters()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      */
getEncodedParams()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      */
equals(AlgorithmId other)281     public boolean equals(AlgorithmId other) {
282         boolean paramsEqual =
283           (params == null ? other.params == null : params.equals(other.params));
284         return (algid.equals((Object)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      */
equals(Object other)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      */
equals(ObjectIdentifier id)311     public final boolean equals(ObjectIdentifier id) {
312         return algid.equals((Object)id);
313     }
314 
315     /**
316      * Returns a hashcode for this AlgorithmId.
317      *
318      * @return a hashcode for this AlgorithmId.
319      */
hashCode()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      */
paramsToString()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      */
toString()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      */
parse(DerValue val)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
getAlgorithmId(String algname)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      */
get(String algname)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      */
get(AlgorithmParameters algparams)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      */
algOID(String name)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         if (name.equalsIgnoreCase("SHA-224") ||
500             name.equalsIgnoreCase("SHA224")) {
501             return AlgorithmId.SHA224_oid;
502         }
503 
504         // Various public key algorithms
505         if (name.equalsIgnoreCase("RSA")) {
506             return AlgorithmId.RSAEncryption_oid;
507         }
508         if (name.equalsIgnoreCase("Diffie-Hellman")
509             || name.equalsIgnoreCase("DH")) {
510             return AlgorithmId.DH_oid;
511         }
512         if (name.equalsIgnoreCase("DSA")) {
513             return AlgorithmId.DSA_oid;
514         }
515         if (name.equalsIgnoreCase("EC")) {
516             return EC_oid;
517         }
518         if (name.equalsIgnoreCase("ECDH")) {
519             return AlgorithmId.ECDH_oid;
520         }
521 
522         // Secret key algorithms
523         if (name.equalsIgnoreCase("AES")) {
524             return AlgorithmId.AES_oid;
525         }
526 
527         // Common signature types
528         if (name.equalsIgnoreCase("MD5withRSA")
529             || name.equalsIgnoreCase("MD5/RSA")) {
530             return AlgorithmId.md5WithRSAEncryption_oid;
531         }
532         if (name.equalsIgnoreCase("MD2withRSA")
533             || name.equalsIgnoreCase("MD2/RSA")) {
534             return AlgorithmId.md2WithRSAEncryption_oid;
535         }
536         if (name.equalsIgnoreCase("SHAwithDSA")
537             || name.equalsIgnoreCase("SHA1withDSA")
538             || name.equalsIgnoreCase("SHA/DSA")
539             || name.equalsIgnoreCase("SHA1/DSA")
540             || name.equalsIgnoreCase("DSAWithSHA1")
541             || name.equalsIgnoreCase("DSS")
542             || name.equalsIgnoreCase("SHA-1/DSA")) {
543             return AlgorithmId.sha1WithDSA_oid;
544         }
545         if (name.equalsIgnoreCase("SHA224WithDSA")) {
546             return AlgorithmId.sha224WithDSA_oid;
547         }
548         if (name.equalsIgnoreCase("SHA256WithDSA")) {
549             return AlgorithmId.sha256WithDSA_oid;
550         }
551         if (name.equalsIgnoreCase("SHA1WithRSA")
552             || name.equalsIgnoreCase("SHA1/RSA")) {
553             return AlgorithmId.sha1WithRSAEncryption_oid;
554         }
555         if (name.equalsIgnoreCase("SHA1withECDSA")
556                 || name.equalsIgnoreCase("ECDSA")) {
557             return AlgorithmId.sha1WithECDSA_oid;
558         }
559         if (name.equalsIgnoreCase("SHA224withECDSA")) {
560             return AlgorithmId.sha224WithECDSA_oid;
561         }
562         if (name.equalsIgnoreCase("SHA256withECDSA")) {
563             return AlgorithmId.sha256WithECDSA_oid;
564         }
565         if (name.equalsIgnoreCase("SHA384withECDSA")) {
566             return AlgorithmId.sha384WithECDSA_oid;
567         }
568         if (name.equalsIgnoreCase("SHA512withECDSA")) {
569             return AlgorithmId.sha512WithECDSA_oid;
570         }
571 
572         // See if any of the installed providers supply a mapping from
573         // the given algorithm name to an OID string
574         // BEGIN Android-changed: Update algorithm mapping tables for names when OID is used
575         synchronized (oidTable) {
576             reinitializeMappingTableLocked();
577             return oidTable.get(name.toUpperCase(Locale.ENGLISH));
578         }
579     }
580 
reinitializeMappingTableLocked()581     private static void reinitializeMappingTableLocked() {
582         // Android-changed: Update the table only if the OID changed. Also synchronize
583         // on oidTable for thread safety.
584         int currentVersion = Security.getVersion();
585         if (initOidTableVersion != currentVersion) {
586             Provider[] provs = Security.getProviders();
587             for (int i=0; i<provs.length; i++) {
588                 for (Enumeration<Object> enum_ = provs[i].keys();
589                      enum_.hasMoreElements(); ) {
590                     String alias = (String)enum_.nextElement();
591                     String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH);
592                     int index;
593                     if (upperCaseAlias.startsWith("ALG.ALIAS")) {
594                         if ((index=upperCaseAlias.indexOf("OID.", 0)) != -1) {
595                             index += "OID.".length();
596                             if (index == alias.length()) {
597                                 // invalid alias entry
598                                 break;
599                             }
600                             String oidString = alias.substring(index);
601                             String stdAlgName = provs[i].getProperty(alias);
602                             if (stdAlgName != null) {
603                                 stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH);
604 
605                                 ObjectIdentifier oid = null;
606                                 try {
607                                     oid = new ObjectIdentifier(oidString);
608                                 } catch (IOException e) {
609                                     // Not an OID.
610                                 }
611 
612                                 if (oid != null) {
613                                     if (!oidTable.containsKey(stdAlgName)) {
614                                         oidTable.put(stdAlgName, oid);
615                                     }
616                                     if (!nameTable.containsKey(oid)) {
617                                         nameTable.put(oid, stdAlgName);
618                                     }
619                                 }
620                             }
621                         } else {
622                             // Android-changed: If the alias isn't specified with an explicit
623                             // "OID." in the name, we still attempt to parse it as one.
624                             final int sep = alias.indexOf('.', "ALG.ALIAS.".length());
625                             String suffix = alias.substring(sep + 1);
626 
627                             ObjectIdentifier oid = null;
628                             try {
629                                 oid = new ObjectIdentifier(suffix);
630                             } catch (IOException e) {
631                                 // Not an OID.
632                             }
633 
634                             if (oid != null) {
635                                 String stdAlgName = provs[i].getProperty(alias);
636                                 if (stdAlgName != null) {
637                                     stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH);
638                                     if (!oidTable.containsKey(stdAlgName)) {
639                                         oidTable.put(stdAlgName, oid);
640                                     }
641                                     if (!nameTable.containsKey(oid)) {
642                                         nameTable.put(oid, stdAlgName);
643                                     }
644                                 }
645                             }
646                         }
647                     }
648                 }
649             }
650 
651             initOidTableVersion = currentVersion;
652         }
653     // END Android-changed: Update algorithm mapping tables for names when OID is used
654     }
655 
oid(int ... values)656     private static ObjectIdentifier oid(int ... values) {
657         return ObjectIdentifier.newInternal(values);
658     }
659 
660     // BEGIN Android-changed: Parsing mapping as OID even if "OID." prefix isn't specified
661     private static int initOidTableVersion = -1;
662     private static final Map<String,ObjectIdentifier> oidTable =
663         new HashMap<String,ObjectIdentifier>(1);
664     private static final Map<ObjectIdentifier,String> nameTable =
665         new HashMap<ObjectIdentifier,String>();
666     // END Android-changed: Parsing mapping as OID even if "OID." prefix isn't specified
667 
668     /*****************************************************************/
669 
670     /*
671      * HASHING ALGORITHMS
672      */
673 
674     /**
675      * Algorithm ID for the MD2 Message Digest Algorthm, from RFC 1319.
676      * OID = 1.2.840.113549.2.2
677      */
678     public static final ObjectIdentifier MD2_oid =
679     ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 2});
680 
681     /**
682      * Algorithm ID for the MD5 Message Digest Algorthm, from RFC 1321.
683      * OID = 1.2.840.113549.2.5
684      */
685     public static final ObjectIdentifier MD5_oid =
686     ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 5});
687 
688     /**
689      * Algorithm ID for the SHA1 Message Digest Algorithm, from FIPS 180-1.
690      * This is sometimes called "SHA", though that is often confusing since
691      * many people refer to FIPS 180 (which has an error) as defining SHA.
692      * OID = 1.3.14.3.2.26. Old SHA-0 OID: 1.3.14.3.2.18.
693      */
694     public static final ObjectIdentifier SHA_oid =
695     ObjectIdentifier.newInternal(new int[] {1, 3, 14, 3, 2, 26});
696 
697     public static final ObjectIdentifier SHA224_oid =
698     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 4});
699 
700     public static final ObjectIdentifier SHA256_oid =
701     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 1});
702 
703     public static final ObjectIdentifier SHA384_oid =
704     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 2});
705 
706     public static final ObjectIdentifier SHA512_oid =
707     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 3});
708 
709     /*
710      * COMMON PUBLIC KEY TYPES
711      */
712     private static final int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 };
713     private static final int DH_PKIX_data[] = { 1, 2, 840, 10046, 2, 1 };
714     private static final int DSA_OIW_data[] = { 1, 3, 14, 3, 2, 12 };
715     private static final int DSA_PKIX_data[] = { 1, 2, 840, 10040, 4, 1 };
716     private static final int RSA_data[] = { 2, 5, 8, 1, 1 };
717     private static final int RSAEncryption_data[] =
718                                  { 1, 2, 840, 113549, 1, 1, 1 };
719 
720     public static final ObjectIdentifier DH_oid;
721     public static final ObjectIdentifier DH_PKIX_oid;
722     public static final ObjectIdentifier DSA_oid;
723     public static final ObjectIdentifier DSA_OIW_oid;
724     public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1);
725     public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12);
726     public static final ObjectIdentifier RSA_oid;
727     public static final ObjectIdentifier RSAEncryption_oid;
728 
729     /*
730      * COMMON SECRET KEY TYPES
731      */
732     public static final ObjectIdentifier AES_oid =
733                                             oid(2, 16, 840, 1, 101, 3, 4, 1);
734 
735     /*
736      * COMMON SIGNATURE ALGORITHMS
737      */
738     private static final int md2WithRSAEncryption_data[] =
739                                        { 1, 2, 840, 113549, 1, 1, 2 };
740     private static final int md5WithRSAEncryption_data[] =
741                                        { 1, 2, 840, 113549, 1, 1, 4 };
742     private static final int sha1WithRSAEncryption_data[] =
743                                        { 1, 2, 840, 113549, 1, 1, 5 };
744     private static final int sha1WithRSAEncryption_OIW_data[] =
745                                        { 1, 3, 14, 3, 2, 29 };
746     private static final int sha224WithRSAEncryption_data[] =
747                                        { 1, 2, 840, 113549, 1, 1, 14 };
748     private static final int sha256WithRSAEncryption_data[] =
749                                        { 1, 2, 840, 113549, 1, 1, 11 };
750     private static final int sha384WithRSAEncryption_data[] =
751                                        { 1, 2, 840, 113549, 1, 1, 12 };
752     private static final int sha512WithRSAEncryption_data[] =
753                                        { 1, 2, 840, 113549, 1, 1, 13 };
754     private static final int shaWithDSA_OIW_data[] =
755                                        { 1, 3, 14, 3, 2, 13 };
756     private static final int sha1WithDSA_OIW_data[] =
757                                        { 1, 3, 14, 3, 2, 27 };
758     private static final int dsaWithSHA1_PKIX_data[] =
759                                        { 1, 2, 840, 10040, 4, 3 };
760 
761     public static final ObjectIdentifier md2WithRSAEncryption_oid;
762     public static final ObjectIdentifier md5WithRSAEncryption_oid;
763     public static final ObjectIdentifier sha1WithRSAEncryption_oid;
764     public static final ObjectIdentifier sha1WithRSAEncryption_OIW_oid;
765     public static final ObjectIdentifier sha224WithRSAEncryption_oid;
766     public static final ObjectIdentifier sha256WithRSAEncryption_oid;
767     public static final ObjectIdentifier sha384WithRSAEncryption_oid;
768     public static final ObjectIdentifier sha512WithRSAEncryption_oid;
769     public static final ObjectIdentifier shaWithDSA_OIW_oid;
770     public static final ObjectIdentifier sha1WithDSA_OIW_oid;
771     public static final ObjectIdentifier sha1WithDSA_oid;
772     public static final ObjectIdentifier sha224WithDSA_oid =
773                                             oid(2, 16, 840, 1, 101, 3, 4, 3, 1);
774     public static final ObjectIdentifier sha256WithDSA_oid =
775                                             oid(2, 16, 840, 1, 101, 3, 4, 3, 2);
776 
777     public static final ObjectIdentifier sha1WithECDSA_oid =
778                                             oid(1, 2, 840, 10045, 4, 1);
779     public static final ObjectIdentifier sha224WithECDSA_oid =
780                                             oid(1, 2, 840, 10045, 4, 3, 1);
781     public static final ObjectIdentifier sha256WithECDSA_oid =
782                                             oid(1, 2, 840, 10045, 4, 3, 2);
783     public static final ObjectIdentifier sha384WithECDSA_oid =
784                                             oid(1, 2, 840, 10045, 4, 3, 3);
785     public static final ObjectIdentifier sha512WithECDSA_oid =
786                                             oid(1, 2, 840, 10045, 4, 3, 4);
787     public static final ObjectIdentifier specifiedWithECDSA_oid =
788                                             oid(1, 2, 840, 10045, 4, 3);
789 
790     /**
791      * Algorithm ID for the PBE encryption algorithms from PKCS#5 and
792      * PKCS#12.
793      */
794     public static final ObjectIdentifier pbeWithMD5AndDES_oid =
795         ObjectIdentifier.newInternal(new int[]{1, 2, 840, 113549, 1, 5, 3});
796     public static final ObjectIdentifier pbeWithMD5AndRC2_oid =
797         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 6});
798     public static final ObjectIdentifier pbeWithSHA1AndDES_oid =
799         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 10});
800     public static final ObjectIdentifier pbeWithSHA1AndRC2_oid =
801         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 11});
802     public static ObjectIdentifier pbeWithSHA1AndDESede_oid =
803         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 3});
804     public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid =
805         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6});
806 
807     static {
808     /*
809      * Note the preferred OIDs are named simply with no "OIW" or
810      * "PKIX" in them, even though they may point to data from these
811      * specs; e.g. SHA_oid, DH_oid, DSA_oid, SHA1WithDSA_oid...
812      */
813     /**
814      * Algorithm ID for Diffie Hellman Key agreement, from PKCS #3.
815      * Parameters include public values P and G, and may optionally specify
816      * the length of the private key X.  Alternatively, algorithm parameters
817      * may be derived from another source such as a Certificate Authority's
818      * certificate.
819      * OID = 1.2.840.113549.1.3.1
820      */
821         DH_oid = ObjectIdentifier.newInternal(DH_data);
822 
823     /**
824      * Algorithm ID for the Diffie Hellman Key Agreement (DH), from RFC 3279.
825      * Parameters may include public values P and G.
826      * OID = 1.2.840.10046.2.1
827      */
828         DH_PKIX_oid = ObjectIdentifier.newInternal(DH_PKIX_data);
829 
830     /**
831      * Algorithm ID for the Digital Signing Algorithm (DSA), from the
832      * NIST OIW Stable Agreements part 12.
833      * Parameters may include public values P, Q, and G; or these may be
834      * derived from
835      * another source such as a Certificate Authority's certificate.
836      * OID = 1.3.14.3.2.12
837      */
838         DSA_OIW_oid = ObjectIdentifier.newInternal(DSA_OIW_data);
839 
840     /**
841      * Algorithm ID for the Digital Signing Algorithm (DSA), from RFC 3279.
842      * Parameters may include public values P, Q, and G; or these may be
843      * derived from another source such as a Certificate Authority's
844      * certificate.
845      * OID = 1.2.840.10040.4.1
846      */
847         DSA_oid = ObjectIdentifier.newInternal(DSA_PKIX_data);
848 
849     /**
850      * Algorithm ID for RSA keys used for any purpose, as defined in X.509.
851      * The algorithm parameter is a single value, the number of bits in the
852      * public modulus.
853      * OID = 2.5.8.1.1
854      */
855         RSA_oid = ObjectIdentifier.newInternal(RSA_data);
856 
857     /**
858      * Algorithm ID for RSA keys used with RSA encryption, as defined
859      * in PKCS #1.  There are no parameters associated with this algorithm.
860      * OID = 1.2.840.113549.1.1.1
861      */
862         RSAEncryption_oid = ObjectIdentifier.newInternal(RSAEncryption_data);
863 
864     /**
865      * Identifies a signing algorithm where an MD2 digest is encrypted
866      * using an RSA private key; defined in PKCS #1.  Use of this
867      * signing algorithm is discouraged due to MD2 vulnerabilities.
868      * OID = 1.2.840.113549.1.1.2
869      */
870         md2WithRSAEncryption_oid =
871             ObjectIdentifier.newInternal(md2WithRSAEncryption_data);
872 
873     /**
874      * Identifies a signing algorithm where an MD5 digest is
875      * encrypted using an RSA private key; defined in PKCS #1.
876      * OID = 1.2.840.113549.1.1.4
877      */
878         md5WithRSAEncryption_oid =
879             ObjectIdentifier.newInternal(md5WithRSAEncryption_data);
880 
881     /**
882      * Identifies a signing algorithm where a SHA1 digest is
883      * encrypted using an RSA private key; defined by RSA DSI.
884      * OID = 1.2.840.113549.1.1.5
885      */
886         sha1WithRSAEncryption_oid =
887             ObjectIdentifier.newInternal(sha1WithRSAEncryption_data);
888 
889     /**
890      * Identifies a signing algorithm where a SHA1 digest is
891      * encrypted using an RSA private key; defined in NIST OIW.
892      * OID = 1.3.14.3.2.29
893      */
894         sha1WithRSAEncryption_OIW_oid =
895             ObjectIdentifier.newInternal(sha1WithRSAEncryption_OIW_data);
896 
897     /**
898      * Identifies a signing algorithm where a SHA224 digest is
899      * encrypted using an RSA private key; defined by PKCS #1.
900      * OID = 1.2.840.113549.1.1.14
901      */
902         sha224WithRSAEncryption_oid =
903             ObjectIdentifier.newInternal(sha224WithRSAEncryption_data);
904 
905     /**
906      * Identifies a signing algorithm where a SHA256 digest is
907      * encrypted using an RSA private key; defined by PKCS #1.
908      * OID = 1.2.840.113549.1.1.11
909      */
910         sha256WithRSAEncryption_oid =
911             ObjectIdentifier.newInternal(sha256WithRSAEncryption_data);
912 
913     /**
914      * Identifies a signing algorithm where a SHA384 digest is
915      * encrypted using an RSA private key; defined by PKCS #1.
916      * OID = 1.2.840.113549.1.1.12
917      */
918         sha384WithRSAEncryption_oid =
919             ObjectIdentifier.newInternal(sha384WithRSAEncryption_data);
920 
921     /**
922      * Identifies a signing algorithm where a SHA512 digest is
923      * encrypted using an RSA private key; defined by PKCS #1.
924      * OID = 1.2.840.113549.1.1.13
925      */
926         sha512WithRSAEncryption_oid =
927             ObjectIdentifier.newInternal(sha512WithRSAEncryption_data);
928 
929     /**
930      * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
931      * SHA digest is signed using the Digital Signing Algorithm (DSA).
932      * This should not be used.
933      * OID = 1.3.14.3.2.13
934      */
935         shaWithDSA_OIW_oid = ObjectIdentifier.newInternal(shaWithDSA_OIW_data);
936 
937     /**
938      * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
939      * SHA1 digest is signed using the Digital Signing Algorithm (DSA).
940      * OID = 1.3.14.3.2.27
941      */
942         sha1WithDSA_OIW_oid = ObjectIdentifier.newInternal(sha1WithDSA_OIW_data);
943 
944     /**
945      * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
946      * SHA1 digest is signed using the Digital Signing Algorithm (DSA).
947      * OID = 1.2.840.10040.4.3
948      */
949         sha1WithDSA_oid = ObjectIdentifier.newInternal(dsaWithSHA1_PKIX_data);
950 
951         // Android-removed: Parsing mapping as OID even if "OID." prefix isn't specified
952         //nameTable = new HashMap<ObjectIdentifier,String>();
nameTable.put(MD5_oid, "MD5")953         nameTable.put(MD5_oid, "MD5");
nameTable.put(MD2_oid, "MD2")954         nameTable.put(MD2_oid, "MD2");
nameTable.put(SHA_oid, "SHA-1")955         nameTable.put(SHA_oid, "SHA-1");
nameTable.put(SHA224_oid, "SHA-224")956         nameTable.put(SHA224_oid, "SHA-224");
nameTable.put(SHA256_oid, "SHA-256")957         nameTable.put(SHA256_oid, "SHA-256");
nameTable.put(SHA384_oid, "SHA-384")958         nameTable.put(SHA384_oid, "SHA-384");
nameTable.put(SHA512_oid, "SHA-512")959         nameTable.put(SHA512_oid, "SHA-512");
nameTable.put(RSAEncryption_oid, "RSA")960         nameTable.put(RSAEncryption_oid, "RSA");
nameTable.put(RSA_oid, "RSA")961         nameTable.put(RSA_oid, "RSA");
nameTable.put(DH_oid, "Diffie-Hellman")962         nameTable.put(DH_oid, "Diffie-Hellman");
nameTable.put(DH_PKIX_oid, "Diffie-Hellman")963         nameTable.put(DH_PKIX_oid, "Diffie-Hellman");
nameTable.put(DSA_oid, "DSA")964         nameTable.put(DSA_oid, "DSA");
nameTable.put(DSA_OIW_oid, "DSA")965         nameTable.put(DSA_OIW_oid, "DSA");
nameTable.put(EC_oid, "EC")966         nameTable.put(EC_oid, "EC");
nameTable.put(ECDH_oid, "ECDH")967         nameTable.put(ECDH_oid, "ECDH");
968 
nameTable.put(AES_oid, "AES")969         nameTable.put(AES_oid, "AES");
970 
nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA")971         nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA");
nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA")972         nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA");
nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA")973         nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA");
nameTable.put(sha384WithECDSA_oid, "SHA384withECDSA")974         nameTable.put(sha384WithECDSA_oid, "SHA384withECDSA");
nameTable.put(sha512WithECDSA_oid, "SHA512withECDSA")975         nameTable.put(sha512WithECDSA_oid, "SHA512withECDSA");
nameTable.put(md5WithRSAEncryption_oid, "MD5withRSA")976         nameTable.put(md5WithRSAEncryption_oid, "MD5withRSA");
nameTable.put(md2WithRSAEncryption_oid, "MD2withRSA")977         nameTable.put(md2WithRSAEncryption_oid, "MD2withRSA");
nameTable.put(sha1WithDSA_oid, "SHA1withDSA")978         nameTable.put(sha1WithDSA_oid, "SHA1withDSA");
nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA")979         nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA");
nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA")980         nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA");
nameTable.put(sha224WithDSA_oid, "SHA224withDSA")981         nameTable.put(sha224WithDSA_oid, "SHA224withDSA");
nameTable.put(sha256WithDSA_oid, "SHA256withDSA")982         nameTable.put(sha256WithDSA_oid, "SHA256withDSA");
nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA")983         nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA");
nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA")984         nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA");
nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA")985         nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA");
nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA")986         nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA");
nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA")987         nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA");
nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA")988         nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA");
nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES")989         nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES");
nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2")990         nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2");
nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES")991         nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES");
nameTable.put(pbeWithSHA1AndRC2_oid, "PBEWithSHA1AndRC2")992         nameTable.put(pbeWithSHA1AndRC2_oid, "PBEWithSHA1AndRC2");
nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede")993         nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede");
nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40")994         nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40");
995     }
996 
997     /**
998      * Creates a signature algorithm name from a digest algorithm
999      * name and a encryption algorithm name.
1000      */
makeSigAlg(String digAlg, String encAlg)1001     public static String makeSigAlg(String digAlg, String encAlg) {
1002         digAlg = digAlg.replace("-", "");
1003         if (encAlg.equalsIgnoreCase("EC")) encAlg = "ECDSA";
1004 
1005         return digAlg + "with" + encAlg;
1006     }
1007 
1008     /**
1009      * Extracts the encryption algorithm name from a signature
1010      * algorithm name.
1011       */
getEncAlgFromSigAlg(String signatureAlgorithm)1012     public static String getEncAlgFromSigAlg(String signatureAlgorithm) {
1013         signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH);
1014         int with = signatureAlgorithm.indexOf("WITH");
1015         String keyAlgorithm = null;
1016         if (with > 0) {
1017             int and = signatureAlgorithm.indexOf("AND", with + 4);
1018             if (and > 0) {
1019                 keyAlgorithm = signatureAlgorithm.substring(with + 4, and);
1020             } else {
1021                 keyAlgorithm = signatureAlgorithm.substring(with + 4);
1022             }
1023             if (keyAlgorithm.equalsIgnoreCase("ECDSA")) {
1024                 keyAlgorithm = "EC";
1025             }
1026         }
1027         return keyAlgorithm;
1028     }
1029 
1030     /**
1031      * Extracts the digest algorithm name from a signature
1032      * algorithm name.
1033       */
getDigAlgFromSigAlg(String signatureAlgorithm)1034     public static String getDigAlgFromSigAlg(String signatureAlgorithm) {
1035         signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH);
1036         int with = signatureAlgorithm.indexOf("WITH");
1037         if (with > 0) {
1038             return signatureAlgorithm.substring(0, with);
1039         }
1040         return null;
1041     }
1042 }
1043