blob: a5de20b9f5783d7f04e7e121fa3767beaa980658 [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
Paul Bakkercff68422013-09-15 20:43:33 +020043#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +020044#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 )
Manuel Pégourié-Gonnard387a2112013-09-18 18:54:01 +0200258 return( POLARSSL_ERR_PK_INVALID_PUBKEY );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200259
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 */
Paul Bakkerda771152013-09-16 22:45:03 +0200305int pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
306 pk_context *pk )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200307{
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 /*
Manuel Pégourié-Gonnardff29f9c2013-09-18 16:13:02 +0200516 * Is 'publickey' present? If not, create it from the private key.
Paul Bakker1a7550a2013-09-15 13:01:22 +0200517 */
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 }
Manuel Pégourié-Gonnardff29f9c2013-09-18 16:13:02 +0200538 else if( ( ret = ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
539 NULL, NULL ) ) != 0 )
540 {
541 ecp_keypair_free( eck );
542 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
543 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200544
545 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
546 {
547 ecp_keypair_free( eck );
548 return( ret );
549 }
550
551 return 0;
552}
553#endif /* POLARSSL_ECP_C */
554
555/*
556 * Parse an unencrypted PKCS#8 encoded private key
557 */
558static int pk_parse_key_pkcs8_unencrypted_der(
559 pk_context *pk,
560 const unsigned char* key,
561 size_t keylen )
562{
563 int ret, version;
564 size_t len;
565 asn1_buf params;
566 unsigned char *p = (unsigned char *) key;
567 unsigned char *end = p + keylen;
568 pk_type_t pk_alg = POLARSSL_PK_NONE;
569 const pk_info_t *pk_info;
570
571 /*
572 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
573 *
574 * PrivateKeyInfo ::= SEQUENCE {
575 * version Version,
576 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
577 * privateKey PrivateKey,
578 * attributes [0] IMPLICIT Attributes OPTIONAL }
579 *
580 * Version ::= INTEGER
581 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
582 * PrivateKey ::= OCTET STRING
583 *
584 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
585 */
586
587 if( ( ret = asn1_get_tag( &p, end, &len,
588 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
589 {
590 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
591 }
592
593 end = p + len;
594
595 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
596 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
597
598 if( version != 0 )
599 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION + ret );
600
601 if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
602 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
603
604 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
605 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
606
607 if( len < 1 )
608 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
609 POLARSSL_ERR_ASN1_OUT_OF_DATA );
610
611 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
612 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
613
614 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
615 return( ret );
616
617#if defined(POLARSSL_RSA_C)
618 if( pk_alg == POLARSSL_PK_RSA )
619 {
620 if( ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), p, len ) ) != 0 )
621 {
622 pk_free( pk );
623 return( ret );
624 }
625 } else
626#endif /* POLARSSL_RSA_C */
627#if defined(POLARSSL_ECP_C)
628 if( pk_alg == POLARSSL_PK_ECKEY || pk_alg == POLARSSL_PK_ECKEY_DH )
629 {
630 if( ( ret = pk_use_ecparams( &params, &pk_ec( *pk )->grp ) ) != 0 ||
631 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), p, len ) ) != 0 )
632 {
633 pk_free( pk );
634 return( ret );
635 }
636 } else
637#endif /* POLARSSL_ECP_C */
638 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
639
640 return 0;
641}
642
643/*
644 * Parse an encrypted PKCS#8 encoded private key
645 */
646static int pk_parse_key_pkcs8_encrypted_der(
647 pk_context *pk,
648 const unsigned char *key, size_t keylen,
649 const unsigned char *pwd, size_t pwdlen )
650{
651 int ret;
652 size_t len;
653 unsigned char buf[2048];
654 unsigned char *p, *end;
655 asn1_buf pbe_alg_oid, pbe_params;
656#if defined(POLARSSL_PKCS12_C)
657 cipher_type_t cipher_alg;
658 md_type_t md_alg;
659#endif
660
661 memset( buf, 0, sizeof( buf ) );
662
663 p = (unsigned char *) key;
664 end = p + keylen;
665
666 if( pwdlen == 0 )
667 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
668
669 /*
670 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
671 *
672 * EncryptedPrivateKeyInfo ::= SEQUENCE {
673 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
674 * encryptedData EncryptedData
675 * }
676 *
677 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
678 *
679 * EncryptedData ::= OCTET STRING
680 *
681 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
682 */
683 if( ( ret = asn1_get_tag( &p, end, &len,
684 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
685 {
686 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
687 }
688
689 end = p + len;
690
691 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
692 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
693
694 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
695 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
696
697 if( len > sizeof( buf ) )
698 return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
699
700 /*
701 * Decrypt EncryptedData with appropriate PDE
702 */
703#if defined(POLARSSL_PKCS12_C)
704 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
705 {
706 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
707 cipher_alg, md_alg,
708 pwd, pwdlen, p, len, buf ) ) != 0 )
709 {
710 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
711 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
712
713 return( ret );
714 }
715 }
716 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
717 {
718 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
719 PKCS12_PBE_DECRYPT,
720 pwd, pwdlen,
721 p, len, buf ) ) != 0 )
722 {
723 return( ret );
724 }
725
726 // Best guess for password mismatch when using RC4. If first tag is
727 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
728 //
729 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
730 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
731 }
732 else
733#endif /* POLARSSL_PKCS12_C */
734#if defined(POLARSSL_PKCS5_C)
735 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
736 {
737 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
738 p, len, buf ) ) != 0 )
739 {
740 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
741 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
742
743 return( ret );
744 }
745 }
746 else
747#endif /* POLARSSL_PKCS5_C */
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +0200748 {
749 ((void) pwd);
Paul Bakker1a7550a2013-09-15 13:01:22 +0200750 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +0200751 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200752
753 return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
754}
755
756/*
757 * Parse a private key
758 */
759int pk_parse_key( pk_context *pk,
760 const unsigned char *key, size_t keylen,
761 const unsigned char *pwd, size_t pwdlen )
762{
763 int ret;
764 const pk_info_t *pk_info;
765
Paul Bakkercff68422013-09-15 20:43:33 +0200766#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +0200767 size_t len;
768 pem_context pem;
769
770 pem_init( &pem );
771
772#if defined(POLARSSL_RSA_C)
773 ret = pem_read_buffer( &pem,
774 "-----BEGIN RSA PRIVATE KEY-----",
775 "-----END RSA PRIVATE KEY-----",
776 key, pwd, pwdlen, &len );
777 if( ret == 0 )
778 {
779 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
780 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
781
782 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
783 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ),
784 pem.buf, pem.buflen ) ) != 0 )
785 {
786 pk_free( pk );
787 }
788
789 pem_free( &pem );
790 return( ret );
791 }
792 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
793 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
794 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
795 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
796 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
797 return( ret );
798#endif /* POLARSSL_RSA_C */
799
800#if defined(POLARSSL_ECP_C)
801 ret = pem_read_buffer( &pem,
802 "-----BEGIN EC PRIVATE KEY-----",
803 "-----END EC PRIVATE KEY-----",
804 key, pwd, pwdlen, &len );
805 if( ret == 0 )
806 {
807 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
808 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
809
810 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
811 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ),
812 pem.buf, pem.buflen ) ) != 0 )
813 {
814 pk_free( pk );
815 }
816
817 pem_free( &pem );
818 return( ret );
819 }
820 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
821 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
822 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
823 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
824 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
825 return( ret );
826#endif /* POLARSSL_ECP_C */
827
828 ret = pem_read_buffer( &pem,
829 "-----BEGIN PRIVATE KEY-----",
830 "-----END PRIVATE KEY-----",
831 key, NULL, 0, &len );
832 if( ret == 0 )
833 {
834 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
835 pem.buf, pem.buflen ) ) != 0 )
836 {
837 pk_free( pk );
838 }
839
840 pem_free( &pem );
841 return( ret );
842 }
843 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
844 return( ret );
845
846 ret = pem_read_buffer( &pem,
847 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
848 "-----END ENCRYPTED PRIVATE KEY-----",
849 key, NULL, 0, &len );
850 if( ret == 0 )
851 {
852 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
853 pem.buf, pem.buflen,
854 pwd, pwdlen ) ) != 0 )
855 {
856 pk_free( pk );
857 }
858
859 pem_free( &pem );
860 return( ret );
861 }
862 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
863 return( ret );
864#else
865 ((void) pwd);
866 ((void) pwdlen);
Paul Bakkercff68422013-09-15 20:43:33 +0200867#endif /* POLARSSL_PEM_PARSE_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +0200868
869 /*
870 * At this point we only know it's not a PEM formatted key. Could be any
871 * of the known DER encoded private key formats
872 *
873 * We try the different DER format parsers to see if one passes without
874 * error
875 */
876 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
877 pwd, pwdlen ) ) == 0 )
878 {
879 return( 0 );
880 }
881
882 pk_free( pk );
883
884 if( ret == POLARSSL_ERR_PK_PASSWORD_MISMATCH )
885 {
886 return( ret );
887 }
888
889 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
890 return( 0 );
891
892 pk_free( pk );
893
894#if defined(POLARSSL_RSA_C)
895 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
896 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
897
898 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
899 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), key, keylen ) ) == 0 )
900 {
901 return( 0 );
902 }
903
904 pk_free( pk );
905#endif /* POLARSSL_RSA_C */
906
907#if defined(POLARSSL_ECP_C)
908 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
909 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
910
911 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
912 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), key, keylen ) ) == 0 )
913 {
914 return( 0 );
915 }
916
917 pk_free( pk );
918#endif /* POLARSSL_ECP_C */
919
920 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
921}
922
923/*
924 * Parse a public key
925 */
926int pk_parse_public_key( pk_context *ctx,
927 const unsigned char *key, size_t keylen )
928{
929 int ret;
930 unsigned char *p;
Paul Bakkercff68422013-09-15 20:43:33 +0200931#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +0200932 size_t len;
933 pem_context pem;
934
935 pem_init( &pem );
936 ret = pem_read_buffer( &pem,
937 "-----BEGIN PUBLIC KEY-----",
938 "-----END PUBLIC KEY-----",
939 key, NULL, 0, &len );
940
941 if( ret == 0 )
942 {
943 /*
944 * Was PEM encoded
945 */
946 key = pem.buf;
947 keylen = pem.buflen;
948 }
949 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
950 {
951 pem_free( &pem );
952 return( ret );
953 }
954#endif
955 p = (unsigned char *) key;
956
Paul Bakkerda771152013-09-16 22:45:03 +0200957 ret = pk_parse_subpubkey( &p, p + keylen, ctx );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200958
Paul Bakkercff68422013-09-15 20:43:33 +0200959#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +0200960 pem_free( &pem );
961#endif
962
963 return( ret );
964}
965
Paul Bakker4606c732013-09-15 17:04:23 +0200966#endif /* POLARSSL_PK_PARSE_C */