blob: 371d1ba16fe7b458519fd1a477bc15ea0181f1b5 [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 Bakkerc70b9822013-04-07 22:00:46 +020037/*
38 * For X520 attribute types
39 */
40typedef struct {
41 oid_descriptor_t descriptor;
42 const char *short_name;
43} oid_x520_attr_t;
44
45static const oid_x520_attr_t oid_x520_attr_type[] =
46{
47 {
48 { OID_AT_CN, "id-at-commonName", "Common Name" },
49 "CN",
50 },
51 {
52 { OID_AT_COUNTRY, "id-at-countryName", "Country" },
53 "C",
54 },
55 {
56 { OID_AT_LOCALITY, "id-at-locality", "Locality" },
57 "L",
58 },
59 {
60 { OID_AT_STATE, "id-at-state", "State" },
61 "ST",
62 },
63 {
64 { OID_AT_ORGANIZATION,"id-at-organizationName", "Organization" },
65 "O",
66 },
67 {
68 { OID_AT_ORG_UNIT, "id-at-organizationalUnitName", "Org Unit" },
69 "OU",
70 },
71 {
72 { OID_PKCS9_EMAIL, "emailAddress", "E-mail address" },
73 "emailAddress",
74 },
75 {
76 { NULL, NULL, NULL },
77 NULL,
78 }
79};
80
Paul Bakkered27a042013-04-18 22:46:23 +020081#if defined(POLARSSL_X509_PARSE_C) || defined(POLARSSL_X509_WRITE_C)
Paul Bakkerc70b9822013-04-07 22:00:46 +020082/*
83 * For X509 extensions
84 */
85typedef struct {
86 oid_descriptor_t descriptor;
87 int ext_type;
88} oid_x509_ext_t;
89
90static const oid_x509_ext_t oid_x509_ext[] =
91{
92 {
93 { OID_BASIC_CONSTRAINTS, "id-ce-basicConstraints", "Basic Constraints" },
94 EXT_BASIC_CONSTRAINTS,
95 },
96 {
97 { OID_KEY_USAGE, "id-ce-keyUsage", "Key Usage" },
98 EXT_KEY_USAGE,
99 },
100 {
101 { OID_EXTENDED_KEY_USAGE, "id-ce-keyUsage", "Extended Key Usage" },
102 EXT_EXTENDED_KEY_USAGE,
103 },
104 {
105 { OID_SUBJECT_ALT_NAME, "id-ce-subjectAltName", "Subject Alt Name" },
106 EXT_SUBJECT_ALT_NAME,
107 },
108 {
109 { OID_NS_CERT_TYPE, "id-netscape-certtype", "Netscape Certificate Type" },
110 EXT_NS_CERT_TYPE,
111 },
112 {
113 { NULL, NULL, NULL },
114 0,
115 },
116};
117
118static const oid_descriptor_t oid_ext_key_usage[] =
119{
120 { OID_SERVER_AUTH, "id-kp-serverAuth", "TLS Web Server Authentication" },
121 { OID_CLIENT_AUTH, "id-kp-clientAuth", "TLS Web Client Authentication" },
122 { OID_CODE_SIGNING, "id-kp-codeSigning", "Code Signing" },
123 { OID_EMAIL_PROTECTION, "id-kp-emailProtection", "E-mail Protection" },
124 { OID_TIME_STAMPING, "id-kp-timeStamping", "Time Stamping" },
125 { OID_OCSP_SIGNING, "id-kp-OCSPSigning", "OCSP Signing" },
126 { NULL, NULL, NULL },
127};
Paul Bakkered27a042013-04-18 22:46:23 +0200128#endif /* POLARSSL_X509_PARSE_C || POLARSSL_X509_WRITE_C */
Paul Bakkerc70b9822013-04-07 22:00:46 +0200129
130/*
131 * For SignatureAlgorithmIdentifier
132 */
133typedef struct {
134 oid_descriptor_t descriptor;
135 md_type_t md_alg;
136 pk_type_t pk_alg;
137} oid_sig_alg_t;
138
139static const oid_sig_alg_t oid_sig_alg[] =
140{
141 {
142 { OID_PKCS1_MD2, "md2WithRSAEncryption", "RSA with MD2" },
143 POLARSSL_MD_MD2, POLARSSL_PK_RSA,
144 },
145 {
146 { OID_PKCS1_MD4, "md4WithRSAEncryption", "RSA with MD4" },
147 POLARSSL_MD_MD4, POLARSSL_PK_RSA,
148 },
149 {
150 { OID_PKCS1_MD5, "md5WithRSAEncryption", "RSA with MD5" },
151 POLARSSL_MD_MD5, POLARSSL_PK_RSA,
152 },
153 {
154 { OID_PKCS1_SHA1, "sha-1WithRSAEncryption", "RSA with SHA1" },
155 POLARSSL_MD_SHA1, POLARSSL_PK_RSA,
156 },
157 {
158 { OID_PKCS1_SHA224, "sha224WithRSAEncryption", "RSA with SHA-224" },
159 POLARSSL_MD_SHA224, POLARSSL_PK_RSA,
160 },
161 {
162 { OID_PKCS1_SHA256, "sha256WithRSAEncryption", "RSA with SHA-256" },
163 POLARSSL_MD_SHA256, POLARSSL_PK_RSA,
164 },
165 {
166 { OID_PKCS1_SHA384, "sha384WithRSAEncryption", "RSA with SHA-384" },
167 POLARSSL_MD_SHA384, POLARSSL_PK_RSA,
168 },
169 {
170 { OID_PKCS1_SHA512, "sha512WithRSAEncryption", "RSA with SHA-512" },
171 POLARSSL_MD_SHA512, POLARSSL_PK_RSA,
172 },
173 {
174 { OID_RSA_SHA_OBS, "sha-1WithRSAEncryption", "RSA with SHA1" },
175 POLARSSL_MD_SHA1, POLARSSL_PK_RSA,
176 },
177 {
178 { NULL, NULL, NULL },
179 0, 0,
180 },
181};
182
183/*
184 * For PublicKeyInfo
185 */
186typedef struct {
187 oid_descriptor_t descriptor;
188 pk_type_t pk_alg;
189} oid_pk_alg_t;
190
191static const oid_pk_alg_t oid_pk_alg[] =
192{
193 {
194 { OID_PKCS1_RSA, "rsaEncryption", "RSA" },
195 POLARSSL_PK_RSA,
196 },
197 {
198 { NULL, NULL, NULL },
199 0,
200 },
201};
202
203/*
Paul Bakker9b5e8852013-06-28 16:12:50 +0200204 * For PKCS#5 PBES2 encryption algorithm
205 */
206typedef struct {
207 oid_descriptor_t descriptor;
208 cipher_type_t cipher_alg;
209} oid_cipher_alg_t;
210
211static const oid_cipher_alg_t oid_cipher_alg[] =
212{
213 {
214 { OID_DES_CBC, "desCBC", "DES-CBC" },
215 POLARSSL_CIPHER_DES_CBC,
216 },
217 {
218 { OID_DES_EDE3_CBC, "des-ede3-cbc", "DES-EDE3-CBC" },
219 POLARSSL_CIPHER_DES_EDE3_CBC,
220 },
221 {
222 { NULL, NULL, NULL },
223 0,
224 },
225};
226
227/*
Paul Bakkerc70b9822013-04-07 22:00:46 +0200228 * For digestAlgorithm
229 */
230typedef struct {
231 oid_descriptor_t descriptor;
232 md_type_t md_alg;
233} oid_md_alg_t;
234
235static const oid_md_alg_t oid_md_alg[] =
236{
237 {
238 { OID_DIGEST_ALG_MD2, "id-md2", "MD2" },
239 POLARSSL_MD_MD2,
240 },
241 {
242 { OID_DIGEST_ALG_MD4, "id-md4", "MD4" },
243 POLARSSL_MD_MD4,
244 },
245 {
246 { OID_DIGEST_ALG_MD5, "id-md5", "MD5" },
247 POLARSSL_MD_MD5,
248 },
249 {
250 { OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1" },
251 POLARSSL_MD_SHA1,
252 },
253 {
254 { OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1" },
255 POLARSSL_MD_SHA1,
256 },
257 {
258 { OID_DIGEST_ALG_SHA224, "id-sha224", "SHA-224" },
259 POLARSSL_MD_SHA224,
260 },
261 {
262 { OID_DIGEST_ALG_SHA256, "id-sha256", "SHA-256" },
263 POLARSSL_MD_SHA256,
264 },
265 {
266 { OID_DIGEST_ALG_SHA384, "id-sha384", "SHA-384" },
267 POLARSSL_MD_SHA384,
268 },
269 {
270 { OID_DIGEST_ALG_SHA512, "id-sha512", "SHA-512" },
271 POLARSSL_MD_SHA512,
272 },
273 {
274 { NULL, NULL, NULL },
275 0,
276 },
277};
278
279#if defined _MSC_VER && !defined snprintf
280#include <stdarg.h>
281
282#if !defined vsnprintf
283#define vsnprintf _vsnprintf
284#endif // vsnprintf
285
286/*
287 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
288 * Result value is not size of buffer needed, but -1 if no fit is possible.
289 *
290 * This fuction tries to 'fix' this by at least suggesting enlarging the
291 * size by 20.
292 */
293static int compat_snprintf(char *str, size_t size, const char *format, ...)
294{
295 va_list ap;
296 int res = -1;
297
298 va_start( ap, format );
299
300 res = vsnprintf( str, size, format, ap );
301
302 va_end( ap );
303
304 // No quick fix possible
305 if ( res < 0 )
306 return( (int) size + 20 );
307
308 return res;
309}
310
311#define snprintf compat_snprintf
312#endif
313
314#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
315
316#define SAFE_SNPRINTF() \
317{ \
318 if( ret == -1 ) \
319 return( -1 ); \
320 \
321 if ( (unsigned int) ret > n ) { \
322 p[n - 1] = '\0'; \
323 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
324 } \
325 \
326 n -= (unsigned int) ret; \
327 p += (unsigned int) ret; \
328}
329
330/* Return the x.y.z.... style numeric string for the given OID */
331int oid_get_numeric_string( char *buf, size_t size,
332 const asn1_buf *oid )
333{
334 int ret;
335 size_t i, n;
336 unsigned int value;
337 char *p;
338
339 p = buf;
340 n = size;
341
342 /* First byte contains first two dots */
343 if( oid->len > 0 )
344 {
345 ret = snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 );
346 SAFE_SNPRINTF();
347 }
348
349 /* Prevent overflow in value. */
350 if( oid->len > sizeof(value) )
351 return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
352
353 value = 0;
354 for( i = 1; i < oid->len; i++ )
355 {
356 value <<= 7;
357 value += oid->p[i] & 0x7F;
358
359 if( !( oid->p[i] & 0x80 ) )
360 {
361 /* Last byte */
362 ret = snprintf( p, n, ".%d", value );
363 SAFE_SNPRINTF();
364 value = 0;
365 }
366 }
367
368 return( (int) ( size - n ) );
369}
370
371static const oid_descriptor_t *oid_descriptor_from_buf(
372 const void *struct_set,
373 size_t struct_size,
374 const unsigned char *oid,
375 size_t len )
376{
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200377 const unsigned char *p = (const unsigned char *) struct_set;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200378 const oid_descriptor_t *cur;
379
380 if( struct_set == NULL || oid == NULL )
381 return( NULL );
382
383 cur = (const oid_descriptor_t *) p;
384 while( cur->asn1 != NULL )
385 {
386 if( strlen( cur->asn1 ) == len &&
387 memcmp( cur->asn1, oid, len ) == 0 )
388 {
389 return( cur );
390 }
391
392 p += struct_size;
393 cur = (const oid_descriptor_t *) p;
394 }
395
396 return( NULL );
397}
398
399static const oid_descriptor_t *oid_descriptor_from_asn1(
400 const void *struct_set,
401 size_t struct_size,
402 const asn1_buf *oid )
403{
404 return oid_descriptor_from_buf( struct_set, struct_size,
405 oid->p, oid->len );
406}
407
Paul Bakkered27a042013-04-18 22:46:23 +0200408#if defined(POLARSSL_X509_PARSE_C) || defined(POLARSSL_X509_WRITE_C)
Paul Bakkerc70b9822013-04-07 22:00:46 +0200409int oid_get_extended_key_usage( const asn1_buf *oid, const char **desc )
410{
411 const oid_descriptor_t *data = oid_descriptor_from_asn1(
412 oid_ext_key_usage,
413 sizeof(oid_descriptor_t),
414 oid );
415
416 if( data == NULL )
417 return( POLARSSL_ERR_OID_NOT_FOUND );
418
419 *desc = data->description;
420
421 return( 0 );
422}
423
424static const oid_x509_ext_t *oid_x509_ext_from_asn1( const asn1_buf *oid )
425{
426 return (const oid_x509_ext_t *) oid_descriptor_from_asn1(
427 oid_x509_ext,
428 sizeof(oid_x509_ext_t),
429 oid );
430}
431
Paul Bakkered27a042013-04-18 22:46:23 +0200432int oid_get_x509_ext_type( const asn1_buf *oid, int *ext_type )
433{
434 const oid_x509_ext_t *data = oid_x509_ext_from_asn1( oid );
435
436 if( data == NULL )
437 return( POLARSSL_ERR_OID_NOT_FOUND );
438
439 *ext_type = data->ext_type;
440
441 return( 0 );
442}
443
444#endif /* POLARSSL_X509_PARSE_C || POLARSSL_X509_WRITE_C */
445
Paul Bakkerc70b9822013-04-07 22:00:46 +0200446static const oid_x520_attr_t *oid_x520_attr_from_asn1( const asn1_buf *oid )
447{
448 return (const oid_x520_attr_t *) oid_descriptor_from_asn1(
449 oid_x520_attr_type,
450 sizeof(oid_x520_attr_t),
451 oid );
452}
453
454static const oid_pk_alg_t *oid_pk_alg_from_asn1( const asn1_buf *oid )
455{
456 return (const oid_pk_alg_t *) oid_descriptor_from_asn1(
457 oid_pk_alg,
458 sizeof(oid_pk_alg_t),
459 oid );
460}
461
462static const oid_sig_alg_t *oid_sig_alg_from_asn1( const asn1_buf *oid )
463{
464 return (const oid_sig_alg_t *) oid_descriptor_from_asn1(
465 oid_sig_alg,
466 sizeof(oid_sig_alg_t),
467 oid );
468}
469
470static const oid_md_alg_t *oid_md_alg_from_asn1( const asn1_buf *oid )
471{
472 return (const oid_md_alg_t *) oid_descriptor_from_asn1(
473 oid_md_alg,
474 sizeof(oid_md_alg_t),
475 oid );
476}
477
Paul Bakker9b5e8852013-06-28 16:12:50 +0200478static const oid_cipher_alg_t *oid_cipher_alg_from_asn1( const asn1_buf *oid )
479{
480 return (const oid_cipher_alg_t *) oid_descriptor_from_asn1(
481 oid_cipher_alg,
482 sizeof(oid_cipher_alg_t),
483 oid );
484}
485
Paul Bakkerc70b9822013-04-07 22:00:46 +0200486int oid_get_attr_short_name( const asn1_buf *oid, const char **short_name )
487{
488 const oid_x520_attr_t *data = oid_x520_attr_from_asn1( oid );
489
490 if( data == NULL )
491 return( POLARSSL_ERR_OID_NOT_FOUND );
492
493 *short_name = data->short_name;
494
495 return( 0 );
496}
497
498int oid_get_pk_alg( const asn1_buf *oid, pk_type_t *pk_alg )
499{
500 const oid_pk_alg_t *data = oid_pk_alg_from_asn1( oid );
501
502 if( data == NULL )
503 return( POLARSSL_ERR_OID_NOT_FOUND );
504
505 *pk_alg = data->pk_alg;
506
507 return( 0 );
508}
509
510int oid_get_sig_alg_desc( const asn1_buf *oid, const char **desc )
511{
512 const oid_sig_alg_t *data = oid_sig_alg_from_asn1( oid );
513
514 if( data == NULL )
515 return( POLARSSL_ERR_OID_NOT_FOUND );
516
517 *desc = data->descriptor.description;
518
519 return( 0 );
520}
521
522int oid_get_sig_alg( const asn1_buf *oid,
523 md_type_t *md_alg, pk_type_t *pk_alg )
524{
525 const oid_sig_alg_t *data = oid_sig_alg_from_asn1( oid );
526
527 if( data == NULL )
528 return( POLARSSL_ERR_OID_NOT_FOUND );
529
530 *md_alg = data->md_alg;
531 *pk_alg = data->pk_alg;
532
533 return( 0 );
534}
535
536int oid_get_oid_by_sig_alg( pk_type_t pk_alg, md_type_t md_alg,
537 const char **oid_str )
538{
539 const oid_sig_alg_t *cur = oid_sig_alg;
540
541 while( cur->descriptor.asn1 != NULL )
542 {
543 if( cur->pk_alg == pk_alg &&
544 cur->md_alg == md_alg )
545 {
546 *oid_str = cur->descriptor.asn1;
547 return( 0 );
548 }
549
550 cur++;
551 }
552
553 return( POLARSSL_ERR_OID_NOT_FOUND );
554}
555
556int oid_get_md_alg( const asn1_buf *oid,
557 md_type_t *md_alg )
558{
559 const oid_md_alg_t *data = oid_md_alg_from_asn1( oid );
560
561 if( data == NULL )
562 return( POLARSSL_ERR_OID_NOT_FOUND );
563
564 *md_alg = data->md_alg;
565
566 return( 0 );
567}
568
569int oid_get_oid_by_md( md_type_t md_alg,
570 const char **oid_str )
571{
572 const oid_md_alg_t *cur = oid_md_alg;
573
574 while( cur->descriptor.asn1 != NULL )
575 {
576 if( cur->md_alg == md_alg )
577 {
578 *oid_str = cur->descriptor.asn1;
579 return( 0 );
580 }
581
582 cur++;
583 }
584
585 return( POLARSSL_ERR_OID_NOT_FOUND );
586}
587
Paul Bakker9b5e8852013-06-28 16:12:50 +0200588int oid_get_cipher_alg( const asn1_buf *oid,
589 cipher_type_t *cipher_alg )
590{
591 const oid_cipher_alg_t *data = oid_cipher_alg_from_asn1( oid );
592
593 if( data == NULL )
594 return( POLARSSL_ERR_OID_NOT_FOUND );
595
596 *cipher_alg = data->cipher_alg;
597
598 return( 0 );
599}
600
Paul Bakkerc70b9822013-04-07 22:00:46 +0200601#endif /* POLARSSL_OID_C */