2 * X.509 certificate and private key decoding
4 * Copyright (C) 2006-2007 Christophe Devine
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License, version 2.1 as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * The ITU-T X.509 standard defines a certificat format for PKI.
23 * http://www.ietf.org/rfc/rfc2459.txt
24 * http://www.ietf.org/rfc/rfc3279.txt
26 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
28 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
29 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
32 #include "xyssl/config.h"
34 #if defined(XYSSL_X509_PARSE_C)
36 #include "xyssl/x509.h"
37 #include "xyssl/base64.h"
38 #include "xyssl/des.h"
39 #include "xyssl/md2.h"
40 #include "xyssl/md4.h"
41 #include "xyssl/md5.h"
42 #include "xyssl/sha1.h"
50 * ASN.1 DER decoding routines
52 static int asn1_get_len( unsigned char **p
,
56 if( ( end
- *p
) < 1 )
57 return( XYSSL_ERR_ASN1_OUT_OF_DATA
);
59 if( ( **p
& 0x80 ) == 0 )
66 if( ( end
- *p
) < 2 )
67 return( XYSSL_ERR_ASN1_OUT_OF_DATA
);
74 if( ( end
- *p
) < 3 )
75 return( XYSSL_ERR_ASN1_OUT_OF_DATA
);
77 *len
= ( (*p
)[1] << 8 ) | (*p
)[2];
82 return( XYSSL_ERR_ASN1_INVALID_LENGTH
);
87 if( *len
> (int) ( end
- *p
) )
88 return( XYSSL_ERR_ASN1_OUT_OF_DATA
);
93 static int asn1_get_tag( unsigned char **p
,
97 if( ( end
- *p
) < 1 )
98 return( XYSSL_ERR_ASN1_OUT_OF_DATA
);
101 return( XYSSL_ERR_ASN1_UNEXPECTED_TAG
);
105 return( asn1_get_len( p
, end
, len
) );
108 static int asn1_get_bool( unsigned char **p
,
114 if( ( ret
= asn1_get_tag( p
, end
, &len
, ASN1_BOOLEAN
) ) != 0 )
118 return( XYSSL_ERR_ASN1_INVALID_LENGTH
);
120 *val
= ( **p
!= 0 ) ? 1 : 0;
126 static int asn1_get_int( unsigned char **p
,
132 if( ( ret
= asn1_get_tag( p
, end
, &len
, ASN1_INTEGER
) ) != 0 )
135 if( len
> (int) sizeof( int ) || ( **p
& 0x80 ) != 0 )
136 return( XYSSL_ERR_ASN1_INVALID_LENGTH
);
142 *val
= ( *val
<< 8 ) | **p
;
149 static int asn1_get_mpi( unsigned char **p
,
155 if( ( ret
= asn1_get_tag( p
, end
, &len
, ASN1_INTEGER
) ) != 0 )
158 ret
= mpi_read_binary( X
, *p
, len
);
166 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
168 static int x509_get_version( unsigned char **p
,
174 if( ( ret
= asn1_get_tag( p
, end
, &len
,
175 ASN1_CONTEXT_SPECIFIC
| ASN1_CONSTRUCTED
| 0 ) ) != 0 )
177 if( ret
== XYSSL_ERR_ASN1_UNEXPECTED_TAG
)
185 if( ( ret
= asn1_get_int( p
, end
, ver
) ) != 0 )
186 return( XYSSL_ERR_X509_CERT_INVALID_VERSION
| ret
);
189 return( XYSSL_ERR_X509_CERT_INVALID_VERSION
|
190 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
196 * CertificateSerialNumber ::= INTEGER
198 static int x509_get_serial( unsigned char **p
,
204 if( ( end
- *p
) < 1 )
205 return( XYSSL_ERR_X509_CERT_INVALID_SERIAL
|
206 XYSSL_ERR_ASN1_OUT_OF_DATA
);
208 if( **p
!= ( ASN1_CONTEXT_SPECIFIC
| ASN1_PRIMITIVE
| 2 ) &&
209 **p
!= ASN1_INTEGER
)
210 return( XYSSL_ERR_X509_CERT_INVALID_SERIAL
|
211 XYSSL_ERR_ASN1_UNEXPECTED_TAG
);
213 serial
->tag
= *(*p
)++;
215 if( ( ret
= asn1_get_len( p
, end
, &serial
->len
) ) != 0 )
216 return( XYSSL_ERR_X509_CERT_INVALID_SERIAL
| ret
);
225 * AlgorithmIdentifier ::= SEQUENCE {
226 * algorithm OBJECT IDENTIFIER,
227 * parameters ANY DEFINED BY algorithm OPTIONAL }
229 static int x509_get_alg( unsigned char **p
,
235 if( ( ret
= asn1_get_tag( p
, end
, &len
,
236 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
237 return( XYSSL_ERR_X509_CERT_INVALID_ALG
| ret
);
242 if( ( ret
= asn1_get_tag( p
, end
, &alg
->len
, ASN1_OID
) ) != 0 )
243 return( XYSSL_ERR_X509_CERT_INVALID_ALG
| ret
);
252 * assume the algorithm parameters must be NULL
254 if( ( ret
= asn1_get_tag( p
, end
, &len
, ASN1_NULL
) ) != 0 )
255 return( XYSSL_ERR_X509_CERT_INVALID_ALG
| ret
);
258 return( XYSSL_ERR_X509_CERT_INVALID_ALG
|
259 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
265 * RelativeDistinguishedName ::=
266 * SET OF AttributeTypeAndValue
268 * AttributeTypeAndValue ::= SEQUENCE {
269 * type AttributeType,
270 * value AttributeValue }
272 * AttributeType ::= OBJECT IDENTIFIER
274 * AttributeValue ::= ANY DEFINED BY AttributeType
276 static int x509_get_name( unsigned char **p
,
285 if( ( ret
= asn1_get_tag( p
, end
, &len
,
286 ASN1_CONSTRUCTED
| ASN1_SET
) ) != 0 )
287 return( XYSSL_ERR_X509_CERT_INVALID_NAME
| ret
);
292 if( ( ret
= asn1_get_tag( p
, end
, &len
,
293 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
294 return( XYSSL_ERR_X509_CERT_INVALID_NAME
| ret
);
296 if( *p
+ len
!= end
)
297 return( XYSSL_ERR_X509_CERT_INVALID_NAME
|
298 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
303 if( ( ret
= asn1_get_tag( p
, end
, &oid
->len
, ASN1_OID
) ) != 0 )
304 return( XYSSL_ERR_X509_CERT_INVALID_NAME
| ret
);
309 if( ( end
- *p
) < 1 )
310 return( XYSSL_ERR_X509_CERT_INVALID_NAME
|
311 XYSSL_ERR_ASN1_OUT_OF_DATA
);
313 if( **p
!= ASN1_BMP_STRING
&& **p
!= ASN1_UTF8_STRING
&&
314 **p
!= ASN1_T61_STRING
&& **p
!= ASN1_PRINTABLE_STRING
&&
315 **p
!= ASN1_IA5_STRING
&& **p
!= ASN1_UNIVERSAL_STRING
)
316 return( XYSSL_ERR_X509_CERT_INVALID_NAME
|
317 XYSSL_ERR_ASN1_UNEXPECTED_TAG
);
322 if( ( ret
= asn1_get_len( p
, end
, &val
->len
) ) != 0 )
323 return( XYSSL_ERR_X509_CERT_INVALID_NAME
| ret
);
331 return( XYSSL_ERR_X509_CERT_INVALID_NAME
|
332 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
335 * recurse until end of SEQUENCE is reached
340 cur
->next
= (x509_name
*) malloc(
341 sizeof( x509_name
) );
343 if( cur
->next
== NULL
)
346 return( x509_get_name( p
, end2
, cur
->next
) );
350 * Validity ::= SEQUENCE {
356 * generalTime GeneralizedTime }
358 static int x509_get_dates( unsigned char **p
,
366 if( ( ret
= asn1_get_tag( p
, end
, &len
,
367 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
368 return( XYSSL_ERR_X509_CERT_INVALID_DATE
| ret
);
373 * TODO: also handle GeneralizedTime
375 if( ( ret
= asn1_get_tag( p
, end
, &len
, ASN1_UTC_TIME
) ) != 0 )
376 return( XYSSL_ERR_X509_CERT_INVALID_DATE
| ret
);
378 memset( date
, 0, sizeof( date
) );
379 memcpy( date
, *p
, ( len
< (int) sizeof( date
) - 1 ) ?
380 len
: (int) sizeof( date
) - 1 );
382 if( sscanf( date
, "%2d%2d%2d%2d%2d%2d",
383 &from
->year
, &from
->mon
, &from
->day
,
384 &from
->hour
, &from
->min
, &from
->sec
) < 5 )
385 return( XYSSL_ERR_X509_CERT_INVALID_DATE
);
387 from
->year
+= 100 * ( from
->year
< 90 );
392 if( ( ret
= asn1_get_tag( p
, end
, &len
, ASN1_UTC_TIME
) ) != 0 )
393 return( XYSSL_ERR_X509_CERT_INVALID_DATE
| ret
);
395 memset( date
, 0, sizeof( date
) );
396 memcpy( date
, *p
, ( len
< (int) sizeof( date
) - 1 ) ?
397 len
: (int) sizeof( date
) - 1 );
399 if( sscanf( date
, "%2d%2d%2d%2d%2d%2d",
400 &to
->year
, &to
->mon
, &to
->day
,
401 &to
->hour
, &to
->min
, &to
->sec
) < 5 )
402 return( XYSSL_ERR_X509_CERT_INVALID_DATE
);
404 to
->year
+= 100 * ( to
->year
< 90 );
410 return( XYSSL_ERR_X509_CERT_INVALID_DATE
|
411 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
417 * SubjectPublicKeyInfo ::= SEQUENCE {
418 * algorithm AlgorithmIdentifier,
419 * subjectPublicKey BIT STRING }
421 static int x509_get_pubkey( unsigned char **p
,
423 x509_buf
*pk_alg_oid
,
429 if( ( ret
= x509_get_alg( p
, end
, pk_alg_oid
) ) != 0 )
433 * only RSA public keys handled at this time
435 if( pk_alg_oid
->len
!= 9 ||
436 memcmp( pk_alg_oid
->p
, OID_PKCS1_RSA
, 9 ) != 0 )
437 return( XYSSL_ERR_X509_CERT_UNKNOWN_PK_ALG
);
439 if( ( ret
= asn1_get_tag( p
, end
, &len
, ASN1_BIT_STRING
) ) != 0 )
440 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY
| ret
);
442 if( ( end
- *p
) < 1 )
443 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY
|
444 XYSSL_ERR_ASN1_OUT_OF_DATA
);
449 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY
);
452 * RSAPublicKey ::= SEQUENCE {
453 * modulus INTEGER, -- n
454 * publicExponent INTEGER -- e
457 if( ( ret
= asn1_get_tag( p
, end2
, &len
,
458 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
459 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY
| ret
);
461 if( *p
+ len
!= end2
)
462 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY
|
463 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
465 if( ( ret
= asn1_get_mpi( p
, end2
, N
) ) != 0 ||
466 ( ret
= asn1_get_mpi( p
, end2
, E
) ) != 0 )
467 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY
| ret
);
470 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY
|
471 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
476 static int x509_get_sig( unsigned char **p
,
484 if( ( ret
= asn1_get_tag( p
, end
, &len
, ASN1_BIT_STRING
) ) != 0 )
485 return( XYSSL_ERR_X509_CERT_INVALID_SIGNATURE
| ret
);
487 if( --len
< 1 || *(*p
)++ != 0 )
488 return( XYSSL_ERR_X509_CERT_INVALID_SIGNATURE
);
499 * X.509 v2/v3 unique identifier (not parsed)
501 static int x509_get_uid( unsigned char **p
,
503 x509_buf
*uid
, int n
)
512 if( ( ret
= asn1_get_tag( p
, end
, &uid
->len
,
513 ASN1_CONTEXT_SPECIFIC
| ASN1_CONSTRUCTED
| n
) ) != 0 )
515 if( ret
== XYSSL_ERR_ASN1_UNEXPECTED_TAG
)
528 * X.509 v3 extensions (only BasicConstraints are parsed)
530 static int x509_get_ext( unsigned char **p
,
546 if( ( ret
= asn1_get_tag( p
, end
, &ext
->len
,
547 ASN1_CONTEXT_SPECIFIC
| ASN1_CONSTRUCTED
| 3 ) ) != 0 )
549 if( ret
== XYSSL_ERR_ASN1_UNEXPECTED_TAG
)
559 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
561 * Extension ::= SEQUENCE {
562 * extnID OBJECT IDENTIFIER,
563 * critical BOOLEAN DEFAULT FALSE,
564 * extnValue OCTET STRING }
566 if( ( ret
= asn1_get_tag( p
, end
, &len
,
567 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
568 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
| ret
);
570 if( end
!= *p
+ len
)
571 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
|
572 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
576 if( ( ret
= asn1_get_tag( p
, end
, &len
,
577 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
578 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
| ret
);
580 if( memcmp( *p
, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
588 if( ( ret
= asn1_get_bool( p
, end
, &is_critical
) ) != 0 &&
589 ( ret
!= XYSSL_ERR_ASN1_UNEXPECTED_TAG
) )
590 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
| ret
);
592 if( ( ret
= asn1_get_tag( p
, end
, &len
,
593 ASN1_OCTET_STRING
) ) != 0 )
594 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
| ret
);
597 * BasicConstraints ::= SEQUENCE {
598 * cA BOOLEAN DEFAULT FALSE,
599 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
603 if( ( ret
= asn1_get_tag( p
, end2
, &len
,
604 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
605 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
| ret
);
610 if( ( ret
= asn1_get_bool( p
, end2
, &is_cacert
) ) != 0 )
611 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
| ret
);
616 if( ( ret
= asn1_get_int( p
, end2
, max_pathlen
) ) != 0 )
617 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
| ret
);
620 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
|
621 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
627 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS
|
628 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
630 *ca_istrue
= is_critical
& is_cacert
;
636 * Parse one or more certificates and add them to the chained list
638 int x509parse_crt( x509_cert
*chain
, unsigned char *buf
, int buflen
)
641 unsigned char *s1
, *s2
;
642 unsigned char *p
, *end
;
647 while( crt
->version
!= 0 )
651 * check if the certificate is encoded in base64
653 s1
= (unsigned char *) strstr( (char *) buf
,
654 "-----BEGIN CERTIFICATE-----" );
658 s2
= (unsigned char *) strstr( (char *) buf
,
659 "-----END CERTIFICATE-----" );
661 if( s2
== NULL
|| s2
<= s1
)
662 return( XYSSL_ERR_X509_CERT_INVALID_PEM
);
665 if( *s1
== '\r' ) s1
++;
666 if( *s1
== '\n' ) s1
++;
667 else return( XYSSL_ERR_X509_CERT_INVALID_PEM
);
670 * get the DER data length and decode the buffer
673 ret
= base64_decode( NULL
, &len
, s1
, s2
- s1
);
675 if( ret
== XYSSL_ERR_BASE64_INVALID_CHARACTER
)
676 return( XYSSL_ERR_X509_CERT_INVALID_PEM
| ret
);
678 if( ( p
= (unsigned char *) malloc( len
) ) == NULL
)
681 if( ( ret
= base64_decode( p
, &len
, s1
, s2
- s1
) ) != 0 )
684 return( XYSSL_ERR_X509_CERT_INVALID_PEM
| ret
);
688 * update the buffer size and offset
691 if( *s2
== '\r' ) s2
++;
692 if( *s2
== '\n' ) s2
++;
693 else return( XYSSL_ERR_X509_CERT_INVALID_PEM
);
701 * nope, copy the raw DER data
703 p
= (unsigned char *) malloc( len
= buflen
);
708 memcpy( p
, buf
, buflen
);
718 * Certificate ::= SEQUENCE {
719 * tbsCertificate TBSCertificate,
720 * signatureAlgorithm AlgorithmIdentifier,
721 * signatureValue BIT STRING }
723 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
724 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
727 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT
);
730 if( len
!= (int) ( end
- p
) )
733 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT
|
734 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
738 * TBSCertificate ::= SEQUENCE {
742 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
743 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
746 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT
| ret
);
750 crt
->tbs
.len
= end
- crt
->tbs
.p
;
753 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
755 * CertificateSerialNumber ::= INTEGER
757 * signature AlgorithmIdentifier
759 if( ( ret
= x509_get_version( &p
, end
, &crt
->version
) ) != 0 ||
760 ( ret
= x509_get_serial( &p
, end
, &crt
->serial
) ) != 0 ||
761 ( ret
= x509_get_alg( &p
, end
, &crt
->sig_oid1
) ) != 0 )
769 if( crt
->version
> 3 )
772 return( XYSSL_ERR_X509_CERT_UNKNOWN_VERSION
);
775 if( crt
->sig_oid1
.len
!= 9 ||
776 memcmp( crt
->sig_oid1
.p
, OID_PKCS1
, 8 ) != 0 )
779 return( XYSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG
);
782 if( crt
->sig_oid1
.p
[8] < 2 ||
783 crt
->sig_oid1
.p
[8] > 5 )
786 return( XYSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG
);
792 crt
->issuer_raw
.p
= p
;
794 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
795 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
798 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT
| ret
);
801 if( ( ret
= x509_get_name( &p
, p
+ len
, &crt
->issuer
) ) != 0 )
807 crt
->issuer_raw
.len
= p
- crt
->issuer_raw
.p
;
810 * Validity ::= SEQUENCE {
815 if( ( ret
= x509_get_dates( &p
, end
, &crt
->valid_from
,
816 &crt
->valid_to
) ) != 0 )
825 crt
->subject_raw
.p
= p
;
827 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
828 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
831 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT
| ret
);
834 if( ( ret
= x509_get_name( &p
, p
+ len
, &crt
->subject
) ) != 0 )
840 crt
->subject_raw
.len
= p
- crt
->subject_raw
.p
;
843 * SubjectPublicKeyInfo ::= SEQUENCE
844 * algorithm AlgorithmIdentifier,
845 * subjectPublicKey BIT STRING }
847 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
848 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
851 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT
| ret
);
854 if( ( ret
= x509_get_pubkey( &p
, p
+ len
, &crt
->pk_oid
,
855 &crt
->rsa
.N
, &crt
->rsa
.E
) ) != 0 )
861 if( ( ret
= rsa_check_pubkey( &crt
->rsa
) ) != 0 )
867 crt
->rsa
.len
= mpi_size( &crt
->rsa
.N
);
870 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
871 * -- If present, version shall be v2 or v3
872 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
873 * -- If present, version shall be v2 or v3
874 * extensions [3] EXPLICIT Extensions OPTIONAL
875 * -- If present, version shall be v3
877 if( crt
->version
== 2 || crt
->version
== 3 )
879 ret
= x509_get_uid( &p
, end
, &crt
->issuer_id
, 1 );
887 if( crt
->version
== 2 || crt
->version
== 3 )
889 ret
= x509_get_uid( &p
, end
, &crt
->subject_id
, 2 );
897 if( crt
->version
== 3 )
899 ret
= x509_get_ext( &p
, end
, &crt
->v3_ext
,
900 &crt
->ca_istrue
, &crt
->max_pathlen
);
911 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT
|
912 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
915 end
= crt
->raw
.p
+ crt
->raw
.len
;
918 * signatureAlgorithm AlgorithmIdentifier,
919 * signatureValue BIT STRING
921 if( ( ret
= x509_get_alg( &p
, end
, &crt
->sig_oid2
) ) != 0 )
927 if( memcmp( crt
->sig_oid1
.p
, crt
->sig_oid2
.p
, 9 ) != 0 )
930 return( XYSSL_ERR_X509_CERT_SIG_MISMATCH
);
933 if( ( ret
= x509_get_sig( &p
, end
, &crt
->sig
) ) != 0 )
942 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT
|
943 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
946 crt
->next
= (x509_cert
*) malloc( sizeof( x509_cert
) );
948 if( crt
->next
== NULL
)
955 memset( crt
, 0, sizeof( x509_cert
) );
958 return( x509parse_crt( crt
, buf
, buflen
) );
964 * Load one or more certificates and add them to the chained list
966 int x509parse_crtfile( x509_cert
*chain
, char *path
)
973 if( ( f
= fopen( path
, "rb" ) ) == NULL
)
976 fseek( f
, 0, SEEK_END
);
977 n
= (size_t) ftell( f
);
978 fseek( f
, 0, SEEK_SET
);
980 if( ( buf
= (unsigned char *) malloc( n
+ 1 ) ) == NULL
)
983 if( fread( buf
, 1, n
, f
) != n
)
992 ret
= x509parse_crt( chain
, buf
, (int) n
);
994 memset( buf
, 0, n
+ 1 );
1001 #if defined(XYSSL_DES_C)
1003 * Read a 16-byte hex string and convert it to binary
1005 static int x509_get_iv( unsigned char *s
, unsigned char iv
[8] )
1011 for( i
= 0; i
< 16; i
++, s
++ )
1013 if( *s
>= '0' && *s
<= '9' ) j
= *s
- '0'; else
1014 if( *s
>= 'A' && *s
<= 'F' ) j
= *s
- '7'; else
1015 if( *s
>= 'a' && *s
<= 'f' ) j
= *s
- 'W'; else
1016 return( XYSSL_ERR_X509_KEY_INVALID_ENC_IV
);
1018 k
= ( ( i
& 1 ) != 0 ) ? j
: j
<< 4;
1020 iv
[i
>> 1] = (unsigned char)( iv
[i
>> 1] | k
);
1027 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1029 static void x509_des3_decrypt( unsigned char des3_iv
[8],
1030 unsigned char *buf
, int buflen
,
1031 unsigned char *pwd
, int pwdlen
)
1033 md5_context md5_ctx
;
1034 des3_context des3_ctx
;
1035 unsigned char md5sum
[16];
1036 unsigned char des3_key
[24];
1039 * 3DES key[ 0..15] = MD5(pwd || IV)
1040 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1042 md5_starts( &md5_ctx
);
1043 md5_update( &md5_ctx
, pwd
, pwdlen
);
1044 md5_update( &md5_ctx
, des3_iv
, 8 );
1045 md5_finish( &md5_ctx
, md5sum
);
1046 memcpy( des3_key
, md5sum
, 16 );
1048 md5_starts( &md5_ctx
);
1049 md5_update( &md5_ctx
, md5sum
, 16 );
1050 md5_update( &md5_ctx
, pwd
, pwdlen
);
1051 md5_update( &md5_ctx
, des3_iv
, 8 );
1052 md5_finish( &md5_ctx
, md5sum
);
1053 memcpy( des3_key
+ 16, md5sum
, 8 );
1055 des3_set3key_dec( &des3_ctx
, des3_key
);
1056 des3_crypt_cbc( &des3_ctx
, DES_DECRYPT
, buflen
,
1057 des3_iv
, buf
, buf
);
1059 memset( &md5_ctx
, 0, sizeof( md5_ctx
) );
1060 memset( &des3_ctx
, 0, sizeof( des3_ctx
) );
1061 memset( md5sum
, 0, 16 );
1062 memset( des3_key
, 0, 24 );
1067 * Parse a private RSA key
1069 int x509parse_key( rsa_context
*rsa
, unsigned char *buf
, int buflen
,
1070 unsigned char *pwd
, int pwdlen
)
1073 unsigned char *s1
, *s2
;
1074 unsigned char *p
, *end
;
1075 unsigned char des3_iv
[8];
1077 s1
= (unsigned char *) strstr( (char *) buf
,
1078 "-----BEGIN RSA PRIVATE KEY-----" );
1082 s2
= (unsigned char *) strstr( (char *) buf
,
1083 "-----END RSA PRIVATE KEY-----" );
1085 if( s2
== NULL
|| s2
<= s1
)
1086 return( XYSSL_ERR_X509_KEY_INVALID_PEM
);
1089 if( *s1
== '\r' ) s1
++;
1090 if( *s1
== '\n' ) s1
++;
1091 else return( XYSSL_ERR_X509_KEY_INVALID_PEM
);
1095 if( memcmp( s1
, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1097 #if defined(XYSSL_DES_C)
1101 if( *s1
== '\r' ) s1
++;
1102 if( *s1
== '\n' ) s1
++;
1103 else return( XYSSL_ERR_X509_KEY_INVALID_PEM
);
1105 if( memcmp( s1
, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
1106 return( XYSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG
);
1109 if( x509_get_iv( s1
, des3_iv
) != 0 )
1110 return( XYSSL_ERR_X509_KEY_INVALID_ENC_IV
);
1113 if( *s1
== '\r' ) s1
++;
1114 if( *s1
== '\n' ) s1
++;
1115 else return( XYSSL_ERR_X509_KEY_INVALID_PEM
);
1117 return( XYSSL_ERR_X509_FEATURE_UNAVAILABLE
);
1122 ret
= base64_decode( NULL
, &len
, s1
, s2
- s1
);
1124 if( ret
== XYSSL_ERR_BASE64_INVALID_CHARACTER
)
1125 return( ret
| XYSSL_ERR_X509_KEY_INVALID_PEM
);
1127 if( ( buf
= (unsigned char *) malloc( len
) ) == NULL
)
1130 if( ( ret
= base64_decode( buf
, &len
, s1
, s2
- s1
) ) != 0 )
1133 return( ret
| XYSSL_ERR_X509_KEY_INVALID_PEM
);
1140 #if defined(XYSSL_DES_C)
1144 return( XYSSL_ERR_X509_KEY_PASSWORD_REQUIRED
);
1147 x509_des3_decrypt( des3_iv
, buf
, buflen
, pwd
, pwdlen
);
1149 if( buf
[0] != 0x30 || buf
[1] != 0x82 ||
1150 buf
[4] != 0x02 || buf
[5] != 0x01 )
1153 return( XYSSL_ERR_X509_KEY_PASSWORD_MISMATCH
);
1156 return( XYSSL_ERR_X509_FEATURE_UNAVAILABLE
);
1161 memset( rsa
, 0, sizeof( rsa_context
) );
1167 * RSAPrivateKey ::= SEQUENCE {
1169 * modulus INTEGER, -- n
1170 * publicExponent INTEGER, -- e
1171 * privateExponent INTEGER, -- d
1172 * prime1 INTEGER, -- p
1173 * prime2 INTEGER, -- q
1174 * exponent1 INTEGER, -- d mod (p-1)
1175 * exponent2 INTEGER, -- d mod (q-1)
1176 * coefficient INTEGER, -- (inverse of q) mod p
1177 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1180 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
1181 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
1187 return( XYSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
1192 if( ( ret
= asn1_get_int( &p
, end
, &rsa
->ver
) ) != 0 )
1198 return( XYSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
1207 return( ret
| XYSSL_ERR_X509_KEY_INVALID_VERSION
);
1210 if( ( ret
= asn1_get_mpi( &p
, end
, &rsa
->N
) ) != 0 ||
1211 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->E
) ) != 0 ||
1212 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->D
) ) != 0 ||
1213 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->P
) ) != 0 ||
1214 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->Q
) ) != 0 ||
1215 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->DP
) ) != 0 ||
1216 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->DQ
) ) != 0 ||
1217 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->QP
) ) != 0 )
1223 return( ret
| XYSSL_ERR_X509_KEY_INVALID_FORMAT
);
1226 rsa
->len
= mpi_size( &rsa
->N
);
1234 return( XYSSL_ERR_X509_KEY_INVALID_FORMAT
|
1235 XYSSL_ERR_ASN1_LENGTH_MISMATCH
);
1238 if( ( ret
= rsa_check_privkey( rsa
) ) != 0 )
1254 * Load and parse a private RSA key
1256 int x509parse_keyfile( rsa_context
*rsa
, char *path
, char *pwd
)
1263 if( ( f
= fopen( path
, "rb" ) ) == NULL
)
1266 fseek( f
, 0, SEEK_END
);
1267 n
= (size_t) ftell( f
);
1268 fseek( f
, 0, SEEK_SET
);
1270 if( ( buf
= (unsigned char *) malloc( n
+ 1 ) ) == NULL
)
1273 if( fread( buf
, 1, n
, f
) != n
)
1283 ret
= x509parse_key( rsa
, buf
, (int) n
, NULL
, 0 );
1285 ret
= x509parse_key( rsa
, buf
, (int) n
,
1286 (unsigned char *) pwd
, strlen( pwd
) );
1288 memset( buf
, 0, n
+ 1 );
1295 #if defined _MSC_VER && !defined snprintf
1296 #define snprintf _snprintf
1300 * Store the name in printable form into buf; no more
1301 * than (end - buf) characters will be written
1303 int x509parse_dn_gets( char *buf
, char *end
, x509_name
*dn
)
1310 memset( s
, 0, sizeof( s
) );
1315 while( name
!= NULL
)
1318 p
+= snprintf( p
, end
- p
, ", " );
1320 if( memcmp( name
->oid
.p
, OID_X520
, 2 ) == 0 )
1322 switch( name
->oid
.p
[2] )
1324 case X520_COMMON_NAME
:
1325 p
+= snprintf( p
, end
- p
, "CN=" ); break;
1328 p
+= snprintf( p
, end
- p
, "C=" ); break;
1331 p
+= snprintf( p
, end
- p
, "L=" ); break;
1334 p
+= snprintf( p
, end
- p
, "ST=" ); break;
1336 case X520_ORGANIZATION
:
1337 p
+= snprintf( p
, end
- p
, "O=" ); break;
1340 p
+= snprintf( p
, end
- p
, "OU=" ); break;
1343 p
+= snprintf( p
, end
- p
, "0x%02X=",
1348 else if( memcmp( name
->oid
.p
, OID_PKCS9
, 8 ) == 0 )
1350 switch( name
->oid
.p
[8] )
1353 p
+= snprintf( p
, end
- p
, "emailAddress=" ); break;
1356 p
+= snprintf( p
, end
- p
, "0x%02X=",
1362 p
+= snprintf( p
, end
- p
, "\?\?=" );
1364 for( i
= 0; i
< name
->val
.len
; i
++ )
1366 if( i
>= (int) sizeof( s
) - 1 )
1370 if( c
< 32 || c
== 127 || ( c
> 128 && c
< 160 ) )
1375 p
+= snprintf( p
, end
- p
, "%s", s
);
1383 * Return an informational string about the
1384 * certificate, or NULL if memory allocation failed
1386 char *x509parse_cert_info( char *prefix
, x509_cert
*crt
)
1389 char *buf
, *p
, *end
;
1391 if( ( buf
= (char *) malloc( 4096 ) ) == NULL
)
1394 memset( buf
, 0, 4096 );
1397 end
= buf
+ 4096 - 1;
1399 p
+= snprintf( p
, end
- p
, "%scert. version : %d\n",
1400 prefix
, crt
->version
);
1401 p
+= snprintf( p
, end
- p
, "%sserial number : ",
1404 n
= ( crt
->serial
.len
<= 32 )
1405 ? crt
->serial
.len
: 32;
1407 for( i
= 1; i
< n
; i
++ )
1408 p
+= snprintf( p
, end
- p
, "%02X%s",
1409 crt
->serial
.p
[i
], ( i
< n
- 1 ) ? ":" : "" );
1411 p
+= snprintf( p
, end
- p
, "\n%sissuer name : ", prefix
);
1412 p
+= x509parse_dn_gets( p
, end
, &crt
->issuer
);
1414 p
+= snprintf( p
, end
- p
, "\n%ssubject name : ", prefix
);
1415 p
+= x509parse_dn_gets( p
, end
, &crt
->subject
);
1417 p
+= snprintf( p
, end
- p
, "\n%sissued on : " \
1418 "%04d-%02d-%02d %02d:%02d:%02d", prefix
,
1419 crt
->valid_from
.year
, crt
->valid_from
.mon
,
1420 crt
->valid_from
.day
, crt
->valid_from
.hour
,
1421 crt
->valid_from
.min
, crt
->valid_from
.sec
);
1423 p
+= snprintf( p
, end
- p
, "\n%sexpires on : " \
1424 "%04d-%02d-%02d %02d:%02d:%02d", prefix
,
1425 crt
->valid_to
.year
, crt
->valid_to
.mon
,
1426 crt
->valid_to
.day
, crt
->valid_to
.hour
,
1427 crt
->valid_to
.min
, crt
->valid_to
.sec
);
1429 p
+= snprintf( p
, end
- p
, "\n%ssigned using : RSA+", prefix
);
1431 switch( crt
->sig_oid1
.p
[8] )
1433 case RSA_MD2
: p
+= snprintf( p
, end
- p
, "MD2" ); break;
1434 case RSA_MD4
: p
+= snprintf( p
, end
- p
, "MD4" ); break;
1435 case RSA_MD5
: p
+= snprintf( p
, end
- p
, "MD5" ); break;
1436 case RSA_SHA1
: p
+= snprintf( p
, end
- p
, "SHA1" ); break;
1437 default: p
+= snprintf( p
, end
- p
, "???" ); break;
1440 p
+= snprintf( p
, end
- p
, "\n%sRSA key size : %d bits\n", prefix
,
1441 crt
->rsa
.N
.n
* (int) sizeof( unsigned long ) * 8 );
1447 * Return 0 if the certificate is still valid, or BADCERT_EXPIRED
1449 int x509parse_expired( x509_cert
*crt
)
1455 lt
= localtime( &tt
);
1457 if( lt
->tm_year
> crt
->valid_to
.year
- 1900 )
1458 return( BADCERT_EXPIRED
);
1460 if( lt
->tm_year
== crt
->valid_to
.year
- 1900 &&
1461 lt
->tm_mon
> crt
->valid_to
.mon
- 1 )
1462 return( BADCERT_EXPIRED
);
1464 if( lt
->tm_year
== crt
->valid_to
.year
- 1900 &&
1465 lt
->tm_mon
== crt
->valid_to
.mon
- 1 &&
1466 lt
->tm_mday
> crt
->valid_to
.day
)
1467 return( BADCERT_EXPIRED
);
1472 static void x509_hash( unsigned char *in
, int len
, int alg
,
1473 unsigned char *out
)
1477 #if defined(XYSSL_MD2_C)
1478 case RSA_MD2
: md2( in
, len
, out
); break;
1480 #if defined(XYSSL_MD4_C)
1481 case RSA_MD4
: md4( in
, len
, out
); break;
1483 case RSA_MD5
: md5( in
, len
, out
); break;
1484 case RSA_SHA1
: sha1( in
, len
, out
); break;
1486 memset( out
, '\xFF', len
);
1492 * Verify the certificate validity
1494 int x509parse_verify( x509_cert
*crt
,
1495 x509_cert
*trust_ca
,
1496 char *cn
, int *flags
)
1502 unsigned char hash
[20];
1504 *flags
= x509parse_expired( crt
);
1508 name
= &crt
->subject
;
1510 while( name
!= NULL
)
1512 if( memcmp( name
->oid
.p
, "\x55\x04\x03", 3 ) == 0 &&
1513 memcmp( name
->val
.p
, cn
, strlen( cn
) ) == 0 )
1520 *flags
|= BADCERT_CN_MISMATCH
;
1523 *flags
|= BADCERT_NOT_TRUSTED
;
1526 * Iterate upwards in the given cert chain,
1527 * ignoring any upper cert with CA != TRUE.
1533 while( cur
->version
!= 0 )
1535 if( cur
->ca_istrue
== 0 ||
1536 crt
->issuer_raw
.len
!= cur
->subject_raw
.len
||
1537 memcmp( crt
->issuer_raw
.p
, cur
->subject_raw
.p
,
1538 crt
->issuer_raw
.len
) != 0 )
1544 hash_id
= crt
->sig_oid1
.p
[8];
1546 x509_hash( crt
->tbs
.p
, crt
->tbs
.len
, hash_id
, hash
);
1548 if( rsa_pkcs1_verify( &cur
->rsa
, RSA_PUBLIC
, hash_id
,
1549 0, hash
, crt
->sig
.p
) != 0 )
1550 return( XYSSL_ERR_X509_CERT_VERIFY_FAILED
);
1559 * Atempt to validate topmost cert with our CA chain.
1561 while( trust_ca
->version
!= 0 )
1563 if( crt
->issuer_raw
.len
!= trust_ca
->subject_raw
.len
||
1564 memcmp( crt
->issuer_raw
.p
, trust_ca
->subject_raw
.p
,
1565 crt
->issuer_raw
.len
) != 0 )
1567 trust_ca
= trust_ca
->next
;
1571 if( trust_ca
->max_pathlen
> 0 &&
1572 trust_ca
->max_pathlen
< pathlen
)
1575 hash_id
= crt
->sig_oid1
.p
[8];
1577 x509_hash( crt
->tbs
.p
, crt
->tbs
.len
, hash_id
, hash
);
1579 if( rsa_pkcs1_verify( &trust_ca
->rsa
, RSA_PUBLIC
, hash_id
,
1580 0, hash
, crt
->sig
.p
) == 0 )
1583 * cert. is signed by a trusted CA
1585 *flags
&= ~BADCERT_NOT_TRUSTED
;
1591 return( XYSSL_ERR_X509_CERT_VERIFY_FAILED
);
1597 * Unallocate all certificate data
1599 void x509_free( x509_cert
*crt
)
1601 x509_cert
*cert_cur
= crt
;
1602 x509_cert
*cert_prv
;
1603 x509_name
*name_cur
;
1604 x509_name
*name_prv
;
1611 rsa_free( &cert_cur
->rsa
);
1613 name_cur
= cert_cur
->issuer
.next
;
1614 while( name_cur
!= NULL
)
1616 name_prv
= name_cur
;
1617 name_cur
= name_cur
->next
;
1621 name_cur
= cert_cur
->subject
.next
;
1622 while( name_cur
!= NULL
)
1624 name_prv
= name_cur
;
1625 name_cur
= name_cur
->next
;
1629 if( cert_cur
->raw
.p
!= NULL
)
1630 free( cert_cur
->raw
.p
);
1632 cert_cur
= cert_cur
->next
;
1634 while( cert_cur
!= NULL
);
1639 cert_prv
= cert_cur
;
1640 cert_cur
= cert_cur
->next
;
1642 if( cert_prv
!= crt
)
1645 while( cert_cur
!= NULL
);
1648 #if defined(XYSSL_SELF_TEST)
1650 #include "xyssl/certs.h"
1655 int x509_self_test( int verbose
)
1663 printf( " X.509 certificate load: " );
1665 memset( &clicert
, 0, sizeof( x509_cert
) );
1667 ret
= x509parse_crt( &clicert
, (unsigned char *) test_cli_crt
,
1668 strlen( test_cli_crt
) );
1672 printf( "failed\n" );
1677 memset( &cacert
, 0, sizeof( x509_cert
) );
1679 ret
= x509parse_crt( &cacert
, (unsigned char *) test_ca_crt
,
1680 strlen( test_ca_crt
) );
1684 printf( "failed\n" );
1690 printf( "passed\n X.509 private key load: " );
1692 i
= strlen( test_ca_key
);
1693 j
= strlen( test_ca_pwd
);
1695 if( ( ret
= x509parse_key( &rsa
,
1696 (unsigned char *) test_ca_key
, i
,
1697 (unsigned char *) test_ca_pwd
, j
) ) != 0 )
1700 printf( "failed\n" );
1706 printf( "passed\n X.509 signature verify: ");
1708 ret
= x509parse_verify( &clicert
, &cacert
, "Joe User", &i
);
1712 printf( "failed\n" );
1718 printf( "passed\n\n" );
1720 x509_free( &cacert
);
1721 x509_free( &clicert
);