1 /*
2  * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.security.x509;
27 
28 import java.io.*;
29 import java.security.spec.AlgorithmParameterSpec;
30 import java.security.spec.InvalidParameterSpecException;
31 import java.security.spec.MGF1ParameterSpec;
32 import java.security.spec.PSSParameterSpec;
33 import java.util.*;
34 import java.security.*;
35 
36 import sun.security.rsa.PSSParameters;
37 import sun.security.util.*;
38 
39 
40 /**
41  * This class identifies algorithms, such as cryptographic transforms, each
42  * of which may be associated with parameters.  Instances of this base class
43  * are used when this runtime environment has no special knowledge of the
44  * algorithm type, and may also be used in other cases.  Equivalence is
45  * defined according to OID and (where relevant) parameters.
46  *
47  * <P>Subclasses may be used, for example when the algorithm ID has
48  * associated parameters which some code (e.g. code using public keys) needs
49  * to have parsed.  Two examples of such algorithms are Diffie-Hellman key
50  * exchange, and the Digital Signature Standard Algorithm (DSS/DSA).
51  *
52  * <P>The OID constants defined in this class correspond to some widely
53  * used algorithms, for which conventional string names have been defined.
54  * This class is not a general repository for OIDs, or for such string names.
55  * Note that the mappings between algorithm IDs and algorithm names is
56  * not one-to-one.
57  *
58  *
59  * @author David Brownell
60  * @author Amit Kapoor
61  * @author Hemma Prafullchandra
62  */
63 public class AlgorithmId implements Serializable, DerEncoder {
64 
65     /** use serialVersionUID from JDK 1.1. for interoperability */
66     private static final long serialVersionUID = 7205873507486557157L;
67 
68     /**
69      * The object identitifer being used for this algorithm.
70      */
71     private ObjectIdentifier algid;
72 
73     // The (parsed) parameters
74     private AlgorithmParameters algParams;
75     private boolean constructedFromDer = true;
76 
77     /**
78      * Parameters for this algorithm.  These are stored in unparsed
79      * DER-encoded form; subclasses can be made to automaticaly parse
80      * them so there is fast access to these parameters.
81      */
82     protected DerValue          params;
83 
84     private transient byte[] encodedParams;
85 
86     /**
87      * Constructs an algorithm ID which will be initialized
88      * separately, for example by deserialization.
89      * @deprecated use one of the other constructors.
90      */
91     @Deprecated
AlgorithmId()92     public AlgorithmId() { }
93 
94     /**
95      * Constructs a parameterless algorithm ID.
96      *
97      * @param oid the identifier for the algorithm
98      */
AlgorithmId(ObjectIdentifier oid)99     public AlgorithmId(ObjectIdentifier oid) {
100         algid = oid;
101     }
102 
103     /**
104      * Constructs an algorithm ID with algorithm parameters.
105      *
106      * @param oid the identifier for the algorithm.
107      * @param algparams the associated algorithm parameters.
108      */
AlgorithmId(ObjectIdentifier oid, AlgorithmParameters algparams)109     public AlgorithmId(ObjectIdentifier oid, AlgorithmParameters algparams) {
110         algid = oid;
111         algParams = algparams;
112         constructedFromDer = false;
113         if (algParams != null) {
114             try {
115                 encodedParams = algParams.getEncoded();
116             } catch (IOException ioe) {
117                 // It should be safe to ignore this.
118                 // This exception can occur if AlgorithmParameters was not
119                 // initialized (which should not occur), or if it was
120                 // initialized with bogus parameters, which should have
121                 // been detected when init was called.
122                 assert false;
123             }
124         }
125     }
126 
AlgorithmId(ObjectIdentifier oid, DerValue params)127     private AlgorithmId(ObjectIdentifier oid, DerValue params)
128             throws IOException {
129         this.algid = oid;
130         this.params = params;
131         if (this.params != null) {
132             encodedParams = params.toByteArray();
133             decodeParams();
134         }
135     }
136 
decodeParams()137     protected void decodeParams() throws IOException {
138         String algidString = algid.toString();
139         try {
140             algParams = AlgorithmParameters.getInstance(algidString);
141         } catch (NoSuchAlgorithmException e) {
142             /*
143              * This algorithm parameter type is not supported, so we cannot
144              * parse the parameters.
145              */
146             algParams = null;
147             return;
148         }
149 
150         // Decode (parse) the parameters
151         algParams.init(encodedParams.clone());
152     }
153 
154     /**
155      * Marshal a DER-encoded "AlgorithmID" sequence on the DER stream.
156      */
encode(DerOutputStream out)157     public final void encode(DerOutputStream out) throws IOException {
158         derEncode(out);
159     }
160 
161     /**
162      * DER encode this object onto an output stream.
163      * Implements the <code>DerEncoder</code> interface.
164      *
165      * @param out
166      * the output stream on which to write the DER encoding.
167      *
168      * @exception IOException on encoding error.
169      */
170     @Override
derEncode(OutputStream out)171     public void derEncode (OutputStream out) throws IOException {
172         DerOutputStream bytes = new DerOutputStream();
173         DerOutputStream tmp = new DerOutputStream();
174 
175         bytes.putOID(algid);
176         // Setup params from algParams since no DER encoding is given
177         if (constructedFromDer == false) {
178             if (encodedParams != null) {
179                 params = new DerValue(encodedParams);
180             } else {
181                 params = null;
182             }
183         }
184         if (params == null) {
185             // Changes backed out for compatibility with Solaris
186 
187             // Several AlgorithmId should omit the whole parameter part when
188             // it's NULL. They are ---
189             // RFC 3370 2.1: Implementations SHOULD generate SHA-1
190             // AlgorithmIdentifiers with absent parameters.
191             // RFC 3447 C1: When id-sha1, id-sha224, id-sha256, id-sha384 and
192             // id-sha512 are used in an AlgorithmIdentifier the parameters
193             // (which are optional) SHOULD be omitted.
194             // RFC 3279 2.3.2: The id-dsa algorithm syntax includes optional
195             // domain parameters... When omitted, the parameters component
196             // MUST be omitted entirely
197             // RFC 3370 3.1: When the id-dsa-with-sha1 algorithm identifier
198             // is used, the AlgorithmIdentifier parameters field MUST be absent.
199             /*if (
200                 algid.equals((Object)SHA_oid) ||
201                 algid.equals((Object)SHA224_oid) ||
202                 algid.equals((Object)SHA256_oid) ||
203                 algid.equals((Object)SHA384_oid) ||
204                 algid.equals((Object)SHA512_oid) ||
205                 algid.equals((Object)SHA512_224_oid) ||
206                 algid.equals((Object)SHA512_256_oid) ||
207                 algid.equals((Object)DSA_oid) ||
208                 algid.equals((Object)sha1WithDSA_oid)) {
209                 ; // no parameter part encoded
210             } else {
211                 bytes.putNull();
212             }*/
213             if (algid.equals(RSASSA_PSS_oid)) {
214                 // RFC 4055 3.3: when an RSASSA-PSS key does not require
215                 // parameter validation, field is absent.
216             } else {
217                 bytes.putNull();
218             }
219         } else {
220             bytes.putDerValue(params);
221         }
222         tmp.write(DerValue.tag_Sequence, bytes);
223         out.write(tmp.toByteArray());
224     }
225 
226 
227     /**
228      * Returns the DER-encoded X.509 AlgorithmId as a byte array.
229      */
encode()230     public final byte[] encode() throws IOException {
231         DerOutputStream out = new DerOutputStream();
232         derEncode(out);
233         return out.toByteArray();
234     }
235 
236     /**
237      * Returns the ISO OID for this algorithm.  This is usually converted
238      * to a string and used as part of an algorithm name, for example
239      * "OID.1.3.14.3.2.13" style notation.  Use the <code>getName</code>
240      * call when you do not need to ensure cross-system portability
241      * of algorithm names, or need a user friendly name.
242      */
getOID()243     public final ObjectIdentifier getOID () {
244         return algid;
245     }
246 
247     /**
248      * Returns a name for the algorithm which may be more intelligible
249      * to humans than the algorithm's OID, but which won't necessarily
250      * be comprehensible on other systems.  For example, this might
251      * return a name such as "MD5withRSA" for a signature algorithm on
252      * some systems.  It also returns names like "OID.1.2.3.4", when
253      * no particular name for the algorithm is known.
254      *
255      * Note: for ecdsa-with-SHA2 plus hash algorithm (Ex: SHA-256), this method
256      * returns the "full" signature algorithm (Ex: SHA256withECDSA) directly.
257      */
getName()258     public String getName() {
259         String algName = nameTable.get(algid);
260         if (algName != null) {
261             return algName;
262         }
263         if ((params != null) && algid.equals((Object)specifiedWithECDSA_oid)) {
264             try {
265                 AlgorithmId paramsId =
266                         AlgorithmId.parse(new DerValue(encodedParams));
267                 String paramsName = paramsId.getName();
268                 algName = makeSigAlg(paramsName, "EC");
269             } catch (IOException e) {
270                 // ignore
271             }
272         }
273         return (algName == null) ? algid.toString() : algName;
274     }
275 
getParameters()276     public AlgorithmParameters getParameters() {
277         return algParams;
278     }
279 
280     /**
281      * Returns the DER encoded parameter, which can then be
282      * used to initialize java.security.AlgorithmParameters.
283      *
284      * Note that this* method should always return a new array as it is called
285      * directly by the JDK implementation of X509Certificate.getSigAlgParams()
286      * and X509CRL.getSigAlgParams().
287      *
288      * Note: for ecdsa-with-SHA2 plus hash algorithm (Ex: SHA-256), this method
289      * returns null because {@link #getName()} has already returned the "full"
290      * signature algorithm (Ex: SHA256withECDSA).
291      *
292      * @return DER encoded parameters, or null not present.
293      */
getEncodedParams()294     public byte[] getEncodedParams() throws IOException {
295         return (encodedParams == null || algid.equals(specifiedWithECDSA_oid))
296                 ? null
297                 : encodedParams.clone();
298     }
299 
300     /**
301      * Returns true iff the argument indicates the same algorithm
302      * with the same parameters.
303      */
equals(AlgorithmId other)304     public boolean equals(AlgorithmId other) {
305         return algid.equals((Object)other.algid) &&
306             Arrays.equals(encodedParams, other.encodedParams);
307     }
308 
309     /**
310      * Compares this AlgorithmID to another.  If algorithm parameters are
311      * available, they are compared.  Otherwise, just the object IDs
312      * for the algorithm are compared.
313      *
314      * @param other preferably an AlgorithmId, else an ObjectIdentifier
315      */
316     @Override
equals(Object other)317     public boolean equals(Object other) {
318         if (this == other) {
319             return true;
320         }
321         if (other instanceof AlgorithmId) {
322             return equals((AlgorithmId) other);
323         } else if (other instanceof ObjectIdentifier) {
324             return equals((ObjectIdentifier) other);
325         } else {
326             return false;
327         }
328     }
329 
330     /**
331      * Compares two algorithm IDs for equality.  Returns true iff
332      * they are the same algorithm, ignoring algorithm parameters.
333      */
equals(ObjectIdentifier id)334     public final boolean equals(ObjectIdentifier id) {
335         return algid.equals((Object)id);
336     }
337 
338     /**
339      * Returns a hashcode for this AlgorithmId.
340      *
341      * @return a hashcode for this AlgorithmId.
342      */
343     @Override
hashCode()344     public int hashCode() {
345         int hashCode = algid.hashCode();
346         hashCode = 31 * hashCode + Arrays.hashCode(encodedParams);
347         return hashCode;
348     }
349 
350     /**
351      * Provides a human-readable description of the algorithm parameters.
352      * This may be redefined by subclasses which parse those parameters.
353      */
paramsToString()354     protected String paramsToString() {
355         if (encodedParams == null) {
356             return "";
357         } else if (algParams != null) {
358             return ", " + algParams.toString();
359         } else {
360             return ", params unparsed";
361         }
362     }
363 
364     /**
365      * Returns a string describing the algorithm and its parameters.
366      */
367     @Override
toString()368     public String toString() {
369         return getName() + paramsToString();
370     }
371 
372     /**
373      * Parse (unmarshal) an ID from a DER sequence input value.  This form
374      * parsing might be used when expanding a value which has already been
375      * partially unmarshaled as a set or sequence member.
376      *
377      * @exception IOException on error.
378      * @param val the input value, which contains the algid and, if
379      *          there are any parameters, those parameters.
380      * @return an ID for the algorithm.  If the system is configured
381      *          appropriately, this may be an instance of a class
382      *          with some kind of special support for this algorithm.
383      *          In that case, you may "narrow" the type of the ID.
384      */
parse(DerValue val)385     public static AlgorithmId parse(DerValue val) throws IOException {
386         if (val.tag != DerValue.tag_Sequence) {
387             throw new IOException("algid parse error, not a sequence");
388         }
389 
390         /*
391          * Get the algorithm ID and any parameters.
392          */
393         ObjectIdentifier        algid;
394         DerValue                params;
395         DerInputStream          in = val.toDerInputStream();
396 
397         algid = in.getOID();
398         if (in.available() == 0) {
399             params = null;
400         } else {
401             params = in.getDerValue();
402             if (params.tag == DerValue.tag_Null) {
403                 if (params.length() != 0) {
404                     throw new IOException("invalid NULL");
405                 }
406                 params = null;
407             }
408             if (in.available() != 0) {
409                 throw new IOException("Invalid AlgorithmIdentifier: extra data");
410             }
411         }
412 
413         return new AlgorithmId(algid, params);
414     }
415 
416     /**
417      * Returns one of the algorithm IDs most commonly associated
418      * with this algorithm name.
419      *
420      * @param algname the name being used
421      * @deprecated use the short get form of this method.
422      * @exception NoSuchAlgorithmException on error.
423      */
424     @Deprecated
getAlgorithmId(String algname)425     public static AlgorithmId getAlgorithmId(String algname)
426             throws NoSuchAlgorithmException {
427         return get(algname);
428     }
429 
430     /**
431      * Returns one of the algorithm IDs most commonly associated
432      * with this algorithm name.
433      *
434      * @param algname the name being used
435      * @exception NoSuchAlgorithmException on error.
436      */
get(String algname)437     public static AlgorithmId get(String algname)
438             throws NoSuchAlgorithmException {
439         ObjectIdentifier oid;
440         try {
441             oid = algOID(algname);
442         } catch (IOException ioe) {
443             throw new NoSuchAlgorithmException
444                 ("Invalid ObjectIdentifier " + algname);
445         }
446 
447         if (oid == null) {
448             throw new NoSuchAlgorithmException
449                 ("unrecognized algorithm name: " + algname);
450         }
451         return new AlgorithmId(oid);
452     }
453 
454     /**
455      * Returns one of the algorithm IDs most commonly associated
456      * with this algorithm parameters.
457      *
458      * @param algparams the associated algorithm parameters.
459      * @exception NoSuchAlgorithmException on error.
460      */
get(AlgorithmParameters algparams)461     public static AlgorithmId get(AlgorithmParameters algparams)
462             throws NoSuchAlgorithmException {
463         ObjectIdentifier oid;
464         String algname = algparams.getAlgorithm();
465         try {
466             oid = algOID(algname);
467         } catch (IOException ioe) {
468             throw new NoSuchAlgorithmException
469                 ("Invalid ObjectIdentifier " + algname);
470         }
471         if (oid == null) {
472             throw new NoSuchAlgorithmException
473                 ("unrecognized algorithm name: " + algname);
474         }
475         return new AlgorithmId(oid, algparams);
476     }
477 
478     /*
479      * Translates from some common algorithm names to the
480      * OID with which they're usually associated ... this mapping
481      * is the reverse of the one below, except in those cases
482      * where synonyms are supported or where a given algorithm
483      * is commonly associated with multiple OIDs.
484      *
485      * XXX This method needs to be enhanced so that we can also pass the
486      * scope of the algorithm name to it, e.g., the algorithm name "DSA"
487      * may have a different OID when used as a "Signature" algorithm than when
488      * used as a "KeyPairGenerator" algorithm.
489      */
algOID(String name)490     private static ObjectIdentifier algOID(String name) throws IOException {
491         // See if algname is in printable OID ("dot-dot") notation
492         if (name.indexOf('.') != -1) {
493             if (name.startsWith("OID.")) {
494                 return new ObjectIdentifier(name.substring("OID.".length()));
495             } else {
496                 return new ObjectIdentifier(name);
497             }
498         }
499 
500         // Digesting algorithms
501         if (name.equalsIgnoreCase("MD5")) {
502             return AlgorithmId.MD5_oid;
503         }
504         if (name.equalsIgnoreCase("MD2")) {
505             return AlgorithmId.MD2_oid;
506         }
507         if (name.equalsIgnoreCase("SHA") || name.equalsIgnoreCase("SHA1")
508             || name.equalsIgnoreCase("SHA-1")) {
509             return AlgorithmId.SHA_oid;
510         }
511         if (name.equalsIgnoreCase("SHA-256") ||
512             name.equalsIgnoreCase("SHA256")) {
513             return AlgorithmId.SHA256_oid;
514         }
515         if (name.equalsIgnoreCase("SHA-384") ||
516             name.equalsIgnoreCase("SHA384")) {
517             return AlgorithmId.SHA384_oid;
518         }
519         if (name.equalsIgnoreCase("SHA-512") ||
520             name.equalsIgnoreCase("SHA512")) {
521             return AlgorithmId.SHA512_oid;
522         }
523         if (name.equalsIgnoreCase("SHA-224") ||
524             name.equalsIgnoreCase("SHA224")) {
525             return AlgorithmId.SHA224_oid;
526         }
527         if (name.equalsIgnoreCase("SHA-512/224") ||
528             name.equalsIgnoreCase("SHA512/224")) {
529             return AlgorithmId.SHA512_224_oid;
530         }
531         if (name.equalsIgnoreCase("SHA-512/256") ||
532             name.equalsIgnoreCase("SHA512/256")) {
533             return AlgorithmId.SHA512_256_oid;
534         }
535         // Various public key algorithms
536         if (name.equalsIgnoreCase("RSA")) {
537             return AlgorithmId.RSAEncryption_oid;
538         }
539         if (name.equalsIgnoreCase("RSASSA-PSS")) {
540             return AlgorithmId.RSASSA_PSS_oid;
541         }
542         if (name.equalsIgnoreCase("RSAES-OAEP")) {
543             return AlgorithmId.RSAES_OAEP_oid;
544         }
545         if (name.equalsIgnoreCase("Diffie-Hellman")
546             || name.equalsIgnoreCase("DH")) {
547             return AlgorithmId.DH_oid;
548         }
549         if (name.equalsIgnoreCase("DSA")) {
550             return AlgorithmId.DSA_oid;
551         }
552         if (name.equalsIgnoreCase("EC")) {
553             return EC_oid;
554         }
555         if (name.equalsIgnoreCase("ECDH")) {
556             return AlgorithmId.ECDH_oid;
557         }
558 
559         // Secret key algorithms
560         if (name.equalsIgnoreCase("AES")) {
561             return AlgorithmId.AES_oid;
562         }
563 
564         // Common signature types
565         if (name.equalsIgnoreCase("MD5withRSA")
566             || name.equalsIgnoreCase("MD5/RSA")) {
567             return AlgorithmId.md5WithRSAEncryption_oid;
568         }
569         if (name.equalsIgnoreCase("MD2withRSA")
570             || name.equalsIgnoreCase("MD2/RSA")) {
571             return AlgorithmId.md2WithRSAEncryption_oid;
572         }
573         if (name.equalsIgnoreCase("SHAwithDSA")
574             || name.equalsIgnoreCase("SHA1withDSA")
575             || name.equalsIgnoreCase("SHA/DSA")
576             || name.equalsIgnoreCase("SHA1/DSA")
577             || name.equalsIgnoreCase("DSAWithSHA1")
578             || name.equalsIgnoreCase("DSS")
579             || name.equalsIgnoreCase("SHA-1/DSA")) {
580             return AlgorithmId.sha1WithDSA_oid;
581         }
582         if (name.equalsIgnoreCase("SHA224WithDSA")) {
583             return AlgorithmId.sha224WithDSA_oid;
584         }
585         if (name.equalsIgnoreCase("SHA256WithDSA")) {
586             return AlgorithmId.sha256WithDSA_oid;
587         }
588         if (name.equalsIgnoreCase("SHA1WithRSA")
589             || name.equalsIgnoreCase("SHA1/RSA")) {
590             return AlgorithmId.sha1WithRSAEncryption_oid;
591         }
592         if (name.equalsIgnoreCase("SHA1withECDSA")
593                 || name.equalsIgnoreCase("ECDSA")) {
594             return AlgorithmId.sha1WithECDSA_oid;
595         }
596         if (name.equalsIgnoreCase("SHA224withECDSA")) {
597             return AlgorithmId.sha224WithECDSA_oid;
598         }
599         if (name.equalsIgnoreCase("SHA256withECDSA")) {
600             return AlgorithmId.sha256WithECDSA_oid;
601         }
602         if (name.equalsIgnoreCase("SHA384withECDSA")) {
603             return AlgorithmId.sha384WithECDSA_oid;
604         }
605         if (name.equalsIgnoreCase("SHA512withECDSA")) {
606             return AlgorithmId.sha512WithECDSA_oid;
607         }
608 
609         return oidTable().get(name.toUpperCase(Locale.ENGLISH));
610     }
611 
oid(int ... values)612     private static ObjectIdentifier oid(int ... values) {
613         return ObjectIdentifier.newInternal(values);
614     }
615 
616     private static volatile Map<String,ObjectIdentifier> oidTable;
617     private static final Map<ObjectIdentifier,String> nameTable;
618 
619     /** Returns the oidTable, lazily initializing it on first access. */
oidTable()620     private static Map<String,ObjectIdentifier> oidTable()
621         throws IOException {
622         // Double checked locking; safe because oidTable is volatile
623         Map<String,ObjectIdentifier> tab;
624         if ((tab = oidTable) == null) {
625             synchronized (AlgorithmId.class) {
626                 if ((tab = oidTable) == null)
627                     oidTable = tab = computeOidTable();
628             }
629         }
630         return tab;
631     }
632 
633     /** Collects the algorithm names from the installed providers. */
computeOidTable()634     private static HashMap<String,ObjectIdentifier> computeOidTable()
635         throws IOException {
636         HashMap<String,ObjectIdentifier> tab = new HashMap<>();
637         for (Provider provider : Security.getProviders()) {
638             for (Object key : provider.keySet()) {
639                 String alias = (String)key;
640                 String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH);
641                 int index;
642                 if (upperCaseAlias.startsWith("ALG.ALIAS") &&
643                     (index=upperCaseAlias.indexOf("OID.", 0)) != -1) {
644                     index += "OID.".length();
645                     if (index == alias.length()) {
646                         // invalid alias entry
647                         break;
648                     }
649                     String oidString = alias.substring(index);
650                     String stdAlgName = provider.getProperty(alias);
651                     if (stdAlgName != null) {
652                         stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH);
653                     }
654                     if (stdAlgName != null &&
655                         tab.get(stdAlgName) == null) {
656                         tab.put(stdAlgName, new ObjectIdentifier(oidString));
657                     }
658                 }
659             }
660         }
661         return tab;
662     }
663 
664     /*****************************************************************/
665 
666     /*
667      * HASHING ALGORITHMS
668      */
669 
670     /**
671      * Algorithm ID for the MD2 Message Digest Algorthm, from RFC 1319.
672      * OID = 1.2.840.113549.2.2
673      */
674     public static final ObjectIdentifier MD2_oid =
675     ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 2});
676 
677     /**
678      * Algorithm ID for the MD5 Message Digest Algorthm, from RFC 1321.
679      * OID = 1.2.840.113549.2.5
680      */
681     public static final ObjectIdentifier MD5_oid =
682     ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 5});
683 
684     /**
685      * Algorithm ID for the SHA1 Message Digest Algorithm, from FIPS 180-1.
686      * This is sometimes called "SHA", though that is often confusing since
687      * many people refer to FIPS 180 (which has an error) as defining SHA.
688      * OID = 1.3.14.3.2.26. Old SHA-0 OID: 1.3.14.3.2.18.
689      */
690     public static final ObjectIdentifier SHA_oid =
691     ObjectIdentifier.newInternal(new int[] {1, 3, 14, 3, 2, 26});
692 
693     public static final ObjectIdentifier SHA224_oid =
694     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 4});
695 
696     public static final ObjectIdentifier SHA256_oid =
697     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 1});
698 
699     public static final ObjectIdentifier SHA384_oid =
700     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 2});
701 
702     public static final ObjectIdentifier SHA512_oid =
703     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 3});
704 
705     public static final ObjectIdentifier SHA512_224_oid =
706     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 5});
707 
708     public static final ObjectIdentifier SHA512_256_oid =
709     ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 6});
710 
711     /*
712      * COMMON PUBLIC KEY TYPES
713      */
714     private static final int[] DH_data = { 1, 2, 840, 113549, 1, 3, 1 };
715     private static final int[] DH_PKIX_data = { 1, 2, 840, 10046, 2, 1 };
716     private static final int[] DSA_OIW_data = { 1, 3, 14, 3, 2, 12 };
717     private static final int[] DSA_PKIX_data = { 1, 2, 840, 10040, 4, 1 };
718     private static final int[] RSA_data = { 2, 5, 8, 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                                             oid(1, 2, 840, 113549, 1, 1, 1);
729     public static final ObjectIdentifier RSAES_OAEP_oid =
730                                             oid(1, 2, 840, 113549, 1, 1, 7);
731     public static final ObjectIdentifier mgf1_oid =
732                                             oid(1, 2, 840, 113549, 1, 1, 8);
733     public static final ObjectIdentifier RSASSA_PSS_oid =
734                                             oid(1, 2, 840, 113549, 1, 1, 10);
735 
736     /*
737      * COMMON SECRET KEY TYPES
738      */
739     public static final ObjectIdentifier AES_oid =
740                                             oid(2, 16, 840, 1, 101, 3, 4, 1);
741 
742     /*
743      * COMMON SIGNATURE ALGORITHMS
744      */
745     private static final int[] md2WithRSAEncryption_data =
746                                        { 1, 2, 840, 113549, 1, 1, 2 };
747     private static final int[] md5WithRSAEncryption_data =
748                                        { 1, 2, 840, 113549, 1, 1, 4 };
749     private static final int[] sha1WithRSAEncryption_data =
750                                        { 1, 2, 840, 113549, 1, 1, 5 };
751     private static final int[] sha1WithRSAEncryption_OIW_data =
752                                        { 1, 3, 14, 3, 2, 29 };
753     private static final int[] sha224WithRSAEncryption_data =
754                                        { 1, 2, 840, 113549, 1, 1, 14 };
755     private static final int[] sha256WithRSAEncryption_data =
756                                        { 1, 2, 840, 113549, 1, 1, 11 };
757     private static final int[] sha384WithRSAEncryption_data =
758                                        { 1, 2, 840, 113549, 1, 1, 12 };
759     private static final int[] sha512WithRSAEncryption_data =
760                                        { 1, 2, 840, 113549, 1, 1, 13 };
761 
762     private static final int[] shaWithDSA_OIW_data =
763                                        { 1, 3, 14, 3, 2, 13 };
764     private static final int[] sha1WithDSA_OIW_data =
765                                        { 1, 3, 14, 3, 2, 27 };
766     private static final int[] dsaWithSHA1_PKIX_data =
767                                        { 1, 2, 840, 10040, 4, 3 };
768 
769     public static final ObjectIdentifier md2WithRSAEncryption_oid;
770     public static final ObjectIdentifier md5WithRSAEncryption_oid;
771     public static final ObjectIdentifier sha1WithRSAEncryption_oid;
772     public static final ObjectIdentifier sha1WithRSAEncryption_OIW_oid;
773     public static final ObjectIdentifier sha224WithRSAEncryption_oid;
774     public static final ObjectIdentifier sha256WithRSAEncryption_oid;
775     public static final ObjectIdentifier sha384WithRSAEncryption_oid;
776     public static final ObjectIdentifier sha512WithRSAEncryption_oid;
777     public static final ObjectIdentifier sha512_224WithRSAEncryption_oid =
778                                             oid(1, 2, 840, 113549, 1, 1, 15);
779     public static final ObjectIdentifier sha512_256WithRSAEncryption_oid =
780                                             oid(1, 2, 840, 113549, 1, 1, 16);;
781 
782     public static final ObjectIdentifier shaWithDSA_OIW_oid;
783     public static final ObjectIdentifier sha1WithDSA_OIW_oid;
784     public static final ObjectIdentifier sha1WithDSA_oid;
785     public static final ObjectIdentifier sha224WithDSA_oid =
786                                             oid(2, 16, 840, 1, 101, 3, 4, 3, 1);
787     public static final ObjectIdentifier sha256WithDSA_oid =
788                                             oid(2, 16, 840, 1, 101, 3, 4, 3, 2);
789 
790     public static final ObjectIdentifier sha1WithECDSA_oid =
791                                             oid(1, 2, 840, 10045, 4, 1);
792     public static final ObjectIdentifier sha224WithECDSA_oid =
793                                             oid(1, 2, 840, 10045, 4, 3, 1);
794     public static final ObjectIdentifier sha256WithECDSA_oid =
795                                             oid(1, 2, 840, 10045, 4, 3, 2);
796     public static final ObjectIdentifier sha384WithECDSA_oid =
797                                             oid(1, 2, 840, 10045, 4, 3, 3);
798     public static final ObjectIdentifier sha512WithECDSA_oid =
799                                             oid(1, 2, 840, 10045, 4, 3, 4);
800     public static final ObjectIdentifier specifiedWithECDSA_oid =
801                                             oid(1, 2, 840, 10045, 4, 3);
802 
803     /**
804      * Algorithm ID for the PBE encryption algorithms from PKCS#5 and
805      * PKCS#12.
806      */
807     public static final ObjectIdentifier pbeWithMD5AndDES_oid =
808         ObjectIdentifier.newInternal(new int[]{1, 2, 840, 113549, 1, 5, 3});
809     public static final ObjectIdentifier pbeWithMD5AndRC2_oid =
810         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 6});
811     public static final ObjectIdentifier pbeWithSHA1AndDES_oid =
812         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 10});
813     public static final ObjectIdentifier pbeWithSHA1AndRC2_oid =
814         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 11});
815     public static ObjectIdentifier pbeWithSHA1AndRC4_128_oid =
816         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 1});
817     public static ObjectIdentifier pbeWithSHA1AndRC4_40_oid =
818         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 2});
819     public static ObjectIdentifier pbeWithSHA1AndDESede_oid =
820         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 3});
821     public static ObjectIdentifier pbeWithSHA1AndRC2_128_oid =
822         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 5});
823     public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid =
824         ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6});
825 
826     static {
827     /*
828      * Note the preferred OIDs are named simply with no "OIW" or
829      * "PKIX" in them, even though they may point to data from these
830      * specs; e.g. SHA_oid, DH_oid, DSA_oid, SHA1WithDSA_oid...
831      */
832     /**
833      * Algorithm ID for Diffie Hellman Key agreement, from PKCS #3.
834      * Parameters include public values P and G, and may optionally specify
835      * the length of the private key X.  Alternatively, algorithm parameters
836      * may be derived from another source such as a Certificate Authority's
837      * certificate.
838      * OID = 1.2.840.113549.1.3.1
839      */
840         DH_oid = ObjectIdentifier.newInternal(DH_data);
841 
842     /**
843      * Algorithm ID for the Diffie Hellman Key Agreement (DH), from RFC 3279.
844      * Parameters may include public values P and G.
845      * OID = 1.2.840.10046.2.1
846      */
847         DH_PKIX_oid = ObjectIdentifier.newInternal(DH_PKIX_data);
848 
849     /**
850      * Algorithm ID for the Digital Signing Algorithm (DSA), from the
851      * NIST OIW Stable Agreements part 12.
852      * Parameters may include public values P, Q, and G; or these may be
853      * derived from
854      * another source such as a Certificate Authority's certificate.
855      * OID = 1.3.14.3.2.12
856      */
857         DSA_OIW_oid = ObjectIdentifier.newInternal(DSA_OIW_data);
858 
859     /**
860      * Algorithm ID for the Digital Signing Algorithm (DSA), from RFC 3279.
861      * Parameters may include public values P, Q, and G; or these may be
862      * derived from another source such as a Certificate Authority's
863      * certificate.
864      * OID = 1.2.840.10040.4.1
865      */
866         DSA_oid = ObjectIdentifier.newInternal(DSA_PKIX_data);
867 
868     /**
869      * Algorithm ID for RSA keys used for any purpose, as defined in X.509.
870      * The algorithm parameter is a single value, the number of bits in the
871      * public modulus.
872      * OID = 2.5.8.1.1
873      */
874         RSA_oid = ObjectIdentifier.newInternal(RSA_data);
875 
876     /**
877      * Identifies a signing algorithm where an MD2 digest is encrypted
878      * using an RSA private key; defined in PKCS #1.  Use of this
879      * signing algorithm is discouraged due to MD2 vulnerabilities.
880      * OID = 1.2.840.113549.1.1.2
881      */
882         md2WithRSAEncryption_oid =
883             ObjectIdentifier.newInternal(md2WithRSAEncryption_data);
884 
885     /**
886      * Identifies a signing algorithm where an MD5 digest is
887      * encrypted using an RSA private key; defined in PKCS #1.
888      * OID = 1.2.840.113549.1.1.4
889      */
890         md5WithRSAEncryption_oid =
891             ObjectIdentifier.newInternal(md5WithRSAEncryption_data);
892 
893     /**
894      * Identifies a signing algorithm where a SHA1 digest is
895      * encrypted using an RSA private key; defined by RSA DSI.
896      * OID = 1.2.840.113549.1.1.5
897      */
898         sha1WithRSAEncryption_oid =
899             ObjectIdentifier.newInternal(sha1WithRSAEncryption_data);
900 
901     /**
902      * Identifies a signing algorithm where a SHA1 digest is
903      * encrypted using an RSA private key; defined in NIST OIW.
904      * OID = 1.3.14.3.2.29
905      */
906         sha1WithRSAEncryption_OIW_oid =
907             ObjectIdentifier.newInternal(sha1WithRSAEncryption_OIW_data);
908 
909     /**
910      * Identifies a signing algorithm where a SHA224 digest is
911      * encrypted using an RSA private key; defined by PKCS #1.
912      * OID = 1.2.840.113549.1.1.14
913      */
914         sha224WithRSAEncryption_oid =
915             ObjectIdentifier.newInternal(sha224WithRSAEncryption_data);
916 
917     /**
918      * Identifies a signing algorithm where a SHA256 digest is
919      * encrypted using an RSA private key; defined by PKCS #1.
920      * OID = 1.2.840.113549.1.1.11
921      */
922         sha256WithRSAEncryption_oid =
923             ObjectIdentifier.newInternal(sha256WithRSAEncryption_data);
924 
925     /**
926      * Identifies a signing algorithm where a SHA384 digest is
927      * encrypted using an RSA private key; defined by PKCS #1.
928      * OID = 1.2.840.113549.1.1.12
929      */
930         sha384WithRSAEncryption_oid =
931             ObjectIdentifier.newInternal(sha384WithRSAEncryption_data);
932 
933     /**
934      * Identifies a signing algorithm where a SHA512 digest is
935      * encrypted using an RSA private key; defined by PKCS #1.
936      * OID = 1.2.840.113549.1.1.13
937      */
938         sha512WithRSAEncryption_oid =
939             ObjectIdentifier.newInternal(sha512WithRSAEncryption_data);
940 
941     /**
942      * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
943      * SHA digest is signed using the Digital Signing Algorithm (DSA).
944      * This should not be used.
945      * OID = 1.3.14.3.2.13
946      */
947         shaWithDSA_OIW_oid = ObjectIdentifier.newInternal(shaWithDSA_OIW_data);
948 
949     /**
950      * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
951      * SHA1 digest is signed using the Digital Signing Algorithm (DSA).
952      * OID = 1.3.14.3.2.27
953      */
954         sha1WithDSA_OIW_oid = ObjectIdentifier.newInternal(sha1WithDSA_OIW_data);
955 
956     /**
957      * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a
958      * SHA1 digest is signed using the Digital Signing Algorithm (DSA).
959      * OID = 1.2.840.10040.4.3
960      */
961         sha1WithDSA_oid = ObjectIdentifier.newInternal(dsaWithSHA1_PKIX_data);
962 
963         nameTable = new HashMap<>();
nameTable.put(MD5_oid, R)964         nameTable.put(MD5_oid, "MD5");
nameTable.put(MD2_oid, R)965         nameTable.put(MD2_oid, "MD2");
nameTable.put(SHA_oid, R)966         nameTable.put(SHA_oid, "SHA-1");
nameTable.put(SHA224_oid, R)967         nameTable.put(SHA224_oid, "SHA-224");
nameTable.put(SHA256_oid, R)968         nameTable.put(SHA256_oid, "SHA-256");
nameTable.put(SHA384_oid, R)969         nameTable.put(SHA384_oid, "SHA-384");
nameTable.put(SHA512_oid, R)970         nameTable.put(SHA512_oid, "SHA-512");
nameTable.put(SHA512_224_oid, R)971         nameTable.put(SHA512_224_oid, "SHA-512/224");
nameTable.put(SHA512_256_oid, R)972         nameTable.put(SHA512_256_oid, "SHA-512/256");
nameTable.put(RSAEncryption_oid, R)973         nameTable.put(RSAEncryption_oid, "RSA");
nameTable.put(RSA_oid, R)974         nameTable.put(RSA_oid, "RSA");
nameTable.put(DH_oid, R)975         nameTable.put(DH_oid, "Diffie-Hellman");
nameTable.put(DH_PKIX_oid, R)976         nameTable.put(DH_PKIX_oid, "Diffie-Hellman");
nameTable.put(DSA_oid, R)977         nameTable.put(DSA_oid, "DSA");
nameTable.put(DSA_OIW_oid, R)978         nameTable.put(DSA_OIW_oid, "DSA");
nameTable.put(EC_oid, R)979         nameTable.put(EC_oid, "EC");
nameTable.put(ECDH_oid, R)980         nameTable.put(ECDH_oid, "ECDH");
981 
nameTable.put(AES_oid, R)982         nameTable.put(AES_oid, "AES");
983 
nameTable.put(sha1WithECDSA_oid, R)984         nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA");
nameTable.put(sha224WithECDSA_oid, R)985         nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA");
nameTable.put(sha256WithECDSA_oid, R)986         nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA");
nameTable.put(sha384WithECDSA_oid, R)987         nameTable.put(sha384WithECDSA_oid, "SHA384withECDSA");
nameTable.put(sha512WithECDSA_oid, R)988         nameTable.put(sha512WithECDSA_oid, "SHA512withECDSA");
nameTable.put(md5WithRSAEncryption_oid, R)989         nameTable.put(md5WithRSAEncryption_oid, "MD5withRSA");
nameTable.put(md2WithRSAEncryption_oid, R)990         nameTable.put(md2WithRSAEncryption_oid, "MD2withRSA");
nameTable.put(sha1WithDSA_oid, R)991         nameTable.put(sha1WithDSA_oid, "SHA1withDSA");
nameTable.put(sha1WithDSA_OIW_oid, R)992         nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA");
nameTable.put(shaWithDSA_OIW_oid, R)993         nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA");
nameTable.put(sha224WithDSA_oid, R)994         nameTable.put(sha224WithDSA_oid, "SHA224withDSA");
nameTable.put(sha256WithDSA_oid, R)995         nameTable.put(sha256WithDSA_oid, "SHA256withDSA");
nameTable.put(sha1WithRSAEncryption_oid, R)996         nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA");
nameTable.put(sha1WithRSAEncryption_OIW_oid, R)997         nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA");
nameTable.put(sha224WithRSAEncryption_oid, R)998         nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA");
nameTable.put(sha256WithRSAEncryption_oid, R)999         nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA");
nameTable.put(sha384WithRSAEncryption_oid, R)1000         nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA");
nameTable.put(sha512WithRSAEncryption_oid, R)1001         nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA");
nameTable.put(sha512_224WithRSAEncryption_oid, R)1002         nameTable.put(sha512_224WithRSAEncryption_oid, "SHA512/224withRSA");
nameTable.put(sha512_256WithRSAEncryption_oid, R)1003         nameTable.put(sha512_256WithRSAEncryption_oid, "SHA512/256withRSA");
nameTable.put(RSASSA_PSS_oid, R)1004         nameTable.put(RSASSA_PSS_oid, "RSASSA-PSS");
nameTable.put(RSAES_OAEP_oid, R)1005         nameTable.put(RSAES_OAEP_oid, "RSAES-OAEP");
1006 
nameTable.put(pbeWithMD5AndDES_oid, R)1007         nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES");
nameTable.put(pbeWithMD5AndRC2_oid, R)1008         nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2");
nameTable.put(pbeWithSHA1AndDES_oid, R)1009         nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES");
nameTable.put(pbeWithSHA1AndRC2_oid, R)1010         nameTable.put(pbeWithSHA1AndRC2_oid, "PBEWithSHA1AndRC2");
nameTable.put(pbeWithSHA1AndRC4_128_oid, R)1011         nameTable.put(pbeWithSHA1AndRC4_128_oid, "PBEWithSHA1AndRC4_128");
nameTable.put(pbeWithSHA1AndRC4_40_oid, R)1012         nameTable.put(pbeWithSHA1AndRC4_40_oid, "PBEWithSHA1AndRC4_40");
nameTable.put(pbeWithSHA1AndDESede_oid, R)1013         nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede");
nameTable.put(pbeWithSHA1AndRC2_128_oid, R)1014         nameTable.put(pbeWithSHA1AndRC2_128_oid, "PBEWithSHA1AndRC2_128");
nameTable.put(pbeWithSHA1AndRC2_40_oid, R)1015         nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40");
1016     }
1017 
1018     /**
1019      * Creates a signature algorithm name from a digest algorithm
1020      * name and a encryption algorithm name.
1021      */
makeSigAlg(String digAlg, String encAlg)1022     public static String makeSigAlg(String digAlg, String encAlg) {
1023         digAlg = digAlg.replace("-", "");
1024         if (encAlg.equalsIgnoreCase("EC")) encAlg = "ECDSA";
1025 
1026         return digAlg + "with" + encAlg;
1027     }
1028 
1029     /**
1030      * Extracts the encryption algorithm name from a signature
1031      * algorithm name.
1032       */
getEncAlgFromSigAlg(String signatureAlgorithm)1033     public static String getEncAlgFromSigAlg(String signatureAlgorithm) {
1034         signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH);
1035         int with = signatureAlgorithm.indexOf("WITH");
1036         String keyAlgorithm = null;
1037         if (with > 0) {
1038             int and = signatureAlgorithm.indexOf("AND", with + 4);
1039             if (and > 0) {
1040                 keyAlgorithm = signatureAlgorithm.substring(with + 4, and);
1041             } else {
1042                 keyAlgorithm = signatureAlgorithm.substring(with + 4);
1043             }
1044             if (keyAlgorithm.equalsIgnoreCase("ECDSA")) {
1045                 keyAlgorithm = "EC";
1046             }
1047         }
1048         return keyAlgorithm;
1049     }
1050 
1051     /**
1052      * Extracts the digest algorithm name from a signature
1053      * algorithm name.
1054       */
getDigAlgFromSigAlg(String signatureAlgorithm)1055     public static String getDigAlgFromSigAlg(String signatureAlgorithm) {
1056         signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH);
1057         int with = signatureAlgorithm.indexOf("WITH");
1058         if (with > 0) {
1059             return signatureAlgorithm.substring(0, with);
1060         }
1061         return null;
1062     }
1063 
1064     /**
1065      * Checks if a signature algorithm matches a key algorithm, i.e. a
1066      * signature can be initialized with a key.
1067      *
1068      * @param kAlg must not be null
1069      * @param sAlg must not be null
1070      * @throws IllegalArgumentException if they do not match
1071      */
checkKeyAndSigAlgMatch(String kAlg, String sAlg)1072     public static void checkKeyAndSigAlgMatch(String kAlg, String sAlg) {
1073         String sAlgUp = sAlg.toUpperCase(Locale.US);
1074         if ((sAlgUp.endsWith("WITHRSA") && !kAlg.equalsIgnoreCase("RSA")) ||
1075                 (sAlgUp.endsWith("WITHECDSA") && !kAlg.equalsIgnoreCase("EC")) ||
1076                 (sAlgUp.endsWith("WITHDSA") && !kAlg.equalsIgnoreCase("DSA"))) {
1077             throw new IllegalArgumentException(
1078                     "key algorithm not compatible with signature algorithm");
1079         }
1080     }
1081 
1082     /**
1083      * Returns the default signature algorithm for a private key. The digest
1084      * part might evolve with time. Remember to update the spec of
1085      * {@link jdk.security.jarsigner.JarSigner.Builder#getDefaultSignatureAlgorithm(PrivateKey)}
1086      * if updated.
1087      *
1088      * @param k cannot be null
1089      * @return the default alg, might be null if unsupported
1090      */
getDefaultSigAlgForKey(PrivateKey k)1091     public static String getDefaultSigAlgForKey(PrivateKey k) {
1092         switch (k.getAlgorithm().toUpperCase(Locale.ENGLISH)) {
1093             case "EC":
1094                 return ecStrength(KeyUtil.getKeySize(k))
1095                     + "withECDSA";
1096             case "DSA":
1097                 return ifcFfcStrength(KeyUtil.getKeySize(k))
1098                     + "withDSA";
1099             case "RSA":
1100                 return ifcFfcStrength(KeyUtil.getKeySize(k))
1101                     + "withRSA";
1102             case "RSASSA-PSS":
1103                 return "RSASSA-PSS";
1104             default:
1105                 return null;
1106         }
1107     }
1108 
1109     // Most commonly used PSSParameterSpec and AlgorithmId
1110     private static class PSSParamsHolder {
1111 
1112         final static PSSParameterSpec PSS_256_SPEC = new PSSParameterSpec(
1113                 "SHA-256", "MGF1",
1114                 new MGF1ParameterSpec("SHA-256"),
1115                 32, PSSParameterSpec.TRAILER_FIELD_BC);
1116         final static PSSParameterSpec PSS_384_SPEC = new PSSParameterSpec(
1117                 "SHA-384", "MGF1",
1118                 new MGF1ParameterSpec("SHA-384"),
1119                 48, PSSParameterSpec.TRAILER_FIELD_BC);
1120         final static PSSParameterSpec PSS_512_SPEC = new PSSParameterSpec(
1121                 "SHA-512", "MGF1",
1122                 new MGF1ParameterSpec("SHA-512"),
1123                 64, PSSParameterSpec.TRAILER_FIELD_BC);
1124 
1125         final static AlgorithmId PSS_256_ID;
1126         final static AlgorithmId PSS_384_ID;
1127         final static AlgorithmId PSS_512_ID;
1128 
1129         static {
1130             try {
1131                 PSS_256_ID = new AlgorithmId(RSASSA_PSS_oid,
1132                         new DerValue(PSSParameters.getEncoded(PSS_256_SPEC)));
1133                 PSS_384_ID = new AlgorithmId(RSASSA_PSS_oid,
1134                         new DerValue(PSSParameters.getEncoded(PSS_384_SPEC)));
1135                 PSS_512_ID = new AlgorithmId(RSASSA_PSS_oid,
1136                         new DerValue(PSSParameters.getEncoded(PSS_512_SPEC)));
1137             } catch (IOException e) {
1138                 throw new AssertionError("Should not happen", e);
1139             }
1140         }
1141     }
1142 
getWithParameterSpec(String algName, AlgorithmParameterSpec spec)1143     public static AlgorithmId getWithParameterSpec(String algName,
1144             AlgorithmParameterSpec spec) throws NoSuchAlgorithmException {
1145 
1146         if (spec == null) {
1147             return AlgorithmId.get(algName);
1148         } else if (spec == PSSParamsHolder.PSS_256_SPEC) {
1149             return PSSParamsHolder.PSS_256_ID;
1150         } else if (spec == PSSParamsHolder.PSS_384_SPEC) {
1151             return PSSParamsHolder.PSS_384_ID;
1152         } else if (spec == PSSParamsHolder.PSS_512_SPEC) {
1153             return PSSParamsHolder.PSS_512_ID;
1154         } else {
1155             try {
1156                 AlgorithmParameters result =
1157                         AlgorithmParameters.getInstance(algName);
1158                 result.init(spec);
1159                 return get(result);
1160             } catch (InvalidParameterSpecException | NoSuchAlgorithmException e) {
1161                 throw new ProviderException(e);
1162             }
1163         }
1164     }
1165 
getDefaultAlgorithmParameterSpec( String sigAlg, PrivateKey k)1166     public static PSSParameterSpec getDefaultAlgorithmParameterSpec(
1167             String sigAlg, PrivateKey k) {
1168         if (sigAlg.equalsIgnoreCase("RSASSA-PSS")) {
1169             switch (ifcFfcStrength(KeyUtil.getKeySize(k))) {
1170                 case "SHA256":
1171                     return PSSParamsHolder.PSS_256_SPEC;
1172                 case "SHA384":
1173                     return PSSParamsHolder.PSS_384_SPEC;
1174                 case "SHA512":
1175                     return PSSParamsHolder.PSS_512_SPEC;
1176                 default:
1177                     throw new AssertionError("Should not happen");
1178             }
1179         } else {
1180             return null;
1181         }
1182     }
1183 
1184     // Values from SP800-57 part 1 rev 4 tables 2 and 3
ecStrength(int bitLength)1185     private static String ecStrength (int bitLength) {
1186         if (bitLength >= 512) { // 256 bits of strength
1187             return "SHA512";
1188         } else if (bitLength >= 384) {  // 192 bits of strength
1189             return "SHA384";
1190         } else { // 128 bits of strength and less
1191             return "SHA256";
1192         }
1193     }
1194 
1195     // Same values for RSA and DSA
ifcFfcStrength(int bitLength)1196     private static String ifcFfcStrength (int bitLength) {
1197         if (bitLength > 7680) { // 256 bits
1198             return "SHA512";
1199         } else if (bitLength > 3072) {  // 192 bits
1200             return "SHA384";
1201         } else  { // 128 bits and less
1202             return "SHA256";
1203         }
1204     }
1205 }
1206