blob: 5bac80fc6aa2980bcbb0980d84a37d3b239bf510 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * X.509 certificate and private key decoding
3 *
4 * Copyright (C) 2006-2007 Christophe Devine
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20/*
21 * The ITU-T X.509 standard defines a certificat format for PKI.
22 *
23 * http://www.ietf.org/rfc/rfc2459.txt
24 * http://www.ietf.org/rfc/rfc3279.txt
25 *
26 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
27 *
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
30 */
31
32#include "xyssl/config.h"
33
34#if defined(XYSSL_X509_PARSE_C)
35
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"
43
44#include <string.h>
45#include <stdlib.h>
46#include <stdio.h>
47#include <time.h>
48
49/*
50 * ASN.1 DER decoding routines
51 */
52static int asn1_get_len( unsigned char **p,
53 unsigned char *end,
54 int *len )
55{
56 if( ( end - *p ) < 1 )
57 return( XYSSL_ERR_ASN1_OUT_OF_DATA );
58
59 if( ( **p & 0x80 ) == 0 )
60 *len = *(*p)++;
61 else
62 {
63 switch( **p & 0x7F )
64 {
65 case 1:
66 if( ( end - *p ) < 2 )
67 return( XYSSL_ERR_ASN1_OUT_OF_DATA );
68
69 *len = (*p)[1];
70 (*p) += 2;
71 break;
72
73 case 2:
74 if( ( end - *p ) < 3 )
75 return( XYSSL_ERR_ASN1_OUT_OF_DATA );
76
77 *len = ( (*p)[1] << 8 ) | (*p)[2];
78 (*p) += 3;
79 break;
80
81 default:
82 return( XYSSL_ERR_ASN1_INVALID_LENGTH );
83 break;
84 }
85 }
86
87 if( *len > (int) ( end - *p ) )
88 return( XYSSL_ERR_ASN1_OUT_OF_DATA );
89
90 return( 0 );
91}
92
93static int asn1_get_tag( unsigned char **p,
94 unsigned char *end,
95 int *len, int tag )
96{
97 if( ( end - *p ) < 1 )
98 return( XYSSL_ERR_ASN1_OUT_OF_DATA );
99
100 if( **p != tag )
101 return( XYSSL_ERR_ASN1_UNEXPECTED_TAG );
102
103 (*p)++;
104
105 return( asn1_get_len( p, end, len ) );
106}
107
108static int asn1_get_bool( unsigned char **p,
109 unsigned char *end,
110 int *val )
111{
112 int ret, len;
113
114 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
115 return( ret );
116
117 if( len != 1 )
118 return( XYSSL_ERR_ASN1_INVALID_LENGTH );
119
120 *val = ( **p != 0 ) ? 1 : 0;
121 (*p)++;
122
123 return( 0 );
124}
125
126static int asn1_get_int( unsigned char **p,
127 unsigned char *end,
128 int *val )
129{
130 int ret, len;
131
132 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
133 return( ret );
134
135 if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
136 return( XYSSL_ERR_ASN1_INVALID_LENGTH );
137
138 *val = 0;
139
140 while( len-- > 0 )
141 {
142 *val = ( *val << 8 ) | **p;
143 (*p)++;
144 }
145
146 return( 0 );
147}
148
149static int asn1_get_mpi( unsigned char **p,
150 unsigned char *end,
151 mpi *X )
152{
153 int ret, len;
154
155 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
156 return( ret );
157
158 ret = mpi_read_binary( X, *p, len );
159
160 *p += len;
161
162 return( ret );
163}
164
165/*
166 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
167 */
168static int x509_get_version( unsigned char **p,
169 unsigned char *end,
170 int *ver )
171{
172 int ret, len;
173
174 if( ( ret = asn1_get_tag( p, end, &len,
175 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
176 {
177 if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG )
178 return( *ver = 0 );
179
180 return( ret );
181 }
182
183 end = *p + len;
184
185 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
186 return( XYSSL_ERR_X509_CERT_INVALID_VERSION | ret );
187
188 if( *p != end )
189 return( XYSSL_ERR_X509_CERT_INVALID_VERSION |
190 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
191
192 return( 0 );
193}
194
195/*
196 * CertificateSerialNumber ::= INTEGER
197 */
198static int x509_get_serial( unsigned char **p,
199 unsigned char *end,
200 x509_buf *serial )
201{
202 int ret;
203
204 if( ( end - *p ) < 1 )
205 return( XYSSL_ERR_X509_CERT_INVALID_SERIAL |
206 XYSSL_ERR_ASN1_OUT_OF_DATA );
207
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 );
212
213 serial->tag = *(*p)++;
214
215 if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
216 return( XYSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
217
218 serial->p = *p;
219 *p += serial->len;
220
221 return( 0 );
222}
223
224/*
225 * AlgorithmIdentifier ::= SEQUENCE {
226 * algorithm OBJECT IDENTIFIER,
227 * parameters ANY DEFINED BY algorithm OPTIONAL }
228 */
229static int x509_get_alg( unsigned char **p,
230 unsigned char *end,
231 x509_buf *alg )
232{
233 int ret, len;
234
235 if( ( ret = asn1_get_tag( p, end, &len,
236 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
237 return( XYSSL_ERR_X509_CERT_INVALID_ALG | ret );
238
239 end = *p + len;
240 alg->tag = **p;
241
242 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
243 return( XYSSL_ERR_X509_CERT_INVALID_ALG | ret );
244
245 alg->p = *p;
246 *p += alg->len;
247
248 if( *p == end )
249 return( 0 );
250
251 /*
252 * assume the algorithm parameters must be NULL
253 */
254 if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
255 return( XYSSL_ERR_X509_CERT_INVALID_ALG | ret );
256
257 if( *p != end )
258 return( XYSSL_ERR_X509_CERT_INVALID_ALG |
259 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
260
261 return( 0 );
262}
263
264/*
265 * RelativeDistinguishedName ::=
266 * SET OF AttributeTypeAndValue
267 *
268 * AttributeTypeAndValue ::= SEQUENCE {
269 * type AttributeType,
270 * value AttributeValue }
271 *
272 * AttributeType ::= OBJECT IDENTIFIER
273 *
274 * AttributeValue ::= ANY DEFINED BY AttributeType
275 */
276static int x509_get_name( unsigned char **p,
277 unsigned char *end,
278 x509_name *cur )
279{
280 int ret, len;
281 unsigned char *end2;
282 x509_buf *oid;
283 x509_buf *val;
284
285 if( ( ret = asn1_get_tag( p, end, &len,
286 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
287 return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret );
288
289 end2 = end;
290 end = *p + len;
291
292 if( ( ret = asn1_get_tag( p, end, &len,
293 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
294 return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret );
295
296 if( *p + len != end )
297 return( XYSSL_ERR_X509_CERT_INVALID_NAME |
298 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
299
300 oid = &cur->oid;
301 oid->tag = **p;
302
303 if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
304 return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret );
305
306 oid->p = *p;
307 *p += oid->len;
308
309 if( ( end - *p ) < 1 )
310 return( XYSSL_ERR_X509_CERT_INVALID_NAME |
311 XYSSL_ERR_ASN1_OUT_OF_DATA );
312
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 );
318
319 val = &cur->val;
320 val->tag = *(*p)++;
321
322 if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
323 return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret );
324
325 val->p = *p;
326 *p += val->len;
327
328 cur->next = NULL;
329
330 if( *p != end )
331 return( XYSSL_ERR_X509_CERT_INVALID_NAME |
332 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
333
334 /*
335 * recurse until end of SEQUENCE is reached
336 */
337 if( *p == end2 )
338 return( 0 );
339
340 cur->next = (x509_name *) malloc(
341 sizeof( x509_name ) );
342
343 if( cur->next == NULL )
344 return( 1 );
345
346 return( x509_get_name( p, end2, cur->next ) );
347}
348
349/*
350 * Validity ::= SEQUENCE {
351 * notBefore Time,
352 * notAfter Time }
353 *
354 * Time ::= CHOICE {
355 * utcTime UTCTime,
356 * generalTime GeneralizedTime }
357 */
358static int x509_get_dates( unsigned char **p,
359 unsigned char *end,
360 x509_time *from,
361 x509_time *to )
362{
363 int ret, len;
364 char date[64];
365
366 if( ( ret = asn1_get_tag( p, end, &len,
367 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
368 return( XYSSL_ERR_X509_CERT_INVALID_DATE | ret );
369
370 end = *p + len;
371
372 /*
373 * TODO: also handle GeneralizedTime
374 */
375 if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 )
376 return( XYSSL_ERR_X509_CERT_INVALID_DATE | ret );
377
378 memset( date, 0, sizeof( date ) );
379 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
380 len : (int) sizeof( date ) - 1 );
381
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 );
386
387 from->year += 100 * ( from->year < 90 );
388 from->year += 1900;
389
390 *p += len;
391
392 if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 )
393 return( XYSSL_ERR_X509_CERT_INVALID_DATE | ret );
394
395 memset( date, 0, sizeof( date ) );
396 memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
397 len : (int) sizeof( date ) - 1 );
398
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 );
403
404 to->year += 100 * ( to->year < 90 );
405 to->year += 1900;
406
407 *p += len;
408
409 if( *p != end )
410 return( XYSSL_ERR_X509_CERT_INVALID_DATE |
411 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
412
413 return( 0 );
414}
415
416/*
417 * SubjectPublicKeyInfo ::= SEQUENCE {
418 * algorithm AlgorithmIdentifier,
419 * subjectPublicKey BIT STRING }
420 */
421static int x509_get_pubkey( unsigned char **p,
422 unsigned char *end,
423 x509_buf *pk_alg_oid,
424 mpi *N, mpi *E )
425{
426 int ret, len;
427 unsigned char *end2;
428
429 if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
430 return( ret );
431
432 /*
433 * only RSA public keys handled at this time
434 */
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 );
438
439 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
440 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
441
442 if( ( end - *p ) < 1 )
443 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY |
444 XYSSL_ERR_ASN1_OUT_OF_DATA );
445
446 end2 = *p + len;
447
448 if( *(*p)++ != 0 )
449 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY );
450
451 /*
452 * RSAPublicKey ::= SEQUENCE {
453 * modulus INTEGER, -- n
454 * publicExponent INTEGER -- e
455 * }
456 */
457 if( ( ret = asn1_get_tag( p, end2, &len,
458 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
459 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
460
461 if( *p + len != end2 )
462 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY |
463 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
464
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 );
468
469 if( *p != end )
470 return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY |
471 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
472
473 return( 0 );
474}
475
476static int x509_get_sig( unsigned char **p,
477 unsigned char *end,
478 x509_buf *sig )
479{
480 int ret, len;
481
482 sig->tag = **p;
483
484 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
485 return( XYSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
486
487 if( --len < 1 || *(*p)++ != 0 )
488 return( XYSSL_ERR_X509_CERT_INVALID_SIGNATURE );
489
490 sig->len = len;
491 sig->p = *p;
492
493 *p += len;
494
495 return( 0 );
496}
497
498/*
499 * X.509 v2/v3 unique identifier (not parsed)
500 */
501static int x509_get_uid( unsigned char **p,
502 unsigned char *end,
503 x509_buf *uid, int n )
504{
505 int ret;
506
507 if( *p == end )
508 return( 0 );
509
510 uid->tag = **p;
511
512 if( ( ret = asn1_get_tag( p, end, &uid->len,
513 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
514 {
515 if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG )
516 return( 0 );
517
518 return( ret );
519 }
520
521 uid->p = *p;
522 *p += uid->len;
523
524 return( 0 );
525}
526
527/*
528 * X.509 v3 extensions (only BasicConstraints are parsed)
529 */
530static int x509_get_ext( unsigned char **p,
531 unsigned char *end,
532 x509_buf *ext,
533 int *ca_istrue,
534 int *max_pathlen )
535{
536 int ret, len;
537 int is_critical = 1;
538 int is_cacert = 0;
539 unsigned char *end2;
540
541 if( *p == end )
542 return( 0 );
543
544 ext->tag = **p;
545
546 if( ( ret = asn1_get_tag( p, end, &ext->len,
547 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
548 {
549 if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG )
550 return( 0 );
551
552 return( ret );
553 }
554
555 ext->p = *p;
556 end = *p + ext->len;
557
558 /*
559 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
560 *
561 * Extension ::= SEQUENCE {
562 * extnID OBJECT IDENTIFIER,
563 * critical BOOLEAN DEFAULT FALSE,
564 * extnValue OCTET STRING }
565 */
566 if( ( ret = asn1_get_tag( p, end, &len,
567 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
568 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
569
570 if( end != *p + len )
571 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
572 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
573
574 while( *p < end )
575 {
576 if( ( ret = asn1_get_tag( p, end, &len,
577 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
578 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
579
580 if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
581 {
582 *p += len;
583 continue;
584 }
585
586 *p += 5;
587
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 );
591
592 if( ( ret = asn1_get_tag( p, end, &len,
593 ASN1_OCTET_STRING ) ) != 0 )
594 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
595
596 /*
597 * BasicConstraints ::= SEQUENCE {
598 * cA BOOLEAN DEFAULT FALSE,
599 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
600 */
601 end2 = *p + len;
602
603 if( ( ret = asn1_get_tag( p, end2, &len,
604 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
605 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
606
607 if( *p == end2 )
608 continue;
609
610 if( ( ret = asn1_get_bool( p, end2, &is_cacert ) ) != 0 )
611 {
612 if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG )
613 ret = asn1_get_int( p, end2, &is_cacert );
614
615 if( ret != 0 )
616 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
617
618 if( is_cacert != 0 )
619 is_cacert = 1;
620 }
621
622 if( *p == end2 )
623 continue;
624
625 if( ( ret = asn1_get_int( p, end2, max_pathlen ) ) != 0 )
626 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
627
628 if( *p != end2 )
629 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
630 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
631
632 max_pathlen++;
633 }
634
635 if( *p != end )
636 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
637 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
638
639 *ca_istrue = is_critical & is_cacert;
640
641 return( 0 );
642}
643
644/*
645 * Parse one or more certificates and add them to the chained list
646 */
647int x509parse_crt( x509_cert *chain, unsigned char *buf, int buflen )
648{
649 int ret, len;
650 unsigned char *s1, *s2;
651 unsigned char *p, *end;
652 x509_cert *crt;
653
654 crt = chain;
655
656 while( crt->version != 0 )
657 crt = crt->next;
658
659 /*
660 * check if the certificate is encoded in base64
661 */
662 s1 = (unsigned char *) strstr( (char *) buf,
663 "-----BEGIN CERTIFICATE-----" );
664
665 if( s1 != NULL )
666 {
667 s2 = (unsigned char *) strstr( (char *) buf,
668 "-----END CERTIFICATE-----" );
669
670 if( s2 == NULL || s2 <= s1 )
671 return( XYSSL_ERR_X509_CERT_INVALID_PEM );
672
673 s1 += 27;
674 if( *s1 == '\r' ) s1++;
675 if( *s1 == '\n' ) s1++;
676 else return( XYSSL_ERR_X509_CERT_INVALID_PEM );
677
678 /*
679 * get the DER data length and decode the buffer
680 */
681 len = 0;
682 ret = base64_decode( NULL, &len, s1, s2 - s1 );
683
684 if( ret == XYSSL_ERR_BASE64_INVALID_CHARACTER )
685 return( XYSSL_ERR_X509_CERT_INVALID_PEM | ret );
686
687 if( ( p = (unsigned char *) malloc( len ) ) == NULL )
688 return( 1 );
689
690 if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
691 {
692 free( p );
693 return( XYSSL_ERR_X509_CERT_INVALID_PEM | ret );
694 }
695
696 /*
697 * update the buffer size and offset
698 */
699 s2 += 25;
700 if( *s2 == '\r' ) s2++;
701 if( *s2 == '\n' ) s2++;
702 else
703 {
704 free( p );
705 return( XYSSL_ERR_X509_CERT_INVALID_PEM );
706 }
707
708 buflen -= s2 - buf;
709 buf = s2;
710 }
711 else
712 {
713 /*
714 * nope, copy the raw DER data
715 */
716 p = (unsigned char *) malloc( len = buflen );
717
718 if( p == NULL )
719 return( 1 );
720
721 memcpy( p, buf, buflen );
722
723 buflen = 0;
724 }
725
726 crt->raw.p = p;
727 crt->raw.len = len;
728 end = p + len;
729
730 /*
731 * Certificate ::= SEQUENCE {
732 * tbsCertificate TBSCertificate,
733 * signatureAlgorithm AlgorithmIdentifier,
734 * signatureValue BIT STRING }
735 */
736 if( ( ret = asn1_get_tag( &p, end, &len,
737 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
738 {
739 x509_free( crt );
740 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT );
741 }
742
743 if( len != (int) ( end - p ) )
744 {
745 x509_free( crt );
746 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT |
747 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
748 }
749
750 /*
751 * TBSCertificate ::= SEQUENCE {
752 */
753 crt->tbs.p = p;
754
755 if( ( ret = asn1_get_tag( &p, end, &len,
756 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
757 {
758 x509_free( crt );
759 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
760 }
761
762 end = p + len;
763 crt->tbs.len = end - crt->tbs.p;
764
765 /*
766 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
767 *
768 * CertificateSerialNumber ::= INTEGER
769 *
770 * signature AlgorithmIdentifier
771 */
772 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
773 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
774 ( ret = x509_get_alg( &p, end, &crt->sig_oid1 ) ) != 0 )
775 {
776 x509_free( crt );
777 return( ret );
778 }
779
780 crt->version++;
781
782 if( crt->version > 3 )
783 {
784 x509_free( crt );
785 return( XYSSL_ERR_X509_CERT_UNKNOWN_VERSION );
786 }
787
788 if( crt->sig_oid1.len != 9 ||
789 memcmp( crt->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
790 {
791 x509_free( crt );
792 return( XYSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
793 }
794
795 if( crt->sig_oid1.p[8] < 2 ||
796 crt->sig_oid1.p[8] > 5 )
797 {
798 x509_free( crt );
799 return( XYSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
800 }
801
802 /*
803 * issuer Name
804 */
805 crt->issuer_raw.p = p;
806
807 if( ( ret = asn1_get_tag( &p, end, &len,
808 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
809 {
810 x509_free( crt );
811 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
812 }
813
814 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
815 {
816 x509_free( crt );
817 return( ret );
818 }
819
820 crt->issuer_raw.len = p - crt->issuer_raw.p;
821
822 /*
823 * Validity ::= SEQUENCE {
824 * notBefore Time,
825 * notAfter Time }
826 *
827 */
828 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
829 &crt->valid_to ) ) != 0 )
830 {
831 x509_free( crt );
832 return( ret );
833 }
834
835 /*
836 * subject Name
837 */
838 crt->subject_raw.p = p;
839
840 if( ( ret = asn1_get_tag( &p, end, &len,
841 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
842 {
843 x509_free( crt );
844 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
845 }
846
847 if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
848 {
849 x509_free( crt );
850 return( ret );
851 }
852
853 crt->subject_raw.len = p - crt->subject_raw.p;
854
855 /*
856 * SubjectPublicKeyInfo ::= SEQUENCE
857 * algorithm AlgorithmIdentifier,
858 * subjectPublicKey BIT STRING }
859 */
860 if( ( ret = asn1_get_tag( &p, end, &len,
861 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
862 {
863 x509_free( crt );
864 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
865 }
866
867 if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
868 &crt->rsa.N, &crt->rsa.E ) ) != 0 )
869 {
870 x509_free( crt );
871 return( ret );
872 }
873
874 if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
875 {
876 x509_free( crt );
877 return( ret );
878 }
879
880 crt->rsa.len = mpi_size( &crt->rsa.N );
881
882 /*
883 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
884 * -- If present, version shall be v2 or v3
885 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
886 * -- If present, version shall be v2 or v3
887 * extensions [3] EXPLICIT Extensions OPTIONAL
888 * -- If present, version shall be v3
889 */
890 if( crt->version == 2 || crt->version == 3 )
891 {
892 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
893 if( ret != 0 )
894 {
895 x509_free( crt );
896 return( ret );
897 }
898 }
899
900 if( crt->version == 2 || crt->version == 3 )
901 {
902 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
903 if( ret != 0 )
904 {
905 x509_free( crt );
906 return( ret );
907 }
908 }
909
910 if( crt->version == 3 )
911 {
912 ret = x509_get_ext( &p, end, &crt->v3_ext,
913 &crt->ca_istrue, &crt->max_pathlen );
914 if( ret != 0 )
915 {
916 x509_free( crt );
917 return( ret );
918 }
919 }
920
921 if( p != end )
922 {
923 x509_free( crt );
924 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT |
925 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
926 }
927
928 end = crt->raw.p + crt->raw.len;
929
930 /*
931 * signatureAlgorithm AlgorithmIdentifier,
932 * signatureValue BIT STRING
933 */
934 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
935 {
936 x509_free( crt );
937 return( ret );
938 }
939
940 if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, 9 ) != 0 )
941 {
942 x509_free( crt );
943 return( XYSSL_ERR_X509_CERT_SIG_MISMATCH );
944 }
945
946 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
947 {
948 x509_free( crt );
949 return( ret );
950 }
951
952 if( p != end )
953 {
954 x509_free( crt );
955 return( XYSSL_ERR_X509_CERT_INVALID_FORMAT |
956 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
957 }
958
959 crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
960
961 if( crt->next == NULL )
962 {
963 x509_free( crt );
964 return( 1 );
965 }
966
967 crt = crt->next;
968 memset( crt, 0, sizeof( x509_cert ) );
969
970 if( buflen > 0 )
971 return( x509parse_crt( crt, buf, buflen ) );
972
973 return( 0 );
974}
975
976/*
977 * Load one or more certificates and add them to the chained list
978 */
979int x509parse_crtfile( x509_cert *chain, char *path )
980{
981 int ret;
982 FILE *f;
983 size_t n;
984 unsigned char *buf;
985
986 if( ( f = fopen( path, "rb" ) ) == NULL )
987 return( 1 );
988
989 fseek( f, 0, SEEK_END );
990 n = (size_t) ftell( f );
991 fseek( f, 0, SEEK_SET );
992
993 if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
994 return( 1 );
995
996 if( fread( buf, 1, n, f ) != n )
997 {
998 fclose( f );
999 free( buf );
1000 return( 1 );
1001 }
1002
1003 buf[n] = '\0';
1004
1005 ret = x509parse_crt( chain, buf, (int) n );
1006
1007 memset( buf, 0, n + 1 );
1008 free( buf );
1009 fclose( f );
1010
1011 return( ret );
1012}
1013
1014#if defined(XYSSL_DES_C)
1015/*
1016 * Read a 16-byte hex string and convert it to binary
1017 */
1018static int x509_get_iv( unsigned char *s, unsigned char iv[8] )
1019{
1020 int i, j, k;
1021
1022 memset( iv, 0, 8 );
1023
1024 for( i = 0; i < 16; i++, s++ )
1025 {
1026 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
1027 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
1028 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
1029 return( XYSSL_ERR_X509_KEY_INVALID_ENC_IV );
1030
1031 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
1032
1033 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
1034 }
1035
1036 return( 0 );
1037}
1038
1039/*
1040 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
1041 */
1042static void x509_des3_decrypt( unsigned char des3_iv[8],
1043 unsigned char *buf, int buflen,
1044 unsigned char *pwd, int pwdlen )
1045{
1046 md5_context md5_ctx;
1047 des3_context des3_ctx;
1048 unsigned char md5sum[16];
1049 unsigned char des3_key[24];
1050
1051 /*
1052 * 3DES key[ 0..15] = MD5(pwd || IV)
1053 * key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
1054 */
1055 md5_starts( &md5_ctx );
1056 md5_update( &md5_ctx, pwd, pwdlen );
1057 md5_update( &md5_ctx, des3_iv, 8 );
1058 md5_finish( &md5_ctx, md5sum );
1059 memcpy( des3_key, md5sum, 16 );
1060
1061 md5_starts( &md5_ctx );
1062 md5_update( &md5_ctx, md5sum, 16 );
1063 md5_update( &md5_ctx, pwd, pwdlen );
1064 md5_update( &md5_ctx, des3_iv, 8 );
1065 md5_finish( &md5_ctx, md5sum );
1066 memcpy( des3_key + 16, md5sum, 8 );
1067
1068 des3_set3key_dec( &des3_ctx, des3_key );
1069 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
1070 des3_iv, buf, buf );
1071
1072 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
1073 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
1074 memset( md5sum, 0, 16 );
1075 memset( des3_key, 0, 24 );
1076}
1077#endif
1078
1079/*
1080 * Parse a private RSA key
1081 */
1082int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
1083 unsigned char *pwd, int pwdlen )
1084{
1085 int ret, len, enc;
1086 unsigned char *s1, *s2;
1087 unsigned char *p, *end;
1088 unsigned char des3_iv[8];
1089
1090 s1 = (unsigned char *) strstr( (char *) buf,
1091 "-----BEGIN RSA PRIVATE KEY-----" );
1092
1093 if( s1 != NULL )
1094 {
1095 s2 = (unsigned char *) strstr( (char *) buf,
1096 "-----END RSA PRIVATE KEY-----" );
1097
1098 if( s2 == NULL || s2 <= s1 )
1099 return( XYSSL_ERR_X509_KEY_INVALID_PEM );
1100
1101 s1 += 31;
1102 if( *s1 == '\r' ) s1++;
1103 if( *s1 == '\n' ) s1++;
1104 else return( XYSSL_ERR_X509_KEY_INVALID_PEM );
1105
1106 enc = 0;
1107
1108 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
1109 {
1110#if defined(XYSSL_DES_C)
1111 enc++;
1112
1113 s1 += 22;
1114 if( *s1 == '\r' ) s1++;
1115 if( *s1 == '\n' ) s1++;
1116 else return( XYSSL_ERR_X509_KEY_INVALID_PEM );
1117
1118 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
1119 return( XYSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
1120
1121 s1 += 23;
1122 if( x509_get_iv( s1, des3_iv ) != 0 )
1123 return( XYSSL_ERR_X509_KEY_INVALID_ENC_IV );
1124
1125 s1 += 16;
1126 if( *s1 == '\r' ) s1++;
1127 if( *s1 == '\n' ) s1++;
1128 else return( XYSSL_ERR_X509_KEY_INVALID_PEM );
1129#else
1130 return( XYSSL_ERR_X509_FEATURE_UNAVAILABLE );
1131#endif
1132 }
1133
1134 len = 0;
1135 ret = base64_decode( NULL, &len, s1, s2 - s1 );
1136
1137 if( ret == XYSSL_ERR_BASE64_INVALID_CHARACTER )
1138 return( ret | XYSSL_ERR_X509_KEY_INVALID_PEM );
1139
1140 if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
1141 return( 1 );
1142
1143 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
1144 {
1145 free( buf );
1146 return( ret | XYSSL_ERR_X509_KEY_INVALID_PEM );
1147 }
1148
1149 buflen = len;
1150
1151 if( enc != 0 )
1152 {
1153#if defined(XYSSL_DES_C)
1154 if( pwd == NULL )
1155 {
1156 free( buf );
1157 return( XYSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
1158 }
1159
1160 x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );
1161
1162 if( buf[0] != 0x30 || buf[1] != 0x82 ||
1163 buf[4] != 0x02 || buf[5] != 0x01 )
1164 {
1165 free( buf );
1166 return( XYSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
1167 }
1168#else
1169 return( XYSSL_ERR_X509_FEATURE_UNAVAILABLE );
1170#endif
1171 }
1172 }
1173
1174 memset( rsa, 0, sizeof( rsa_context ) );
1175
1176 p = buf;
1177 end = buf + buflen;
1178
1179 /*
1180 * RSAPrivateKey ::= SEQUENCE {
1181 * version Version,
1182 * modulus INTEGER, -- n
1183 * publicExponent INTEGER, -- e
1184 * privateExponent INTEGER, -- d
1185 * prime1 INTEGER, -- p
1186 * prime2 INTEGER, -- q
1187 * exponent1 INTEGER, -- d mod (p-1)
1188 * exponent2 INTEGER, -- d mod (q-1)
1189 * coefficient INTEGER, -- (inverse of q) mod p
1190 * otherPrimeInfos OtherPrimeInfos OPTIONAL
1191 * }
1192 */
1193 if( ( ret = asn1_get_tag( &p, end, &len,
1194 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
1195 {
1196 if( s1 != NULL )
1197 free( buf );
1198
1199 rsa_free( rsa );
1200 return( XYSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
1201 }
1202
1203 end = p + len;
1204
1205 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
1206 {
1207 if( s1 != NULL )
1208 free( buf );
1209
1210 rsa_free( rsa );
1211 return( XYSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
1212 }
1213
1214 if( rsa->ver != 0 )
1215 {
1216 if( s1 != NULL )
1217 free( buf );
1218
1219 rsa_free( rsa );
1220 return( ret | XYSSL_ERR_X509_KEY_INVALID_VERSION );
1221 }
1222
1223 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
1224 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
1225 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
1226 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
1227 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
1228 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
1229 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
1230 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
1231 {
1232 if( s1 != NULL )
1233 free( buf );
1234
1235 rsa_free( rsa );
1236 return( ret | XYSSL_ERR_X509_KEY_INVALID_FORMAT );
1237 }
1238
1239 rsa->len = mpi_size( &rsa->N );
1240
1241 if( p != end )
1242 {
1243 if( s1 != NULL )
1244 free( buf );
1245
1246 rsa_free( rsa );
1247 return( XYSSL_ERR_X509_KEY_INVALID_FORMAT |
1248 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
1249 }
1250
1251 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
1252 {
1253 if( s1 != NULL )
1254 free( buf );
1255
1256 rsa_free( rsa );
1257 return( ret );
1258 }
1259
1260 if( s1 != NULL )
1261 free( buf );
1262
1263 return( 0 );
1264}
1265
1266/*
1267 * Load and parse a private RSA key
1268 */
1269int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd )
1270{
1271 int ret;
1272 FILE *f;
1273 size_t n;
1274 unsigned char *buf;
1275
1276 if( ( f = fopen( path, "rb" ) ) == NULL )
1277 return( 1 );
1278
1279 fseek( f, 0, SEEK_END );
1280 n = (size_t) ftell( f );
1281 fseek( f, 0, SEEK_SET );
1282
1283 if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
1284 return( 1 );
1285
1286 if( fread( buf, 1, n, f ) != n )
1287 {
1288 fclose( f );
1289 free( buf );
1290 return( 1 );
1291 }
1292
1293 buf[n] = '\0';
1294
1295 if( pwd == NULL )
1296 ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
1297 else
1298 ret = x509parse_key( rsa, buf, (int) n,
1299 (unsigned char *) pwd, strlen( pwd ) );
1300
1301 memset( buf, 0, n + 1 );
1302 free( buf );
1303 fclose( f );
1304
1305 return( ret );
1306}
1307
1308#if defined _MSC_VER && !defined snprintf
1309#define snprintf _snprintf
1310#endif
1311
1312/*
1313 * Store the name in printable form into buf; no more
1314 * than (end - buf) characters will be written
1315 */
1316int x509parse_dn_gets( char *buf, char *end, x509_name *dn )
1317{
1318 int i;
1319 unsigned char c;
1320 x509_name *name;
1321 char s[128], *p;
1322
1323 memset( s, 0, sizeof( s ) );
1324
1325 name = dn;
1326 p = buf;
1327
1328 while( name != NULL )
1329 {
1330 if( name != dn )
1331 p += snprintf( p, end - p, ", " );
1332
1333 if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
1334 {
1335 switch( name->oid.p[2] )
1336 {
1337 case X520_COMMON_NAME:
1338 p += snprintf( p, end - p, "CN=" ); break;
1339
1340 case X520_COUNTRY:
1341 p += snprintf( p, end - p, "C=" ); break;
1342
1343 case X520_LOCALITY:
1344 p += snprintf( p, end - p, "L=" ); break;
1345
1346 case X520_STATE:
1347 p += snprintf( p, end - p, "ST=" ); break;
1348
1349 case X520_ORGANIZATION:
1350 p += snprintf( p, end - p, "O=" ); break;
1351
1352 case X520_ORG_UNIT:
1353 p += snprintf( p, end - p, "OU=" ); break;
1354
1355 default:
1356 p += snprintf( p, end - p, "0x%02X=",
1357 name->oid.p[2] );
1358 break;
1359 }
1360 }
1361 else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
1362 {
1363 switch( name->oid.p[8] )
1364 {
1365 case PKCS9_EMAIL:
1366 p += snprintf( p, end - p, "emailAddress=" ); break;
1367
1368 default:
1369 p += snprintf( p, end - p, "0x%02X=",
1370 name->oid.p[8] );
1371 break;
1372 }
1373 }
1374 else
1375 p += snprintf( p, end - p, "\?\?=" );
1376
1377 for( i = 0; i < name->val.len; i++ )
1378 {
1379 if( i >= (int) sizeof( s ) - 1 )
1380 break;
1381
1382 c = name->val.p[i];
1383 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
1384 s[i] = '?';
1385 else s[i] = c;
1386 }
1387 s[i] = '\0';
1388 p += snprintf( p, end - p, "%s", s );
1389 name = name->next;
1390 }
1391
1392 return( p - buf );
1393}
1394
1395/*
1396 * Return an informational string about the
1397 * certificate, or NULL if memory allocation failed
1398 */
1399char *x509parse_cert_info( char *prefix, x509_cert *crt )
1400{
1401 int i, n;
1402 char *p, *end;
1403 static char buf[512];
1404
1405 p = buf;
1406 end = buf + sizeof( buf ) - 1;
1407
1408 p += snprintf( p, end - p, "%scert. version : %d\n",
1409 prefix, crt->version );
1410 p += snprintf( p, end - p, "%sserial number : ",
1411 prefix );
1412
1413 n = ( crt->serial.len <= 32 )
1414 ? crt->serial.len : 32;
1415
1416 for( i = 0; i < n; i++ )
1417 p += snprintf( p, end - p, "%02X%s",
1418 crt->serial.p[i], ( i < n - 1 ) ? ":" : "" );
1419
1420 p += snprintf( p, end - p, "\n%sissuer name : ", prefix );
1421 p += x509parse_dn_gets( p, end, &crt->issuer );
1422
1423 p += snprintf( p, end - p, "\n%ssubject name : ", prefix );
1424 p += x509parse_dn_gets( p, end, &crt->subject );
1425
1426 p += snprintf( p, end - p, "\n%sissued on : " \
1427 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1428 crt->valid_from.year, crt->valid_from.mon,
1429 crt->valid_from.day, crt->valid_from.hour,
1430 crt->valid_from.min, crt->valid_from.sec );
1431
1432 p += snprintf( p, end - p, "\n%sexpires on : " \
1433 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1434 crt->valid_to.year, crt->valid_to.mon,
1435 crt->valid_to.day, crt->valid_to.hour,
1436 crt->valid_to.min, crt->valid_to.sec );
1437
1438 p += snprintf( p, end - p, "\n%ssigned using : RSA+", prefix );
1439
1440 switch( crt->sig_oid1.p[8] )
1441 {
1442 case RSA_MD2 : p += snprintf( p, end - p, "MD2" ); break;
1443 case RSA_MD4 : p += snprintf( p, end - p, "MD4" ); break;
1444 case RSA_MD5 : p += snprintf( p, end - p, "MD5" ); break;
1445 case RSA_SHA1: p += snprintf( p, end - p, "SHA1" ); break;
1446 default: p += snprintf( p, end - p, "???" ); break;
1447 }
1448
1449 p += snprintf( p, end - p, "\n%sRSA key size : %d bits\n", prefix,
1450 crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
1451
1452 return( buf );
1453}
1454
1455/*
1456 * Return 0 if the certificate is still valid, or BADCERT_EXPIRED
1457 */
1458int x509parse_expired( x509_cert *crt )
1459{
1460 struct tm *lt;
1461 time_t tt;
1462
1463 tt = time( NULL );
1464 lt = localtime( &tt );
1465
1466 if( lt->tm_year > crt->valid_to.year - 1900 )
1467 return( BADCERT_EXPIRED );
1468
1469 if( lt->tm_year == crt->valid_to.year - 1900 &&
1470 lt->tm_mon > crt->valid_to.mon - 1 )
1471 return( BADCERT_EXPIRED );
1472
1473 if( lt->tm_year == crt->valid_to.year - 1900 &&
1474 lt->tm_mon == crt->valid_to.mon - 1 &&
1475 lt->tm_mday > crt->valid_to.day )
1476 return( BADCERT_EXPIRED );
1477
1478 return( 0 );
1479}
1480
1481static void x509_hash( unsigned char *in, int len, int alg,
1482 unsigned char *out )
1483{
1484 switch( alg )
1485 {
1486#if defined(XYSSL_MD2_C)
1487 case RSA_MD2 : md2( in, len, out ); break;
1488#endif
1489#if defined(XYSSL_MD4_C)
1490 case RSA_MD4 : md4( in, len, out ); break;
1491#endif
1492 case RSA_MD5 : md5( in, len, out ); break;
1493 case RSA_SHA1 : sha1( in, len, out ); break;
1494 default:
1495 memset( out, '\xFF', len );
1496 break;
1497 }
1498}
1499
1500/*
1501 * Verify the certificate validity
1502 */
1503int x509parse_verify( x509_cert *crt,
1504 x509_cert *trust_ca,
1505 char *cn, int *flags )
1506{
1507 int cn_len;
1508 int hash_id;
1509 int pathlen;
1510 x509_cert *cur;
1511 x509_name *name;
1512 unsigned char hash[20];
1513
1514 *flags = x509parse_expired( crt );
1515
1516 if( cn != NULL )
1517 {
1518 name = &crt->subject;
1519 cn_len = strlen( cn );
1520
1521 while( name != NULL )
1522 {
1523 if( memcmp( name->oid.p, OID_CN, 3 ) == 0 &&
1524 memcmp( name->val.p, cn, cn_len ) == 0 &&
1525 name->val.len == cn_len )
1526 break;
1527
1528 name = name->next;
1529 }
1530
1531 if( name == NULL )
1532 *flags |= BADCERT_CN_MISMATCH;
1533 }
1534
1535 *flags |= BADCERT_NOT_TRUSTED;
1536
1537 /*
1538 * Iterate upwards in the given cert chain,
1539 * ignoring any upper cert with CA != TRUE.
1540 */
1541 cur = crt->next;
1542
1543 pathlen = 1;
1544
1545 while( cur->version != 0 )
1546 {
1547 if( cur->ca_istrue == 0 ||
1548 crt->issuer_raw.len != cur->subject_raw.len ||
1549 memcmp( crt->issuer_raw.p, cur->subject_raw.p,
1550 crt->issuer_raw.len ) != 0 )
1551 {
1552 cur = cur->next;
1553 continue;
1554 }
1555
1556 hash_id = crt->sig_oid1.p[8];
1557
1558 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
1559
1560 if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
1561 0, hash, crt->sig.p ) != 0 )
1562 return( XYSSL_ERR_X509_CERT_VERIFY_FAILED );
1563
1564 pathlen++;
1565
1566 crt = cur;
1567 cur = crt->next;
1568 }
1569
1570 /*
1571 * Atempt to validate topmost cert with our CA chain.
1572 */
1573 while( trust_ca->version != 0 )
1574 {
1575 if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
1576 memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
1577 crt->issuer_raw.len ) != 0 )
1578 {
1579 trust_ca = trust_ca->next;
1580 continue;
1581 }
1582
1583 if( trust_ca->max_pathlen > 0 &&
1584 trust_ca->max_pathlen < pathlen )
1585 break;
1586
1587 hash_id = crt->sig_oid1.p[8];
1588
1589 x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
1590
1591 if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
1592 0, hash, crt->sig.p ) == 0 )
1593 {
1594 /*
1595 * cert. is signed by a trusted CA
1596 */
1597 *flags &= ~BADCERT_NOT_TRUSTED;
1598 break;
1599 }
1600
1601 trust_ca = trust_ca->next;
1602 }
1603
1604 if( *flags != 0 )
1605 return( XYSSL_ERR_X509_CERT_VERIFY_FAILED );
1606
1607 return( 0 );
1608}
1609
1610/*
1611 * Unallocate all certificate data
1612 */
1613void x509_free( x509_cert *crt )
1614{
1615 x509_cert *cert_cur = crt;
1616 x509_cert *cert_prv;
1617 x509_name *name_cur;
1618 x509_name *name_prv;
1619
1620 if( crt == NULL )
1621 return;
1622
1623 do
1624 {
1625 rsa_free( &cert_cur->rsa );
1626
1627 name_cur = cert_cur->issuer.next;
1628 while( name_cur != NULL )
1629 {
1630 name_prv = name_cur;
1631 name_cur = name_cur->next;
1632 memset( name_prv, 0, sizeof( x509_name ) );
1633 free( name_prv );
1634 }
1635
1636 name_cur = cert_cur->subject.next;
1637 while( name_cur != NULL )
1638 {
1639 name_prv = name_cur;
1640 name_cur = name_cur->next;
1641 memset( name_prv, 0, sizeof( x509_name ) );
1642 free( name_prv );
1643 }
1644
1645 if( cert_cur->raw.p != NULL )
1646 {
1647 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
1648 free( cert_cur->raw.p );
1649 }
1650
1651 cert_cur = cert_cur->next;
1652 }
1653 while( cert_cur != NULL );
1654
1655 cert_cur = crt;
1656 do
1657 {
1658 cert_prv = cert_cur;
1659 cert_cur = cert_cur->next;
1660
1661 memset( cert_prv, 0, sizeof( x509_cert ) );
1662 if( cert_prv != crt )
1663 free( cert_prv );
1664 }
1665 while( cert_cur != NULL );
1666}
1667
1668#if defined(XYSSL_SELF_TEST)
1669
1670#include "xyssl/certs.h"
1671
1672/*
1673 * Checkup routine
1674 */
1675int x509_self_test( int verbose )
1676{
1677 int ret, i, j;
1678 x509_cert cacert;
1679 x509_cert clicert;
1680 rsa_context rsa;
1681
1682 if( verbose != 0 )
1683 printf( " X.509 certificate load: " );
1684
1685 memset( &clicert, 0, sizeof( x509_cert ) );
1686
1687 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
1688 strlen( test_cli_crt ) );
1689 if( ret != 0 )
1690 {
1691 if( verbose != 0 )
1692 printf( "failed\n" );
1693
1694 return( ret );
1695 }
1696
1697 memset( &cacert, 0, sizeof( x509_cert ) );
1698
1699 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
1700 strlen( test_ca_crt ) );
1701 if( ret != 0 )
1702 {
1703 if( verbose != 0 )
1704 printf( "failed\n" );
1705
1706 return( ret );
1707 }
1708
1709 if( verbose != 0 )
1710 printf( "passed\n X.509 private key load: " );
1711
1712 i = strlen( test_ca_key );
1713 j = strlen( test_ca_pwd );
1714
1715 if( ( ret = x509parse_key( &rsa,
1716 (unsigned char *) test_ca_key, i,
1717 (unsigned char *) test_ca_pwd, j ) ) != 0 )
1718 {
1719 if( verbose != 0 )
1720 printf( "failed\n" );
1721
1722 return( ret );
1723 }
1724
1725 if( verbose != 0 )
1726 printf( "passed\n X.509 signature verify: ");
1727
1728 ret = x509parse_verify( &clicert, &cacert, "Joe User", &i );
1729 if( ret != 0 )
1730 {
1731 if( verbose != 0 )
1732 printf( "failed\n" );
1733
1734 return( ret );
1735 }
1736
1737 if( verbose != 0 )
1738 printf( "passed\n\n" );
1739
1740 x509_free( &cacert );
1741 x509_free( &clicert );
1742 rsa_free( &rsa );
1743
1744 return( 0 );
1745}
1746
1747#endif
1748
1749#endif