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