blob: 9d91f2f136da9f81fc105fd55f1f13cbbd8f6a56 [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é-Gonnard085ab042015-01-23 11:06:27 +00006 * This file is part of mbed TLS (https://www.polarssl.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
35#if defined(POLARSSL_RSA_C)
36#include "polarssl/rsa.h"
37#endif
38#if defined(POLARSSL_ECP_C)
39#include "polarssl/ecp.h"
40#endif
41#if defined(POLARSSL_ECDSA_C)
42#include "polarssl/ecdsa.h"
43#endif
Paul Bakkercff68422013-09-15 20:43:33 +020044#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +020045#include "polarssl/pem.h"
46#endif
47#if defined(POLARSSL_PKCS5_C)
48#include "polarssl/pkcs5.h"
49#endif
50#if defined(POLARSSL_PKCS12_C)
51#include "polarssl/pkcs12.h"
52#endif
53
Paul Bakker7dc4c442014-02-01 22:50:26 +010054#if defined(POLARSSL_PLATFORM_C)
55#include "polarssl/platform.h"
Paul Bakker1a7550a2013-09-15 13:01:22 +020056#else
57#include <stdlib.h>
58#define polarssl_malloc malloc
59#define polarssl_free free
60#endif
61
Manuel Pégourié-Gonnard66e20c62014-06-24 17:47:40 +020062#if defined(POLARSSL_FS_IO)
Paul Bakker34617722014-06-13 17:20:13 +020063/* Implementation that should never be optimized out by the compiler */
64static void polarssl_zeroize( void *v, size_t n ) {
65 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
66}
67
Paul Bakker1a7550a2013-09-15 13:01:22 +020068/*
69 * Load all data from a file into a given buffer.
70 */
Manuel Pégourié-Gonnard9439f932014-11-21 09:49:43 +010071int pk_load_file( const char *path, unsigned char **buf, size_t *n )
Paul Bakker1a7550a2013-09-15 13:01:22 +020072{
73 FILE *f;
74 long size;
75
76 if( ( f = fopen( path, "rb" ) ) == NULL )
77 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
78
79 fseek( f, 0, SEEK_END );
80 if( ( size = ftell( f ) ) == -1 )
81 {
82 fclose( f );
83 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
84 }
85 fseek( f, 0, SEEK_SET );
86
87 *n = (size_t) size;
88
89 if( *n + 1 == 0 ||
90 ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
91 {
92 fclose( f );
93 return( POLARSSL_ERR_PK_MALLOC_FAILED );
94 }
95
96 if( fread( *buf, 1, *n, f ) != *n )
97 {
98 fclose( f );
99 polarssl_free( *buf );
100 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
101 }
102
103 fclose( f );
104
105 (*buf)[*n] = '\0';
106
107 return( 0 );
108}
109
110/*
111 * Load and parse a private key
112 */
113int pk_parse_keyfile( pk_context *ctx,
114 const char *path, const char *pwd )
115{
116 int ret;
117 size_t n;
118 unsigned char *buf;
119
Manuel Pégourié-Gonnard9439f932014-11-21 09:49:43 +0100120 if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200121 return( ret );
122
123 if( pwd == NULL )
124 ret = pk_parse_key( ctx, buf, n, NULL, 0 );
125 else
126 ret = pk_parse_key( ctx, buf, n,
127 (const unsigned char *) pwd, strlen( pwd ) );
128
Paul Bakker34617722014-06-13 17:20:13 +0200129 polarssl_zeroize( buf, n + 1 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200130 polarssl_free( buf );
131
132 return( ret );
133}
134
135/*
136 * Load and parse a public key
137 */
138int pk_parse_public_keyfile( pk_context *ctx, const char *path )
139{
140 int ret;
141 size_t n;
142 unsigned char *buf;
143
Manuel Pégourié-Gonnard9439f932014-11-21 09:49:43 +0100144 if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200145 return( ret );
146
147 ret = pk_parse_public_key( ctx, buf, n );
148
Paul Bakker34617722014-06-13 17:20:13 +0200149 polarssl_zeroize( buf, n + 1 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200150 polarssl_free( buf );
151
152 return( ret );
153}
154#endif /* POLARSSL_FS_IO */
155
156#if defined(POLARSSL_ECP_C)
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100157/* Minimally parse an ECParameters buffer to and asn1_buf
Paul Bakker1a7550a2013-09-15 13:01:22 +0200158 *
159 * ECParameters ::= CHOICE {
160 * namedCurve OBJECT IDENTIFIER
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100161 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200162 * -- implicitCurve NULL
Paul Bakker1a7550a2013-09-15 13:01:22 +0200163 * }
164 */
165static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
166 asn1_buf *params )
167{
168 int ret;
169
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100170 /* Tag may be either OID or SEQUENCE */
Paul Bakker1a7550a2013-09-15 13:01:22 +0200171 params->tag = **p;
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100172 if( params->tag != ASN1_OID
173#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
174 && params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE )
175#endif
176 )
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100177 {
178 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
179 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
180 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200181
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100182 if( ( ret = asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
183 {
Paul Bakker1a7550a2013-09-15 13:01:22 +0200184 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100185 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200186
187 params->p = *p;
188 *p += params->len;
189
190 if( *p != end )
191 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
192 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
193
194 return( 0 );
195}
196
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100197#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
Paul Bakker1a7550a2013-09-15 13:01:22 +0200198/*
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100199 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
200 * WARNING: the resulting group should only be used with
201 * pk_group_id_from_specified(), since its base point may not be set correctly
202 * if it was encoded compressed.
203 *
204 * SpecifiedECDomain ::= SEQUENCE {
205 * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
206 * fieldID FieldID {{FieldTypes}},
207 * curve Curve,
208 * base ECPoint,
209 * order INTEGER,
210 * cofactor INTEGER OPTIONAL,
211 * hash HashAlgorithm OPTIONAL,
212 * ...
213 * }
214 *
215 * We only support prime-field as field type, and ignore hash and cofactor.
216 */
217static int pk_group_from_specified( const asn1_buf *params, ecp_group *grp )
218{
219 int ret;
220 unsigned char *p = params->p;
221 const unsigned char * const end = params->p + params->len;
222 const unsigned char *end_field, *end_curve;
223 size_t len;
224 int ver;
225
226 /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
227 if( ( ret = asn1_get_int( &p, end, &ver ) ) != 0 )
228 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
229
230 if( ver < 1 || ver > 3 )
231 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
232
233 /*
234 * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
235 * fieldType FIELD-ID.&id({IOSet}),
236 * parameters FIELD-ID.&Type({IOSet}{@fieldType})
237 * }
238 */
239 if( ( ret = asn1_get_tag( &p, end, &len,
240 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
241 return( ret );
242
243 end_field = p + len;
244
245 /*
246 * FIELD-ID ::= TYPE-IDENTIFIER
247 * FieldTypes FIELD-ID ::= {
248 * { Prime-p IDENTIFIED BY prime-field } |
249 * { Characteristic-two IDENTIFIED BY characteristic-two-field }
250 * }
251 * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
252 */
253 if( ( ret = asn1_get_tag( &p, end_field, &len, ASN1_OID ) ) != 0 )
254 return( ret );
255
256 if( len != OID_SIZE( OID_ANSI_X9_62_PRIME_FIELD ) ||
257 memcmp( p, OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
258 {
259 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
260 }
261
262 p += len;
263
264 /* Prime-p ::= INTEGER -- Field of size p. */
265 if( ( ret = asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
266 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
267
268 grp->pbits = mpi_msb( &grp->P );
269
270 if( p != end_field )
271 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
272 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
273
274 /*
275 * Curve ::= SEQUENCE {
276 * a FieldElement,
277 * b FieldElement,
278 * seed BIT STRING OPTIONAL
279 * -- Shall be present if used in SpecifiedECDomain
280 * -- with version equal to ecdpVer2 or ecdpVer3
281 * }
282 */
283 if( ( ret = asn1_get_tag( &p, end, &len,
284 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
285 return( ret );
286
287 end_curve = p + len;
288
289 /*
290 * FieldElement ::= OCTET STRING
291 * containing an integer in the case of a prime field
292 */
293 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
294 ( ret = mpi_read_binary( &grp->A, p, len ) ) != 0 )
295 {
296 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
297 }
298
299 p += len;
300
301 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
302 ( ret = mpi_read_binary( &grp->B, p, len ) ) != 0 )
303 {
304 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
305 }
306
307 p += len;
308
309 /* Ignore seed BIT STRING OPTIONAL */
310 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_BIT_STRING ) ) == 0 )
311 p += len;
312
313 if( p != end_curve )
314 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
315 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
316
317 /*
318 * ECPoint ::= OCTET STRING
319 */
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100320 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100321 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
322
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100323 if( ( ret = ecp_point_read_binary( grp, &grp->G,
324 ( const unsigned char *) p, len ) ) != 0 )
325 {
326 /*
327 * If we can't read the point because it's compressed, cheat by
328 * reading only the X coordinate and the parity bit of Y.
329 */
330 if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ||
331 ( p[0] != 0x02 && p[0] != 0x03 ) ||
332 len != mpi_size( &grp->P ) + 1 ||
333 mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
334 mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
335 mpi_lset( &grp->G.Z, 1 ) != 0 )
336 {
337 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
338 }
339 }
340
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100341 p += len;
342
343 /*
344 * order INTEGER
345 */
346 if( ( ret = asn1_get_mpi( &p, end, &grp->N ) ) )
347 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
348
349 grp->nbits = mpi_msb( &grp->N );
350
351 /*
352 * Allow optional elements by purposefully not enforcing p == end here.
353 */
354
355 return( 0 );
356}
357
358/*
359 * Find the group id associated with an (almost filled) group as generated by
360 * pk_group_from_specified(), or return an error if unknown.
361 */
362static int pk_group_id_from_group( const ecp_group *grp, ecp_group_id *grp_id )
363{
Manuel Pégourié-Gonnard5b8c4092014-03-27 14:59:42 +0100364 int ret = 0;
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100365 ecp_group ref;
366 const ecp_group_id *id;
367
368 ecp_group_init( &ref );
369
370 for( id = ecp_grp_id_list(); *id != POLARSSL_ECP_DP_NONE; id++ )
371 {
372 /* Load the group associated to that id */
373 ecp_group_free( &ref );
374 MPI_CHK( ecp_use_known_dp( &ref, *id ) );
375
376 /* Compare to the group we were given, starting with easy tests */
377 if( grp->pbits == ref.pbits && grp->nbits == ref.nbits &&
378 mpi_cmp_mpi( &grp->P, &ref.P ) == 0 &&
379 mpi_cmp_mpi( &grp->A, &ref.A ) == 0 &&
380 mpi_cmp_mpi( &grp->B, &ref.B ) == 0 &&
381 mpi_cmp_mpi( &grp->N, &ref.N ) == 0 &&
382 mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 &&
383 mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 &&
384 /* For Y we may only know the parity bit, so compare only that */
385 mpi_get_bit( &grp->G.Y, 0 ) == mpi_get_bit( &ref.G.Y, 0 ) )
386 {
387 break;
388 }
389
390 }
391
392cleanup:
393 ecp_group_free( &ref );
394
395 *grp_id = *id;
396
397 if( ret == 0 && *id == POLARSSL_ECP_DP_NONE )
398 ret = POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE;
399
400 return( ret );
401}
402
403/*
404 * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
405 */
406static int pk_group_id_from_specified( const asn1_buf *params,
407 ecp_group_id *grp_id )
408{
409 int ret;
410 ecp_group grp;
411
412 ecp_group_init( &grp );
413
414 if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 )
415 goto cleanup;
416
417 ret = pk_group_id_from_group( &grp, grp_id );
418
419cleanup:
420 ecp_group_free( &grp );
421
422 return( ret );
423}
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100424#endif /* POLARSSL_PK_PARSE_EC_EXTENDED */
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100425
426/*
Paul Bakker1a7550a2013-09-15 13:01:22 +0200427 * Use EC parameters to initialise an EC group
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100428 *
429 * ECParameters ::= CHOICE {
430 * namedCurve OBJECT IDENTIFIER
431 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
432 * -- implicitCurve NULL
Paul Bakker1a7550a2013-09-15 13:01:22 +0200433 */
434static int pk_use_ecparams( const asn1_buf *params, ecp_group *grp )
435{
436 int ret;
437 ecp_group_id grp_id;
438
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100439 if( params->tag == ASN1_OID )
440 {
441 if( oid_get_ec_grp( params, &grp_id ) != 0 )
442 return( POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE );
443 }
444 else
445 {
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100446#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100447 if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 )
448 return( ret );
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100449#else
450 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
451#endif
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100452 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200453
454 /*
455 * grp may already be initilialized; if so, make sure IDs match
456 */
457 if( grp->id != POLARSSL_ECP_DP_NONE && grp->id != grp_id )
458 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
459
460 if( ( ret = ecp_use_known_dp( grp, grp_id ) ) != 0 )
461 return( ret );
462
463 return( 0 );
464}
465
466/*
467 * EC public key is an EC point
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100468 *
469 * The caller is responsible for clearing the structure upon failure if
470 * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
471 * return code of ecp_point_read_binary() and leave p in a usable state.
Paul Bakker1a7550a2013-09-15 13:01:22 +0200472 */
473static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
474 ecp_keypair *key )
475{
476 int ret;
477
478 if( ( ret = ecp_point_read_binary( &key->grp, &key->Q,
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100479 (const unsigned char *) *p, end - *p ) ) == 0 )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200480 {
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100481 ret = ecp_check_pubkey( &key->grp, &key->Q );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200482 }
483
484 /*
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100485 * We know ecp_point_read_binary consumed all bytes or failed
Paul Bakker1a7550a2013-09-15 13:01:22 +0200486 */
487 *p = (unsigned char *) end;
488
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100489 return( ret );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200490}
491#endif /* POLARSSL_ECP_C */
492
493#if defined(POLARSSL_RSA_C)
494/*
495 * RSAPublicKey ::= SEQUENCE {
496 * modulus INTEGER, -- n
497 * publicExponent INTEGER -- e
498 * }
499 */
500static int pk_get_rsapubkey( unsigned char **p,
501 const unsigned char *end,
502 rsa_context *rsa )
503{
504 int ret;
505 size_t len;
506
507 if( ( ret = asn1_get_tag( p, end, &len,
508 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
509 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
510
511 if( *p + len != end )
512 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
513 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
514
515 if( ( ret = asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
516 ( ret = asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
517 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
518
519 if( *p != end )
520 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
521 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
522
523 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
Manuel Pégourié-Gonnard387a2112013-09-18 18:54:01 +0200524 return( POLARSSL_ERR_PK_INVALID_PUBKEY );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200525
526 rsa->len = mpi_size( &rsa->N );
527
528 return( 0 );
529}
530#endif /* POLARSSL_RSA_C */
531
532/* Get a PK algorithm identifier
533 *
534 * AlgorithmIdentifier ::= SEQUENCE {
535 * algorithm OBJECT IDENTIFIER,
536 * parameters ANY DEFINED BY algorithm OPTIONAL }
537 */
538static int pk_get_pk_alg( unsigned char **p,
539 const unsigned char *end,
540 pk_type_t *pk_alg, asn1_buf *params )
541{
542 int ret;
543 asn1_buf alg_oid;
544
545 memset( params, 0, sizeof(asn1_buf) );
546
547 if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
548 return( POLARSSL_ERR_PK_INVALID_ALG + ret );
549
550 if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
551 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
552
553 /*
554 * No parameters with RSA (only for EC)
555 */
556 if( *pk_alg == POLARSSL_PK_RSA &&
557 ( ( params->tag != ASN1_NULL && params->tag != 0 ) ||
558 params->len != 0 ) )
559 {
560 return( POLARSSL_ERR_PK_INVALID_ALG );
561 }
562
563 return( 0 );
564}
565
566/*
567 * SubjectPublicKeyInfo ::= SEQUENCE {
568 * algorithm AlgorithmIdentifier,
569 * subjectPublicKey BIT STRING }
570 */
Paul Bakkerda771152013-09-16 22:45:03 +0200571int pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
572 pk_context *pk )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200573{
574 int ret;
575 size_t len;
576 asn1_buf alg_params;
577 pk_type_t pk_alg = POLARSSL_PK_NONE;
578 const pk_info_t *pk_info;
579
580 if( ( ret = asn1_get_tag( p, end, &len,
581 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
582 {
583 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
584 }
585
586 end = *p + len;
587
588 if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
589 return( ret );
590
591 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
592 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
593
594 if( *p + len != end )
595 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
596 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
597
598 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
599 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
600
601 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
602 return( ret );
603
604#if defined(POLARSSL_RSA_C)
605 if( pk_alg == POLARSSL_PK_RSA )
606 {
607 ret = pk_get_rsapubkey( p, end, pk_rsa( *pk ) );
608 } else
609#endif /* POLARSSL_RSA_C */
610#if defined(POLARSSL_ECP_C)
611 if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY )
612 {
613 ret = pk_use_ecparams( &alg_params, &pk_ec( *pk )->grp );
614 if( ret == 0 )
615 ret = pk_get_ecpubkey( p, end, pk_ec( *pk ) );
616 } else
617#endif /* POLARSSL_ECP_C */
618 ret = POLARSSL_ERR_PK_UNKNOWN_PK_ALG;
619
620 if( ret == 0 && *p != end )
621 ret = POLARSSL_ERR_PK_INVALID_PUBKEY
622 POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
623
624 if( ret != 0 )
625 pk_free( pk );
626
627 return( ret );
628}
629
630#if defined(POLARSSL_RSA_C)
631/*
632 * Parse a PKCS#1 encoded private RSA key
633 */
634static int pk_parse_key_pkcs1_der( rsa_context *rsa,
635 const unsigned char *key,
636 size_t keylen )
637{
638 int ret;
639 size_t len;
640 unsigned char *p, *end;
641
642 p = (unsigned char *) key;
643 end = p + keylen;
644
645 /*
646 * This function parses the RSAPrivateKey (PKCS#1)
647 *
648 * RSAPrivateKey ::= SEQUENCE {
649 * version Version,
650 * modulus INTEGER, -- n
651 * publicExponent INTEGER, -- e
652 * privateExponent INTEGER, -- d
653 * prime1 INTEGER, -- p
654 * prime2 INTEGER, -- q
655 * exponent1 INTEGER, -- d mod (p-1)
656 * exponent2 INTEGER, -- d mod (q-1)
657 * coefficient INTEGER, -- (inverse of q) mod p
658 * otherPrimeInfos OtherPrimeInfos OPTIONAL
659 * }
660 */
661 if( ( ret = asn1_get_tag( &p, end, &len,
662 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
663 {
664 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
665 }
666
667 end = p + len;
668
669 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
670 {
671 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
672 }
673
674 if( rsa->ver != 0 )
675 {
676 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
677 }
678
679 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
680 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
681 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
682 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
683 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
684 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
685 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
686 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
687 {
688 rsa_free( rsa );
689 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
690 }
691
692 rsa->len = mpi_size( &rsa->N );
693
694 if( p != end )
695 {
696 rsa_free( rsa );
697 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
698 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
699 }
700
701 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
702 {
703 rsa_free( rsa );
704 return( ret );
705 }
706
707 return( 0 );
708}
709#endif /* POLARSSL_RSA_C */
710
711#if defined(POLARSSL_ECP_C)
712/*
713 * Parse a SEC1 encoded private EC key
714 */
715static int pk_parse_key_sec1_der( ecp_keypair *eck,
716 const unsigned char *key,
717 size_t keylen )
718{
719 int ret;
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100720 int version, pubkey_done;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200721 size_t len;
722 asn1_buf params;
723 unsigned char *p = (unsigned char *) key;
724 unsigned char *end = p + keylen;
725 unsigned char *end2;
726
727 /*
728 * RFC 5915, or SEC1 Appendix C.4
729 *
730 * ECPrivateKey ::= SEQUENCE {
731 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
732 * privateKey OCTET STRING,
733 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
734 * publicKey [1] BIT STRING OPTIONAL
735 * }
736 */
737 if( ( ret = asn1_get_tag( &p, end, &len,
738 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
739 {
740 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
741 }
742
743 end = p + len;
744
745 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
746 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
747
748 if( version != 1 )
749 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
750
751 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
752 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
753
754 if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 )
755 {
756 ecp_keypair_free( eck );
757 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
758 }
759
760 p += len;
761
762 /*
763 * Is 'parameters' present?
764 */
765 if( ( ret = asn1_get_tag( &p, end, &len,
766 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
767 {
768 if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
769 ( ret = pk_use_ecparams( &params, &eck->grp ) ) != 0 )
770 {
771 ecp_keypair_free( eck );
772 return( ret );
773 }
774 }
775 else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
776 {
777 ecp_keypair_free( eck );
778 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
779 }
780
781 /*
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100782 * Is 'publickey' present? If not, or if we can't read it (eg because it
783 * is compressed), create it from the private key.
Paul Bakker1a7550a2013-09-15 13:01:22 +0200784 */
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100785 pubkey_done = 0;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200786 if( ( ret = asn1_get_tag( &p, end, &len,
787 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
788 {
789 end2 = p + len;
790
791 if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
792 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
793
794 if( p + len != end2 )
795 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
796 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
797
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100798 if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
799 pubkey_done = 1;
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100800 else
801 {
802 /*
803 * The only acceptable failure mode of pk_get_ecpubkey() above
804 * is if the point format is not recognized.
805 */
806 if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE )
807 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
808 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200809 }
Paul Bakker66d5d072014-06-17 16:39:18 +0200810 else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200811 {
812 ecp_keypair_free( eck );
813 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
814 }
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100815
816 if( ! pubkey_done &&
817 ( ret = ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
818 NULL, NULL ) ) != 0 )
Manuel Pégourié-Gonnardff29f9c2013-09-18 16:13:02 +0200819 {
820 ecp_keypair_free( eck );
821 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
822 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200823
824 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
825 {
826 ecp_keypair_free( eck );
827 return( ret );
828 }
829
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200830 return( 0 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200831}
832#endif /* POLARSSL_ECP_C */
833
834/*
835 * Parse an unencrypted PKCS#8 encoded private key
836 */
837static int pk_parse_key_pkcs8_unencrypted_der(
838 pk_context *pk,
839 const unsigned char* key,
840 size_t keylen )
841{
842 int ret, version;
843 size_t len;
844 asn1_buf params;
845 unsigned char *p = (unsigned char *) key;
846 unsigned char *end = p + keylen;
847 pk_type_t pk_alg = POLARSSL_PK_NONE;
848 const pk_info_t *pk_info;
849
850 /*
851 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
852 *
853 * PrivateKeyInfo ::= SEQUENCE {
854 * version Version,
855 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
856 * privateKey PrivateKey,
857 * attributes [0] IMPLICIT Attributes OPTIONAL }
858 *
859 * Version ::= INTEGER
860 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
861 * PrivateKey ::= OCTET STRING
862 *
863 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
864 */
865
866 if( ( ret = asn1_get_tag( &p, end, &len,
867 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
868 {
869 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
870 }
871
872 end = p + len;
873
874 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
875 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
876
877 if( version != 0 )
878 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION + ret );
879
880 if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
881 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
882
883 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
884 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
885
886 if( len < 1 )
887 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
888 POLARSSL_ERR_ASN1_OUT_OF_DATA );
889
890 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
891 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
892
893 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
894 return( ret );
895
896#if defined(POLARSSL_RSA_C)
897 if( pk_alg == POLARSSL_PK_RSA )
898 {
899 if( ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), p, len ) ) != 0 )
900 {
901 pk_free( pk );
902 return( ret );
903 }
904 } else
905#endif /* POLARSSL_RSA_C */
906#if defined(POLARSSL_ECP_C)
907 if( pk_alg == POLARSSL_PK_ECKEY || pk_alg == POLARSSL_PK_ECKEY_DH )
908 {
909 if( ( ret = pk_use_ecparams( &params, &pk_ec( *pk )->grp ) ) != 0 ||
910 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), p, len ) ) != 0 )
911 {
912 pk_free( pk );
913 return( ret );
914 }
915 } else
916#endif /* POLARSSL_ECP_C */
917 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
918
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200919 return( 0 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200920}
921
922/*
923 * Parse an encrypted PKCS#8 encoded private key
924 */
925static int pk_parse_key_pkcs8_encrypted_der(
926 pk_context *pk,
927 const unsigned char *key, size_t keylen,
928 const unsigned char *pwd, size_t pwdlen )
929{
Paul Bakkerf4cf80b2014-04-17 17:19:56 +0200930 int ret, decrypted = 0;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200931 size_t len;
932 unsigned char buf[2048];
933 unsigned char *p, *end;
934 asn1_buf pbe_alg_oid, pbe_params;
935#if defined(POLARSSL_PKCS12_C)
936 cipher_type_t cipher_alg;
937 md_type_t md_alg;
938#endif
939
940 memset( buf, 0, sizeof( buf ) );
941
942 p = (unsigned char *) key;
943 end = p + keylen;
944
945 if( pwdlen == 0 )
946 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
947
948 /*
949 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
950 *
951 * EncryptedPrivateKeyInfo ::= SEQUENCE {
952 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
953 * encryptedData EncryptedData
954 * }
955 *
956 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
957 *
958 * EncryptedData ::= OCTET STRING
959 *
960 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
961 */
962 if( ( ret = asn1_get_tag( &p, end, &len,
963 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
964 {
965 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
966 }
967
968 end = p + len;
969
970 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
971 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
972
973 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
974 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
975
976 if( len > sizeof( buf ) )
977 return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
978
979 /*
980 * Decrypt EncryptedData with appropriate PDE
981 */
982#if defined(POLARSSL_PKCS12_C)
983 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
984 {
985 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
986 cipher_alg, md_alg,
987 pwd, pwdlen, p, len, buf ) ) != 0 )
988 {
989 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
990 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
991
992 return( ret );
993 }
Paul Bakkerf4cf80b2014-04-17 17:19:56 +0200994
995 decrypted = 1;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200996 }
997 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
998 {
999 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
1000 PKCS12_PBE_DECRYPT,
1001 pwd, pwdlen,
1002 p, len, buf ) ) != 0 )
1003 {
1004 return( ret );
1005 }
1006
1007 // Best guess for password mismatch when using RC4. If first tag is
1008 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
1009 //
1010 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
1011 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001012
1013 decrypted = 1;
Paul Bakker1a7550a2013-09-15 13:01:22 +02001014 }
1015 else
1016#endif /* POLARSSL_PKCS12_C */
1017#if defined(POLARSSL_PKCS5_C)
1018 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
1019 {
1020 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
1021 p, len, buf ) ) != 0 )
1022 {
1023 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
1024 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
1025
1026 return( ret );
1027 }
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001028
1029 decrypted = 1;
Paul Bakker1a7550a2013-09-15 13:01:22 +02001030 }
1031 else
1032#endif /* POLARSSL_PKCS5_C */
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001033 {
1034 ((void) pwd);
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001035 }
Paul Bakker1a7550a2013-09-15 13:01:22 +02001036
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001037 if( decrypted == 0 )
1038 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
1039
Paul Bakker1a7550a2013-09-15 13:01:22 +02001040 return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
1041}
1042
1043/*
1044 * Parse a private key
1045 */
1046int pk_parse_key( pk_context *pk,
1047 const unsigned char *key, size_t keylen,
1048 const unsigned char *pwd, size_t pwdlen )
1049{
1050 int ret;
1051 const pk_info_t *pk_info;
1052
Paul Bakkercff68422013-09-15 20:43:33 +02001053#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001054 size_t len;
1055 pem_context pem;
1056
1057 pem_init( &pem );
1058
1059#if defined(POLARSSL_RSA_C)
1060 ret = pem_read_buffer( &pem,
1061 "-----BEGIN RSA PRIVATE KEY-----",
1062 "-----END RSA PRIVATE KEY-----",
1063 key, pwd, pwdlen, &len );
1064 if( ret == 0 )
1065 {
1066 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
1067 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
1068
1069 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1070 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ),
1071 pem.buf, pem.buflen ) ) != 0 )
1072 {
1073 pk_free( pk );
1074 }
1075
1076 pem_free( &pem );
1077 return( ret );
1078 }
1079 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
1080 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
1081 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
1082 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
1083 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1084 return( ret );
1085#endif /* POLARSSL_RSA_C */
1086
1087#if defined(POLARSSL_ECP_C)
1088 ret = pem_read_buffer( &pem,
1089 "-----BEGIN EC PRIVATE KEY-----",
1090 "-----END EC PRIVATE KEY-----",
1091 key, pwd, pwdlen, &len );
1092 if( ret == 0 )
1093 {
1094 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
1095 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
1096
1097 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1098 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ),
1099 pem.buf, pem.buflen ) ) != 0 )
1100 {
1101 pk_free( pk );
1102 }
1103
1104 pem_free( &pem );
1105 return( ret );
1106 }
1107 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
1108 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
1109 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
1110 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
1111 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1112 return( ret );
1113#endif /* POLARSSL_ECP_C */
1114
1115 ret = pem_read_buffer( &pem,
1116 "-----BEGIN PRIVATE KEY-----",
1117 "-----END PRIVATE KEY-----",
1118 key, NULL, 0, &len );
1119 if( ret == 0 )
1120 {
1121 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
1122 pem.buf, pem.buflen ) ) != 0 )
1123 {
1124 pk_free( pk );
1125 }
1126
1127 pem_free( &pem );
1128 return( ret );
1129 }
1130 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1131 return( ret );
1132
1133 ret = pem_read_buffer( &pem,
1134 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
1135 "-----END ENCRYPTED PRIVATE KEY-----",
1136 key, NULL, 0, &len );
1137 if( ret == 0 )
1138 {
1139 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
1140 pem.buf, pem.buflen,
1141 pwd, pwdlen ) ) != 0 )
1142 {
1143 pk_free( pk );
1144 }
1145
1146 pem_free( &pem );
1147 return( ret );
1148 }
1149 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1150 return( ret );
1151#else
1152 ((void) pwd);
1153 ((void) pwdlen);
Paul Bakkercff68422013-09-15 20:43:33 +02001154#endif /* POLARSSL_PEM_PARSE_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001155
1156 /*
1157 * At this point we only know it's not a PEM formatted key. Could be any
1158 * of the known DER encoded private key formats
1159 *
1160 * We try the different DER format parsers to see if one passes without
1161 * error
1162 */
1163 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
1164 pwd, pwdlen ) ) == 0 )
1165 {
1166 return( 0 );
1167 }
1168
1169 pk_free( pk );
1170
1171 if( ret == POLARSSL_ERR_PK_PASSWORD_MISMATCH )
1172 {
1173 return( ret );
1174 }
1175
1176 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
1177 return( 0 );
1178
1179 pk_free( pk );
1180
1181#if defined(POLARSSL_RSA_C)
1182 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
1183 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
1184
1185 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1186 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), key, keylen ) ) == 0 )
1187 {
1188 return( 0 );
1189 }
1190
1191 pk_free( pk );
1192#endif /* POLARSSL_RSA_C */
1193
1194#if defined(POLARSSL_ECP_C)
1195 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
1196 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
1197
1198 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1199 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), key, keylen ) ) == 0 )
1200 {
1201 return( 0 );
1202 }
1203
1204 pk_free( pk );
1205#endif /* POLARSSL_ECP_C */
1206
1207 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
1208}
1209
1210/*
1211 * Parse a public key
1212 */
1213int pk_parse_public_key( pk_context *ctx,
1214 const unsigned char *key, size_t keylen )
1215{
1216 int ret;
1217 unsigned char *p;
Paul Bakkercff68422013-09-15 20:43:33 +02001218#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001219 size_t len;
1220 pem_context pem;
1221
1222 pem_init( &pem );
1223 ret = pem_read_buffer( &pem,
1224 "-----BEGIN PUBLIC KEY-----",
1225 "-----END PUBLIC KEY-----",
1226 key, NULL, 0, &len );
1227
1228 if( ret == 0 )
1229 {
1230 /*
1231 * Was PEM encoded
1232 */
1233 key = pem.buf;
1234 keylen = pem.buflen;
1235 }
1236 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1237 {
1238 pem_free( &pem );
1239 return( ret );
1240 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001241#endif /* POLARSSL_PEM_PARSE_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001242 p = (unsigned char *) key;
1243
Paul Bakkerda771152013-09-16 22:45:03 +02001244 ret = pk_parse_subpubkey( &p, p + keylen, ctx );
Paul Bakker1a7550a2013-09-15 13:01:22 +02001245
Paul Bakkercff68422013-09-15 20:43:33 +02001246#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001247 pem_free( &pem );
1248#endif
1249
1250 return( ret );
1251}
1252
Paul Bakker4606c732013-09-15 17:04:23 +02001253#endif /* POLARSSL_PK_PARSE_C */