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