blob: 2d244f16a65771c8a90cb062fdc87cc3b075f8f2 [file] [log] [blame]
Paul Bakker1a7550a2013-09-15 13:01:22 +02001/*
2 * Public Key layer for parsing key files and structures
3 *
4 * Copyright (C) 2006-2013, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#include "polarssl/config.h"
27
Paul Bakker4606c732013-09-15 17:04:23 +020028#if defined(POLARSSL_PK_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +020029
30#include "polarssl/pk.h"
31#include "polarssl/asn1.h"
32#include "polarssl/oid.h"
33
34#if defined(POLARSSL_RSA_C)
35#include "polarssl/rsa.h"
36#endif
37#if defined(POLARSSL_ECP_C)
38#include "polarssl/ecp.h"
39#endif
40#if defined(POLARSSL_ECDSA_C)
41#include "polarssl/ecdsa.h"
42#endif
43#if defined(POLARSSL_PEM_C)
44#include "polarssl/pem.h"
45#endif
46#if defined(POLARSSL_PKCS5_C)
47#include "polarssl/pkcs5.h"
48#endif
49#if defined(POLARSSL_PKCS12_C)
50#include "polarssl/pkcs12.h"
51#endif
52
53#if defined(POLARSSL_MEMORY_C)
54#include "polarssl/memory.h"
55#else
56#include <stdlib.h>
57#define polarssl_malloc malloc
58#define polarssl_free free
59#endif
60
61#if defined(POLARSSL_FS_IO)
62/*
63 * Load all data from a file into a given buffer.
64 */
65static int load_file( const char *path, unsigned char **buf, size_t *n )
66{
67 FILE *f;
68 long size;
69
70 if( ( f = fopen( path, "rb" ) ) == NULL )
71 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
72
73 fseek( f, 0, SEEK_END );
74 if( ( size = ftell( f ) ) == -1 )
75 {
76 fclose( f );
77 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
78 }
79 fseek( f, 0, SEEK_SET );
80
81 *n = (size_t) size;
82
83 if( *n + 1 == 0 ||
84 ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
85 {
86 fclose( f );
87 return( POLARSSL_ERR_PK_MALLOC_FAILED );
88 }
89
90 if( fread( *buf, 1, *n, f ) != *n )
91 {
92 fclose( f );
93 polarssl_free( *buf );
94 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
95 }
96
97 fclose( f );
98
99 (*buf)[*n] = '\0';
100
101 return( 0 );
102}
103
104/*
105 * Load and parse a private key
106 */
107int pk_parse_keyfile( pk_context *ctx,
108 const char *path, const char *pwd )
109{
110 int ret;
111 size_t n;
112 unsigned char *buf;
113
114 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
115 return( ret );
116
117 if( pwd == NULL )
118 ret = pk_parse_key( ctx, buf, n, NULL, 0 );
119 else
120 ret = pk_parse_key( ctx, buf, n,
121 (const unsigned char *) pwd, strlen( pwd ) );
122
123 memset( buf, 0, n + 1 );
124 polarssl_free( buf );
125
126 return( ret );
127}
128
129/*
130 * Load and parse a public key
131 */
132int pk_parse_public_keyfile( pk_context *ctx, const char *path )
133{
134 int ret;
135 size_t n;
136 unsigned char *buf;
137
138 if ( (ret = load_file( path, &buf, &n ) ) != 0 )
139 return( ret );
140
141 ret = pk_parse_public_key( ctx, buf, n );
142
143 memset( buf, 0, n + 1 );
144 polarssl_free( buf );
145
146 return( ret );
147}
148#endif /* POLARSSL_FS_IO */
149
150#if defined(POLARSSL_ECP_C)
151/* Get an EC group id from an ECParameters buffer
152 *
153 * ECParameters ::= CHOICE {
154 * namedCurve OBJECT IDENTIFIER
155 * -- implicitCurve NULL
156 * -- specifiedCurve SpecifiedECDomain
157 * }
158 */
159static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
160 asn1_buf *params )
161{
162 int ret;
163
164 params->tag = **p;
165
166 if( ( ret = asn1_get_tag( p, end, &params->len, ASN1_OID ) ) != 0 )
167 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
168
169 params->p = *p;
170 *p += params->len;
171
172 if( *p != end )
173 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
174 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
175
176 return( 0 );
177}
178
179/*
180 * Use EC parameters to initialise an EC group
181 */
182static int pk_use_ecparams( const asn1_buf *params, ecp_group *grp )
183{
184 int ret;
185 ecp_group_id grp_id;
186
187 if( oid_get_ec_grp( params, &grp_id ) != 0 )
188 return( POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE );
189
190 /*
191 * grp may already be initilialized; if so, make sure IDs match
192 */
193 if( grp->id != POLARSSL_ECP_DP_NONE && grp->id != grp_id )
194 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
195
196 if( ( ret = ecp_use_known_dp( grp, grp_id ) ) != 0 )
197 return( ret );
198
199 return( 0 );
200}
201
202/*
203 * EC public key is an EC point
204 */
205static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
206 ecp_keypair *key )
207{
208 int ret;
209
210 if( ( ret = ecp_point_read_binary( &key->grp, &key->Q,
211 (const unsigned char *) *p, end - *p ) ) != 0 ||
212 ( ret = ecp_check_pubkey( &key->grp, &key->Q ) ) != 0 )
213 {
214 ecp_keypair_free( key );
215 return( POLARSSL_ERR_PK_INVALID_PUBKEY );
216 }
217
218 /*
219 * We know ecp_point_read_binary consumed all bytes
220 */
221 *p = (unsigned char *) end;
222
223 return( 0 );
224}
225#endif /* POLARSSL_ECP_C */
226
227#if defined(POLARSSL_RSA_C)
228/*
229 * RSAPublicKey ::= SEQUENCE {
230 * modulus INTEGER, -- n
231 * publicExponent INTEGER -- e
232 * }
233 */
234static int pk_get_rsapubkey( unsigned char **p,
235 const unsigned char *end,
236 rsa_context *rsa )
237{
238 int ret;
239 size_t len;
240
241 if( ( ret = asn1_get_tag( p, end, &len,
242 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
243 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
244
245 if( *p + len != end )
246 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
247 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
248
249 if( ( ret = asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
250 ( ret = asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
251 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
252
253 if( *p != end )
254 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
255 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
256
257 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
258 return( ret );
259
260 rsa->len = mpi_size( &rsa->N );
261
262 return( 0 );
263}
264#endif /* POLARSSL_RSA_C */
265
266/* Get a PK algorithm identifier
267 *
268 * AlgorithmIdentifier ::= SEQUENCE {
269 * algorithm OBJECT IDENTIFIER,
270 * parameters ANY DEFINED BY algorithm OPTIONAL }
271 */
272static int pk_get_pk_alg( unsigned char **p,
273 const unsigned char *end,
274 pk_type_t *pk_alg, asn1_buf *params )
275{
276 int ret;
277 asn1_buf alg_oid;
278
279 memset( params, 0, sizeof(asn1_buf) );
280
281 if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
282 return( POLARSSL_ERR_PK_INVALID_ALG + ret );
283
284 if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
285 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
286
287 /*
288 * No parameters with RSA (only for EC)
289 */
290 if( *pk_alg == POLARSSL_PK_RSA &&
291 ( ( params->tag != ASN1_NULL && params->tag != 0 ) ||
292 params->len != 0 ) )
293 {
294 return( POLARSSL_ERR_PK_INVALID_ALG );
295 }
296
297 return( 0 );
298}
299
300/*
301 * SubjectPublicKeyInfo ::= SEQUENCE {
302 * algorithm AlgorithmIdentifier,
303 * subjectPublicKey BIT STRING }
304 */
305int pk_parse_get_pubkey( unsigned char **p, const unsigned char *end,
306 pk_context *pk )
307{
308 int ret;
309 size_t len;
310 asn1_buf alg_params;
311 pk_type_t pk_alg = POLARSSL_PK_NONE;
312 const pk_info_t *pk_info;
313
314 if( ( ret = asn1_get_tag( p, end, &len,
315 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
316 {
317 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
318 }
319
320 end = *p + len;
321
322 if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
323 return( ret );
324
325 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
326 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
327
328 if( *p + len != end )
329 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
330 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
331
332 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
333 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
334
335 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
336 return( ret );
337
338#if defined(POLARSSL_RSA_C)
339 if( pk_alg == POLARSSL_PK_RSA )
340 {
341 ret = pk_get_rsapubkey( p, end, pk_rsa( *pk ) );
342 } else
343#endif /* POLARSSL_RSA_C */
344#if defined(POLARSSL_ECP_C)
345 if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY )
346 {
347 ret = pk_use_ecparams( &alg_params, &pk_ec( *pk )->grp );
348 if( ret == 0 )
349 ret = pk_get_ecpubkey( p, end, pk_ec( *pk ) );
350 } else
351#endif /* POLARSSL_ECP_C */
352 ret = POLARSSL_ERR_PK_UNKNOWN_PK_ALG;
353
354 if( ret == 0 && *p != end )
355 ret = POLARSSL_ERR_PK_INVALID_PUBKEY
356 POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
357
358 if( ret != 0 )
359 pk_free( pk );
360
361 return( ret );
362}
363
364#if defined(POLARSSL_RSA_C)
365/*
366 * Parse a PKCS#1 encoded private RSA key
367 */
368static int pk_parse_key_pkcs1_der( rsa_context *rsa,
369 const unsigned char *key,
370 size_t keylen )
371{
372 int ret;
373 size_t len;
374 unsigned char *p, *end;
375
376 p = (unsigned char *) key;
377 end = p + keylen;
378
379 /*
380 * This function parses the RSAPrivateKey (PKCS#1)
381 *
382 * RSAPrivateKey ::= SEQUENCE {
383 * version Version,
384 * modulus INTEGER, -- n
385 * publicExponent INTEGER, -- e
386 * privateExponent INTEGER, -- d
387 * prime1 INTEGER, -- p
388 * prime2 INTEGER, -- q
389 * exponent1 INTEGER, -- d mod (p-1)
390 * exponent2 INTEGER, -- d mod (q-1)
391 * coefficient INTEGER, -- (inverse of q) mod p
392 * otherPrimeInfos OtherPrimeInfos OPTIONAL
393 * }
394 */
395 if( ( ret = asn1_get_tag( &p, end, &len,
396 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
397 {
398 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
399 }
400
401 end = p + len;
402
403 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
404 {
405 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
406 }
407
408 if( rsa->ver != 0 )
409 {
410 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
411 }
412
413 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
414 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
415 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
416 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
417 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
418 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
419 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
420 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
421 {
422 rsa_free( rsa );
423 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
424 }
425
426 rsa->len = mpi_size( &rsa->N );
427
428 if( p != end )
429 {
430 rsa_free( rsa );
431 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
432 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
433 }
434
435 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
436 {
437 rsa_free( rsa );
438 return( ret );
439 }
440
441 return( 0 );
442}
443#endif /* POLARSSL_RSA_C */
444
445#if defined(POLARSSL_ECP_C)
446/*
447 * Parse a SEC1 encoded private EC key
448 */
449static int pk_parse_key_sec1_der( ecp_keypair *eck,
450 const unsigned char *key,
451 size_t keylen )
452{
453 int ret;
454 int version;
455 size_t len;
456 asn1_buf params;
457 unsigned char *p = (unsigned char *) key;
458 unsigned char *end = p + keylen;
459 unsigned char *end2;
460
461 /*
462 * RFC 5915, or SEC1 Appendix C.4
463 *
464 * ECPrivateKey ::= SEQUENCE {
465 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
466 * privateKey OCTET STRING,
467 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
468 * publicKey [1] BIT STRING OPTIONAL
469 * }
470 */
471 if( ( ret = asn1_get_tag( &p, end, &len,
472 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
473 {
474 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
475 }
476
477 end = p + len;
478
479 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
480 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
481
482 if( version != 1 )
483 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
484
485 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
486 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
487
488 if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 )
489 {
490 ecp_keypair_free( eck );
491 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
492 }
493
494 p += len;
495
496 /*
497 * Is 'parameters' present?
498 */
499 if( ( ret = asn1_get_tag( &p, end, &len,
500 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
501 {
502 if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
503 ( ret = pk_use_ecparams( &params, &eck->grp ) ) != 0 )
504 {
505 ecp_keypair_free( eck );
506 return( ret );
507 }
508 }
509 else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
510 {
511 ecp_keypair_free( eck );
512 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
513 }
514
515 /*
516 * Is 'publickey' present?
517 */
518 if( ( ret = asn1_get_tag( &p, end, &len,
519 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
520 {
521 end2 = p + len;
522
523 if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
524 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
525
526 if( p + len != end2 )
527 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
528 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
529
530 if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) != 0 )
531 return( ret );
532 }
533 else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
534 {
535 ecp_keypair_free( eck );
536 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
537 }
538
539 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
540 {
541 ecp_keypair_free( eck );
542 return( ret );
543 }
544
545 return 0;
546}
547#endif /* POLARSSL_ECP_C */
548
549/*
550 * Parse an unencrypted PKCS#8 encoded private key
551 */
552static int pk_parse_key_pkcs8_unencrypted_der(
553 pk_context *pk,
554 const unsigned char* key,
555 size_t keylen )
556{
557 int ret, version;
558 size_t len;
559 asn1_buf params;
560 unsigned char *p = (unsigned char *) key;
561 unsigned char *end = p + keylen;
562 pk_type_t pk_alg = POLARSSL_PK_NONE;
563 const pk_info_t *pk_info;
564
565 /*
566 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
567 *
568 * PrivateKeyInfo ::= SEQUENCE {
569 * version Version,
570 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
571 * privateKey PrivateKey,
572 * attributes [0] IMPLICIT Attributes OPTIONAL }
573 *
574 * Version ::= INTEGER
575 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
576 * PrivateKey ::= OCTET STRING
577 *
578 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
579 */
580
581 if( ( ret = asn1_get_tag( &p, end, &len,
582 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
583 {
584 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
585 }
586
587 end = p + len;
588
589 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
590 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
591
592 if( version != 0 )
593 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION + ret );
594
595 if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
596 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
597
598 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
599 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
600
601 if( len < 1 )
602 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
603 POLARSSL_ERR_ASN1_OUT_OF_DATA );
604
605 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
606 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
607
608 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
609 return( ret );
610
611#if defined(POLARSSL_RSA_C)
612 if( pk_alg == POLARSSL_PK_RSA )
613 {
614 if( ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), p, len ) ) != 0 )
615 {
616 pk_free( pk );
617 return( ret );
618 }
619 } else
620#endif /* POLARSSL_RSA_C */
621#if defined(POLARSSL_ECP_C)
622 if( pk_alg == POLARSSL_PK_ECKEY || pk_alg == POLARSSL_PK_ECKEY_DH )
623 {
624 if( ( ret = pk_use_ecparams( &params, &pk_ec( *pk )->grp ) ) != 0 ||
625 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), p, len ) ) != 0 )
626 {
627 pk_free( pk );
628 return( ret );
629 }
630 } else
631#endif /* POLARSSL_ECP_C */
632 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
633
634 return 0;
635}
636
637/*
638 * Parse an encrypted PKCS#8 encoded private key
639 */
640static int pk_parse_key_pkcs8_encrypted_der(
641 pk_context *pk,
642 const unsigned char *key, size_t keylen,
643 const unsigned char *pwd, size_t pwdlen )
644{
645 int ret;
646 size_t len;
647 unsigned char buf[2048];
648 unsigned char *p, *end;
649 asn1_buf pbe_alg_oid, pbe_params;
650#if defined(POLARSSL_PKCS12_C)
651 cipher_type_t cipher_alg;
652 md_type_t md_alg;
653#endif
654
655 memset( buf, 0, sizeof( buf ) );
656
657 p = (unsigned char *) key;
658 end = p + keylen;
659
660 if( pwdlen == 0 )
661 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
662
663 /*
664 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
665 *
666 * EncryptedPrivateKeyInfo ::= SEQUENCE {
667 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
668 * encryptedData EncryptedData
669 * }
670 *
671 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
672 *
673 * EncryptedData ::= OCTET STRING
674 *
675 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
676 */
677 if( ( ret = asn1_get_tag( &p, end, &len,
678 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
679 {
680 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
681 }
682
683 end = p + len;
684
685 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
686 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
687
688 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
689 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
690
691 if( len > sizeof( buf ) )
692 return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
693
694 /*
695 * Decrypt EncryptedData with appropriate PDE
696 */
697#if defined(POLARSSL_PKCS12_C)
698 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
699 {
700 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
701 cipher_alg, md_alg,
702 pwd, pwdlen, p, len, buf ) ) != 0 )
703 {
704 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
705 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
706
707 return( ret );
708 }
709 }
710 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
711 {
712 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
713 PKCS12_PBE_DECRYPT,
714 pwd, pwdlen,
715 p, len, buf ) ) != 0 )
716 {
717 return( ret );
718 }
719
720 // Best guess for password mismatch when using RC4. If first tag is
721 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
722 //
723 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
724 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
725 }
726 else
727#endif /* POLARSSL_PKCS12_C */
728#if defined(POLARSSL_PKCS5_C)
729 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
730 {
731 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
732 p, len, buf ) ) != 0 )
733 {
734 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
735 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
736
737 return( ret );
738 }
739 }
740 else
741#endif /* POLARSSL_PKCS5_C */
742 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
743
744 return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
745}
746
747/*
748 * Parse a private key
749 */
750int pk_parse_key( pk_context *pk,
751 const unsigned char *key, size_t keylen,
752 const unsigned char *pwd, size_t pwdlen )
753{
754 int ret;
755 const pk_info_t *pk_info;
756
757#if defined(POLARSSL_PEM_C)
758 size_t len;
759 pem_context pem;
760
761 pem_init( &pem );
762
763#if defined(POLARSSL_RSA_C)
764 ret = pem_read_buffer( &pem,
765 "-----BEGIN RSA PRIVATE KEY-----",
766 "-----END RSA PRIVATE KEY-----",
767 key, pwd, pwdlen, &len );
768 if( ret == 0 )
769 {
770 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
771 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
772
773 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
774 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ),
775 pem.buf, pem.buflen ) ) != 0 )
776 {
777 pk_free( pk );
778 }
779
780 pem_free( &pem );
781 return( ret );
782 }
783 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
784 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
785 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
786 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
787 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
788 return( ret );
789#endif /* POLARSSL_RSA_C */
790
791#if defined(POLARSSL_ECP_C)
792 ret = pem_read_buffer( &pem,
793 "-----BEGIN EC PRIVATE KEY-----",
794 "-----END EC PRIVATE KEY-----",
795 key, pwd, pwdlen, &len );
796 if( ret == 0 )
797 {
798 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
799 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
800
801 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
802 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ),
803 pem.buf, pem.buflen ) ) != 0 )
804 {
805 pk_free( pk );
806 }
807
808 pem_free( &pem );
809 return( ret );
810 }
811 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
812 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
813 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
814 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
815 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
816 return( ret );
817#endif /* POLARSSL_ECP_C */
818
819 ret = pem_read_buffer( &pem,
820 "-----BEGIN PRIVATE KEY-----",
821 "-----END PRIVATE KEY-----",
822 key, NULL, 0, &len );
823 if( ret == 0 )
824 {
825 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
826 pem.buf, pem.buflen ) ) != 0 )
827 {
828 pk_free( pk );
829 }
830
831 pem_free( &pem );
832 return( ret );
833 }
834 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
835 return( ret );
836
837 ret = pem_read_buffer( &pem,
838 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
839 "-----END ENCRYPTED PRIVATE KEY-----",
840 key, NULL, 0, &len );
841 if( ret == 0 )
842 {
843 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
844 pem.buf, pem.buflen,
845 pwd, pwdlen ) ) != 0 )
846 {
847 pk_free( pk );
848 }
849
850 pem_free( &pem );
851 return( ret );
852 }
853 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
854 return( ret );
855#else
856 ((void) pwd);
857 ((void) pwdlen);
858#endif /* POLARSSL_PEM_C */
859
860 /*
861 * At this point we only know it's not a PEM formatted key. Could be any
862 * of the known DER encoded private key formats
863 *
864 * We try the different DER format parsers to see if one passes without
865 * error
866 */
867 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
868 pwd, pwdlen ) ) == 0 )
869 {
870 return( 0 );
871 }
872
873 pk_free( pk );
874
875 if( ret == POLARSSL_ERR_PK_PASSWORD_MISMATCH )
876 {
877 return( ret );
878 }
879
880 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
881 return( 0 );
882
883 pk_free( pk );
884
885#if defined(POLARSSL_RSA_C)
886 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
887 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
888
889 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
890 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), key, keylen ) ) == 0 )
891 {
892 return( 0 );
893 }
894
895 pk_free( pk );
896#endif /* POLARSSL_RSA_C */
897
898#if defined(POLARSSL_ECP_C)
899 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
900 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
901
902 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
903 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), key, keylen ) ) == 0 )
904 {
905 return( 0 );
906 }
907
908 pk_free( pk );
909#endif /* POLARSSL_ECP_C */
910
911 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
912}
913
914/*
915 * Parse a public key
916 */
917int pk_parse_public_key( pk_context *ctx,
918 const unsigned char *key, size_t keylen )
919{
920 int ret;
921 unsigned char *p;
922#if defined(POLARSSL_PEM_C)
923 size_t len;
924 pem_context pem;
925
926 pem_init( &pem );
927 ret = pem_read_buffer( &pem,
928 "-----BEGIN PUBLIC KEY-----",
929 "-----END PUBLIC KEY-----",
930 key, NULL, 0, &len );
931
932 if( ret == 0 )
933 {
934 /*
935 * Was PEM encoded
936 */
937 key = pem.buf;
938 keylen = pem.buflen;
939 }
940 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
941 {
942 pem_free( &pem );
943 return( ret );
944 }
945#endif
946 p = (unsigned char *) key;
947
948 ret = pk_parse_get_pubkey( &p, p + keylen, ctx );
949
950#if defined(POLARSSL_PEM_C)
951 pem_free( &pem );
952#endif
953
954 return( ret );
955}
956
Paul Bakker4606c732013-09-15 17:04:23 +0200957#endif /* POLARSSL_PK_PARSE_C */