1 /*
  2  * Copyright (c) 2020, 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.util;
 27 
 28 import java.util.List;
 29 import java.util.Locale;
 30 import java.util.Objects;
 31 import java.util.concurrent.ConcurrentHashMap;
 32 
 33 /**
 34  * This utility class maps algorithm name to the corresponding oid strings.
 35  * NOTE: for 100% backward compatibility, the standard name for the enum
 36  * is determined by existing usage and may be in lowercase/uppercase in
 37  * order to match existing output.
 38  */
 39 public enum KnownOIDs {
 40 
 41     // X.500 Attributes 2.5.4.*
 42     CommonName("2.5.4.3"),
 43     Surname("2.5.4.4"),
 44     SerialNumber("2.5.4.5"),
 45     CountryName("2.5.4.6"),
 46     LocalityName("2.5.4.7"),
 47     StateName("2.5.4.8"),
 48     StreetAddress("2.5.4.9"),
 49     OrgName("2.5.4.10"),
 50     OrgUnitName("2.5.4.11"),
 51     Title("2.5.4.12"),
 52     GivenName("2.5.4.42"),
 53     Initials("2.5.4.43"),
 54     GenerationQualifier("2.5.4.44"),
 55     DNQualifier("2.5.4.46"),
 56 
 57     // Certificate Extension 2.5.29.*
 58     SubjectDirectoryAttributes("2.5.29.9"),
 59     SubjectKeyID("2.5.29.14"),
 60     KeyUsage("2.5.29.15"),
 61     PrivateKeyUsage("2.5.29.16"),
 62     SubjectAlternativeName("2.5.29.17"),
 63     IssuerAlternativeName("2.5.29.18"),
 64     BasicConstraints("2.5.29.19"),
 65     CRLNumber("2.5.29.20"),
 66     ReasonCode("2.5.29.21"),
 67     HoldInstructionCode("2.5.29.23"),
 68     InvalidityDate("2.5.29.24"),
 69     DeltaCRLIndicator("2.5.29.27"),
 70     IssuingDistributionPoint("2.5.29.28"),
 71     CertificateIssuer("2.5.29.29"),
 72     NameConstraints("2.5.29.30"),
 73     CRLDistributionPoints("2.5.29.31"),
 74     CertificatePolicies("2.5.29.32"),
 75     CE_CERT_POLICIES_ANY("2.5.29.32.0"),
 76     PolicyMappings("2.5.29.33"),
 77     AuthorityKeyID("2.5.29.35"),
 78     PolicyConstraints("2.5.29.36"),
 79     extendedKeyUsage("2.5.29.37"),
 80     anyExtendedKeyUsage("2.5.29.37.0"),
 81     FreshestCRL("2.5.29.46"),
 82     InhibitAnyPolicy("2.5.29.54"),
 83 
 84     // PKIX 1.3.6.1.5.5.7.
 85     AuthInfoAccess("1.3.6.1.5.5.7.1.1"),
 86     SubjectInfoAccess("1.3.6.1.5.5.7.1.11"),
 87     // key usage purposes - PKIX.3.*
 88     serverAuth("1.3.6.1.5.5.7.3.1"),
 89     clientAuth("1.3.6.1.5.5.7.3.2"),
 90     codeSigning("1.3.6.1.5.5.7.3.3"),
 91     emailProtection("1.3.6.1.5.5.7.3.4"),
 92     ipsecEndSystem("1.3.6.1.5.5.7.3.5"),
 93     ipsecTunnel("1.3.6.1.5.5.7.3.6"),
 94     ipsecUser("1.3.6.1.5.5.7.3.7"),
 95     KP_TimeStamping("1.3.6.1.5.5.7.3.8", "timeStamping") {
 96         @Override
 97         boolean registerNames() { return false; }
 98     },
 99     OCSPSigning("1.3.6.1.5.5.7.3.9"),
100     // access descriptors - PKIX.48.*
101     OCSP("1.3.6.1.5.5.7.48.1"),
102     OCSPBasicResponse("1.3.6.1.5.5.7.48.1.1"),
103     OCSPNonceExt("1.3.6.1.5.5.7.48.1.2"),
104     OCSPNoCheck("1.3.6.1.5.5.7.48.1.5"),
105     caIssuers("1.3.6.1.5.5.7.48.2"),
106     AD_TimeStamping("1.3.6.1.5.5.7.48.3", "timeStamping") {
107         @Override
108         boolean registerNames() { return false; }
109     },
110     caRepository("1.3.6.1.5.5.7.48.5", "caRepository"),
111 
112     // NIST --
113     // AES 2.16.840.1.101.3.4.1.*
114     AES("2.16.840.1.101.3.4.1"),
115     AES_128$ECB$NoPadding("2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding"),
116     AES_128$CBC$NoPadding("2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding"),
117     AES_128$OFB$NoPadding("2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding"),
118     AES_128$CFB$NoPadding("2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding"),
119     AESWRAP_128("2.16.840.1.101.3.4.1.5"),
120     AES_128$GCM$NoPadding("2.16.840.1.101.3.4.1.6", "AES_128/GCM/NoPadding"),
121     AES_192$ECB$NoPadding("2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding"),
122     AES_192$CBC$NoPadding("2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding"),
123     AES_192$OFB$NoPadding("2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding"),
124     AES_192$CFB$NoPadding("2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding"),
125     AESWRAP_192("2.16.840.1.101.3.4.1.25"),
126     AES_192$GCM$NoPadding("2.16.840.1.101.3.4.1.26", "AES_192/GCM/NoPadding"),
127     AES_256$ECB$NoPadding("2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding"),
128     AES_256$CBC$NoPadding("2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding"),
129     AES_256$OFB$NoPadding("2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding"),
130     AES_256$CFB$NoPadding("2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding"),
131     AESWRAP_256("2.16.840.1.101.3.4.1.45"),
132     AES_256$GCM$NoPadding("2.16.840.1.101.3.4.1.46", "AES_256/GCM/NoPadding"),
133 
134     // hashAlgs 2.16.840.1.101.3.4.2.*
135     SHA_256("2.16.840.1.101.3.4.2.1", "SHA-256", "SHA256"),
136     SHA_384("2.16.840.1.101.3.4.2.2", "SHA-384", "SHA384"),
137     SHA_512("2.16.840.1.101.3.4.2.3", "SHA-512", "SHA512"),
138     SHA_224("2.16.840.1.101.3.4.2.4", "SHA-224", "SHA224"),
139     SHA_512$224("2.16.840.1.101.3.4.2.5", "SHA-512/224", "SHA512/224"),
140     SHA_512$256("2.16.840.1.101.3.4.2.6", "SHA-512/256", "SHA512/256"),
141     SHA3_224("2.16.840.1.101.3.4.2.7", "SHA3-224"),
142     SHA3_256("2.16.840.1.101.3.4.2.8", "SHA3-256"),
143     SHA3_384("2.16.840.1.101.3.4.2.9", "SHA3-384"),
144     SHA3_512("2.16.840.1.101.3.4.2.10", "SHA3-512"),
145     SHAKE128("2.16.840.1.101.3.4.2.11"),
146     SHAKE256("2.16.840.1.101.3.4.2.12"),
147     HmacSHA3_224("2.16.840.1.101.3.4.2.13", "HmacSHA3-224"),
148     HmacSHA3_256("2.16.840.1.101.3.4.2.14", "HmacSHA3-256"),
149     HmacSHA3_384("2.16.840.1.101.3.4.2.15", "HmacSHA3-384"),
150     HmacSHA3_512("2.16.840.1.101.3.4.2.16", "HmacSHA3-512"),
151 
152     // sigAlgs 2.16.840.1.101.3.4.3.*
153     SHA224withDSA("2.16.840.1.101.3.4.3.1"),
154     SHA256withDSA("2.16.840.1.101.3.4.3.2"),
155     SHA384withDSA("2.16.840.1.101.3.4.3.3"),
156     SHA512withDSA("2.16.840.1.101.3.4.3.4"),
157     SHA3_224withRSA("2.16.840.1.101.3.4.3.13", "SHA3-224withRSA"),
158     SHA3_256withRSA("2.16.840.1.101.3.4.3.14", "SHA3-256withRSA"),
159     SHA3_384withRSA("2.16.840.1.101.3.4.3.15", "SHA3-384withRSA"),
160     SHA3_512withRSA("2.16.840.1.101.3.4.3.16", "SHA3-512withRSA"),
161 
162     // RSASecurity
163     // PKCS1 1.2.840.113549.1.1.*
164     PKCS1("1.2.840.113549.1.1", "RSA") { // RSA KeyPairGenerator and KeyFactory
165         @Override
166         boolean registerNames() { return false; }
167     },
168     RSA("1.2.840.113549.1.1.1"), // RSA encryption
169 
170     MD2withRSA("1.2.840.113549.1.1.2"),
171     MD5withRSA("1.2.840.113549.1.1.4"),
172     SHA1withRSA("1.2.840.113549.1.1.5"),
173     OAEP("1.2.840.113549.1.1.7"),
174     MGF1("1.2.840.113549.1.1.8"),
175     PSpecified("1.2.840.113549.1.1.9"),
176     RSASSA_PSS("1.2.840.113549.1.1.10", "RSASSA-PSS"),
177     SHA256withRSA("1.2.840.113549.1.1.11"),
178     SHA384withRSA("1.2.840.113549.1.1.12"),
179     SHA512withRSA("1.2.840.113549.1.1.13"),
180     SHA224withRSA("1.2.840.113549.1.1.14"),
181     SHA512$224withRSA("1.2.840.113549.1.1.15", "SHA512/224withRSA"),
182     SHA512$256withRSA("1.2.840.113549.1.1.16", "SHA512/256withRSA"),
183 
184     // PKCS3 1.2.840.113549.1.3.*
185     DiffieHellman("1.2.840.113549.1.3.1", "DiffieHellman", "DH"),
186 
187     // PKCS5 1.2.840.113549.1.5.*
188     PBEWithMD5AndDES("1.2.840.113549.1.5.3"),
189     PBEWithMD5AndRC2("1.2.840.113549.1.5.6"),
190     PBEWithSHA1AndDES("1.2.840.113549.1.5.10"),
191     PBEWithSHA1AndRC2("1.2.840.113549.1.5.11"),
192     PBKDF2WithHmacSHA1("1.2.840.113549.1.5.12"),
193     PBES2("1.2.840.113549.1.5.13"),
194 
195     // PKCS7 1.2.840.113549.1.7.*
196     PKCS7("1.2.840.113549.1.7"),
197     Data("1.2.840.113549.1.7.1"),
198     SignedData("1.2.840.113549.1.7.2"),
199     JDK_OLD_Data("1.2.840.1113549.1.7.1"), // extra 1 in 4th component
200     JDK_OLD_SignedData("1.2.840.1113549.1.7.2"),
201     EnvelopedData("1.2.840.113549.1.7.3"),
202     SignedAndEnvelopedData("1.2.840.113549.1.7.4"),
203     DigestedData("1.2.840.113549.1.7.5"),
204     EncryptedData("1.2.840.113549.1.7.6"),
205 
206     // PKCS9 1.2.840.113549.1.9.*
207     EmailAddress("1.2.840.113549.1.9.1"),
208     UnstructuredName("1.2.840.113549.1.9.2"),
209     ContentType("1.2.840.113549.1.9.3"),
210     MessageDigest("1.2.840.113549.1.9.4"),
211     SigningTime("1.2.840.113549.1.9.5"),
212     CounterSignature("1.2.840.113549.1.9.6"),
213     ChallengePassword("1.2.840.113549.1.9.7"),
214     UnstructuredAddress("1.2.840.113549.1.9.8"),
215     ExtendedCertificateAttributes("1.2.840.113549.1.9.9"),
216     IssuerAndSerialNumber("1.2.840.113549.1.9.10"),
217     ExtensionRequest("1.2.840.113549.1.9.14"),
218     SMIMECapability("1.2.840.113549.1.9.15"),
219     TimeStampTokenInfo("1.2.840.113549.1.9.16.1.4"),
220     SigningCertificate("1.2.840.113549.1.9.16.2.12"),
221     SignatureTimestampToken("1.2.840.113549.1.9.16.2.14"),
222     CHACHA20_POLY1305("1.2.840.113549.1.9.16.3.18", "CHACHA20-POLY1305"),
223     FriendlyName("1.2.840.113549.1.9.20"),
224     LocalKeyID("1.2.840.113549.1.9.21"),
225     CertTypeX509("1.2.840.113549.1.9.22.1"),
226 
227     // PKCS12 1.2.840.113549.1.12.*
228     PBEWithSHA1AndRC4_128("1.2.840.113549.1.12.1.1"),
229     PBEWithSHA1AndRC4_40("1.2.840.113549.1.12.1.2"),
230     PBEWithSHA1AndDESede("1.2.840.113549.1.12.1.3"),
231     PBEWithSHA1AndRC2_128("1.2.840.113549.1.12.1.5"),
232     PBEWithSHA1AndRC2_40("1.2.840.113549.1.12.1.6"),
233     PKCS8ShroudedKeyBag("1.2.840.113549.1.12.10.1.2"),
234     CertBag("1.2.840.113549.1.12.10.1.3"),
235     SecretBag("1.2.840.113549.1.12.10.1.5"),
236 
237     // digestAlgs 1.2.840.113549.2.*
238     MD2("1.2.840.113549.2.2"),
239     MD5("1.2.840.113549.2.5"),
240     HmacSHA1("1.2.840.113549.2.7"),
241     HmacSHA224("1.2.840.113549.2.8"),
242     HmacSHA256("1.2.840.113549.2.9"),
243     HmacSHA384("1.2.840.113549.2.10"),
244     HmacSHA512("1.2.840.113549.2.11"),
245     HmacSHA512$224("1.2.840.113549.2.12", "HmacSHA512/224"),
246     HmacSHA512$256("1.2.840.113549.2.13", "HmacSHA512/256"),
247 
248     // encryptionAlgs 1.2.840.113549.3.*
249     RC2$CBC$PKCS5Padding("1.2.840.113549.3.2", "RC2/CBC/PKCS5Padding"),
250     ARCFOUR("1.2.840.113549.3.4", "ARCFOUR", "RC4"),
251     DESede$CBC$NoPadding("1.2.840.113549.3.7", "DESede/CBC/NoPadding"),
252     RC5$CBC$PKCS5Padding("1.2.840.113549.3.9", "RC5/CBC/PKCS5Padding"),
253 
254     // ANSI --
255     // X9 1.2.840.10040.4.*
256     DSA("1.2.840.10040.4.1"),
257     SHA1withDSA("1.2.840.10040.4.3", "SHA1withDSA", "DSS"),
258     // X9.62 1.2.840.10045.*
259     EC("1.2.840.10045.2.1"),
260 
261     //c2pnb163v1("1.2.840.10045.3.0.1", "X9.62 c2pnb163v1"),
262     //c2pnb163v2("1.2.840.10045.3.0.2", "X9.62 c2pnb163v2"),
263     //c2pnb163v3("1.2.840.10045.3.0.3", "X9.62 c2pnb163v3"),
264     //c2pnb176w1("1.2.840.10045.3.0.4", "X9.62 c2pnb176w1"),
265     c2tnb191v1("1.2.840.10045.3.0.5", "X9.62 c2tnb191v1"),
266     c2tnb191v2("1.2.840.10045.3.0.6", "X9.62 c2tnb191v2"),
267     c2tnb191v3("1.2.840.10045.3.0.7", "X9.62 c2tnb191v3"),
268     //c2pnb208w1("1.2.840.10045.3.0.10", "X9.62 c2pnb208w1"),
269     c2tnb239v1("1.2.840.10045.3.0.11", "X9.62 c2tnb239v1"),
270     c2tnb239v2("1.2.840.10045.3.0.12", "X9.62 c2tnb239v2"),
271     c2tnb239v3("1.2.840.10045.3.0.13", "X9.62 c2tnb239v3"),
272     //c2pnb272w1("1.2.840.10045.3.0.16", "X9.62 c2pnb272w1"),
273     //c2pnb304w1("1.2.840.10045.3.0.17", "X9.62 c2pnb304w1"),
274     c2tnb359v1("1.2.840.10045.3.0.18", "X9.62 c2tnb359v1"),
275     //c2pnb368w1("1.2.840.10045.3.0.19", "X9.62 c2pnb368w1"),
276     c2tnb431r1("1.2.840.10045.3.0.20", "X9.62 c2tnb431r1"),
277 
278     secp192r1("1.2.840.10045.3.1.1",
279             "secp192r1", "NIST P-192", "X9.62 prime192v1"),
280     prime192v2("1.2.840.10045.3.1.2", "X9.62 prime192v2"),
281     prime192v3("1.2.840.10045.3.1.3", "X9.62 prime192v3"),
282     prime239v1("1.2.840.10045.3.1.4", "X9.62 prime239v1"),
283     prime239v2("1.2.840.10045.3.1.5", "X9.62 prime239v2"),
284     prime239v3("1.2.840.10045.3.1.6", "X9.62 prime239v3"),
285     secp256r1("1.2.840.10045.3.1.7",
286             "secp256r1", "NIST P-256", "X9.62 prime256v1"),
287     SHA1withECDSA("1.2.840.10045.4.1"),
288     SHA224withECDSA("1.2.840.10045.4.3.1"),
289     SHA256withECDSA("1.2.840.10045.4.3.2"),
290     SHA384withECDSA("1.2.840.10045.4.3.3"),
291     SHA512withECDSA("1.2.840.10045.4.3.4"),
292     SpecifiedSHA2withECDSA("1.2.840.10045.4.3"),
293 
294     // X9.42 1.2.840.10046.2.*
295     X942_DH("1.2.840.10046.2.1", "DiffieHellman") { // unused by JDK providers
296         @Override
297         boolean registerNames() { return false; }
298     },
299 
300     // Teletrust 1.3.36.*
301     brainpoolP160r1("1.3.36.3.3.2.8.1.1.1"),
302     brainpoolP192r1("1.3.36.3.3.2.8.1.1.3"),
303     brainpoolP224r1("1.3.36.3.3.2.8.1.1.5"),
304     brainpoolP256r1("1.3.36.3.3.2.8.1.1.7"),
305     brainpoolP320r1("1.3.36.3.3.2.8.1.1.9"),
306     brainpoolP384r1("1.3.36.3.3.2.8.1.1.11"),
307     brainpoolP512r1("1.3.36.3.3.2.8.1.1.13"),
308 
309     // Certicom 1.3.132.*
310     sect163k1("1.3.132.0.1", "sect163k1", "NIST K-163"),
311     sect163r1("1.3.132.0.2"),
312     sect239k1("1.3.132.0.3"),
313     sect113r1("1.3.132.0.4"),
314     sect113r2("1.3.132.0.5"),
315     secp112r1("1.3.132.0.6"),
316     secp112r2("1.3.132.0.7"),
317     secp160r1("1.3.132.0.8"),
318     secp160k1("1.3.132.0.9"),
319     secp256k1("1.3.132.0.10"),
320     sect163r2("1.3.132.0.15", "sect163r2", "NIST B-163"),
321     sect283k1("1.3.132.0.16", "sect283k1", "NIST K-283"),
322     sect283r1("1.3.132.0.17", "sect283r1", "NIST B-283"),
323 
324     sect131r1("1.3.132.0.22"),
325     sect131r2("1.3.132.0.23"),
326     sect193r1("1.3.132.0.24"),
327     sect193r2("1.3.132.0.25"),
328     sect233k1("1.3.132.0.26", "sect233k1", "NIST K-233"),
329     sect233r1("1.3.132.0.27", "sect233r1", "NIST B-233"),
330     secp128r1("1.3.132.0.28"),
331     secp128r2("1.3.132.0.29"),
332     secp160r2("1.3.132.0.30"),
333     secp192k1("1.3.132.0.31"),
334     secp224k1("1.3.132.0.32"),
335     secp224r1("1.3.132.0.33", "secp224r1", "NIST P-224"),
336     secp384r1("1.3.132.0.34", "secp384r1", "NIST P-384"),
337     secp521r1("1.3.132.0.35", "secp521r1", "NIST P-521"),
338     sect409k1("1.3.132.0.36", "sect409k1", "NIST K-409"),
339     sect409r1("1.3.132.0.37", "sect409r1", "NIST B-409"),
340     sect571k1("1.3.132.0.38", "sect571k1", "NIST K-571"),
341     sect571r1("1.3.132.0.39", "sect571r1", "NIST B-571"),
342 
343     ECDH("1.3.132.1.12"),
344 
345     // OIW secsig 1.3.14.3.*
346     OIW_DES_CBC("1.3.14.3.2.7", "DES/CBC"),
347 
348     OIW_DSA("1.3.14.3.2.12", "DSA") {
349         @Override
350         boolean registerNames() { return false; }
351     },
352 
353     OIW_JDK_SHA1withDSA("1.3.14.3.2.13", "SHA1withDSA") {
354         @Override
355         boolean registerNames() { return false; }
356     },
357 
358     OIW_SHA1withRSA_Odd("1.3.14.3.2.15", "SHA1withRSA") {
359         @Override
360         boolean registerNames() { return false; }
361     },
362 
363     SHA_1("1.3.14.3.2.26", "SHA-1", "SHA", "SHA1"),
364 
365     OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA") {
366         @Override
367         boolean registerNames() { return false; }
368     },
369 
370     OIW_SHA1withRSA("1.3.14.3.2.29", "SHA1withRSA") {
371         @Override
372         boolean registerNames() { return false; }
373     },
374 
375     // Thawte 1.3.101.*
376     X25519("1.3.101.110"),
377     X448("1.3.101.111"),
378     Ed25519("1.3.101.112"),
379     Ed448("1.3.101.113"),
380 
381     // University College London (UCL) 0.9.2342.19200300.*
382     UCL_UserID("0.9.2342.19200300.100.1.1"),
383     UCL_DomainComponent("0.9.2342.19200300.100.1.25"),
384 
385     // Netscape 2.16.840.1.113730.*
386     NETSCAPE_CertType("2.16.840.1.113730.1.1"),
387     NETSCAPE_CertSequence("2.16.840.1.113730.2.5"),
388     NETSCAPE_ExportApproved("2.16.840.1.113730.4.1"),
389 
390     // Oracle 2.16.840.1.113894.*
391     ORACLE_TrustedKeyUsage("2.16.840.1.113894.746875.1.1"),
392 
393     // Miscellaneous oids below which are legacy, and not well known
394     // Consider removing them in future releases when their usage
395     // have died out
396 
397     ITUX509_RSA("2.5.8.1.1", "RSA") { // unused by JDK providers
398                                       // defined in X.509 for RSA keys
399         @Override                     // with modulus length as its parameter
400         boolean registerNames() { return false; }
401     },
402 
403     SkipIPAddress("1.3.6.1.4.1.42.2.11.2.1"),
404     JAVASOFT_JDKKeyProtector("1.3.6.1.4.1.42.2.17.1.1"),
405     JAVASOFT_JCEKeyProtector("1.3.6.1.4.1.42.2.19.1"),
406     MICROSOFT_ExportApproved("1.3.6.1.4.1.311.10.3.3");
407 
408     private String stdName;
409     private String oid;
410     private String[] aliases;
411 
412     // find the matching enum using either name or oid string
413     // return null if no match found
414     public static KnownOIDs findMatch(String s) {
415         s = s.toUpperCase(Locale.ENGLISH);
416         KnownOIDs res = name2enum.get(s);
417         if (res == null && debug != null) {
418             debug.println("No KnownOIDs enum found for " + s);
419         }
420         return res;
421     }
422 
423     private static final Debug debug = Debug.getInstance("jca");
424     //private static final java.io.PrintStream debug = System.out;
425     private static final ConcurrentHashMap<String, KnownOIDs> name2enum =
426             new ConcurrentHashMap<>();
427 
428     static {
429         if (debug != null) {
430             debug.println("Setting up name2enum:");
431         }
432         List.of(KnownOIDs.values()).forEach(o -> {
433             register(o);
434         });
435     }
436 
437     private static void register(KnownOIDs o) {
438         KnownOIDs ov = name2enum.put(o.oid, o);
439         if (ov != null) {
440             throw new RuntimeException("ERROR: Duplicate " + o.oid +
441                     " between " + o + " and " + ov);
442         } else if (debug != null) {
443             debug.println(o.oid + " => " + o.name());
444         }
445         // only register the stdName and aliases if o.registerNames()
446         // returns true
447         if (o.registerNames()) {
448             String stdNameUpper = o.stdName.toUpperCase(Locale.ENGLISH);
449             if (Objects.nonNull(name2enum.put(stdNameUpper, o))) {
450                 throw new RuntimeException("ERROR: Duplicate " +
451                         stdNameUpper + " exists already");
452             }
453             if (debug != null) {
454                 debug.println(stdNameUpper + " => " + o.name());
455             }
456 
457             for (String a :  o.aliases) {
458                 String aliasUpper = a.toUpperCase(Locale.ENGLISH);
459                 if (Objects.nonNull(name2enum.put(aliasUpper, o))) {
460                     throw new RuntimeException("ERROR: Duplicate " +
461                             aliasUpper + " exists already");
462                 }
463                 if (debug != null) {
464                     debug.println(aliasUpper + " => " + o.name());
465                 }
466             }
467         }
468     }
469 
470     private KnownOIDs(String oid) {
471         this.oid = oid;
472         this.stdName = name(); // defaults to enum name
473         this.aliases = new String[0];
474     }
475 
476     private KnownOIDs(String oid, String stdName, String ... aliases) {
477         this.oid = oid;
478         this.stdName = stdName;
479         this.aliases = aliases;
480     }
481 
482     // returns the oid string associated with this enum
483     public String value() {
484         return oid;
485     }
486 
487     // returns the user-friendly standard algorithm name
488     public String stdName() {
489         return stdName;
490     }
491 
492     // return the internal aliases
493     public String[] aliases() {
494         return aliases;
495     }
496 
497     boolean registerNames() {
498         return true;
499     }
500 }