/home/dko/projects/mobilec/trunk/src/security/xyssl-0.9/library/x509parse.c

Go to the documentation of this file.
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

Generated on Tue Oct 28 17:03:23 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /