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