00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "polarssl/config.h"
00038
00039 #if defined(POLARSSL_X509_USE_C)
00040
00041 #include "polarssl/x509.h"
00042 #include "polarssl/asn1.h"
00043 #include "polarssl/oid.h"
00044 #if defined(POLARSSL_PEM_PARSE_C)
00045 #include "polarssl/pem.h"
00046 #endif
00047
00048 #if defined(POLARSSL_MEMORY_C)
00049 #include "polarssl/memory.h"
00050 #else
00051 #define polarssl_malloc malloc
00052 #define polarssl_free free
00053 #endif
00054
00055 #include <string.h>
00056 #include <stdlib.h>
00057 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00058 #include <windows.h>
00059 #else
00060 #include <time.h>
00061 #endif
00062
00063 #if defined(EFIX64) || defined(EFI32)
00064 #include <stdio.h>
00065 #endif
00066
00067 #if defined(POLARSSL_FS_IO)
00068 #include <stdio.h>
00069 #if !defined(_WIN32)
00070 #include <sys/types.h>
00071 #include <sys/stat.h>
00072 #include <dirent.h>
00073 #endif
00074 #endif
00075
00076
00077
00078
00079 int x509_get_serial( unsigned char **p, const unsigned char *end,
00080 x509_buf *serial )
00081 {
00082 int ret;
00083
00084 if( ( end - *p ) < 1 )
00085 return( POLARSSL_ERR_X509_INVALID_SERIAL +
00086 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00087
00088 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
00089 **p != ASN1_INTEGER )
00090 return( POLARSSL_ERR_X509_INVALID_SERIAL +
00091 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00092
00093 serial->tag = *(*p)++;
00094
00095 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
00096 return( POLARSSL_ERR_X509_INVALID_SERIAL + ret );
00097
00098 serial->p = *p;
00099 *p += serial->len;
00100
00101 return( 0 );
00102 }
00103
00104
00105
00106
00107
00108
00109
00110 int x509_get_alg_null( unsigned char **p, const unsigned char *end,
00111 x509_buf *alg )
00112 {
00113 int ret;
00114
00115 if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
00116 return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00117
00118 return( 0 );
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 static int x509_get_attr_type_value( unsigned char **p,
00131 const unsigned char *end,
00132 x509_name *cur )
00133 {
00134 int ret;
00135 size_t len;
00136 x509_buf *oid;
00137 x509_buf *val;
00138
00139 if( ( ret = asn1_get_tag( p, end, &len,
00140 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00141 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00142
00143 if( ( end - *p ) < 1 )
00144 return( POLARSSL_ERR_X509_INVALID_NAME +
00145 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00146
00147 oid = &cur->oid;
00148 oid->tag = **p;
00149
00150 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
00151 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00152
00153 oid->p = *p;
00154 *p += oid->len;
00155
00156 if( ( end - *p ) < 1 )
00157 return( POLARSSL_ERR_X509_INVALID_NAME +
00158 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00159
00160 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING &&
00161 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
00162 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
00163 return( POLARSSL_ERR_X509_INVALID_NAME +
00164 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00165
00166 val = &cur->val;
00167 val->tag = *(*p)++;
00168
00169 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
00170 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00171
00172 val->p = *p;
00173 *p += val->len;
00174
00175 cur->next = NULL;
00176
00177 return( 0 );
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 int x509_get_name( unsigned char **p, const unsigned char *end,
00193 x509_name *cur )
00194 {
00195 int ret;
00196 size_t len;
00197 const unsigned char *end2;
00198 x509_name *use;
00199
00200 if( ( ret = asn1_get_tag( p, end, &len,
00201 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
00202 return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00203
00204 end2 = end;
00205 end = *p + len;
00206 use = cur;
00207
00208 do
00209 {
00210 if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
00211 return( ret );
00212
00213 if( *p != end )
00214 {
00215 use->next = (x509_name *) polarssl_malloc(
00216 sizeof( x509_name ) );
00217
00218 if( use->next == NULL )
00219 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00220
00221 memset( use->next, 0, sizeof( x509_name ) );
00222
00223 use = use->next;
00224 }
00225 }
00226 while( *p != end );
00227
00228
00229
00230
00231 if( *p == end2 )
00232 return( 0 );
00233
00234 cur->next = (x509_name *) polarssl_malloc(
00235 sizeof( x509_name ) );
00236
00237 if( cur->next == NULL )
00238 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00239
00240 memset( cur->next, 0, sizeof( x509_name ) );
00241
00242 return( x509_get_name( p, end2, cur->next ) );
00243 }
00244
00245
00246
00247
00248
00249
00250 int x509_get_time( unsigned char **p, const unsigned char *end,
00251 x509_time *time )
00252 {
00253 int ret;
00254 size_t len;
00255 char date[64];
00256 unsigned char tag;
00257
00258 if( ( end - *p ) < 1 )
00259 return( POLARSSL_ERR_X509_INVALID_DATE +
00260 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00261
00262 tag = **p;
00263
00264 if ( tag == ASN1_UTC_TIME )
00265 {
00266 (*p)++;
00267 ret = asn1_get_len( p, end, &len );
00268
00269 if( ret != 0 )
00270 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
00271
00272 memset( date, 0, sizeof( date ) );
00273 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
00274 len : sizeof( date ) - 1 );
00275
00276 if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
00277 &time->year, &time->mon, &time->day,
00278 &time->hour, &time->min, &time->sec ) < 5 )
00279 return( POLARSSL_ERR_X509_INVALID_DATE );
00280
00281 time->year += 100 * ( time->year < 50 );
00282 time->year += 1900;
00283
00284 *p += len;
00285
00286 return( 0 );
00287 }
00288 else if ( tag == ASN1_GENERALIZED_TIME )
00289 {
00290 (*p)++;
00291 ret = asn1_get_len( p, end, &len );
00292
00293 if( ret != 0 )
00294 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
00295
00296 memset( date, 0, sizeof( date ) );
00297 memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
00298 len : sizeof( date ) - 1 );
00299
00300 if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
00301 &time->year, &time->mon, &time->day,
00302 &time->hour, &time->min, &time->sec ) < 5 )
00303 return( POLARSSL_ERR_X509_INVALID_DATE );
00304
00305 *p += len;
00306
00307 return( 0 );
00308 }
00309 else
00310 return( POLARSSL_ERR_X509_INVALID_DATE +
00311 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00312 }
00313
00314 int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
00315 {
00316 int ret;
00317 size_t len;
00318
00319 if( ( end - *p ) < 1 )
00320 return( POLARSSL_ERR_X509_INVALID_SIGNATURE +
00321 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00322
00323 sig->tag = **p;
00324
00325 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
00326 return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
00327
00328 sig->len = len;
00329 sig->p = *p;
00330
00331 *p += len;
00332
00333 return( 0 );
00334 }
00335
00336 int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
00337 pk_type_t *pk_alg )
00338 {
00339 int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
00340
00341 if( ret != 0 )
00342 return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
00343
00344 return( 0 );
00345 }
00346
00347
00348
00349
00350
00351 int x509_get_ext( unsigned char **p, const unsigned char *end,
00352 x509_buf *ext, int tag )
00353 {
00354 int ret;
00355 size_t len;
00356
00357 if( *p == end )
00358 return( 0 );
00359
00360 ext->tag = **p;
00361
00362 if( ( ret = asn1_get_tag( p, end, &ext->len,
00363 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
00364 return( ret );
00365
00366 ext->p = *p;
00367 end = *p + ext->len;
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 if( ( ret = asn1_get_tag( p, end, &len,
00378 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00379 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00380
00381 if( end != *p + len )
00382 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00383 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00384
00385 return( 0 );
00386 }
00387
00388 #if defined(POLARSSL_FS_IO)
00389
00390
00391
00392 int x509_load_file( const char *path, unsigned char **buf, size_t *n )
00393 {
00394 FILE *f;
00395 long size;
00396
00397 if( ( f = fopen( path, "rb" ) ) == NULL )
00398 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
00399
00400 fseek( f, 0, SEEK_END );
00401 if( ( size = ftell( f ) ) == -1 )
00402 {
00403 fclose( f );
00404 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
00405 }
00406 fseek( f, 0, SEEK_SET );
00407
00408 *n = (size_t) size;
00409
00410 if( *n + 1 == 0 ||
00411 ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
00412 {
00413 fclose( f );
00414 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00415 }
00416
00417 if( fread( *buf, 1, *n, f ) != *n )
00418 {
00419 fclose( f );
00420 polarssl_free( *buf );
00421 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
00422 }
00423
00424 fclose( f );
00425
00426 (*buf)[*n] = '\0';
00427
00428 return( 0 );
00429 }
00430 #endif
00431
00432 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
00433 !defined(EFI32)
00434 #include <stdarg.h>
00435
00436 #if !defined vsnprintf
00437 #define vsnprintf _vsnprintf
00438 #endif // vsnprintf
00439
00440
00441
00442
00443
00444
00445
00446
00447 static int compat_snprintf(char *str, size_t size, const char *format, ...)
00448 {
00449 va_list ap;
00450 int res = -1;
00451
00452 va_start( ap, format );
00453
00454 res = vsnprintf( str, size, format, ap );
00455
00456 va_end( ap );
00457
00458
00459 if ( res < 0 )
00460 return( (int) size + 20 );
00461
00462 return res;
00463 }
00464
00465 #define snprintf compat_snprintf
00466 #endif
00467
00468 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
00469
00470 #define SAFE_SNPRINTF() \
00471 { \
00472 if( ret == -1 ) \
00473 return( -1 ); \
00474 \
00475 if ( (unsigned int) ret > n ) { \
00476 p[n - 1] = '\0'; \
00477 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
00478 } \
00479 \
00480 n -= (unsigned int) ret; \
00481 p += (unsigned int) ret; \
00482 }
00483
00484
00485
00486
00487
00488 int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
00489 {
00490 int ret;
00491 size_t i, n;
00492 unsigned char c;
00493 const x509_name *name;
00494 const char *short_name = NULL;
00495 char s[128], *p;
00496
00497 memset( s, 0, sizeof( s ) );
00498
00499 name = dn;
00500 p = buf;
00501 n = size;
00502
00503 while( name != NULL )
00504 {
00505 if( !name->oid.p )
00506 {
00507 name = name->next;
00508 continue;
00509 }
00510
00511 if( name != dn )
00512 {
00513 ret = snprintf( p, n, ", " );
00514 SAFE_SNPRINTF();
00515 }
00516
00517 ret = oid_get_attr_short_name( &name->oid, &short_name );
00518
00519 if( ret == 0 )
00520 ret = snprintf( p, n, "%s=", short_name );
00521 else
00522 ret = snprintf( p, n, "\?\?=" );
00523 SAFE_SNPRINTF();
00524
00525 for( i = 0; i < name->val.len; i++ )
00526 {
00527 if( i >= sizeof( s ) - 1 )
00528 break;
00529
00530 c = name->val.p[i];
00531 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
00532 s[i] = '?';
00533 else s[i] = c;
00534 }
00535 s[i] = '\0';
00536 ret = snprintf( p, n, "%s", s );
00537 SAFE_SNPRINTF();
00538 name = name->next;
00539 }
00540
00541 return( (int) ( size - n ) );
00542 }
00543
00544
00545
00546
00547
00548 int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
00549 {
00550 int ret;
00551 size_t i, n, nr;
00552 char *p;
00553
00554 p = buf;
00555 n = size;
00556
00557 nr = ( serial->len <= 32 )
00558 ? serial->len : 28;
00559
00560 for( i = 0; i < nr; i++ )
00561 {
00562 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
00563 continue;
00564
00565 ret = snprintf( p, n, "%02X%s",
00566 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
00567 SAFE_SNPRINTF();
00568 }
00569
00570 if( nr != serial->len )
00571 {
00572 ret = snprintf( p, n, "...." );
00573 SAFE_SNPRINTF();
00574 }
00575
00576 return( (int) ( size - n ) );
00577 }
00578
00579
00580
00581
00582 int x509_key_size_helper( char *buf, size_t size, const char *name )
00583 {
00584 char *p = buf;
00585 size_t n = size;
00586 int ret;
00587
00588 if( strlen( name ) + sizeof( " key size" ) > size )
00589 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;
00590
00591 ret = snprintf( p, n, "%s key size", name );
00592 SAFE_SNPRINTF();
00593
00594 return( 0 );
00595 }
00596
00597
00598
00599
00600 const char *x509_oid_get_description( x509_buf *oid )
00601 {
00602 const char *desc = NULL;
00603 int ret;
00604
00605 ret = oid_get_extended_key_usage( oid, &desc );
00606
00607 if( ret != 0 )
00608 return( NULL );
00609
00610 return( desc );
00611 }
00612
00613
00614 int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
00615 {
00616 return oid_get_numeric_string( buf, size, oid );
00617 }
00618
00619
00620
00621
00622 #if defined(POLARSSL_HAVE_TIME)
00623 int x509_time_expired( const x509_time *to )
00624 {
00625 int year, mon, day;
00626 int hour, min, sec;
00627
00628 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00629 SYSTEMTIME st;
00630
00631 GetLocalTime(&st);
00632
00633 year = st.wYear;
00634 mon = st.wMonth;
00635 day = st.wDay;
00636 hour = st.wHour;
00637 min = st.wMinute;
00638 sec = st.wSecond;
00639 #else
00640 struct tm *lt;
00641 time_t tt;
00642
00643 tt = time( NULL );
00644 lt = localtime( &tt );
00645
00646 year = lt->tm_year + 1900;
00647 mon = lt->tm_mon + 1;
00648 day = lt->tm_mday;
00649 hour = lt->tm_hour;
00650 min = lt->tm_min;
00651 sec = lt->tm_sec;
00652 #endif
00653
00654 if( year > to->year )
00655 return( 1 );
00656
00657 if( year == to->year &&
00658 mon > to->mon )
00659 return( 1 );
00660
00661 if( year == to->year &&
00662 mon == to->mon &&
00663 day > to->day )
00664 return( 1 );
00665
00666 if( year == to->year &&
00667 mon == to->mon &&
00668 day == to->day &&
00669 hour > to->hour )
00670 return( 1 );
00671
00672 if( year == to->year &&
00673 mon == to->mon &&
00674 day == to->day &&
00675 hour == to->hour &&
00676 min > to->min )
00677 return( 1 );
00678
00679 if( year == to->year &&
00680 mon == to->mon &&
00681 day == to->day &&
00682 hour == to->hour &&
00683 min == to->min &&
00684 sec > to->sec )
00685 return( 1 );
00686
00687 return( 0 );
00688 }
00689 #else
00690 int x509_time_expired( const x509_time *to )
00691 {
00692 ((void) to);
00693 return( 0 );
00694 }
00695 #endif
00696
00697 #if defined(POLARSSL_SELF_TEST)
00698
00699 #include "polarssl/x509_crt.h"
00700 #include "polarssl/certs.h"
00701
00702
00703
00704
00705 int x509_self_test( int verbose )
00706 {
00707 #if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
00708 int ret;
00709 int flags;
00710 x509_crt cacert;
00711 x509_crt clicert;
00712
00713 if( verbose != 0 )
00714 printf( " X.509 certificate load: " );
00715
00716 x509_crt_init( &clicert );
00717
00718 ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
00719 strlen( test_cli_crt ) );
00720 if( ret != 0 )
00721 {
00722 if( verbose != 0 )
00723 printf( "failed\n" );
00724
00725 return( ret );
00726 }
00727
00728 x509_crt_init( &cacert );
00729
00730 ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
00731 strlen( test_ca_crt ) );
00732 if( ret != 0 )
00733 {
00734 if( verbose != 0 )
00735 printf( "failed\n" );
00736
00737 return( ret );
00738 }
00739
00740 if( verbose != 0 )
00741 printf( "passed\n X.509 signature verify: ");
00742
00743 ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
00744 if( ret != 0 )
00745 {
00746 if( verbose != 0 )
00747 printf( "failed\n" );
00748
00749 printf("ret = %d, &flags = %04x\n", ret, flags);
00750
00751 return( ret );
00752 }
00753
00754 if( verbose != 0 )
00755 printf( "passed\n\n");
00756
00757 x509_crt_free( &cacert );
00758 x509_crt_free( &clicert );
00759
00760 return( 0 );
00761 #else
00762 ((void) verbose);
00763 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
00764 #endif
00765 }
00766
00767 #endif
00768
00769 #endif