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