1 /**
2 * OID Registry
3 * 
4 * Copyright:
5 * (C) 1999-2007 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.asn1.oids;
12 
13 import botan.constants;
14 public import botan.asn1.asn1_oid;
15 import memutils.hashmap;
16 import botan.utils.types;
17 import core.sys.posix.signal;
18 import core.sys.posix.unistd;
19 
20 struct OIDS {
21 
22 private static:
23     void addOidstr(string oidstr, string name)
24     {
25         auto oid_str = OID(oidstr);
26         addOid(oid_str, name);
27     }    
28     
29     void addOid(in OID oid, in string name)
30     {
31         globalOidMap().addOid(oid, name);
32     }
33 
34     /**
35     * Register an OID to string mapping.
36     * 
37     * Params:
38     *  oid = the oid to register
39     *  name = the name to be associated with the oid
40     */
41     void addOid2str(in OID oid, in string name)
42     {
43         globalOidMap().addOid2str(oid, name);
44     }
45 
46 
47     /// ditto
48     void addStr2oid(in OID oid, in string name)
49     {
50         globalOidMap().addStr2oid(oid, name);
51     }
52 
53 public:
54     /**
55     * See if an OID exists in the internal table.
56     * 
57     * Params:
58     *  oid = the oid to check for
59     * 
60     * Returns: true if the oid is registered
61     */
62     bool haveOid(in string name)
63     {
64         return globalOidMap().haveOid(name);
65     }
66 
67     /**
68     * Resolve an OID
69     * 
70     * Params:
71     *  oid = the OID to look up
72     * 
73     * Returns: name associated with this OID
74     */
75     string lookup(in OID oid)
76     {
77         return globalOidMap().lookup(oid);
78     }
79 
80     /**
81     * Find the OID to a name. The lookup will be performed in the
82     * general OID section of the configuration.
83     * 
84     * Params:
85     *  name = the name to resolve
86     * 
87     * Returns: OID associated with the specified name
88     */
89     OID lookup(in string name)
90     {
91         return globalOidMap().lookup(name);
92     }
93 
94     /**
95     * Tests whether the specified OID stands for the specified name.
96     * 
97     * Params:
98     *  oid = the OID to check
99     *  name = the name to check
100     * 
101     * Returns: true if the specified OID stands for the specified name
102     */
103     bool nameOf(in OID oid, in string name)
104     {
105         return (oid == lookup(name));
106     }
107 
108     /*
109     * Load all of the default OIDs
110     */
111     static void setDefaults()
112     {
113         /* Public key types */
114         addOidstr("1.2.840.113549.1.1.1", "RSA");
115         assert(lookup(OID("1.2.840.113549.1.1.1")) == "RSA");
116         addOidstr("2.5.8.1.1", "RSA"); // RSA alternate
117         addOidstr("1.2.840.10040.4.1", "DSA");
118         assert(lookup(OID("1.2.840.10040.4.1")) == "DSA");
119         addOidstr("1.2.840.10046.2.1", "DH");
120         addOidstr("1.3.6.1.4.1.3029.1.2.1", "ElGamal");
121         addOidstr("1.3.6.1.4.1.25258.1.1", "RW");
122         addOidstr("1.3.6.1.4.1.25258.1.2", "NR");
123 		addOidstr("1.3.6.1.4.1.25258.1.4", "Curve25519");
124 		addOidstr("1.3.6.1.4.1.11591.15.1", "Curve25519");
125         // X9.62 ecPublicKey, valid for ECDSA and ECDH (RFC 3279 sec 2.3.5)
126         addOidstr("1.2.840.10045.2.1", "ECDSA");
127         
128         /*
129         * This is an OID defined for ECDH keys though rarely used for such.
130         * In this configuration it is accepted on decoding, but not used for
131         * encoding. You can enable it for encoding by calling
132         * OIDS.addStr2oid("ECDH", "1.3.132.1.12")
133         * from your application code.
134         */
135         addOid2str(OID("1.3.132.1.12"), "ECDH");
136         
137         addOidstr("1.2.643.2.2.19", "GOST-34.10"); // RFC 4491
138         
139         /* Ciphers */
140         addOidstr("1.3.14.3.2.7", "DES/CBC");
141         addOidstr("1.2.840.113549.3.7", "TripleDES/CBC");
142         addOidstr("1.2.840.113549.3.2", "RC2/CBC");
143         addOidstr("1.2.840.113533.7.66.10", "CAST-128/CBC");
144         addOidstr("2.16.840.1.101.3.4.1.2", "AES-128/CBC");
145         addOidstr("2.16.840.1.101.3.4.1.22", "AES-192/CBC");
146         addOidstr("2.16.840.1.101.3.4.1.42", "AES-256/CBC");
147         addOidstr("1.2.410.200004.1.4", "SEED/CBC"); // RFC 4010
148         addOidstr("1.3.6.1.4.1.25258.3.1", "Serpent/CBC");
149 		addOidstr("1.3.6.1.4.1.25258.3.2", "Threefish-512/CBC");
150 		addOidstr("1.3.6.1.4.1.25258.3.3", "Twofish/CBC");
151 		addOidstr("2.16.840.1.101.3.4.1.6", "AES-128/GCM");
152 		addOidstr("2.16.840.1.101.3.4.1.26", "AES-192/GCM");
153 		addOidstr("2.16.840.1.101.3.4.1.46", "AES-256/GCM");
154 		addOidstr("1.3.6.1.4.1.25258.3.101", "Serpent/GCM");
155 		addOidstr("1.3.6.1.4.1.25258.3.102", "Twofish/GCM");
156 		addOidstr("1.3.6.1.4.1.25258.3.2.1", "AES-128/OCB");
157 		addOidstr("1.3.6.1.4.1.25258.3.2.2", "AES-192/OCB");
158 		addOidstr("1.3.6.1.4.1.25258.3.2.3", "AES-256/OCB");
159 		addOidstr("1.3.6.1.4.1.25258.3.2.4", "Serpent/OCB");
160 		addOidstr("1.3.6.1.4.1.25258.3.2.5", "Twofish/OCB");
161 
162 		/* Hash Functions */
163         addOidstr("1.2.840.113549.2.5", "MD5");
164         addOidstr("1.3.6.1.4.1.11591.12.2", "Tiger(24,3)");
165         
166         addOidstr("1.3.14.3.2.26", "SHA-160");
167         addOidstr("2.16.840.1.101.3.4.2.4", "SHA-224");
168         addOidstr("2.16.840.1.101.3.4.2.1", "SHA-256");
169         addOidstr("2.16.840.1.101.3.4.2.2", "SHA-384");
170         addOidstr("2.16.840.1.101.3.4.2.3", "SHA-512");
171         
172         /* MACs */
173         addOidstr("1.2.840.113549.2.7", "HMAC(SHA-160)");
174         addOidstr("1.2.840.113549.2.8", "HMAC(SHA-224)");
175         addOidstr("1.2.840.113549.2.9", "HMAC(SHA-256)");
176         addOidstr("1.2.840.113549.2.10", "HMAC(SHA-384)");
177         addOidstr("1.2.840.113549.2.11", "HMAC(SHA-512)");
178         
179         /* Key Wrap */
180         addOidstr("1.2.840.113549.1.9.16.3.6", "KeyWrap.TripleDES");
181         addOidstr("1.2.840.113549.1.9.16.3.7", "KeyWrap.RC2");
182         addOidstr("1.2.840.113533.7.66.15", "KeyWrap.CAST-128");
183         addOidstr("2.16.840.1.101.3.4.1.5", "KeyWrap.AES-128");
184         addOidstr("2.16.840.1.101.3.4.1.25", "KeyWrap.AES-192");
185         addOidstr("2.16.840.1.101.3.4.1.45", "KeyWrap.AES-256");
186         
187         /* Compression */
188         addOidstr("1.2.840.113549.1.9.16.3.8", "Compression.Zlib");
189         
190         /* Public key signature schemes */
191         addOidstr("1.2.840.113549.1.1.1", "RSA/EME-PKCS1-v1_5");
192         addOidstr("1.2.840.113549.1.1.2", "RSA/EMSA3(MD2)");
193         addOidstr("1.2.840.113549.1.1.4", "RSA/EMSA3(MD5)");
194         addOidstr("1.2.840.113549.1.1.5", "RSA/EMSA3(SHA-160)");
195         addOidstr("1.2.840.113549.1.1.11", "RSA/EMSA3(SHA-256)");
196         addOidstr("1.2.840.113549.1.1.12", "RSA/EMSA3(SHA-384)");
197         addOidstr("1.2.840.113549.1.1.13", "RSA/EMSA3(SHA-512)");
198         addOidstr("1.3.36.3.3.1.2", "RSA/EMSA3(RIPEMD-160)");
199         
200         addOidstr("1.2.840.10040.4.3", "DSA/EMSA1(SHA-160)");
201         addOidstr("2.16.840.1.101.3.4.3.1", "DSA/EMSA1(SHA-224)");
202         addOidstr("2.16.840.1.101.3.4.3.2", "DSA/EMSA1(SHA-256)");
203         
204         addOidstr("0.4.0.127.0.7.1.1.4.1.1", "ECDSA/EMSA1_BSI(SHA-160)");
205         addOidstr("0.4.0.127.0.7.1.1.4.1.2", "ECDSA/EMSA1_BSI(SHA-224)");
206         addOidstr("0.4.0.127.0.7.1.1.4.1.3", "ECDSA/EMSA1_BSI(SHA-256)");
207         addOidstr("0.4.0.127.0.7.1.1.4.1.4", "ECDSA/EMSA1_BSI(SHA-384)");
208         addOidstr("0.4.0.127.0.7.1.1.4.1.5", "ECDSA/EMSA1_BSI(SHA-512)");
209         addOidstr("0.4.0.127.0.7.1.1.4.1.6", "ECDSA/EMSA1_BSI(RIPEMD-160)");
210         
211         addOidstr("1.2.840.10045.4.1", "ECDSA/EMSA1(SHA-160)");
212         addOidstr("1.2.840.10045.4.3.1", "ECDSA/EMSA1(SHA-224)");
213         addOidstr("1.2.840.10045.4.3.2", "ECDSA/EMSA1(SHA-256)");
214         addOidstr("1.2.840.10045.4.3.3", "ECDSA/EMSA1(SHA-384)");
215         addOidstr("1.2.840.10045.4.3.4", "ECDSA/EMSA1(SHA-512)");
216         
217         addOidstr("1.2.643.2.2.3", "GOST-34.10/EMSA1(GOST-R-34.11-94)");
218         
219         addOidstr("1.3.6.1.4.1.25258.2.1.1.1", "RW/EMSA2(RIPEMD-160)");
220         addOidstr("1.3.6.1.4.1.25258.2.1.1.2", "RW/EMSA2(SHA-160)");
221         addOidstr("1.3.6.1.4.1.25258.2.1.1.3", "RW/EMSA2(SHA-224)");
222         addOidstr("1.3.6.1.4.1.25258.2.1.1.4", "RW/EMSA2(SHA-256)");
223         addOidstr("1.3.6.1.4.1.25258.2.1.1.5", "RW/EMSA2(SHA-384)");
224         addOidstr("1.3.6.1.4.1.25258.2.1.1.6", "RW/EMSA2(SHA-512)");
225         
226         addOidstr("1.3.6.1.4.1.25258.2.1.2.1", "RW/EMSA4(RIPEMD-160)");
227         addOidstr("1.3.6.1.4.1.25258.2.1.2.2", "RW/EMSA4(SHA-160)");
228         addOidstr("1.3.6.1.4.1.25258.2.1.2.3", "RW/EMSA4(SHA-224)");
229         addOidstr("1.3.6.1.4.1.25258.2.1.2.4", "RW/EMSA4(SHA-256)");
230         addOidstr("1.3.6.1.4.1.25258.2.1.2.5", "RW/EMSA4(SHA-384)");
231         addOidstr("1.3.6.1.4.1.25258.2.1.2.6", "RW/EMSA4(SHA-512)");
232         
233         addOidstr("1.3.6.1.4.1.25258.2.2.1.1", "NR/EMSA2(RIPEMD-160)");
234         addOidstr("1.3.6.1.4.1.25258.2.2.1.2", "NR/EMSA2(SHA-160)");
235         addOidstr("1.3.6.1.4.1.25258.2.2.1.3", "NR/EMSA2(SHA-224)");
236         addOidstr("1.3.6.1.4.1.25258.2.2.1.4", "NR/EMSA2(SHA-256)");
237         addOidstr("1.3.6.1.4.1.25258.2.2.1.5", "NR/EMSA2(SHA-384)");
238         addOidstr("1.3.6.1.4.1.25258.2.2.1.6", "NR/EMSA2(SHA-512)");
239         
240         addOidstr("2.5.4.3",  "X520.CommonName");
241         addOidstr("2.5.4.4",  "X520.Surname");
242         addOidstr("2.5.4.5",  "X520.SerialNumber");
243         addOidstr("2.5.4.6",  "X520.Country");
244         addOidstr("2.5.4.7",  "X520.Locality");
245         addOidstr("2.5.4.8",  "X520.State");
246         addOidstr("2.5.4.10", "X520.Organization");
247         addOidstr("2.5.4.11", "X520.OrganizationalUnit");
248         addOidstr("2.5.4.12", "X520.Title");
249         addOidstr("2.5.4.42", "X520.GivenName");
250         addOidstr("2.5.4.43", "X520.Initials");
251         addOidstr("2.5.4.44", "X520.GenerationalQualifier");
252         addOidstr("2.5.4.46", "X520.DNQualifier");
253         addOidstr("2.5.4.65", "X520.Pseudonym");
254         
255         addOidstr("1.2.840.113549.1.5.12", "PKCS5.PBKDF2");
256         addOidstr("1.2.840.113549.1.5.13", "PBE-PKCS5v20");
257         
258         addOidstr("1.2.840.113549.1.9.1", "PKCS9.EmailAddress");
259         addOidstr("1.2.840.113549.1.9.2", "PKCS9.UnstructuredName");
260         addOidstr("1.2.840.113549.1.9.3", "PKCS9.ContentType");
261         addOidstr("1.2.840.113549.1.9.4", "PKCS9.MessageDigest");
262         addOidstr("1.2.840.113549.1.9.7", "PKCS9.ChallengePassword");
263         addOidstr("1.2.840.113549.1.9.14", "PKCS9.ExtensionRequest");
264         
265         addOidstr("1.2.840.113549.1.7.1",        "CMS.DataContent");
266         addOidstr("1.2.840.113549.1.7.2",        "CMS.SignedData");
267         addOidstr("1.2.840.113549.1.7.3",        "CMS.EnvelopedData");
268         addOidstr("1.2.840.113549.1.7.5",        "CMS.DigestedData");
269         addOidstr("1.2.840.113549.1.7.6",        "CMS.EncryptedData");
270         addOidstr("1.2.840.113549.1.9.16.1.2", "CMS.AuthenticatedData");
271         addOidstr("1.2.840.113549.1.9.16.1.9", "CMS.CompressedData");
272         
273         addOidstr("2.5.29.14", "X509v3.SubjectKeyIdentifier");
274         addOidstr("2.5.29.15", "X509v3.KeyUsage");
275         addOidstr("2.5.29.17", "X509v3.SubjectAlternativeName");
276         addOidstr("2.5.29.18", "X509v3.IssuerAlternativeName");
277         addOidstr("2.5.29.19", "X509v3.BasicConstraints");
278         addOidstr("2.5.29.20", "X509v3.CRLNumber");
279         addOidstr("2.5.29.21", "X509v3.ReasonCode");
280         addOidstr("2.5.29.23", "X509v3.HoldInstructionCode");
281         addOidstr("2.5.29.24", "X509v3.InvalidityDate");
282         addOidstr("2.5.29.31", "X509v3.CRLDistributionPoints");
283         addOidstr("2.5.29.32", "X509v3.CertificatePolicies");
284         addOidstr("2.5.29.35", "X509v3.AuthorityKeyIdentifier");
285         addOidstr("2.5.29.36", "X509v3.PolicyConstraints");
286         addOidstr("2.5.29.37", "X509v3.ExtendedKeyUsage");
287         addOidstr("1.3.6.1.5.5.7.1.1", "PKIX.AuthorityInformationAccess");
288         
289         addOidstr("2.5.29.32.0", "X509v3.AnyPolicy");
290         
291         addOidstr("1.3.6.1.5.5.7.3.1", "PKIX.ServerAuth");
292         addOidstr("1.3.6.1.5.5.7.3.2", "PKIX.ClientAuth");
293         addOidstr("1.3.6.1.5.5.7.3.3", "PKIX.CodeSigning");
294         addOidstr("1.3.6.1.5.5.7.3.4", "PKIX.EmailProtection");
295         addOidstr("1.3.6.1.5.5.7.3.5", "PKIX.IPsecEndSystem");
296         addOidstr("1.3.6.1.5.5.7.3.6", "PKIX.IPsecTunnel");
297         addOidstr("1.3.6.1.5.5.7.3.7", "PKIX.IPsecUser");
298         addOidstr("1.3.6.1.5.5.7.3.8", "PKIX.TimeStamping");
299         addOidstr("1.3.6.1.5.5.7.3.9", "PKIX.OCSPSigning");
300         
301         addOidstr("1.3.6.1.5.5.7.8.5", "PKIX.XMPPAddr");
302         
303         addOidstr("1.3.6.1.5.5.7.48.1", "PKIX.OCSP");
304         addOidstr("1.3.6.1.5.5.7.48.1.1", "PKIX.OCSP.BasicResponse");
305         
306         /* ECC domain parameters */
307         addOidstr("1.3.132.0.6",  "secp112r1");
308         addOidstr("1.3.132.0.7",  "secp112r2");
309         addOidstr("1.3.132.0.8",  "secp160r1");
310         addOidstr("1.3.132.0.9",  "secp160k1");
311         addOidstr("1.3.132.0.10", "secp256k1");
312         addOidstr("1.3.132.0.28", "secp128r1");
313         addOidstr("1.3.132.0.29", "secp128r2");
314         addOidstr("1.3.132.0.30", "secp160r2");
315         addOidstr("1.3.132.0.31", "secp192k1");
316         addOidstr("1.3.132.0.32", "secp224k1");
317         addOidstr("1.3.132.0.33", "secp224r1");
318         addOidstr("1.3.132.0.34", "secp384r1");
319         addOidstr("1.3.132.0.35", "secp521r1");
320         
321         addOidstr("1.2.840.10045.3.1.1", "secp192r1");
322         addOidstr("1.2.840.10045.3.1.2", "x962_p192v2");
323         addOidstr("1.2.840.10045.3.1.3", "x962_p192v3");
324         addOidstr("1.2.840.10045.3.1.4", "x962_p239v1");
325         addOidstr("1.2.840.10045.3.1.5", "x962_p239v2");
326         addOidstr("1.2.840.10045.3.1.6", "x962_p239v3");
327         addOidstr("1.2.840.10045.3.1.7", "secp256r1");
328         
329         addOidstr("1.3.36.3.3.2.8.1.1.1",  "brainpool160r1");
330         addOidstr("1.3.36.3.3.2.8.1.1.3",  "brainpool192r1");
331         addOidstr("1.3.36.3.3.2.8.1.1.5",  "brainpool224r1");
332         addOidstr("1.3.36.3.3.2.8.1.1.7",  "brainpool256r1");
333         addOidstr("1.3.36.3.3.2.8.1.1.9",  "brainpool320r1");
334         addOidstr("1.3.36.3.3.2.8.1.1.11", "brainpool384r1");
335         addOidstr("1.3.36.3.3.2.8.1.1.13", "brainpool512r1");
336         
337         addOidstr("1.2.643.2.2.35.1", "gost_256A");
338         addOidstr("1.2.643.2.2.36.0", "gost_256A");
339         
340         /* CVC */
341         addOidstr("0.4.0.127.0.7.3.1.2.1", "CertificateHolderAuthorizationTemplate");
342     }
343 }
344 
345 class OIDMap
346 {
347 public:
348     void addOid(in OID oid, in string str)
349     {
350         //logTrace("addOid: ", str);
351         addStr2oid(oid, str);
352         addOid2str(oid, str);
353     }
354     
355     void addStr2oid(in OID oid, in string str)
356     {
357         if (!haveOid(str))
358             m_str2oid[str] = oid;
359     }
360     
361     void addOid2str(in OID oid, in string str)
362     {
363         if (m_oid2str.get(oid) == string.init) 
364             m_oid2str ~= OID2STR(oid.clone, str);
365     }
366 
367     string lookup(in OID oid)
368     {
369         auto str = m_oid2str.get(oid);
370         //scope(exit) logTrace("OID lookup found: ", str);
371         if (str)
372             return str;
373         
374         return string.init;
375     }
376     
377     OID lookup(in string str)
378     {
379 
380         if (str in m_str2oid)
381             return m_str2oid[str];
382         
383         // Try to parse as plain OID
384         try
385         {
386             return OID(str);
387         }
388         catch(Throwable) {}
389         
390         throw new LookupError("No object identifier found for " ~ str);
391     }
392     
393     bool haveOid(in string str)
394     {
395         return (str in m_str2oid) !is null;
396     }
397     
398 private:
399     HashMap!(string, OID) m_str2oid;
400     Vector!(OID2STR) m_oid2str;
401 }
402 
403 private:
404 
405 string get(ref Vector!OID2STR vec, const ref OID oid) {
406 	foreach (ref OID2STR oids; vec[]) {
407 		if (oids.oid == oid)
408 			return oids.str;
409 	}
410 	return string.init;
411 }
412 
413 struct OID2STR {
414 	OID oid;
415 	string str;
416 }
417 
418 OIDMap globalOidMap(bool free = false)
419 {
420     static OIDMap map;
421 	if (free && map) {
422 		if (map.m_str2oid.length > 0) {
423 			map.m_str2oid.clear();
424 			map.m_str2oid.destroy();
425 		}
426 		if (map.m_oid2str.length > 0) {
427 			map.m_oid2str.clear();
428 			map.m_oid2str.destroy();
429 		}
430 		map = null;
431 		return null;
432 	}
433 	else if (!free && !map) map = new OIDMap;
434     return map;
435 }
436 
437 static ~this() {
438 	globalOidMap(true);
439 }