PolarSSL v1.3.1
oid.c
Go to the documentation of this file.
1 
28 #include "polarssl/config.h"
29 
30 #if defined(POLARSSL_OID_C)
31 
32 #include "polarssl/oid.h"
33 #include "polarssl/rsa.h"
34 
35 #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
36 #include "polarssl/x509.h"
37 #endif
38 
39 #include <stdio.h>
40 
41 /*
42  * Macro to automatically add the size of #define'd OIDs
43  */
44 #define ADD_LEN(s) s, OID_SIZE(s)
45 
46 /*
47  * Macro to generate an internal function for oid_XXX_from_asn1() (used by
48  * the other functions)
49  */
50 #define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \
51 static const TYPE_T * oid_ ## NAME ## _from_asn1( const asn1_buf *oid ) \
52 { return (const TYPE_T *) oid_descriptor_from_buf(LIST, sizeof(TYPE_T), oid->p, oid->len ); }
53 
54 /*
55  * Macro to generate a function for retrieving a single attribute from the
56  * descriptor of an oid_descriptor_t wrapper.
57  */
58 #define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
59 int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
60 { \
61  const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
62  if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND ); \
63  *ATTR1 = data->descriptor.ATTR1; \
64  return( 0 ); \
65 }
66 
67 /*
68  * Macro to generate a function for retrieving a single attribute from an
69  * oid_descriptor_t wrapper.
70  */
71 #define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
72 int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
73 { \
74  const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
75  if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND ); \
76  *ATTR1 = data->ATTR1; \
77  return( 0 ); \
78 }
79 
80 /*
81  * Macro to generate a function for retrieving two attributes from an
82  * oid_descriptor_t wrapper.
83  */
84 #define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \
85  ATTR2_TYPE, ATTR2) \
86 int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \
87 { \
88  const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
89  if( data == NULL ) return ( POLARSSL_ERR_OID_NOT_FOUND ); \
90  *ATTR1 = data->ATTR1; \
91  *ATTR2 = data->ATTR2; \
92  return( 0 ); \
93 }
94 
95 /*
96  * Macro to generate a function for retrieving the OID based on a single
97  * attribute from a oid_descriptor_t wrapper.
98  */
99 #define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \
100 int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \
101 { \
102  const TYPE_T *cur = LIST; \
103  while( cur->descriptor.asn1 != NULL ) { \
104  if( cur->ATTR1 == ATTR1 ) { \
105  *oid = cur->descriptor.asn1; \
106  *olen = cur->descriptor.asn1_len; \
107  return( 0 ); \
108  } \
109  cur++; \
110  } \
111  return( POLARSSL_ERR_OID_NOT_FOUND ); \
112 }
113 
114 /*
115  * Macro to generate a function for retrieving the OID based on two
116  * attributes from a oid_descriptor_t wrapper.
117  */
118 #define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \
119  ATTR2_TYPE, ATTR2) \
120 int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \
121  size_t *olen ) \
122 { \
123  const TYPE_T *cur = LIST; \
124  while( cur->descriptor.asn1 != NULL ) { \
125  if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) { \
126  *oid = cur->descriptor.asn1; \
127  *olen = cur->descriptor.asn1_len; \
128  return( 0 ); \
129  } \
130  cur++; \
131  } \
132  return( POLARSSL_ERR_OID_NOT_FOUND ); \
133 }
134 
135 /*
136  * Core generic function
137  */
138 static const oid_descriptor_t *oid_descriptor_from_buf( const void *struct_set,
139  size_t struct_size, const unsigned char *oid, size_t len )
140 {
141  const unsigned char *p = (const unsigned char *) struct_set;
142  const oid_descriptor_t *cur;
143 
144  if( struct_set == NULL || oid == NULL )
145  return( NULL );
146 
147  cur = (const oid_descriptor_t *) p;
148  while( cur->asn1 != NULL )
149  {
150  if( cur->asn1_len == len &&
151  memcmp( cur->asn1, oid, len ) == 0 )
152  {
153  return( cur );
154  }
155 
156  p += struct_size;
157  cur = (const oid_descriptor_t *) p;
158  }
159 
160  return( NULL );
161 }
162 
163 /*
164  * For X520 attribute types
165  */
166 typedef struct {
167  oid_descriptor_t descriptor;
168  const char *short_name;
169 } oid_x520_attr_t;
170 
171 static const oid_x520_attr_t oid_x520_attr_type[] =
172 {
173  {
174  { ADD_LEN( OID_AT_CN ), "id-at-commonName", "Common Name" },
175  "CN",
176  },
177  {
178  { ADD_LEN( OID_AT_COUNTRY ), "id-at-countryName", "Country" },
179  "C",
180  },
181  {
182  { ADD_LEN( OID_AT_LOCALITY ), "id-at-locality", "Locality" },
183  "L",
184  },
185  {
186  { ADD_LEN( OID_AT_STATE ), "id-at-state", "State" },
187  "ST",
188  },
189  {
190  { ADD_LEN( OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" },
191  "O",
192  },
193  {
194  { ADD_LEN( OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" },
195  "OU",
196  },
197  {
198  { ADD_LEN( OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" },
199  "emailAddress",
200  },
201  {
202  { NULL, 0, NULL, NULL },
203  NULL,
204  }
205 };
206 
207 FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type);
208 FN_OID_GET_ATTR1(oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name);
209 
210 #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
211 /*
212  * For X509 extensions
213  */
214 typedef struct {
215  oid_descriptor_t descriptor;
216  int ext_type;
217 } oid_x509_ext_t;
218 
219 static const oid_x509_ext_t oid_x509_ext[] =
220 {
221  {
222  { ADD_LEN( OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
224  },
225  {
226  { ADD_LEN( OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
228  },
229  {
230  { ADD_LEN( OID_EXTENDED_KEY_USAGE ), "id-ce-keyUsage", "Extended Key Usage" },
232  },
233  {
234  { ADD_LEN( OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
236  },
237  {
238  { ADD_LEN( OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
240  },
241  {
242  { NULL, 0, NULL, NULL },
243  0,
244  },
245 };
246 
247 FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext);
248 FN_OID_GET_ATTR1(oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type);
249 
250 static const oid_descriptor_t oid_ext_key_usage[] =
251 {
252  { ADD_LEN( OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
253  { ADD_LEN( OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
254  { ADD_LEN( OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
255  { ADD_LEN( OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
256  { ADD_LEN( OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
257  { ADD_LEN( OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
258  { NULL, 0, NULL, NULL },
259 };
260 
261 FN_OID_TYPED_FROM_ASN1(oid_descriptor_t, ext_key_usage, oid_ext_key_usage);
262 FN_OID_GET_ATTR1(oid_get_extended_key_usage, oid_descriptor_t, ext_key_usage, const char *, description);
263 #endif /* POLARSSL_X509_USE_C || POLARSSL_X509_CREATE_C */
264 
265 #if defined(POLARSSL_MD_C)
266 /*
267  * For SignatureAlgorithmIdentifier
268  */
269 typedef struct {
270  oid_descriptor_t descriptor;
271  md_type_t md_alg;
272  pk_type_t pk_alg;
273 } oid_sig_alg_t;
274 
275 static const oid_sig_alg_t oid_sig_alg[] =
276 {
277  {
278  { ADD_LEN( OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" },
280  },
281  {
282  { ADD_LEN( OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" },
284  },
285  {
286  { ADD_LEN( OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" },
288  },
289  {
290  { ADD_LEN( OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" },
292  },
293  {
294  { ADD_LEN( OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" },
296  },
297  {
298  { ADD_LEN( OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" },
300  },
301  {
302  { ADD_LEN( OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" },
304  },
305  {
306  { ADD_LEN( OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" },
308  },
309  {
310  { ADD_LEN( OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" },
312  },
313  {
314  { ADD_LEN( OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" },
316  },
317  {
318  { ADD_LEN( OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" },
320  },
321  {
322  { ADD_LEN( OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" },
324  },
325  {
326  { ADD_LEN( OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" },
328  },
329  {
330  { ADD_LEN( OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" },
332  },
333  {
334  { NULL, 0, NULL, NULL },
335  0, 0,
336  },
337 };
338 
339 FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg);
340 FN_OID_GET_DESCRIPTOR_ATTR1(oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description);
341 FN_OID_GET_ATTR2(oid_get_sig_alg, oid_sig_alg_t, sig_alg, md_type_t, md_alg, pk_type_t, pk_alg);
342 FN_OID_GET_OID_BY_ATTR2(oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, pk_type_t, pk_alg, md_type_t, md_alg);
343 #endif /* POLARSSL_MD_C */
344 
345 /*
346  * For PublicKeyInfo (PKCS1, RFC 5480)
347  */
348 typedef struct {
349  oid_descriptor_t descriptor;
350  pk_type_t pk_alg;
351 } oid_pk_alg_t;
352 
353 static const oid_pk_alg_t oid_pk_alg[] =
354 {
355  {
356  { ADD_LEN( OID_PKCS1_RSA ), "rsaEncryption", "RSA" },
358  },
359  {
360  { ADD_LEN( OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" },
362  },
363  {
364  { ADD_LEN( OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" },
366  },
367  {
368  { NULL, 0, NULL, NULL },
369  0,
370  },
371 };
372 
373 FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg);
374 FN_OID_GET_ATTR1(oid_get_pk_alg, oid_pk_alg_t, pk_alg, pk_type_t, pk_alg);
375 FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, pk_type_t, pk_alg);
376 
377 #if defined(POLARSSL_ECP_C)
378 /*
379  * For namedCurve (RFC 5480)
380  */
381 typedef struct {
382  oid_descriptor_t descriptor;
383  ecp_group_id grp_id;
384 } oid_ecp_grp_t;
385 
386 static const oid_ecp_grp_t oid_ecp_grp[] =
387 {
388  {
389  { ADD_LEN( OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" },
391  },
392  {
393  { ADD_LEN( OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" },
395  },
396  {
397  { ADD_LEN( OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" },
399  },
400  {
401  { ADD_LEN( OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" },
403  },
404  {
405  { ADD_LEN( OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" },
407  },
408  {
409  { ADD_LEN( OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" },
411  },
412  {
413  { ADD_LEN( OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" },
415  },
416  {
417  { ADD_LEN( OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" },
419  },
420  {
421  { NULL, 0, NULL, NULL },
422  0,
423  },
424 };
425 
426 FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp);
427 FN_OID_GET_ATTR1(oid_get_ec_grp, oid_ecp_grp_t, grp_id, ecp_group_id, grp_id);
428 FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, ecp_group_id, grp_id);
429 #endif /* POLARSSL_ECP_C */
430 
431 #if defined(POLARSSL_CIPHER_C)
432 /*
433  * For PKCS#5 PBES2 encryption algorithm
434  */
435 typedef struct {
436  oid_descriptor_t descriptor;
437  cipher_type_t cipher_alg;
438 } oid_cipher_alg_t;
439 
440 static const oid_cipher_alg_t oid_cipher_alg[] =
441 {
442  {
443  { ADD_LEN( OID_DES_CBC ), "desCBC", "DES-CBC" },
445  },
446  {
447  { ADD_LEN( OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" },
449  },
450  {
451  { NULL, 0, NULL, NULL },
452  0,
453  },
454 };
455 
456 FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg);
457 FN_OID_GET_ATTR1(oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, cipher_type_t, cipher_alg);
458 #endif /* POLARSSL_CIPHER_C */
459 
460 #if defined(POLARSSL_MD_C)
461 /*
462  * For digestAlgorithm
463  */
464 typedef struct {
465  oid_descriptor_t descriptor;
466  md_type_t md_alg;
467 } oid_md_alg_t;
468 
469 static const oid_md_alg_t oid_md_alg[] =
470 {
471  {
472  { ADD_LEN( OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" },
474  },
475  {
476  { ADD_LEN( OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" },
478  },
479  {
480  { ADD_LEN( OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" },
482  },
483  {
484  { ADD_LEN( OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" },
486  },
487  {
488  { ADD_LEN( OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" },
490  },
491  {
492  { ADD_LEN( OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" },
494  },
495  {
496  { ADD_LEN( OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" },
498  },
499  {
500  { ADD_LEN( OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" },
502  },
503  {
504  { ADD_LEN( OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" },
506  },
507  {
508  { NULL, 0, NULL, NULL },
509  0,
510  },
511 };
512 
513 FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg);
514 FN_OID_GET_ATTR1(oid_get_md_alg, oid_md_alg_t, md_alg, md_type_t, md_alg);
515 FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, md_type_t, md_alg);
516 #endif /* POLARSSL_MD_C */
517 
518 #if defined(POLARSSL_PKCS12_C)
519 /*
520  * For PKCS#12 PBEs
521  */
522 typedef struct {
523  oid_descriptor_t descriptor;
524  md_type_t md_alg;
525  cipher_type_t cipher_alg;
526 } oid_pkcs12_pbe_alg_t;
527 
528 static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] =
529 {
530  {
531  { ADD_LEN( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" },
533  },
534  {
535  { ADD_LEN( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" },
537  },
538  {
539  { NULL, 0, NULL, NULL },
540  0, 0,
541  },
542 };
543 
544 FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg);
545 FN_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);
546 #endif /* POLARSSL_PKCS12_C */
547 
548 #if defined _MSC_VER && !defined snprintf
549 #include <stdarg.h>
550 
551 #if !defined vsnprintf
552 #define vsnprintf _vsnprintf
553 #endif // vsnprintf
554 
555 /*
556  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
557  * Result value is not size of buffer needed, but -1 if no fit is possible.
558  *
559  * This fuction tries to 'fix' this by at least suggesting enlarging the
560  * size by 20.
561  */
562 static int compat_snprintf(char *str, size_t size, const char *format, ...)
563 {
564  va_list ap;
565  int res = -1;
566 
567  va_start( ap, format );
568 
569  res = vsnprintf( str, size, format, ap );
570 
571  va_end( ap );
572 
573  // No quick fix possible
574  if ( res < 0 )
575  return( (int) size + 20 );
576 
577  return res;
578 }
579 
580 #define snprintf compat_snprintf
581 #endif
582 
583 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
584 
585 #define SAFE_SNPRINTF() \
586 { \
587  if( ret == -1 ) \
588  return( -1 ); \
589  \
590  if ( (unsigned int) ret > n ) { \
591  p[n - 1] = '\0'; \
592  return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
593  } \
594  \
595  n -= (unsigned int) ret; \
596  p += (unsigned int) ret; \
597 }
598 
599 /* Return the x.y.z.... style numeric string for the given OID */
600 int oid_get_numeric_string( char *buf, size_t size,
601  const asn1_buf *oid )
602 {
603  int ret;
604  size_t i, n;
605  unsigned int value;
606  char *p;
607 
608  p = buf;
609  n = size;
610 
611  /* First byte contains first two dots */
612  if( oid->len > 0 )
613  {
614  ret = snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 );
615  SAFE_SNPRINTF();
616  }
617 
618  value = 0;
619  for( i = 1; i < oid->len; i++ )
620  {
621  /* Prevent overflow in value. */
622  if ( ( ( value << 7 ) >> 7 ) != value )
623  return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
624 
625  value <<= 7;
626  value += oid->p[i] & 0x7F;
627 
628  if( !( oid->p[i] & 0x80 ) )
629  {
630  /* Last byte */
631  ret = snprintf( p, n, ".%d", value );
632  SAFE_SNPRINTF();
633  value = 0;
634  }
635  }
636 
637  return( (int) ( size - n ) );
638 }
639 
640 #endif /* POLARSSL_OID_C */