blob: 5786db7442adc7ae6bfa447ca0469e6878e8484d [file] [log] [blame]
Paul Bakker1a7550a2013-09-15 13:01:22 +02001/*
2 * Public Key layer for parsing key files and structures
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakker1a7550a2013-09-15 13:01:22 +02005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker1a7550a2013-09-15 13:01:22 +02007 *
Paul Bakker1a7550a2013-09-15 13:01:22 +02008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020023#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker1a7550a2013-09-15 13:01:22 +020024#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020025#else
26#include POLARSSL_CONFIG_FILE
27#endif
Paul Bakker1a7550a2013-09-15 13:01:22 +020028
Paul Bakker4606c732013-09-15 17:04:23 +020029#if defined(POLARSSL_PK_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +020030
31#include "polarssl/pk.h"
32#include "polarssl/asn1.h"
33#include "polarssl/oid.h"
34
Rich Evans00ab4702015-02-06 13:43:58 +000035#include <string.h>
36
Paul Bakker1a7550a2013-09-15 13:01:22 +020037#if defined(POLARSSL_RSA_C)
38#include "polarssl/rsa.h"
39#endif
40#if defined(POLARSSL_ECP_C)
41#include "polarssl/ecp.h"
42#endif
43#if defined(POLARSSL_ECDSA_C)
44#include "polarssl/ecdsa.h"
45#endif
Paul Bakkercff68422013-09-15 20:43:33 +020046#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +020047#include "polarssl/pem.h"
48#endif
49#if defined(POLARSSL_PKCS5_C)
50#include "polarssl/pkcs5.h"
51#endif
52#if defined(POLARSSL_PKCS12_C)
53#include "polarssl/pkcs12.h"
54#endif
55
Paul Bakker7dc4c442014-02-01 22:50:26 +010056#if defined(POLARSSL_PLATFORM_C)
57#include "polarssl/platform.h"
Paul Bakker1a7550a2013-09-15 13:01:22 +020058#else
59#include <stdlib.h>
60#define polarssl_malloc malloc
61#define polarssl_free free
62#endif
63
Gilles Peskinebb709d72017-11-30 11:57:26 +010064#if defined(POLARSSL_FS_IO) || \
65 defined(POLARSSL_PKCS12_C) || defined(POLARSSL_PKCS5_C)
Paul Bakker34617722014-06-13 17:20:13 +020066/* Implementation that should never be optimized out by the compiler */
67static void polarssl_zeroize( void *v, size_t n ) {
68 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
69}
Gilles Peskinebb709d72017-11-30 11:57:26 +010070#endif
Paul Bakker34617722014-06-13 17:20:13 +020071
Gilles Peskinebb709d72017-11-30 11:57:26 +010072#if defined(POLARSSL_FS_IO)
Paul Bakker1a7550a2013-09-15 13:01:22 +020073/*
74 * Load all data from a file into a given buffer.
75 */
Manuel Pégourié-Gonnard9439f932014-11-21 09:49:43 +010076int pk_load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker1a7550a2013-09-15 13:01:22 +020077{
78 FILE *f;
79 long size;
80
81 if( ( f = fopen( path, "rb" ) ) == NULL )
82 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
83
84 fseek( f, 0, SEEK_END );
85 if( ( size = ftell( f ) ) == -1 )
86 {
87 fclose( f );
88 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
89 }
90 fseek( f, 0, SEEK_SET );
91
92 *n = (size_t) size;
93
94 if( *n + 1 == 0 ||
Mansour Moufidc531b4a2015-02-15 17:35:38 -050095 ( *buf = polarssl_malloc( *n + 1 ) ) == NULL )
Paul Bakker1a7550a2013-09-15 13:01:22 +020096 {
97 fclose( f );
98 return( POLARSSL_ERR_PK_MALLOC_FAILED );
99 }
100
101 if( fread( *buf, 1, *n, f ) != *n )
102 {
103 fclose( f );
104 polarssl_free( *buf );
105 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
106 }
107
108 fclose( f );
109
110 (*buf)[*n] = '\0';
111
112 return( 0 );
113}
114
115/*
116 * Load and parse a private key
117 */
118int pk_parse_keyfile( pk_context *ctx,
119 const char *path, const char *pwd )
120{
121 int ret;
122 size_t n;
123 unsigned char *buf;
124
Manuel Pégourié-Gonnard9439f932014-11-21 09:49:43 +0100125 if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200126 return( ret );
127
128 if( pwd == NULL )
129 ret = pk_parse_key( ctx, buf, n, NULL, 0 );
130 else
131 ret = pk_parse_key( ctx, buf, n,
132 (const unsigned char *) pwd, strlen( pwd ) );
133
Paul Bakker34617722014-06-13 17:20:13 +0200134 polarssl_zeroize( buf, n + 1 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200135 polarssl_free( buf );
136
137 return( ret );
138}
139
140/*
141 * Load and parse a public key
142 */
143int pk_parse_public_keyfile( pk_context *ctx, const char *path )
144{
145 int ret;
146 size_t n;
147 unsigned char *buf;
148
Manuel Pégourié-Gonnard9439f932014-11-21 09:49:43 +0100149 if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200150 return( ret );
151
152 ret = pk_parse_public_key( ctx, buf, n );
153
Paul Bakker34617722014-06-13 17:20:13 +0200154 polarssl_zeroize( buf, n + 1 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200155 polarssl_free( buf );
156
157 return( ret );
158}
159#endif /* POLARSSL_FS_IO */
160
161#if defined(POLARSSL_ECP_C)
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100162/* Minimally parse an ECParameters buffer to and asn1_buf
Paul Bakker1a7550a2013-09-15 13:01:22 +0200163 *
164 * ECParameters ::= CHOICE {
165 * namedCurve OBJECT IDENTIFIER
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100166 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200167 * -- implicitCurve NULL
Paul Bakker1a7550a2013-09-15 13:01:22 +0200168 * }
169 */
170static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
171 asn1_buf *params )
172{
173 int ret;
174
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100175 /* Tag may be either OID or SEQUENCE */
Paul Bakker1a7550a2013-09-15 13:01:22 +0200176 params->tag = **p;
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100177 if( params->tag != ASN1_OID
178#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
179 && params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE )
180#endif
181 )
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100182 {
183 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
184 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
185 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200186
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100187 if( ( ret = asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
188 {
Paul Bakker1a7550a2013-09-15 13:01:22 +0200189 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100190 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200191
192 params->p = *p;
193 *p += params->len;
194
195 if( *p != end )
196 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
197 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
198
199 return( 0 );
200}
201
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100202#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
Paul Bakker1a7550a2013-09-15 13:01:22 +0200203/*
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100204 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
205 * WARNING: the resulting group should only be used with
206 * pk_group_id_from_specified(), since its base point may not be set correctly
207 * if it was encoded compressed.
208 *
209 * SpecifiedECDomain ::= SEQUENCE {
210 * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
211 * fieldID FieldID {{FieldTypes}},
212 * curve Curve,
213 * base ECPoint,
214 * order INTEGER,
215 * cofactor INTEGER OPTIONAL,
216 * hash HashAlgorithm OPTIONAL,
217 * ...
218 * }
219 *
220 * We only support prime-field as field type, and ignore hash and cofactor.
221 */
222static int pk_group_from_specified( const asn1_buf *params, ecp_group *grp )
223{
224 int ret;
225 unsigned char *p = params->p;
226 const unsigned char * const end = params->p + params->len;
227 const unsigned char *end_field, *end_curve;
228 size_t len;
229 int ver;
230
231 /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
232 if( ( ret = asn1_get_int( &p, end, &ver ) ) != 0 )
233 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
234
235 if( ver < 1 || ver > 3 )
236 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
237
238 /*
239 * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
240 * fieldType FIELD-ID.&id({IOSet}),
241 * parameters FIELD-ID.&Type({IOSet}{@fieldType})
242 * }
243 */
244 if( ( ret = asn1_get_tag( &p, end, &len,
245 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
246 return( ret );
247
248 end_field = p + len;
249
250 /*
251 * FIELD-ID ::= TYPE-IDENTIFIER
252 * FieldTypes FIELD-ID ::= {
253 * { Prime-p IDENTIFIED BY prime-field } |
254 * { Characteristic-two IDENTIFIED BY characteristic-two-field }
255 * }
256 * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
257 */
258 if( ( ret = asn1_get_tag( &p, end_field, &len, ASN1_OID ) ) != 0 )
259 return( ret );
260
261 if( len != OID_SIZE( OID_ANSI_X9_62_PRIME_FIELD ) ||
262 memcmp( p, OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
263 {
264 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
265 }
266
267 p += len;
268
269 /* Prime-p ::= INTEGER -- Field of size p. */
270 if( ( ret = asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
271 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
272
273 grp->pbits = mpi_msb( &grp->P );
274
275 if( p != end_field )
276 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
277 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
278
279 /*
280 * Curve ::= SEQUENCE {
281 * a FieldElement,
282 * b FieldElement,
283 * seed BIT STRING OPTIONAL
284 * -- Shall be present if used in SpecifiedECDomain
285 * -- with version equal to ecdpVer2 or ecdpVer3
286 * }
287 */
288 if( ( ret = asn1_get_tag( &p, end, &len,
289 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
290 return( ret );
291
292 end_curve = p + len;
293
294 /*
295 * FieldElement ::= OCTET STRING
296 * containing an integer in the case of a prime field
297 */
298 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
299 ( ret = mpi_read_binary( &grp->A, p, len ) ) != 0 )
300 {
301 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
302 }
303
304 p += len;
305
306 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
307 ( ret = mpi_read_binary( &grp->B, p, len ) ) != 0 )
308 {
309 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
310 }
311
312 p += len;
313
314 /* Ignore seed BIT STRING OPTIONAL */
315 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_BIT_STRING ) ) == 0 )
316 p += len;
317
318 if( p != end_curve )
319 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
320 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
321
322 /*
323 * ECPoint ::= OCTET STRING
324 */
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100325 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100326 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
327
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100328 if( ( ret = ecp_point_read_binary( grp, &grp->G,
329 ( const unsigned char *) p, len ) ) != 0 )
330 {
331 /*
332 * If we can't read the point because it's compressed, cheat by
333 * reading only the X coordinate and the parity bit of Y.
334 */
335 if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ||
336 ( p[0] != 0x02 && p[0] != 0x03 ) ||
337 len != mpi_size( &grp->P ) + 1 ||
338 mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
339 mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
340 mpi_lset( &grp->G.Z, 1 ) != 0 )
341 {
342 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
343 }
344 }
345
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100346 p += len;
347
348 /*
349 * order INTEGER
350 */
Manuel Pégourié-Gonnard7f849052015-02-10 17:12:44 +0100351 if( ( ret = asn1_get_mpi( &p, end, &grp->N ) ) != 0 )
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100352 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
353
354 grp->nbits = mpi_msb( &grp->N );
355
356 /*
357 * Allow optional elements by purposefully not enforcing p == end here.
358 */
359
360 return( 0 );
361}
362
363/*
364 * Find the group id associated with an (almost filled) group as generated by
365 * pk_group_from_specified(), or return an error if unknown.
366 */
367static int pk_group_id_from_group( const ecp_group *grp, ecp_group_id *grp_id )
368{
Manuel Pégourié-Gonnard5b8c4092014-03-27 14:59:42 +0100369 int ret = 0;
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100370 ecp_group ref;
371 const ecp_group_id *id;
372
373 ecp_group_init( &ref );
374
375 for( id = ecp_grp_id_list(); *id != POLARSSL_ECP_DP_NONE; id++ )
376 {
377 /* Load the group associated to that id */
378 ecp_group_free( &ref );
379 MPI_CHK( ecp_use_known_dp( &ref, *id ) );
380
381 /* Compare to the group we were given, starting with easy tests */
382 if( grp->pbits == ref.pbits && grp->nbits == ref.nbits &&
383 mpi_cmp_mpi( &grp->P, &ref.P ) == 0 &&
384 mpi_cmp_mpi( &grp->A, &ref.A ) == 0 &&
385 mpi_cmp_mpi( &grp->B, &ref.B ) == 0 &&
386 mpi_cmp_mpi( &grp->N, &ref.N ) == 0 &&
387 mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 &&
388 mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 &&
389 /* For Y we may only know the parity bit, so compare only that */
390 mpi_get_bit( &grp->G.Y, 0 ) == mpi_get_bit( &ref.G.Y, 0 ) )
391 {
392 break;
393 }
394
395 }
396
397cleanup:
398 ecp_group_free( &ref );
399
400 *grp_id = *id;
401
402 if( ret == 0 && *id == POLARSSL_ECP_DP_NONE )
403 ret = POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE;
404
405 return( ret );
406}
407
408/*
409 * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
410 */
411static int pk_group_id_from_specified( const asn1_buf *params,
412 ecp_group_id *grp_id )
413{
414 int ret;
415 ecp_group grp;
416
417 ecp_group_init( &grp );
418
419 if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 )
420 goto cleanup;
421
422 ret = pk_group_id_from_group( &grp, grp_id );
423
424cleanup:
425 ecp_group_free( &grp );
426
427 return( ret );
428}
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100429#endif /* POLARSSL_PK_PARSE_EC_EXTENDED */
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100430
431/*
Paul Bakker1a7550a2013-09-15 13:01:22 +0200432 * Use EC parameters to initialise an EC group
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100433 *
434 * ECParameters ::= CHOICE {
435 * namedCurve OBJECT IDENTIFIER
436 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
437 * -- implicitCurve NULL
Paul Bakker1a7550a2013-09-15 13:01:22 +0200438 */
439static int pk_use_ecparams( const asn1_buf *params, ecp_group *grp )
440{
441 int ret;
442 ecp_group_id grp_id;
443
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100444 if( params->tag == ASN1_OID )
445 {
446 if( oid_get_ec_grp( params, &grp_id ) != 0 )
447 return( POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE );
448 }
449 else
450 {
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100451#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100452 if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 )
453 return( ret );
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100454#else
455 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
456#endif
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100457 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200458
459 /*
460 * grp may already be initilialized; if so, make sure IDs match
461 */
462 if( grp->id != POLARSSL_ECP_DP_NONE && grp->id != grp_id )
463 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
464
465 if( ( ret = ecp_use_known_dp( grp, grp_id ) ) != 0 )
466 return( ret );
467
468 return( 0 );
469}
470
471/*
472 * EC public key is an EC point
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100473 *
474 * The caller is responsible for clearing the structure upon failure if
475 * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
476 * return code of ecp_point_read_binary() and leave p in a usable state.
Paul Bakker1a7550a2013-09-15 13:01:22 +0200477 */
478static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
479 ecp_keypair *key )
480{
481 int ret;
482
483 if( ( ret = ecp_point_read_binary( &key->grp, &key->Q,
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100484 (const unsigned char *) *p, end - *p ) ) == 0 )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200485 {
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100486 ret = ecp_check_pubkey( &key->grp, &key->Q );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200487 }
488
489 /*
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100490 * We know ecp_point_read_binary consumed all bytes or failed
Paul Bakker1a7550a2013-09-15 13:01:22 +0200491 */
492 *p = (unsigned char *) end;
493
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100494 return( ret );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200495}
496#endif /* POLARSSL_ECP_C */
497
498#if defined(POLARSSL_RSA_C)
499/*
500 * RSAPublicKey ::= SEQUENCE {
501 * modulus INTEGER, -- n
502 * publicExponent INTEGER -- e
503 * }
504 */
505static int pk_get_rsapubkey( unsigned char **p,
506 const unsigned char *end,
507 rsa_context *rsa )
508{
509 int ret;
510 size_t len;
511
512 if( ( ret = asn1_get_tag( p, end, &len,
513 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
514 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
515
516 if( *p + len != end )
517 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
518 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
519
520 if( ( ret = asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
521 ( ret = asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
522 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
523
524 if( *p != end )
525 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
526 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
527
528 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
Manuel Pégourié-Gonnard387a2112013-09-18 18:54:01 +0200529 return( POLARSSL_ERR_PK_INVALID_PUBKEY );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200530
531 rsa->len = mpi_size( &rsa->N );
532
533 return( 0 );
534}
535#endif /* POLARSSL_RSA_C */
536
537/* Get a PK algorithm identifier
538 *
539 * AlgorithmIdentifier ::= SEQUENCE {
540 * algorithm OBJECT IDENTIFIER,
541 * parameters ANY DEFINED BY algorithm OPTIONAL }
542 */
543static int pk_get_pk_alg( unsigned char **p,
544 const unsigned char *end,
545 pk_type_t *pk_alg, asn1_buf *params )
546{
547 int ret;
548 asn1_buf alg_oid;
549
550 memset( params, 0, sizeof(asn1_buf) );
551
552 if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
553 return( POLARSSL_ERR_PK_INVALID_ALG + ret );
554
555 if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
556 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
557
558 /*
559 * No parameters with RSA (only for EC)
560 */
561 if( *pk_alg == POLARSSL_PK_RSA &&
562 ( ( params->tag != ASN1_NULL && params->tag != 0 ) ||
563 params->len != 0 ) )
564 {
565 return( POLARSSL_ERR_PK_INVALID_ALG );
566 }
567
568 return( 0 );
569}
570
571/*
572 * SubjectPublicKeyInfo ::= SEQUENCE {
573 * algorithm AlgorithmIdentifier,
574 * subjectPublicKey BIT STRING }
575 */
Paul Bakkerda771152013-09-16 22:45:03 +0200576int pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
577 pk_context *pk )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200578{
579 int ret;
580 size_t len;
581 asn1_buf alg_params;
582 pk_type_t pk_alg = POLARSSL_PK_NONE;
583 const pk_info_t *pk_info;
584
585 if( ( ret = asn1_get_tag( p, end, &len,
586 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
587 {
588 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
589 }
590
591 end = *p + len;
592
593 if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
594 return( ret );
595
596 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
597 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
598
599 if( *p + len != end )
600 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
601 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
602
603 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
604 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
605
606 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
607 return( ret );
608
609#if defined(POLARSSL_RSA_C)
610 if( pk_alg == POLARSSL_PK_RSA )
611 {
612 ret = pk_get_rsapubkey( p, end, pk_rsa( *pk ) );
613 } else
614#endif /* POLARSSL_RSA_C */
615#if defined(POLARSSL_ECP_C)
616 if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY )
617 {
618 ret = pk_use_ecparams( &alg_params, &pk_ec( *pk )->grp );
619 if( ret == 0 )
620 ret = pk_get_ecpubkey( p, end, pk_ec( *pk ) );
621 } else
622#endif /* POLARSSL_ECP_C */
623 ret = POLARSSL_ERR_PK_UNKNOWN_PK_ALG;
624
625 if( ret == 0 && *p != end )
626 ret = POLARSSL_ERR_PK_INVALID_PUBKEY
627 POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
628
629 if( ret != 0 )
630 pk_free( pk );
631
632 return( ret );
633}
634
635#if defined(POLARSSL_RSA_C)
636/*
637 * Parse a PKCS#1 encoded private RSA key
638 */
639static int pk_parse_key_pkcs1_der( rsa_context *rsa,
640 const unsigned char *key,
641 size_t keylen )
642{
643 int ret;
644 size_t len;
645 unsigned char *p, *end;
646
647 p = (unsigned char *) key;
648 end = p + keylen;
649
650 /*
651 * This function parses the RSAPrivateKey (PKCS#1)
652 *
653 * RSAPrivateKey ::= SEQUENCE {
654 * version Version,
655 * modulus INTEGER, -- n
656 * publicExponent INTEGER, -- e
657 * privateExponent INTEGER, -- d
658 * prime1 INTEGER, -- p
659 * prime2 INTEGER, -- q
660 * exponent1 INTEGER, -- d mod (p-1)
661 * exponent2 INTEGER, -- d mod (q-1)
662 * coefficient INTEGER, -- (inverse of q) mod p
663 * otherPrimeInfos OtherPrimeInfos OPTIONAL
664 * }
665 */
666 if( ( ret = asn1_get_tag( &p, end, &len,
667 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
668 {
669 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
670 }
671
672 end = p + len;
673
674 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
675 {
676 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
677 }
678
679 if( rsa->ver != 0 )
680 {
681 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
682 }
683
684 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
685 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
686 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
687 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
688 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
689 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
690 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
691 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
692 {
693 rsa_free( rsa );
694 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
695 }
696
697 rsa->len = mpi_size( &rsa->N );
698
699 if( p != end )
700 {
701 rsa_free( rsa );
702 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
703 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
704 }
705
706 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
707 {
708 rsa_free( rsa );
709 return( ret );
710 }
711
712 return( 0 );
713}
714#endif /* POLARSSL_RSA_C */
715
716#if defined(POLARSSL_ECP_C)
717/*
718 * Parse a SEC1 encoded private EC key
719 */
720static int pk_parse_key_sec1_der( ecp_keypair *eck,
721 const unsigned char *key,
722 size_t keylen )
723{
724 int ret;
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100725 int version, pubkey_done;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200726 size_t len;
727 asn1_buf params;
728 unsigned char *p = (unsigned char *) key;
729 unsigned char *end = p + keylen;
730 unsigned char *end2;
731
732 /*
733 * RFC 5915, or SEC1 Appendix C.4
734 *
735 * ECPrivateKey ::= SEQUENCE {
736 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
737 * privateKey OCTET STRING,
738 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
739 * publicKey [1] BIT STRING OPTIONAL
740 * }
741 */
742 if( ( ret = asn1_get_tag( &p, end, &len,
743 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
744 {
745 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
746 }
747
748 end = p + len;
749
750 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
751 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
752
753 if( version != 1 )
754 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
755
756 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
757 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
758
759 if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 )
760 {
761 ecp_keypair_free( eck );
762 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
763 }
764
765 p += len;
766
Manuel Pégourié-Gonnarde6c83662015-04-14 11:18:04 +0200767 pubkey_done = 0;
768 if( p != end )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200769 {
Manuel Pégourié-Gonnarde6c83662015-04-14 11:18:04 +0200770 /*
771 * Is 'parameters' present?
772 */
773 if( ( ret = asn1_get_tag( &p, end, &len,
774 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
775 {
776 if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
777 ( ret = pk_use_ecparams( &params, &eck->grp ) ) != 0 )
778 {
779 ecp_keypair_free( eck );
780 return( ret );
781 }
782 }
783 else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200784 {
785 ecp_keypair_free( eck );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200786 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100787 }
Manuel Pégourié-Gonnarde6c83662015-04-14 11:18:04 +0200788
789 /*
790 * Is 'publickey' present? If not, or if we can't read it (eg because it
791 * is compressed), create it from the private key.
792 */
793 if( ( ret = asn1_get_tag( &p, end, &len,
794 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
795 {
796 end2 = p + len;
797
798 if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
799 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
800
801 if( p + len != end2 )
802 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
803 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
804
805 if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
806 pubkey_done = 1;
807 else
808 {
809 /*
810 * The only acceptable failure mode of pk_get_ecpubkey() above
811 * is if the point format is not recognized.
812 */
813 if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE )
814 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
815 }
816 }
817 else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
818 {
819 ecp_keypair_free( eck );
820 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
821 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200822 }
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100823
824 if( ! pubkey_done &&
825 ( ret = ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
826 NULL, NULL ) ) != 0 )
Manuel Pégourié-Gonnardff29f9c2013-09-18 16:13:02 +0200827 {
828 ecp_keypair_free( eck );
829 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
830 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200831
832 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
833 {
834 ecp_keypair_free( eck );
835 return( ret );
836 }
837
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200838 return( 0 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200839}
840#endif /* POLARSSL_ECP_C */
841
842/*
843 * Parse an unencrypted PKCS#8 encoded private key
844 */
845static int pk_parse_key_pkcs8_unencrypted_der(
846 pk_context *pk,
847 const unsigned char* key,
848 size_t keylen )
849{
850 int ret, version;
851 size_t len;
852 asn1_buf params;
853 unsigned char *p = (unsigned char *) key;
854 unsigned char *end = p + keylen;
855 pk_type_t pk_alg = POLARSSL_PK_NONE;
856 const pk_info_t *pk_info;
857
858 /*
859 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
860 *
861 * PrivateKeyInfo ::= SEQUENCE {
862 * version Version,
863 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
864 * privateKey PrivateKey,
865 * attributes [0] IMPLICIT Attributes OPTIONAL }
866 *
867 * Version ::= INTEGER
868 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
869 * PrivateKey ::= OCTET STRING
870 *
871 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
872 */
873
874 if( ( ret = asn1_get_tag( &p, end, &len,
875 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
876 {
877 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
878 }
879
880 end = p + len;
881
882 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
883 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
884
885 if( version != 0 )
886 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION + ret );
887
888 if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
889 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
890
891 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
892 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
893
894 if( len < 1 )
895 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
896 POLARSSL_ERR_ASN1_OUT_OF_DATA );
897
898 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
899 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
900
901 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
902 return( ret );
903
904#if defined(POLARSSL_RSA_C)
905 if( pk_alg == POLARSSL_PK_RSA )
906 {
907 if( ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), p, len ) ) != 0 )
908 {
909 pk_free( pk );
910 return( ret );
911 }
912 } else
913#endif /* POLARSSL_RSA_C */
914#if defined(POLARSSL_ECP_C)
915 if( pk_alg == POLARSSL_PK_ECKEY || pk_alg == POLARSSL_PK_ECKEY_DH )
916 {
917 if( ( ret = pk_use_ecparams( &params, &pk_ec( *pk )->grp ) ) != 0 ||
918 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), p, len ) ) != 0 )
919 {
920 pk_free( pk );
921 return( ret );
922 }
923 } else
924#endif /* POLARSSL_ECP_C */
925 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
926
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200927 return( 0 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200928}
929
930/*
931 * Parse an encrypted PKCS#8 encoded private key
932 */
Manuel Pégourié-Gonnarda2424a02014-12-01 18:04:58 +0100933#if defined(POLARSSL_PKCS12_C) || defined(POLARSSL_PKCS5_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +0200934static int pk_parse_key_pkcs8_encrypted_der(
935 pk_context *pk,
Hanno Becker713c9e12017-09-28 16:46:24 +0100936 unsigned char *key, size_t keylen,
Paul Bakker1a7550a2013-09-15 13:01:22 +0200937 const unsigned char *pwd, size_t pwdlen )
938{
Paul Bakkerf4cf80b2014-04-17 17:19:56 +0200939 int ret, decrypted = 0;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200940 size_t len;
Hanno Becker713c9e12017-09-28 16:46:24 +0100941 unsigned char *buf;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200942 unsigned char *p, *end;
943 asn1_buf pbe_alg_oid, pbe_params;
944#if defined(POLARSSL_PKCS12_C)
945 cipher_type_t cipher_alg;
946 md_type_t md_alg;
947#endif
948
Hanno Becker1f30fa12017-09-28 16:48:26 +0100949 p = key;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200950 end = p + keylen;
951
952 if( pwdlen == 0 )
953 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
954
955 /*
956 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
957 *
958 * EncryptedPrivateKeyInfo ::= SEQUENCE {
959 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
960 * encryptedData EncryptedData
961 * }
962 *
963 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
964 *
965 * EncryptedData ::= OCTET STRING
966 *
967 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
968 */
969 if( ( ret = asn1_get_tag( &p, end, &len,
970 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
971 {
972 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
973 }
974
975 end = p + len;
976
977 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
978 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
979
980 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
981 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
982
Hanno Becker713c9e12017-09-28 16:46:24 +0100983 buf = p;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200984
985 /*
986 * Decrypt EncryptedData with appropriate PDE
987 */
988#if defined(POLARSSL_PKCS12_C)
989 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
990 {
991 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
992 cipher_alg, md_alg,
993 pwd, pwdlen, p, len, buf ) ) != 0 )
994 {
995 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
996 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
997
998 return( ret );
999 }
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001000
1001 decrypted = 1;
Paul Bakker1a7550a2013-09-15 13:01:22 +02001002 }
1003 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
1004 {
1005 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
1006 PKCS12_PBE_DECRYPT,
1007 pwd, pwdlen,
1008 p, len, buf ) ) != 0 )
1009 {
1010 return( ret );
1011 }
1012
1013 // Best guess for password mismatch when using RC4. If first tag is
1014 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
1015 //
1016 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
1017 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001018
1019 decrypted = 1;
Paul Bakker1a7550a2013-09-15 13:01:22 +02001020 }
1021 else
1022#endif /* POLARSSL_PKCS12_C */
1023#if defined(POLARSSL_PKCS5_C)
1024 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
1025 {
1026 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
1027 p, len, buf ) ) != 0 )
1028 {
1029 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
1030 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
1031
1032 return( ret );
1033 }
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001034
1035 decrypted = 1;
Paul Bakker1a7550a2013-09-15 13:01:22 +02001036 }
1037 else
1038#endif /* POLARSSL_PKCS5_C */
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001039 {
1040 ((void) pwd);
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001041 }
Paul Bakker1a7550a2013-09-15 13:01:22 +02001042
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001043 if( decrypted == 0 )
1044 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
1045
Paul Bakker1a7550a2013-09-15 13:01:22 +02001046 return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
1047}
Manuel Pégourié-Gonnarda2424a02014-12-01 18:04:58 +01001048#endif /* POLARSSL_PKCS12_C || POLARSSL_PKCS5_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001049
1050/*
1051 * Parse a private key
1052 */
1053int pk_parse_key( pk_context *pk,
1054 const unsigned char *key, size_t keylen,
1055 const unsigned char *pwd, size_t pwdlen )
1056{
1057 int ret;
1058 const pk_info_t *pk_info;
1059
Paul Bakkercff68422013-09-15 20:43:33 +02001060#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001061 size_t len;
1062 pem_context pem;
1063
1064 pem_init( &pem );
1065
1066#if defined(POLARSSL_RSA_C)
1067 ret = pem_read_buffer( &pem,
1068 "-----BEGIN RSA PRIVATE KEY-----",
1069 "-----END RSA PRIVATE KEY-----",
1070 key, pwd, pwdlen, &len );
1071 if( ret == 0 )
1072 {
Hanno Becker1d233392017-09-28 16:49:40 +01001073 pk_info = pk_info_from_type( POLARSSL_PK_RSA );
Hanno Becker713c9e12017-09-28 16:46:24 +01001074 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
Paul Bakker1a7550a2013-09-15 13:01:22 +02001075 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ),
1076 pem.buf, pem.buflen ) ) != 0 )
1077 {
1078 pk_free( pk );
1079 }
1080
1081 pem_free( &pem );
1082 return( ret );
1083 }
1084 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
1085 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
1086 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
1087 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
1088 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1089 return( ret );
1090#endif /* POLARSSL_RSA_C */
1091
1092#if defined(POLARSSL_ECP_C)
1093 ret = pem_read_buffer( &pem,
1094 "-----BEGIN EC PRIVATE KEY-----",
1095 "-----END EC PRIVATE KEY-----",
1096 key, pwd, pwdlen, &len );
1097 if( ret == 0 )
1098 {
Hanno Becker1d233392017-09-28 16:49:40 +01001099 pk_info = pk_info_from_type( POLARSSL_PK_ECKEY );
Hanno Becker713c9e12017-09-28 16:46:24 +01001100 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
Paul Bakker1a7550a2013-09-15 13:01:22 +02001101 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ),
1102 pem.buf, pem.buflen ) ) != 0 )
1103 {
1104 pk_free( pk );
1105 }
1106
1107 pem_free( &pem );
1108 return( ret );
1109 }
1110 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
1111 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
1112 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
1113 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
1114 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1115 return( ret );
1116#endif /* POLARSSL_ECP_C */
1117
1118 ret = pem_read_buffer( &pem,
1119 "-----BEGIN PRIVATE KEY-----",
1120 "-----END PRIVATE KEY-----",
1121 key, NULL, 0, &len );
1122 if( ret == 0 )
1123 {
1124 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
1125 pem.buf, pem.buflen ) ) != 0 )
1126 {
1127 pk_free( pk );
1128 }
1129
1130 pem_free( &pem );
1131 return( ret );
1132 }
1133 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1134 return( ret );
1135
Manuel Pégourié-Gonnarda2424a02014-12-01 18:04:58 +01001136#if defined(POLARSSL_PKCS12_C) || defined(POLARSSL_PKCS5_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001137 ret = pem_read_buffer( &pem,
1138 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
1139 "-----END ENCRYPTED PRIVATE KEY-----",
1140 key, NULL, 0, &len );
1141 if( ret == 0 )
1142 {
1143 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
1144 pem.buf, pem.buflen,
1145 pwd, pwdlen ) ) != 0 )
1146 {
1147 pk_free( pk );
1148 }
1149
1150 pem_free( &pem );
1151 return( ret );
1152 }
1153 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1154 return( ret );
Manuel Pégourié-Gonnarda2424a02014-12-01 18:04:58 +01001155#endif /* POLARSSL_PKCS12_C || POLARSSL_PKCS5_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001156#else
1157 ((void) pwd);
1158 ((void) pwdlen);
Paul Bakkercff68422013-09-15 20:43:33 +02001159#endif /* POLARSSL_PEM_PARSE_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001160
1161 /*
1162 * At this point we only know it's not a PEM formatted key. Could be any
1163 * of the known DER encoded private key formats
1164 *
1165 * We try the different DER format parsers to see if one passes without
1166 * error
1167 */
Manuel Pégourié-Gonnarda2424a02014-12-01 18:04:58 +01001168#if defined(POLARSSL_PKCS12_C) || defined(POLARSSL_PKCS5_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001169 {
Hanno Becker713c9e12017-09-28 16:46:24 +01001170 unsigned char *key_copy;
1171
1172 if( ( key_copy = polarssl_malloc( keylen ) ) == NULL )
1173 return( POLARSSL_ERR_PK_MALLOC_FAILED );
1174
1175 memcpy( key_copy, key, keylen );
1176
1177 ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
1178 pwd, pwdlen );
1179
1180 polarssl_zeroize( key_copy, keylen );
1181 polarssl_free( key_copy );
Paul Bakker1a7550a2013-09-15 13:01:22 +02001182 }
1183
Hanno Becker713c9e12017-09-28 16:46:24 +01001184 if( ret == 0 )
1185 return( 0 );
1186
Paul Bakker1a7550a2013-09-15 13:01:22 +02001187 pk_free( pk );
1188
1189 if( ret == POLARSSL_ERR_PK_PASSWORD_MISMATCH )
1190 {
1191 return( ret );
1192 }
Manuel Pégourié-Gonnarda2424a02014-12-01 18:04:58 +01001193#endif /* POLARSSL_PKCS12_C || POLARSSL_PKCS5_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001194
1195 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
1196 return( 0 );
1197
1198 pk_free( pk );
1199
1200#if defined(POLARSSL_RSA_C)
Hanno Becker20f4c782017-09-28 16:52:51 +01001201 pk_info = pk_info_from_type( POLARSSL_PK_RSA );
Hanno Becker713c9e12017-09-28 16:46:24 +01001202 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
Hanno Becker20f4c782017-09-28 16:52:51 +01001203 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), key, keylen ) ) != 0 )
1204 {
1205 pk_free( pk );
1206 }
1207 else
Paul Bakker1a7550a2013-09-15 13:01:22 +02001208 {
1209 return( 0 );
1210 }
Paul Bakker1a7550a2013-09-15 13:01:22 +02001211#endif /* POLARSSL_RSA_C */
1212
1213#if defined(POLARSSL_ECP_C)
Hanno Becker20f4c782017-09-28 16:52:51 +01001214 pk_info = pk_info_from_type( POLARSSL_PK_ECKEY );
Hanno Becker713c9e12017-09-28 16:46:24 +01001215 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
Hanno Becker20f4c782017-09-28 16:52:51 +01001216 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), key, keylen ) ) != 0 )
1217 {
1218 pk_free( pk );
1219 }
1220 else
Paul Bakker1a7550a2013-09-15 13:01:22 +02001221 {
1222 return( 0 );
1223 }
Paul Bakker1a7550a2013-09-15 13:01:22 +02001224#endif /* POLARSSL_ECP_C */
1225
1226 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
1227}
1228
1229/*
1230 * Parse a public key
1231 */
1232int pk_parse_public_key( pk_context *ctx,
1233 const unsigned char *key, size_t keylen )
1234{
1235 int ret;
1236 unsigned char *p;
Paul Bakkercff68422013-09-15 20:43:33 +02001237#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001238 size_t len;
1239 pem_context pem;
1240
1241 pem_init( &pem );
1242 ret = pem_read_buffer( &pem,
1243 "-----BEGIN PUBLIC KEY-----",
1244 "-----END PUBLIC KEY-----",
1245 key, NULL, 0, &len );
1246
1247 if( ret == 0 )
1248 {
1249 /*
1250 * Was PEM encoded
1251 */
1252 key = pem.buf;
1253 keylen = pem.buflen;
1254 }
1255 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1256 {
1257 pem_free( &pem );
1258 return( ret );
1259 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001260#endif /* POLARSSL_PEM_PARSE_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001261 p = (unsigned char *) key;
1262
Paul Bakkerda771152013-09-16 22:45:03 +02001263 ret = pk_parse_subpubkey( &p, p + keylen, ctx );
Paul Bakker1a7550a2013-09-15 13:01:22 +02001264
Paul Bakkercff68422013-09-15 20:43:33 +02001265#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001266 pem_free( &pem );
1267#endif
1268
1269 return( ret );
1270}
1271
Paul Bakker4606c732013-09-15 17:04:23 +02001272#endif /* POLARSSL_PK_PARSE_C */