blob: 7c1790159a78d640f0804e43d986b67aabae6075 [file] [log] [blame]
Paul Bakkerc70b9822013-04-07 22:00:46 +02001/**
2 * \file oid.c
3 *
4 * \brief Object Identifier (OID) database
5 *
6 * Copyright (C) 2006-2013, Brainspark B.V.
7 *
8 * This file is part of PolarSSL (http://www.polarssl.org)
9 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 */
27
28#include "polarssl/config.h"
29
30#if defined(POLARSSL_OID_C)
31
32#include "polarssl/oid.h"
Paul Bakkerc70b9822013-04-07 22:00:46 +020033#include "polarssl/rsa.h"
34
Paul Bakkered27a042013-04-18 22:46:23 +020035#include <stdio.h>
36
Paul Bakkerdd1150e2013-06-28 17:20:22 +020037/*
38 * Macro to generate an internal function for oid_XXX_from_asn1() (used by
39 * the other functions)
40 */
Paul Bakkerbd51ad52013-06-28 16:51:52 +020041#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \
42static const TYPE_T * oid_ ## NAME ## _from_asn1( const asn1_buf *oid ) \
43{ return (const TYPE_T *) oid_descriptor_from_buf(LIST, sizeof(TYPE_T), oid->p, oid->len ); }
44
45/*
Paul Bakkerdd1150e2013-06-28 17:20:22 +020046 * Macro to generate a function for retrieving a single attribute from the
47 * descriptor of an oid_descriptor_t wrapper.
48 */
49#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
50int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
51{ \
52 const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
53 if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND ); \
54 *ATTR1 = data->descriptor.ATTR1; \
55 return( 0 ); \
56}
57
58/*
59 * Macro to generate a function for retrieving a single attribute from an
60 * oid_descriptor_t wrapper.
61 */
62#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
63int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
64{ \
65 const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
66 if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND ); \
67 *ATTR1 = data->ATTR1; \
68 return( 0 ); \
69}
70
71/*
72 * Macro to generate a function for retrieving two attributes from an
73 * oid_descriptor_t wrapper.
74 */
75#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \
76 ATTR2_TYPE, ATTR2) \
77int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \
78{ \
79 const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
80 if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND ); \
81 *ATTR1 = data->ATTR1; \
82 *ATTR2 = data->ATTR2; \
83 return( 0 ); \
84}
85
86/*
Paul Bakkerbd51ad52013-06-28 16:51:52 +020087 * Core generic function
88 */
89static const oid_descriptor_t *oid_descriptor_from_buf( const void *struct_set,
90 size_t struct_size, const unsigned char *oid, size_t len )
91{
92 const unsigned char *p = (const unsigned char *) struct_set;
93 const oid_descriptor_t *cur;
94
95 if( struct_set == NULL || oid == NULL )
96 return( NULL );
97
98 cur = (const oid_descriptor_t *) p;
99 while( cur->asn1 != NULL )
100 {
101 if( strlen( cur->asn1 ) == len &&
102 memcmp( cur->asn1, oid, len ) == 0 )
103 {
104 return( cur );
105 }
106
107 p += struct_size;
108 cur = (const oid_descriptor_t *) p;
109 }
110
111 return( NULL );
112}
113
Paul Bakkerc70b9822013-04-07 22:00:46 +0200114/*
115 * For X520 attribute types
116 */
117typedef struct {
118 oid_descriptor_t descriptor;
119 const char *short_name;
120} oid_x520_attr_t;
121
122static const oid_x520_attr_t oid_x520_attr_type[] =
123{
124 {
125 { OID_AT_CN, "id-at-commonName", "Common Name" },
126 "CN",
127 },
128 {
129 { OID_AT_COUNTRY, "id-at-countryName", "Country" },
130 "C",
131 },
132 {
133 { OID_AT_LOCALITY, "id-at-locality", "Locality" },
134 "L",
135 },
136 {
137 { OID_AT_STATE, "id-at-state", "State" },
138 "ST",
139 },
140 {
141 { OID_AT_ORGANIZATION,"id-at-organizationName", "Organization" },
142 "O",
143 },
144 {
145 { OID_AT_ORG_UNIT, "id-at-organizationalUnitName", "Org Unit" },
146 "OU",
147 },
148 {
149 { OID_PKCS9_EMAIL, "emailAddress", "E-mail address" },
150 "emailAddress",
151 },
152 {
153 { NULL, NULL, NULL },
154 NULL,
155 }
156};
157
Paul Bakkerdd1150e2013-06-28 17:20:22 +0200158FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type);
159FN_OID_GET_ATTR1(oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name);
Paul Bakkerbd51ad52013-06-28 16:51:52 +0200160
Paul Bakkered27a042013-04-18 22:46:23 +0200161#if defined(POLARSSL_X509_PARSE_C) || defined(POLARSSL_X509_WRITE_C)
Paul Bakkerc70b9822013-04-07 22:00:46 +0200162/*
163 * For X509 extensions
164 */
165typedef struct {
166 oid_descriptor_t descriptor;
167 int ext_type;
168} oid_x509_ext_t;
169
170static const oid_x509_ext_t oid_x509_ext[] =
171{
172 {
173 { OID_BASIC_CONSTRAINTS, "id-ce-basicConstraints", "Basic Constraints" },
174 EXT_BASIC_CONSTRAINTS,
175 },
176 {
177 { OID_KEY_USAGE, "id-ce-keyUsage", "Key Usage" },
178 EXT_KEY_USAGE,
179 },
180 {
181 { OID_EXTENDED_KEY_USAGE, "id-ce-keyUsage", "Extended Key Usage" },
182 EXT_EXTENDED_KEY_USAGE,
183 },
184 {
185 { OID_SUBJECT_ALT_NAME, "id-ce-subjectAltName", "Subject Alt Name" },
186 EXT_SUBJECT_ALT_NAME,
187 },
188 {
189 { OID_NS_CERT_TYPE, "id-netscape-certtype", "Netscape Certificate Type" },
190 EXT_NS_CERT_TYPE,
191 },
192 {
193 { NULL, NULL, NULL },
194 0,
195 },
196};
197
Paul Bakkerdd1150e2013-06-28 17:20:22 +0200198FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext);
199FN_OID_GET_ATTR1(oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type);
Paul Bakkerbd51ad52013-06-28 16:51:52 +0200200
Paul Bakkerc70b9822013-04-07 22:00:46 +0200201static const oid_descriptor_t oid_ext_key_usage[] =
202{
203 { OID_SERVER_AUTH, "id-kp-serverAuth", "TLS Web Server Authentication" },
204 { OID_CLIENT_AUTH, "id-kp-clientAuth", "TLS Web Client Authentication" },
205 { OID_CODE_SIGNING, "id-kp-codeSigning", "Code Signing" },
206 { OID_EMAIL_PROTECTION, "id-kp-emailProtection", "E-mail Protection" },
207 { OID_TIME_STAMPING, "id-kp-timeStamping", "Time Stamping" },
208 { OID_OCSP_SIGNING, "id-kp-OCSPSigning", "OCSP Signing" },
209 { NULL, NULL, NULL },
210};
Paul Bakkerbd51ad52013-06-28 16:51:52 +0200211
Paul Bakkerdd1150e2013-06-28 17:20:22 +0200212FN_OID_TYPED_FROM_ASN1(oid_descriptor_t, ext_key_usage, oid_ext_key_usage);
213FN_OID_GET_ATTR1(oid_get_extended_key_usage, oid_descriptor_t, ext_key_usage, const char *, description);
Paul Bakkerbd51ad52013-06-28 16:51:52 +0200214
Paul Bakkered27a042013-04-18 22:46:23 +0200215#endif /* POLARSSL_X509_PARSE_C || POLARSSL_X509_WRITE_C */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200216
217/*
218 * For SignatureAlgorithmIdentifier
219 */
220typedef struct {
221 oid_descriptor_t descriptor;
222 md_type_t md_alg;
223 pk_type_t pk_alg;
224} oid_sig_alg_t;
225
226static const oid_sig_alg_t oid_sig_alg[] =
227{
228 {
229 { OID_PKCS1_MD2, "md2WithRSAEncryption", "RSA with MD2" },
230 POLARSSL_MD_MD2, POLARSSL_PK_RSA,
231 },
232 {
233 { OID_PKCS1_MD4, "md4WithRSAEncryption", "RSA with MD4" },
234 POLARSSL_MD_MD4, POLARSSL_PK_RSA,
235 },
236 {
237 { OID_PKCS1_MD5, "md5WithRSAEncryption", "RSA with MD5" },
238 POLARSSL_MD_MD5, POLARSSL_PK_RSA,
239 },
240 {
241 { OID_PKCS1_SHA1, "sha-1WithRSAEncryption", "RSA with SHA1" },
242 POLARSSL_MD_SHA1, POLARSSL_PK_RSA,
243 },
244 {
245 { OID_PKCS1_SHA224, "sha224WithRSAEncryption", "RSA with SHA-224" },
246 POLARSSL_MD_SHA224, POLARSSL_PK_RSA,
247 },
248 {
249 { OID_PKCS1_SHA256, "sha256WithRSAEncryption", "RSA with SHA-256" },
250 POLARSSL_MD_SHA256, POLARSSL_PK_RSA,
251 },
252 {
253 { OID_PKCS1_SHA384, "sha384WithRSAEncryption", "RSA with SHA-384" },
254 POLARSSL_MD_SHA384, POLARSSL_PK_RSA,
255 },
256 {
257 { OID_PKCS1_SHA512, "sha512WithRSAEncryption", "RSA with SHA-512" },
258 POLARSSL_MD_SHA512, POLARSSL_PK_RSA,
259 },
260 {
261 { OID_RSA_SHA_OBS, "sha-1WithRSAEncryption", "RSA with SHA1" },
262 POLARSSL_MD_SHA1, POLARSSL_PK_RSA,
263 },
264 {
265 { NULL, NULL, NULL },
266 0, 0,
267 },
268};
269
Paul Bakkerdd1150e2013-06-28 17:20:22 +0200270FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg);
271FN_OID_GET_DESCRIPTOR_ATTR1(oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description);
272FN_OID_GET_ATTR2(oid_get_sig_alg, oid_sig_alg_t, sig_alg, md_type_t, md_alg, pk_type_t, pk_alg);
Paul Bakkerbd51ad52013-06-28 16:51:52 +0200273
274int oid_get_oid_by_sig_alg( pk_type_t pk_alg, md_type_t md_alg,
275 const char **oid_str )
276{
277 const oid_sig_alg_t *cur = oid_sig_alg;
278
279 while( cur->descriptor.asn1 != NULL )
280 {
281 if( cur->pk_alg == pk_alg &&
282 cur->md_alg == md_alg )
283 {
284 *oid_str = cur->descriptor.asn1;
285 return( 0 );
286 }
287
288 cur++;
289 }
290
291 return( POLARSSL_ERR_OID_NOT_FOUND );
292}
293
Paul Bakkerc70b9822013-04-07 22:00:46 +0200294/*
295 * For PublicKeyInfo
296 */
297typedef struct {
298 oid_descriptor_t descriptor;
299 pk_type_t pk_alg;
300} oid_pk_alg_t;
301
302static const oid_pk_alg_t oid_pk_alg[] =
303{
304 {
305 { OID_PKCS1_RSA, "rsaEncryption", "RSA" },
306 POLARSSL_PK_RSA,
307 },
308 {
309 { NULL, NULL, NULL },
310 0,
311 },
312};
313
Paul Bakkerdd1150e2013-06-28 17:20:22 +0200314FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg);
315FN_OID_GET_ATTR1(oid_get_pk_alg, oid_pk_alg_t, pk_alg, pk_type_t, pk_alg);
Paul Bakkerbd51ad52013-06-28 16:51:52 +0200316
Paul Bakkerc70b9822013-04-07 22:00:46 +0200317/*
Paul Bakker9b5e8852013-06-28 16:12:50 +0200318 * For PKCS#5 PBES2 encryption algorithm
319 */
320typedef struct {
321 oid_descriptor_t descriptor;
322 cipher_type_t cipher_alg;
323} oid_cipher_alg_t;
324
325static const oid_cipher_alg_t oid_cipher_alg[] =
326{
327 {
328 { OID_DES_CBC, "desCBC", "DES-CBC" },
329 POLARSSL_CIPHER_DES_CBC,
330 },
331 {
332 { OID_DES_EDE3_CBC, "des-ede3-cbc", "DES-EDE3-CBC" },
333 POLARSSL_CIPHER_DES_EDE3_CBC,
334 },
335 {
336 { NULL, NULL, NULL },
337 0,
338 },
339};
340
Paul Bakkerdd1150e2013-06-28 17:20:22 +0200341FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg);
342FN_OID_GET_ATTR1(oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, cipher_type_t, cipher_alg);
Paul Bakkerbd51ad52013-06-28 16:51:52 +0200343
Paul Bakker9b5e8852013-06-28 16:12:50 +0200344/*
Paul Bakkerc70b9822013-04-07 22:00:46 +0200345 * For digestAlgorithm
346 */
347typedef struct {
348 oid_descriptor_t descriptor;
349 md_type_t md_alg;
350} oid_md_alg_t;
351
352static const oid_md_alg_t oid_md_alg[] =
353{
354 {
355 { OID_DIGEST_ALG_MD2, "id-md2", "MD2" },
356 POLARSSL_MD_MD2,
357 },
358 {
359 { OID_DIGEST_ALG_MD4, "id-md4", "MD4" },
360 POLARSSL_MD_MD4,
361 },
362 {
363 { OID_DIGEST_ALG_MD5, "id-md5", "MD5" },
364 POLARSSL_MD_MD5,
365 },
366 {
367 { OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1" },
368 POLARSSL_MD_SHA1,
369 },
370 {
371 { OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1" },
372 POLARSSL_MD_SHA1,
373 },
374 {
375 { OID_DIGEST_ALG_SHA224, "id-sha224", "SHA-224" },
376 POLARSSL_MD_SHA224,
377 },
378 {
379 { OID_DIGEST_ALG_SHA256, "id-sha256", "SHA-256" },
380 POLARSSL_MD_SHA256,
381 },
382 {
383 { OID_DIGEST_ALG_SHA384, "id-sha384", "SHA-384" },
384 POLARSSL_MD_SHA384,
385 },
386 {
387 { OID_DIGEST_ALG_SHA512, "id-sha512", "SHA-512" },
388 POLARSSL_MD_SHA512,
389 },
390 {
391 { NULL, NULL, NULL },
392 0,
393 },
394};
395
Paul Bakkerdd1150e2013-06-28 17:20:22 +0200396FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg);
397FN_OID_GET_ATTR1(oid_get_md_alg, oid_md_alg_t, md_alg, md_type_t, md_alg);
Paul Bakkerbd51ad52013-06-28 16:51:52 +0200398
399int oid_get_oid_by_md( md_type_t md_alg, const char **oid_str )
400{
401 const oid_md_alg_t *cur = oid_md_alg;
402
403 while( cur->descriptor.asn1 != NULL )
404 {
405 if( cur->md_alg == md_alg )
406 {
407 *oid_str = cur->descriptor.asn1;
408 return( 0 );
409 }
410
411 cur++;
412 }
413
414 return( POLARSSL_ERR_OID_NOT_FOUND );
415}
416
Paul Bakker7749a222013-06-28 17:28:20 +0200417/*
418 * For PKCS#12 PBEs
419 */
420typedef struct {
421 oid_descriptor_t descriptor;
422 md_type_t md_alg;
423 cipher_type_t cipher_alg;
424} oid_pkcs12_pbe_alg_t;
425
426static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] =
427{
428 {
429 { OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" },
430 POLARSSL_MD_SHA1, POLARSSL_CIPHER_DES_EDE3_CBC,
431 },
432 {
433 { OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" },
434 POLARSSL_MD_SHA1, POLARSSL_CIPHER_DES_EDE_CBC,
435 },
436 {
437 { NULL, NULL, NULL },
438 0, 0,
439 },
440};
441
442FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg);
443FN_OID_GET_ATTR2(oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, md_type_t, md_alg, cipher_type_t, cipher_alg);
444
Paul Bakkerc70b9822013-04-07 22:00:46 +0200445#if defined _MSC_VER && !defined snprintf
446#include <stdarg.h>
447
448#if !defined vsnprintf
449#define vsnprintf _vsnprintf
450#endif // vsnprintf
451
452/*
453 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
454 * Result value is not size of buffer needed, but -1 if no fit is possible.
455 *
456 * This fuction tries to 'fix' this by at least suggesting enlarging the
457 * size by 20.
458 */
459static int compat_snprintf(char *str, size_t size, const char *format, ...)
460{
461 va_list ap;
462 int res = -1;
463
464 va_start( ap, format );
465
466 res = vsnprintf( str, size, format, ap );
467
468 va_end( ap );
469
470 // No quick fix possible
471 if ( res < 0 )
472 return( (int) size + 20 );
473
474 return res;
475}
476
477#define snprintf compat_snprintf
478#endif
479
480#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
481
482#define SAFE_SNPRINTF() \
483{ \
484 if( ret == -1 ) \
485 return( -1 ); \
486 \
487 if ( (unsigned int) ret > n ) { \
488 p[n - 1] = '\0'; \
489 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
490 } \
491 \
492 n -= (unsigned int) ret; \
493 p += (unsigned int) ret; \
494}
495
496/* Return the x.y.z.... style numeric string for the given OID */
497int oid_get_numeric_string( char *buf, size_t size,
498 const asn1_buf *oid )
499{
500 int ret;
501 size_t i, n;
502 unsigned int value;
503 char *p;
504
505 p = buf;
506 n = size;
507
508 /* First byte contains first two dots */
509 if( oid->len > 0 )
510 {
511 ret = snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 );
512 SAFE_SNPRINTF();
513 }
514
515 /* Prevent overflow in value. */
516 if( oid->len > sizeof(value) )
517 return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
518
519 value = 0;
520 for( i = 1; i < oid->len; i++ )
521 {
522 value <<= 7;
523 value += oid->p[i] & 0x7F;
524
525 if( !( oid->p[i] & 0x80 ) )
526 {
527 /* Last byte */
528 ret = snprintf( p, n, ".%d", value );
529 SAFE_SNPRINTF();
530 value = 0;
531 }
532 }
533
534 return( (int) ( size - n ) );
535}
536
Paul Bakkerc70b9822013-04-07 22:00:46 +0200537#endif /* POLARSSL_OID_C */