00001 /* 00002 * X.509 certificate and private key decoding 00003 * 00004 * Copyright (C) 2006-2007 Christophe Devine 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 /* 00021 * The ITU-T X.509 standard defines a certificat format for PKI. 00022 * 00023 * http://www.ietf.org/rfc/rfc2459.txt 00024 * http://www.ietf.org/rfc/rfc3279.txt 00025 * 00026 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc 00027 * 00028 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf 00029 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 00030 */ 00031 00032 #include "xyssl/config.h" 00033 00034 #if defined(XYSSL_X509_PARSE_C) 00035 00036 #include "xyssl/x509.h" 00037 #include "xyssl/base64.h" 00038 #include "xyssl/des.h" 00039 #include "xyssl/md2.h" 00040 #include "xyssl/md4.h" 00041 #include "xyssl/md5.h" 00042 #include "xyssl/sha1.h" 00043 00044 #include <string.h> 00045 #include <stdlib.h> 00046 #include <stdio.h> 00047 #include <time.h> 00048 00049 /* 00050 * ASN.1 DER decoding routines 00051 */ 00052 static int asn1_get_len( unsigned char **p, 00053 unsigned char *end, 00054 int *len ) 00055 { 00056 if( ( end - *p ) < 1 ) 00057 return( XYSSL_ERR_ASN1_OUT_OF_DATA ); 00058 00059 if( ( **p & 0x80 ) == 0 ) 00060 *len = *(*p)++; 00061 else 00062 { 00063 switch( **p & 0x7F ) 00064 { 00065 case 1: 00066 if( ( end - *p ) < 2 ) 00067 return( XYSSL_ERR_ASN1_OUT_OF_DATA ); 00068 00069 *len = (*p)[1]; 00070 (*p) += 2; 00071 break; 00072 00073 case 2: 00074 if( ( end - *p ) < 3 ) 00075 return( XYSSL_ERR_ASN1_OUT_OF_DATA ); 00076 00077 *len = ( (*p)[1] << 8 ) | (*p)[2]; 00078 (*p) += 3; 00079 break; 00080 00081 default: 00082 return( XYSSL_ERR_ASN1_INVALID_LENGTH ); 00083 break; 00084 } 00085 } 00086 00087 if( *len > (int) ( end - *p ) ) 00088 return( XYSSL_ERR_ASN1_OUT_OF_DATA ); 00089 00090 return( 0 ); 00091 } 00092 00093 static int asn1_get_tag( unsigned char **p, 00094 unsigned char *end, 00095 int *len, int tag ) 00096 { 00097 if( ( end - *p ) < 1 ) 00098 return( XYSSL_ERR_ASN1_OUT_OF_DATA ); 00099 00100 if( **p != tag ) 00101 return( XYSSL_ERR_ASN1_UNEXPECTED_TAG ); 00102 00103 (*p)++; 00104 00105 return( asn1_get_len( p, end, len ) ); 00106 } 00107 00108 static int asn1_get_bool( unsigned char **p, 00109 unsigned char *end, 00110 int *val ) 00111 { 00112 int ret, len; 00113 00114 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 ) 00115 return( ret ); 00116 00117 if( len != 1 ) 00118 return( XYSSL_ERR_ASN1_INVALID_LENGTH ); 00119 00120 *val = ( **p != 0 ) ? 1 : 0; 00121 (*p)++; 00122 00123 return( 0 ); 00124 } 00125 00126 static int asn1_get_int( unsigned char **p, 00127 unsigned char *end, 00128 int *val ) 00129 { 00130 int ret, len; 00131 00132 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) 00133 return( ret ); 00134 00135 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 ) 00136 return( XYSSL_ERR_ASN1_INVALID_LENGTH ); 00137 00138 *val = 0; 00139 00140 while( len-- > 0 ) 00141 { 00142 *val = ( *val << 8 ) | **p; 00143 (*p)++; 00144 } 00145 00146 return( 0 ); 00147 } 00148 00149 static int asn1_get_mpi( unsigned char **p, 00150 unsigned char *end, 00151 mpi *X ) 00152 { 00153 int ret, len; 00154 00155 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) 00156 return( ret ); 00157 00158 ret = mpi_read_binary( X, *p, len ); 00159 00160 *p += len; 00161 00162 return( ret ); 00163 } 00164 00165 /* 00166 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 00167 */ 00168 static int x509_get_version( unsigned char **p, 00169 unsigned char *end, 00170 int *ver ) 00171 { 00172 int ret, len; 00173 00174 if( ( ret = asn1_get_tag( p, end, &len, 00175 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 ) 00176 { 00177 if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG ) 00178 return( *ver = 0 ); 00179 00180 return( ret ); 00181 } 00182 00183 end = *p + len; 00184 00185 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 ) 00186 return( XYSSL_ERR_X509_CERT_INVALID_VERSION | ret ); 00187 00188 if( *p != end ) 00189 return( XYSSL_ERR_X509_CERT_INVALID_VERSION | 00190 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00191 00192 return( 0 ); 00193 } 00194 00195 /* 00196 * CertificateSerialNumber ::= INTEGER 00197 */ 00198 static int x509_get_serial( unsigned char **p, 00199 unsigned char *end, 00200 x509_buf *serial ) 00201 { 00202 int ret; 00203 00204 if( ( end - *p ) < 1 ) 00205 return( XYSSL_ERR_X509_CERT_INVALID_SERIAL | 00206 XYSSL_ERR_ASN1_OUT_OF_DATA ); 00207 00208 if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) && 00209 **p != ASN1_INTEGER ) 00210 return( XYSSL_ERR_X509_CERT_INVALID_SERIAL | 00211 XYSSL_ERR_ASN1_UNEXPECTED_TAG ); 00212 00213 serial->tag = *(*p)++; 00214 00215 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 ) 00216 return( XYSSL_ERR_X509_CERT_INVALID_SERIAL | ret ); 00217 00218 serial->p = *p; 00219 *p += serial->len; 00220 00221 return( 0 ); 00222 } 00223 00224 /* 00225 * AlgorithmIdentifier ::= SEQUENCE { 00226 * algorithm OBJECT IDENTIFIER, 00227 * parameters ANY DEFINED BY algorithm OPTIONAL } 00228 */ 00229 static int x509_get_alg( unsigned char **p, 00230 unsigned char *end, 00231 x509_buf *alg ) 00232 { 00233 int ret, len; 00234 00235 if( ( ret = asn1_get_tag( p, end, &len, 00236 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00237 return( XYSSL_ERR_X509_CERT_INVALID_ALG | ret ); 00238 00239 end = *p + len; 00240 alg->tag = **p; 00241 00242 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 ) 00243 return( XYSSL_ERR_X509_CERT_INVALID_ALG | ret ); 00244 00245 alg->p = *p; 00246 *p += alg->len; 00247 00248 if( *p == end ) 00249 return( 0 ); 00250 00251 /* 00252 * assume the algorithm parameters must be NULL 00253 */ 00254 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 ) 00255 return( XYSSL_ERR_X509_CERT_INVALID_ALG | ret ); 00256 00257 if( *p != end ) 00258 return( XYSSL_ERR_X509_CERT_INVALID_ALG | 00259 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00260 00261 return( 0 ); 00262 } 00263 00264 /* 00265 * RelativeDistinguishedName ::= 00266 * SET OF AttributeTypeAndValue 00267 * 00268 * AttributeTypeAndValue ::= SEQUENCE { 00269 * type AttributeType, 00270 * value AttributeValue } 00271 * 00272 * AttributeType ::= OBJECT IDENTIFIER 00273 * 00274 * AttributeValue ::= ANY DEFINED BY AttributeType 00275 */ 00276 static int x509_get_name( unsigned char **p, 00277 unsigned char *end, 00278 x509_name *cur ) 00279 { 00280 int ret, len; 00281 unsigned char *end2; 00282 x509_buf *oid; 00283 x509_buf *val; 00284 00285 if( ( ret = asn1_get_tag( p, end, &len, 00286 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 ) 00287 return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret ); 00288 00289 end2 = end; 00290 end = *p + len; 00291 00292 if( ( ret = asn1_get_tag( p, end, &len, 00293 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00294 return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret ); 00295 00296 if( *p + len != end ) 00297 return( XYSSL_ERR_X509_CERT_INVALID_NAME | 00298 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00299 00300 oid = &cur->oid; 00301 oid->tag = **p; 00302 00303 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 ) 00304 return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret ); 00305 00306 oid->p = *p; 00307 *p += oid->len; 00308 00309 if( ( end - *p ) < 1 ) 00310 return( XYSSL_ERR_X509_CERT_INVALID_NAME | 00311 XYSSL_ERR_ASN1_OUT_OF_DATA ); 00312 00313 if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING && 00314 **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING && 00315 **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING ) 00316 return( XYSSL_ERR_X509_CERT_INVALID_NAME | 00317 XYSSL_ERR_ASN1_UNEXPECTED_TAG ); 00318 00319 val = &cur->val; 00320 val->tag = *(*p)++; 00321 00322 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 ) 00323 return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret ); 00324 00325 val->p = *p; 00326 *p += val->len; 00327 00328 cur->next = NULL; 00329 00330 if( *p != end ) 00331 return( XYSSL_ERR_X509_CERT_INVALID_NAME | 00332 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00333 00334 /* 00335 * recurse until end of SEQUENCE is reached 00336 */ 00337 if( *p == end2 ) 00338 return( 0 ); 00339 00340 cur->next = (x509_name *) malloc( 00341 sizeof( x509_name ) ); 00342 00343 if( cur->next == NULL ) 00344 return( 1 ); 00345 00346 return( x509_get_name( p, end2, cur->next ) ); 00347 } 00348 00349 /* 00350 * Validity ::= SEQUENCE { 00351 * notBefore Time, 00352 * notAfter Time } 00353 * 00354 * Time ::= CHOICE { 00355 * utcTime UTCTime, 00356 * generalTime GeneralizedTime } 00357 */ 00358 static int x509_get_dates( unsigned char **p, 00359 unsigned char *end, 00360 x509_time *from, 00361 x509_time *to ) 00362 { 00363 int ret, len; 00364 char date[64]; 00365 00366 if( ( ret = asn1_get_tag( p, end, &len, 00367 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00368 return( XYSSL_ERR_X509_CERT_INVALID_DATE | ret ); 00369 00370 end = *p + len; 00371 00372 /* 00373 * TODO: also handle GeneralizedTime 00374 */ 00375 if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 ) 00376 return( XYSSL_ERR_X509_CERT_INVALID_DATE | ret ); 00377 00378 memset( date, 0, sizeof( date ) ); 00379 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ? 00380 len : (int) sizeof( date ) - 1 ); 00381 00382 if( sscanf( date, "%2d%2d%2d%2d%2d%2d", 00383 &from->year, &from->mon, &from->day, 00384 &from->hour, &from->min, &from->sec ) < 5 ) 00385 return( XYSSL_ERR_X509_CERT_INVALID_DATE ); 00386 00387 from->year += 100 * ( from->year < 90 ); 00388 from->year += 1900; 00389 00390 *p += len; 00391 00392 if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 ) 00393 return( XYSSL_ERR_X509_CERT_INVALID_DATE | ret ); 00394 00395 memset( date, 0, sizeof( date ) ); 00396 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ? 00397 len : (int) sizeof( date ) - 1 ); 00398 00399 if( sscanf( date, "%2d%2d%2d%2d%2d%2d", 00400 &to->year, &to->mon, &to->day, 00401 &to->hour, &to->min, &to->sec ) < 5 ) 00402 return( XYSSL_ERR_X509_CERT_INVALID_DATE ); 00403 00404 to->year += 100 * ( to->year < 90 ); 00405 to->year += 1900; 00406 00407 *p += len; 00408 00409 if( *p != end ) 00410 return( XYSSL_ERR_X509_CERT_INVALID_DATE | 00411 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00412 00413 return( 0 ); 00414 } 00415 00416 /* 00417 * SubjectPublicKeyInfo ::= SEQUENCE { 00418 * algorithm AlgorithmIdentifier, 00419 * subjectPublicKey BIT STRING } 00420 */ 00421 static int x509_get_pubkey( unsigned char **p, 00422 unsigned char *end, 00423 x509_buf *pk_alg_oid, 00424 mpi *N, mpi *E ) 00425 { 00426 int ret, len; 00427 unsigned char *end2; 00428 00429 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 ) 00430 return( ret ); 00431 00432 /* 00433 * only RSA public keys handled at this time 00434 */ 00435 if( pk_alg_oid->len != 9 || 00436 memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 ) 00437 return( XYSSL_ERR_X509_CERT_UNKNOWN_PK_ALG ); 00438 00439 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 ) 00440 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | ret ); 00441 00442 if( ( end - *p ) < 1 ) 00443 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | 00444 XYSSL_ERR_ASN1_OUT_OF_DATA ); 00445 00446 end2 = *p + len; 00447 00448 if( *(*p)++ != 0 ) 00449 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY ); 00450 00451 /* 00452 * RSAPublicKey ::= SEQUENCE { 00453 * modulus INTEGER, -- n 00454 * publicExponent INTEGER -- e 00455 * } 00456 */ 00457 if( ( ret = asn1_get_tag( p, end2, &len, 00458 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00459 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | ret ); 00460 00461 if( *p + len != end2 ) 00462 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | 00463 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00464 00465 if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 || 00466 ( ret = asn1_get_mpi( p, end2, E ) ) != 0 ) 00467 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | ret ); 00468 00469 if( *p != end ) 00470 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | 00471 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00472 00473 return( 0 ); 00474 } 00475 00476 static int x509_get_sig( unsigned char **p, 00477 unsigned char *end, 00478 x509_buf *sig ) 00479 { 00480 int ret, len; 00481 00482 sig->tag = **p; 00483 00484 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 ) 00485 return( XYSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret ); 00486 00487 if( --len < 1 || *(*p)++ != 0 ) 00488 return( XYSSL_ERR_X509_CERT_INVALID_SIGNATURE ); 00489 00490 sig->len = len; 00491 sig->p = *p; 00492 00493 *p += len; 00494 00495 return( 0 ); 00496 } 00497 00498 /* 00499 * X.509 v2/v3 unique identifier (not parsed) 00500 */ 00501 static int x509_get_uid( unsigned char **p, 00502 unsigned char *end, 00503 x509_buf *uid, int n ) 00504 { 00505 int ret; 00506 00507 if( *p == end ) 00508 return( 0 ); 00509 00510 uid->tag = **p; 00511 00512 if( ( ret = asn1_get_tag( p, end, &uid->len, 00513 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 ) 00514 { 00515 if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG ) 00516 return( 0 ); 00517 00518 return( ret ); 00519 } 00520 00521 uid->p = *p; 00522 *p += uid->len; 00523 00524 return( 0 ); 00525 } 00526 00527 /* 00528 * X.509 v3 extensions (only BasicConstraints are parsed) 00529 */ 00530 static int x509_get_ext( unsigned char **p, 00531 unsigned char *end, 00532 x509_buf *ext, 00533 int *ca_istrue, 00534 int *max_pathlen ) 00535 { 00536 int ret, len; 00537 int is_critical = 1; 00538 int is_cacert = 0; 00539 unsigned char *end2; 00540 00541 if( *p == end ) 00542 return( 0 ); 00543 00544 ext->tag = **p; 00545 00546 if( ( ret = asn1_get_tag( p, end, &ext->len, 00547 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 ) 00548 { 00549 if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG ) 00550 return( 0 ); 00551 00552 return( ret ); 00553 } 00554 00555 ext->p = *p; 00556 end = *p + ext->len; 00557 00558 /* 00559 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 00560 * 00561 * Extension ::= SEQUENCE { 00562 * extnID OBJECT IDENTIFIER, 00563 * critical BOOLEAN DEFAULT FALSE, 00564 * extnValue OCTET STRING } 00565 */ 00566 if( ( ret = asn1_get_tag( p, end, &len, 00567 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00568 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret ); 00569 00570 if( end != *p + len ) 00571 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | 00572 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00573 00574 while( *p < end ) 00575 { 00576 if( ( ret = asn1_get_tag( p, end, &len, 00577 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00578 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret ); 00579 00580 if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 ) 00581 { 00582 *p += len; 00583 continue; 00584 } 00585 00586 *p += 5; 00587 00588 if( ( ret = asn1_get_bool( p, end, &is_critical ) ) != 0 && 00589 ( ret != XYSSL_ERR_ASN1_UNEXPECTED_TAG ) ) 00590 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret ); 00591 00592 if( ( ret = asn1_get_tag( p, end, &len, 00593 ASN1_OCTET_STRING ) ) != 0 ) 00594 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret ); 00595 00596 /* 00597 * BasicConstraints ::= SEQUENCE { 00598 * cA BOOLEAN DEFAULT FALSE, 00599 * pathLenConstraint INTEGER (0..MAX) OPTIONAL } 00600 */ 00601 end2 = *p + len; 00602 00603 if( ( ret = asn1_get_tag( p, end2, &len, 00604 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00605 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret ); 00606 00607 if( *p == end2 ) 00608 continue; 00609 00610 if( ( ret = asn1_get_bool( p, end2, &is_cacert ) ) != 0 ) 00611 { 00612 if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG ) 00613 ret = asn1_get_int( p, end2, &is_cacert ); 00614 00615 if( ret != 0 ) 00616 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret ); 00617 00618 if( is_cacert != 0 ) 00619 is_cacert = 1; 00620 } 00621 00622 if( *p == end2 ) 00623 continue; 00624 00625 if( ( ret = asn1_get_int( p, end2, max_pathlen ) ) != 0 ) 00626 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret ); 00627 00628 if( *p != end2 ) 00629 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | 00630 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00631 00632 max_pathlen++; 00633 } 00634 00635 if( *p != end ) 00636 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | 00637 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00638 00639 *ca_istrue = is_critical & is_cacert; 00640 00641 return( 0 ); 00642 } 00643 00644 /* 00645 * Parse one or more certificates and add them to the chained list 00646 */ 00647 int x509parse_crt( x509_cert *chain, unsigned char *buf, int buflen ) 00648 { 00649 int ret, len; 00650 unsigned char *s1, *s2; 00651 unsigned char *p, *end; 00652 x509_cert *crt; 00653 00654 crt = chain; 00655 00656 while( crt->version != 0 ) 00657 crt = crt->next; 00658 00659 /* 00660 * check if the certificate is encoded in base64 00661 */ 00662 s1 = (unsigned char *) strstr( (char *) buf, 00663 "-----BEGIN CERTIFICATE-----" ); 00664 00665 if( s1 != NULL ) 00666 { 00667 s2 = (unsigned char *) strstr( (char *) buf, 00668 "-----END CERTIFICATE-----" ); 00669 00670 if( s2 == NULL || s2 <= s1 ) 00671 return( XYSSL_ERR_X509_CERT_INVALID_PEM ); 00672 00673 s1 += 27; 00674 if( *s1 == '\r' ) s1++; 00675 if( *s1 == '\n' ) s1++; 00676 else return( XYSSL_ERR_X509_CERT_INVALID_PEM ); 00677 00678 /* 00679 * get the DER data length and decode the buffer 00680 */ 00681 len = 0; 00682 ret = base64_decode( NULL, &len, s1, s2 - s1 ); 00683 00684 if( ret == XYSSL_ERR_BASE64_INVALID_CHARACTER ) 00685 return( XYSSL_ERR_X509_CERT_INVALID_PEM | ret ); 00686 00687 if( ( p = (unsigned char *) malloc( len ) ) == NULL ) 00688 return( 1 ); 00689 00690 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 ) 00691 { 00692 free( p ); 00693 return( XYSSL_ERR_X509_CERT_INVALID_PEM | ret ); 00694 } 00695 00696 /* 00697 * update the buffer size and offset 00698 */ 00699 s2 += 25; 00700 if( *s2 == '\r' ) s2++; 00701 if( *s2 == '\n' ) s2++; 00702 else 00703 { 00704 free( p ); 00705 return( XYSSL_ERR_X509_CERT_INVALID_PEM ); 00706 } 00707 00708 buflen -= s2 - buf; 00709 buf = s2; 00710 } 00711 else 00712 { 00713 /* 00714 * nope, copy the raw DER data 00715 */ 00716 p = (unsigned char *) malloc( len = buflen ); 00717 00718 if( p == NULL ) 00719 return( 1 ); 00720 00721 memcpy( p, buf, buflen ); 00722 00723 buflen = 0; 00724 } 00725 00726 crt->raw.p = p; 00727 crt->raw.len = len; 00728 end = p + len; 00729 00730 /* 00731 * Certificate ::= SEQUENCE { 00732 * tbsCertificate TBSCertificate, 00733 * signatureAlgorithm AlgorithmIdentifier, 00734 * signatureValue BIT STRING } 00735 */ 00736 if( ( ret = asn1_get_tag( &p, end, &len, 00737 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00738 { 00739 x509_free( crt ); 00740 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT ); 00741 } 00742 00743 if( len != (int) ( end - p ) ) 00744 { 00745 x509_free( crt ); 00746 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | 00747 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00748 } 00749 00750 /* 00751 * TBSCertificate ::= SEQUENCE { 00752 */ 00753 crt->tbs.p = p; 00754 00755 if( ( ret = asn1_get_tag( &p, end, &len, 00756 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00757 { 00758 x509_free( crt ); 00759 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret ); 00760 } 00761 00762 end = p + len; 00763 crt->tbs.len = end - crt->tbs.p; 00764 00765 /* 00766 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 00767 * 00768 * CertificateSerialNumber ::= INTEGER 00769 * 00770 * signature AlgorithmIdentifier 00771 */ 00772 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || 00773 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 || 00774 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 ) 00775 { 00776 x509_free( crt ); 00777 return( ret ); 00778 } 00779 00780 crt->version++; 00781 00782 if( crt->version > 3 ) 00783 { 00784 x509_free( crt ); 00785 return( XYSSL_ERR_X509_CERT_UNKNOWN_VERSION ); 00786 } 00787 00788 if( crt->sig_oid1.len != 9 || 00789 memcmp( crt->sig_oid1.p, OID_PKCS1, 8 ) != 0 ) 00790 { 00791 x509_free( crt ); 00792 return( XYSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG ); 00793 } 00794 00795 if( crt->sig_oid1.p[8] < 2 || 00796 crt->sig_oid1.p[8] > 5 ) 00797 { 00798 x509_free( crt ); 00799 return( XYSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG ); 00800 } 00801 00802 /* 00803 * issuer Name 00804 */ 00805 crt->issuer_raw.p = p; 00806 00807 if( ( ret = asn1_get_tag( &p, end, &len, 00808 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00809 { 00810 x509_free( crt ); 00811 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret ); 00812 } 00813 00814 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) 00815 { 00816 x509_free( crt ); 00817 return( ret ); 00818 } 00819 00820 crt->issuer_raw.len = p - crt->issuer_raw.p; 00821 00822 /* 00823 * Validity ::= SEQUENCE { 00824 * notBefore Time, 00825 * notAfter Time } 00826 * 00827 */ 00828 if( ( ret = x509_get_dates( &p, end, &crt->valid_from, 00829 &crt->valid_to ) ) != 0 ) 00830 { 00831 x509_free( crt ); 00832 return( ret ); 00833 } 00834 00835 /* 00836 * subject Name 00837 */ 00838 crt->subject_raw.p = p; 00839 00840 if( ( ret = asn1_get_tag( &p, end, &len, 00841 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00842 { 00843 x509_free( crt ); 00844 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret ); 00845 } 00846 00847 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) 00848 { 00849 x509_free( crt ); 00850 return( ret ); 00851 } 00852 00853 crt->subject_raw.len = p - crt->subject_raw.p; 00854 00855 /* 00856 * SubjectPublicKeyInfo ::= SEQUENCE 00857 * algorithm AlgorithmIdentifier, 00858 * subjectPublicKey BIT STRING } 00859 */ 00860 if( ( ret = asn1_get_tag( &p, end, &len, 00861 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00862 { 00863 x509_free( crt ); 00864 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret ); 00865 } 00866 00867 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid, 00868 &crt->rsa.N, &crt->rsa.E ) ) != 0 ) 00869 { 00870 x509_free( crt ); 00871 return( ret ); 00872 } 00873 00874 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 ) 00875 { 00876 x509_free( crt ); 00877 return( ret ); 00878 } 00879 00880 crt->rsa.len = mpi_size( &crt->rsa.N ); 00881 00882 /* 00883 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, 00884 * -- If present, version shall be v2 or v3 00885 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, 00886 * -- If present, version shall be v2 or v3 00887 * extensions [3] EXPLICIT Extensions OPTIONAL 00888 * -- If present, version shall be v3 00889 */ 00890 if( crt->version == 2 || crt->version == 3 ) 00891 { 00892 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); 00893 if( ret != 0 ) 00894 { 00895 x509_free( crt ); 00896 return( ret ); 00897 } 00898 } 00899 00900 if( crt->version == 2 || crt->version == 3 ) 00901 { 00902 ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); 00903 if( ret != 0 ) 00904 { 00905 x509_free( crt ); 00906 return( ret ); 00907 } 00908 } 00909 00910 if( crt->version == 3 ) 00911 { 00912 ret = x509_get_ext( &p, end, &crt->v3_ext, 00913 &crt->ca_istrue, &crt->max_pathlen ); 00914 if( ret != 0 ) 00915 { 00916 x509_free( crt ); 00917 return( ret ); 00918 } 00919 } 00920 00921 if( p != end ) 00922 { 00923 x509_free( crt ); 00924 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | 00925 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00926 } 00927 00928 end = crt->raw.p + crt->raw.len; 00929 00930 /* 00931 * signatureAlgorithm AlgorithmIdentifier, 00932 * signatureValue BIT STRING 00933 */ 00934 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 ) 00935 { 00936 x509_free( crt ); 00937 return( ret ); 00938 } 00939 00940 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, 9 ) != 0 ) 00941 { 00942 x509_free( crt ); 00943 return( XYSSL_ERR_X509_CERT_SIG_MISMATCH ); 00944 } 00945 00946 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 ) 00947 { 00948 x509_free( crt ); 00949 return( ret ); 00950 } 00951 00952 if( p != end ) 00953 { 00954 x509_free( crt ); 00955 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | 00956 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 00957 } 00958 00959 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) ); 00960 00961 if( crt->next == NULL ) 00962 { 00963 x509_free( crt ); 00964 return( 1 ); 00965 } 00966 00967 crt = crt->next; 00968 memset( crt, 0, sizeof( x509_cert ) ); 00969 00970 if( buflen > 0 ) 00971 return( x509parse_crt( crt, buf, buflen ) ); 00972 00973 return( 0 ); 00974 } 00975 00976 /* 00977 * Load one or more certificates and add them to the chained list 00978 */ 00979 int x509parse_crtfile( x509_cert *chain, char *path ) 00980 { 00981 int ret; 00982 FILE *f; 00983 size_t n; 00984 unsigned char *buf; 00985 00986 if( ( f = fopen( path, "rb" ) ) == NULL ) 00987 return( 1 ); 00988 00989 fseek( f, 0, SEEK_END ); 00990 n = (size_t) ftell( f ); 00991 fseek( f, 0, SEEK_SET ); 00992 00993 if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL ) 00994 return( 1 ); 00995 00996 if( fread( buf, 1, n, f ) != n ) 00997 { 00998 fclose( f ); 00999 free( buf ); 01000 return( 1 ); 01001 } 01002 01003 buf[n] = '0円'; 01004 01005 ret = x509parse_crt( chain, buf, (int) n ); 01006 01007 memset( buf, 0, n + 1 ); 01008 free( buf ); 01009 fclose( f ); 01010 01011 return( ret ); 01012 } 01013 01014 #if defined(XYSSL_DES_C) 01015 /* 01016 * Read a 16-byte hex string and convert it to binary 01017 */ 01018 static int x509_get_iv( unsigned char *s, unsigned char iv[8] ) 01019 { 01020 int i, j, k; 01021 01022 memset( iv, 0, 8 ); 01023 01024 for( i = 0; i < 16; i++, s++ ) 01025 { 01026 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else 01027 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else 01028 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else 01029 return( XYSSL_ERR_X509_KEY_INVALID_ENC_IV ); 01030 01031 k = ( ( i & 1 ) != 0 ) ? j : j << 4; 01032 01033 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k ); 01034 } 01035 01036 return( 0 ); 01037 } 01038 01039 /* 01040 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation 01041 */ 01042 static void x509_des3_decrypt( unsigned char des3_iv[8], 01043 unsigned char *buf, int buflen, 01044 unsigned char *pwd, int pwdlen ) 01045 { 01046 md5_context md5_ctx; 01047 des3_context des3_ctx; 01048 unsigned char md5sum[16]; 01049 unsigned char des3_key[24]; 01050 01051 /* 01052 * 3DES key[ 0..15] = MD5(pwd || IV) 01053 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15]) 01054 */ 01055 md5_starts( &md5_ctx ); 01056 md5_update( &md5_ctx, pwd, pwdlen ); 01057 md5_update( &md5_ctx, des3_iv, 8 ); 01058 md5_finish( &md5_ctx, md5sum ); 01059 memcpy( des3_key, md5sum, 16 ); 01060 01061 md5_starts( &md5_ctx ); 01062 md5_update( &md5_ctx, md5sum, 16 ); 01063 md5_update( &md5_ctx, pwd, pwdlen ); 01064 md5_update( &md5_ctx, des3_iv, 8 ); 01065 md5_finish( &md5_ctx, md5sum ); 01066 memcpy( des3_key + 16, md5sum, 8 ); 01067 01068 des3_set3key_dec( &des3_ctx, des3_key ); 01069 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen, 01070 des3_iv, buf, buf ); 01071 01072 memset( &md5_ctx, 0, sizeof( md5_ctx ) ); 01073 memset( &des3_ctx, 0, sizeof( des3_ctx ) ); 01074 memset( md5sum, 0, 16 ); 01075 memset( des3_key, 0, 24 ); 01076 } 01077 #endif 01078 01079 /* 01080 * Parse a private RSA key 01081 */ 01082 int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen, 01083 unsigned char *pwd, int pwdlen ) 01084 { 01085 int ret, len, enc; 01086 unsigned char *s1, *s2; 01087 unsigned char *p, *end; 01088 unsigned char des3_iv[8]; 01089 01090 s1 = (unsigned char *) strstr( (char *) buf, 01091 "-----BEGIN RSA PRIVATE KEY-----" ); 01092 01093 if( s1 != NULL ) 01094 { 01095 s2 = (unsigned char *) strstr( (char *) buf, 01096 "-----END RSA PRIVATE KEY-----" ); 01097 01098 if( s2 == NULL || s2 <= s1 ) 01099 return( XYSSL_ERR_X509_KEY_INVALID_PEM ); 01100 01101 s1 += 31; 01102 if( *s1 == '\r' ) s1++; 01103 if( *s1 == '\n' ) s1++; 01104 else return( XYSSL_ERR_X509_KEY_INVALID_PEM ); 01105 01106 enc = 0; 01107 01108 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) 01109 { 01110 #if defined(XYSSL_DES_C) 01111 enc++; 01112 01113 s1 += 22; 01114 if( *s1 == '\r' ) s1++; 01115 if( *s1 == '\n' ) s1++; 01116 else return( XYSSL_ERR_X509_KEY_INVALID_PEM ); 01117 01118 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 ) 01119 return( XYSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG ); 01120 01121 s1 += 23; 01122 if( x509_get_iv( s1, des3_iv ) != 0 ) 01123 return( XYSSL_ERR_X509_KEY_INVALID_ENC_IV ); 01124 01125 s1 += 16; 01126 if( *s1 == '\r' ) s1++; 01127 if( *s1 == '\n' ) s1++; 01128 else return( XYSSL_ERR_X509_KEY_INVALID_PEM ); 01129 #else 01130 return( XYSSL_ERR_X509_FEATURE_UNAVAILABLE ); 01131 #endif 01132 } 01133 01134 len = 0; 01135 ret = base64_decode( NULL, &len, s1, s2 - s1 ); 01136 01137 if( ret == XYSSL_ERR_BASE64_INVALID_CHARACTER ) 01138 return( ret | XYSSL_ERR_X509_KEY_INVALID_PEM ); 01139 01140 if( ( buf = (unsigned char *) malloc( len ) ) == NULL ) 01141 return( 1 ); 01142 01143 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 ) 01144 { 01145 free( buf ); 01146 return( ret | XYSSL_ERR_X509_KEY_INVALID_PEM ); 01147 } 01148 01149 buflen = len; 01150 01151 if( enc != 0 ) 01152 { 01153 #if defined(XYSSL_DES_C) 01154 if( pwd == NULL ) 01155 { 01156 free( buf ); 01157 return( XYSSL_ERR_X509_KEY_PASSWORD_REQUIRED ); 01158 } 01159 01160 x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen ); 01161 01162 if( buf[0] != 0x30 || buf[1] != 0x82 || 01163 buf[4] != 0x02 || buf[5] != 0x01 ) 01164 { 01165 free( buf ); 01166 return( XYSSL_ERR_X509_KEY_PASSWORD_MISMATCH ); 01167 } 01168 #else 01169 return( XYSSL_ERR_X509_FEATURE_UNAVAILABLE ); 01170 #endif 01171 } 01172 } 01173 01174 memset( rsa, 0, sizeof( rsa_context ) ); 01175 01176 p = buf; 01177 end = buf + buflen; 01178 01179 /* 01180 * RSAPrivateKey ::= SEQUENCE { 01181 * version Version, 01182 * modulus INTEGER, -- n 01183 * publicExponent INTEGER, -- e 01184 * privateExponent INTEGER, -- d 01185 * prime1 INTEGER, -- p 01186 * prime2 INTEGER, -- q 01187 * exponent1 INTEGER, -- d mod (p-1) 01188 * exponent2 INTEGER, -- d mod (q-1) 01189 * coefficient INTEGER, -- (inverse of q) mod p 01190 * otherPrimeInfos OtherPrimeInfos OPTIONAL 01191 * } 01192 */ 01193 if( ( ret = asn1_get_tag( &p, end, &len, 01194 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 01195 { 01196 if( s1 != NULL ) 01197 free( buf ); 01198 01199 rsa_free( rsa ); 01200 return( XYSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); 01201 } 01202 01203 end = p + len; 01204 01205 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) 01206 { 01207 if( s1 != NULL ) 01208 free( buf ); 01209 01210 rsa_free( rsa ); 01211 return( XYSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); 01212 } 01213 01214 if( rsa->ver != 0 ) 01215 { 01216 if( s1 != NULL ) 01217 free( buf ); 01218 01219 rsa_free( rsa ); 01220 return( ret | XYSSL_ERR_X509_KEY_INVALID_VERSION ); 01221 } 01222 01223 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 || 01224 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 || 01225 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 || 01226 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 || 01227 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 || 01228 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 || 01229 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 || 01230 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 ) 01231 { 01232 if( s1 != NULL ) 01233 free( buf ); 01234 01235 rsa_free( rsa ); 01236 return( ret | XYSSL_ERR_X509_KEY_INVALID_FORMAT ); 01237 } 01238 01239 rsa->len = mpi_size( &rsa->N ); 01240 01241 if( p != end ) 01242 { 01243 if( s1 != NULL ) 01244 free( buf ); 01245 01246 rsa_free( rsa ); 01247 return( XYSSL_ERR_X509_KEY_INVALID_FORMAT | 01248 XYSSL_ERR_ASN1_LENGTH_MISMATCH ); 01249 } 01250 01251 if( ( ret = rsa_check_privkey( rsa ) ) != 0 ) 01252 { 01253 if( s1 != NULL ) 01254 free( buf ); 01255 01256 rsa_free( rsa ); 01257 return( ret ); 01258 } 01259 01260 if( s1 != NULL ) 01261 free( buf ); 01262 01263 return( 0 ); 01264 } 01265 01266 /* 01267 * Load and parse a private RSA key 01268 */ 01269 int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd ) 01270 { 01271 int ret; 01272 FILE *f; 01273 size_t n; 01274 unsigned char *buf; 01275 01276 if( ( f = fopen( path, "rb" ) ) == NULL ) 01277 return( 1 ); 01278 01279 fseek( f, 0, SEEK_END ); 01280 n = (size_t) ftell( f ); 01281 fseek( f, 0, SEEK_SET ); 01282 01283 if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL ) 01284 return( 1 ); 01285 01286 if( fread( buf, 1, n, f ) != n ) 01287 { 01288 fclose( f ); 01289 free( buf ); 01290 return( 1 ); 01291 } 01292 01293 buf[n] = '0円'; 01294 01295 if( pwd == NULL ) 01296 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 ); 01297 else 01298 ret = x509parse_key( rsa, buf, (int) n, 01299 (unsigned char *) pwd, strlen( pwd ) ); 01300 01301 memset( buf, 0, n + 1 ); 01302 free( buf ); 01303 fclose( f ); 01304 01305 return( ret ); 01306 } 01307 01308 #if defined _MSC_VER && !defined snprintf 01309 #define snprintf _snprintf 01310 #endif 01311 01312 /* 01313 * Store the name in printable form into buf; no more 01314 * than (end - buf) characters will be written 01315 */ 01316 int x509parse_dn_gets( char *buf, char *end, x509_name *dn ) 01317 { 01318 int i; 01319 unsigned char c; 01320 x509_name *name; 01321 char s[128], *p; 01322 01323 memset( s, 0, sizeof( s ) ); 01324 01325 name = dn; 01326 p = buf; 01327 01328 while( name != NULL ) 01329 { 01330 if( name != dn ) 01331 p += snprintf( p, end - p, ", " ); 01332 01333 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 ) 01334 { 01335 switch( name->oid.p[2] ) 01336 { 01337 case X520_COMMON_NAME: 01338 p += snprintf( p, end - p, "CN=" ); break; 01339 01340 case X520_COUNTRY: 01341 p += snprintf( p, end - p, "C=" ); break; 01342 01343 case X520_LOCALITY: 01344 p += snprintf( p, end - p, "L=" ); break; 01345 01346 case X520_STATE: 01347 p += snprintf( p, end - p, "ST=" ); break; 01348 01349 case X520_ORGANIZATION: 01350 p += snprintf( p, end - p, "O=" ); break; 01351 01352 case X520_ORG_UNIT: 01353 p += snprintf( p, end - p, "OU=" ); break; 01354 01355 default: 01356 p += snprintf( p, end - p, "0x%02X=", 01357 name->oid.p[2] ); 01358 break; 01359 } 01360 } 01361 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 ) 01362 { 01363 switch( name->oid.p[8] ) 01364 { 01365 case PKCS9_EMAIL: 01366 p += snprintf( p, end - p, "emailAddress=" ); break; 01367 01368 default: 01369 p += snprintf( p, end - p, "0x%02X=", 01370 name->oid.p[8] ); 01371 break; 01372 } 01373 } 01374 else 01375 p += snprintf( p, end - p, "\?\?=" ); 01376 01377 for( i = 0; i < name->val.len; i++ ) 01378 { 01379 if( i >= (int) sizeof( s ) - 1 ) 01380 break; 01381 01382 c = name->val.p[i]; 01383 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) 01384 s[i] = '?'; 01385 else s[i] = c; 01386 } 01387 s[i] = '0円'; 01388 p += snprintf( p, end - p, "%s", s ); 01389 name = name->next; 01390 } 01391 01392 return( p - buf ); 01393 } 01394 01395 /* 01396 * Return an informational string about the 01397 * certificate, or NULL if memory allocation failed 01398 */ 01399 char *x509parse_cert_info( char *prefix, x509_cert *crt ) 01400 { 01401 int i, n; 01402 char *p, *end; 01403 static char buf[512]; 01404 01405 p = buf; 01406 end = buf + sizeof( buf ) - 1; 01407 01408 p += snprintf( p, end - p, "%scert. version : %d\n", 01409 prefix, crt->version ); 01410 p += snprintf( p, end - p, "%sserial number : ", 01411 prefix ); 01412 01413 n = ( crt->serial.len <= 32 ) 01414 ? crt->serial.len : 32; 01415 01416 for( i = 0; i < n; i++ ) 01417 p += snprintf( p, end - p, "%02X%s", 01418 crt->serial.p[i], ( i < n - 1 ) ? ":" : "" ); 01419 01420 p += snprintf( p, end - p, "\n%sissuer name : ", prefix ); 01421 p += x509parse_dn_gets( p, end, &crt->issuer ); 01422 01423 p += snprintf( p, end - p, "\n%ssubject name : ", prefix ); 01424 p += x509parse_dn_gets( p, end, &crt->subject ); 01425 01426 p += snprintf( p, end - p, "\n%sissued on : " \ 01427 "%04d-%02d-%02d %02d:%02d:%02d", prefix, 01428 crt->valid_from.year, crt->valid_from.mon, 01429 crt->valid_from.day, crt->valid_from.hour, 01430 crt->valid_from.min, crt->valid_from.sec ); 01431 01432 p += snprintf( p, end - p, "\n%sexpires on : " \ 01433 "%04d-%02d-%02d %02d:%02d:%02d", prefix, 01434 crt->valid_to.year, crt->valid_to.mon, 01435 crt->valid_to.day, crt->valid_to.hour, 01436 crt->valid_to.min, crt->valid_to.sec ); 01437 01438 p += snprintf( p, end - p, "\n%ssigned using : RSA+", prefix ); 01439 01440 switch( crt->sig_oid1.p[8] ) 01441 { 01442 case RSA_MD2 : p += snprintf( p, end - p, "MD2" ); break; 01443 case RSA_MD4 : p += snprintf( p, end - p, "MD4" ); break; 01444 case RSA_MD5 : p += snprintf( p, end - p, "MD5" ); break; 01445 case RSA_SHA1: p += snprintf( p, end - p, "SHA1" ); break; 01446 default: p += snprintf( p, end - p, "???" ); break; 01447 } 01448 01449 p += snprintf( p, end - p, "\n%sRSA key size : %d bits\n", prefix, 01450 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 ); 01451 01452 return( buf ); 01453 } 01454 01455 /* 01456 * Return 0 if the certificate is still valid, or BADCERT_EXPIRED 01457 */ 01458 int x509parse_expired( x509_cert *crt ) 01459 { 01460 struct tm *lt; 01461 time_t tt; 01462 01463 tt = time( NULL ); 01464 lt = localtime( &tt ); 01465 01466 if( lt->tm_year > crt->valid_to.year - 1900 ) 01467 return( BADCERT_EXPIRED ); 01468 01469 if( lt->tm_year == crt->valid_to.year - 1900 && 01470 lt->tm_mon > crt->valid_to.mon - 1 ) 01471 return( BADCERT_EXPIRED ); 01472 01473 if( lt->tm_year == crt->valid_to.year - 1900 && 01474 lt->tm_mon == crt->valid_to.mon - 1 && 01475 lt->tm_mday > crt->valid_to.day ) 01476 return( BADCERT_EXPIRED ); 01477 01478 return( 0 ); 01479 } 01480 01481 static void x509_hash( unsigned char *in, int len, int alg, 01482 unsigned char *out ) 01483 { 01484 switch( alg ) 01485 { 01486 #if defined(XYSSL_MD2_C) 01487 case RSA_MD2 : md2( in, len, out ); break; 01488 #endif 01489 #if defined(XYSSL_MD4_C) 01490 case RSA_MD4 : md4( in, len, out ); break; 01491 #endif 01492 case RSA_MD5 : md5( in, len, out ); break; 01493 case RSA_SHA1 : sha1( in, len, out ); break; 01494 default: 01495 memset( out, '\xFF', len ); 01496 break; 01497 } 01498 } 01499 01500 /* 01501 * Verify the certificate validity 01502 */ 01503 int x509parse_verify( x509_cert *crt, 01504 x509_cert *trust_ca, 01505 char *cn, int *flags ) 01506 { 01507 int cn_len; 01508 int hash_id; 01509 int pathlen; 01510 x509_cert *cur; 01511 x509_name *name; 01512 unsigned char hash[20]; 01513 01514 *flags = x509parse_expired( crt ); 01515 01516 if( cn != NULL ) 01517 { 01518 name = &crt->subject; 01519 cn_len = strlen( cn ); 01520 01521 while( name != NULL ) 01522 { 01523 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 && 01524 memcmp( name->val.p, cn, cn_len ) == 0 && 01525 name->val.len == cn_len ) 01526 break; 01527 01528 name = name->next; 01529 } 01530 01531 if( name == NULL ) 01532 *flags |= BADCERT_CN_MISMATCH; 01533 } 01534 01535 *flags |= BADCERT_NOT_TRUSTED; 01536 01537 /* 01538 * Iterate upwards in the given cert chain, 01539 * ignoring any upper cert with CA != TRUE. 01540 */ 01541 cur = crt->next; 01542 01543 pathlen = 1; 01544 01545 while( cur->version != 0 ) 01546 { 01547 if( cur->ca_istrue == 0 || 01548 crt->issuer_raw.len != cur->subject_raw.len || 01549 memcmp( crt->issuer_raw.p, cur->subject_raw.p, 01550 crt->issuer_raw.len ) != 0 ) 01551 { 01552 cur = cur->next; 01553 continue; 01554 } 01555 01556 hash_id = crt->sig_oid1.p[8]; 01557 01558 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash ); 01559 01560 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id, 01561 0, hash, crt->sig.p ) != 0 ) 01562 return( XYSSL_ERR_X509_CERT_VERIFY_FAILED ); 01563 01564 pathlen++; 01565 01566 crt = cur; 01567 cur = crt->next; 01568 } 01569 01570 /* 01571 * Atempt to validate topmost cert with our CA chain. 01572 */ 01573 while( trust_ca->version != 0 ) 01574 { 01575 if( crt->issuer_raw.len != trust_ca->subject_raw.len || 01576 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p, 01577 crt->issuer_raw.len ) != 0 ) 01578 { 01579 trust_ca = trust_ca->next; 01580 continue; 01581 } 01582 01583 if( trust_ca->max_pathlen > 0 && 01584 trust_ca->max_pathlen < pathlen ) 01585 break; 01586 01587 hash_id = crt->sig_oid1.p[8]; 01588 01589 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash ); 01590 01591 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id, 01592 0, hash, crt->sig.p ) == 0 ) 01593 { 01594 /* 01595 * cert. is signed by a trusted CA 01596 */ 01597 *flags &= ~BADCERT_NOT_TRUSTED; 01598 break; 01599 } 01600 01601 trust_ca = trust_ca->next; 01602 } 01603 01604 if( *flags != 0 ) 01605 return( XYSSL_ERR_X509_CERT_VERIFY_FAILED ); 01606 01607 return( 0 ); 01608 } 01609 01610 /* 01611 * Unallocate all certificate data 01612 */ 01613 void x509_free( x509_cert *crt ) 01614 { 01615 x509_cert *cert_cur = crt; 01616 x509_cert *cert_prv; 01617 x509_name *name_cur; 01618 x509_name *name_prv; 01619 01620 if( crt == NULL ) 01621 return; 01622 01623 do 01624 { 01625 rsa_free( &cert_cur->rsa ); 01626 01627 name_cur = cert_cur->issuer.next; 01628 while( name_cur != NULL ) 01629 { 01630 name_prv = name_cur; 01631 name_cur = name_cur->next; 01632 memset( name_prv, 0, sizeof( x509_name ) ); 01633 free( name_prv ); 01634 } 01635 01636 name_cur = cert_cur->subject.next; 01637 while( name_cur != NULL ) 01638 { 01639 name_prv = name_cur; 01640 name_cur = name_cur->next; 01641 memset( name_prv, 0, sizeof( x509_name ) ); 01642 free( name_prv ); 01643 } 01644 01645 if( cert_cur->raw.p != NULL ) 01646 { 01647 memset( cert_cur->raw.p, 0, cert_cur->raw.len ); 01648 free( cert_cur->raw.p ); 01649 } 01650 01651 cert_cur = cert_cur->next; 01652 } 01653 while( cert_cur != NULL ); 01654 01655 cert_cur = crt; 01656 do 01657 { 01658 cert_prv = cert_cur; 01659 cert_cur = cert_cur->next; 01660 01661 memset( cert_prv, 0, sizeof( x509_cert ) ); 01662 if( cert_prv != crt ) 01663 free( cert_prv ); 01664 } 01665 while( cert_cur != NULL ); 01666 } 01667 01668 #if defined(XYSSL_SELF_TEST) 01669 01670 #include "xyssl/certs.h" 01671 01672 /* 01673 * Checkup routine 01674 */ 01675 int x509_self_test( int verbose ) 01676 { 01677 int ret, i, j; 01678 x509_cert cacert; 01679 x509_cert clicert; 01680 rsa_context rsa; 01681 01682 if( verbose != 0 ) 01683 printf( " X.509 certificate load: " ); 01684 01685 memset( &clicert, 0, sizeof( x509_cert ) ); 01686 01687 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt, 01688 strlen( test_cli_crt ) ); 01689 if( ret != 0 ) 01690 { 01691 if( verbose != 0 ) 01692 printf( "failed\n" ); 01693 01694 return( ret ); 01695 } 01696 01697 memset( &cacert, 0, sizeof( x509_cert ) ); 01698 01699 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt, 01700 strlen( test_ca_crt ) ); 01701 if( ret != 0 ) 01702 { 01703 if( verbose != 0 ) 01704 printf( "failed\n" ); 01705 01706 return( ret ); 01707 } 01708 01709 if( verbose != 0 ) 01710 printf( "passed\n X.509 private key load: " ); 01711 01712 i = strlen( test_ca_key ); 01713 j = strlen( test_ca_pwd ); 01714 01715 if( ( ret = x509parse_key( &rsa, 01716 (unsigned char *) test_ca_key, i, 01717 (unsigned char *) test_ca_pwd, j ) ) != 0 ) 01718 { 01719 if( verbose != 0 ) 01720 printf( "failed\n" ); 01721 01722 return( ret ); 01723 } 01724 01725 if( verbose != 0 ) 01726 printf( "passed\n X.509 signature verify: "); 01727 01728 ret = x509parse_verify( &clicert, &cacert, "Joe User", &i ); 01729 if( ret != 0 ) 01730 { 01731 if( verbose != 0 ) 01732 printf( "failed\n" ); 01733 01734 return( ret ); 01735 } 01736 01737 if( verbose != 0 ) 01738 printf( "passed\n\n" ); 01739 01740 x509_free( &cacert ); 01741 x509_free( &clicert ); 01742 rsa_free( &rsa ); 01743 01744 return( 0 ); 01745 } 01746 01747 #endif 01748 01749 #endif