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