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