blob: 29217a28a2d79d5205cc6b56dc5f73ea7855c1a2 [file] [log] [blame]
Paul Bakker1a7550a2013-09-15 13:01:22 +02001/*
2 * Public Key layer for parsing key files and structures
3 *
Paul Bakker9af723c2014-05-01 13:03:14 +02004 * Copyright (C) 2006-2014, Brainspark B.V.
Paul Bakker1a7550a2013-09-15 13:01:22 +02005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020026#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker1a7550a2013-09-15 13:01:22 +020027#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020028#else
29#include POLARSSL_CONFIG_FILE
30#endif
Paul Bakker1a7550a2013-09-15 13:01:22 +020031
Paul Bakker4606c732013-09-15 17:04:23 +020032#if defined(POLARSSL_PK_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +020033
34#include "polarssl/pk.h"
35#include "polarssl/asn1.h"
36#include "polarssl/oid.h"
37
38#if defined(POLARSSL_RSA_C)
39#include "polarssl/rsa.h"
40#endif
41#if defined(POLARSSL_ECP_C)
42#include "polarssl/ecp.h"
43#endif
44#if defined(POLARSSL_ECDSA_C)
45#include "polarssl/ecdsa.h"
46#endif
Paul Bakkercff68422013-09-15 20:43:33 +020047#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +020048#include "polarssl/pem.h"
49#endif
50#if defined(POLARSSL_PKCS5_C)
51#include "polarssl/pkcs5.h"
52#endif
53#if defined(POLARSSL_PKCS12_C)
54#include "polarssl/pkcs12.h"
55#endif
56
Paul Bakker7dc4c442014-02-01 22:50:26 +010057#if defined(POLARSSL_PLATFORM_C)
58#include "polarssl/platform.h"
Paul Bakker1a7550a2013-09-15 13:01:22 +020059#else
60#include <stdlib.h>
61#define polarssl_malloc malloc
62#define polarssl_free free
63#endif
64
Manuel Pégourié-Gonnard66e20c62014-06-24 17:47:40 +020065#if defined(POLARSSL_FS_IO)
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}
70
Paul Bakker1a7550a2013-09-15 13:01:22 +020071/*
72 * Load all data from a file into a given buffer.
73 */
74static int load_file( const char *path, unsigned char **buf, size_t *n )
75{
76 FILE *f;
77 long size;
78
79 if( ( f = fopen( path, "rb" ) ) == NULL )
80 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
81
82 fseek( f, 0, SEEK_END );
83 if( ( size = ftell( f ) ) == -1 )
84 {
85 fclose( f );
86 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
87 }
88 fseek( f, 0, SEEK_SET );
89
90 *n = (size_t) size;
91
92 if( *n + 1 == 0 ||
93 ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
94 {
95 fclose( f );
96 return( POLARSSL_ERR_PK_MALLOC_FAILED );
97 }
98
99 if( fread( *buf, 1, *n, f ) != *n )
100 {
101 fclose( f );
102 polarssl_free( *buf );
103 return( POLARSSL_ERR_PK_FILE_IO_ERROR );
104 }
105
106 fclose( f );
107
108 (*buf)[*n] = '\0';
109
110 return( 0 );
111}
112
113/*
114 * Load and parse a private key
115 */
116int pk_parse_keyfile( pk_context *ctx,
117 const char *path, const char *pwd )
118{
119 int ret;
120 size_t n;
121 unsigned char *buf;
122
Paul Bakker66d5d072014-06-17 16:39:18 +0200123 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200124 return( ret );
125
126 if( pwd == NULL )
127 ret = pk_parse_key( ctx, buf, n, NULL, 0 );
128 else
129 ret = pk_parse_key( ctx, buf, n,
130 (const unsigned char *) pwd, strlen( pwd ) );
131
Paul Bakker34617722014-06-13 17:20:13 +0200132 polarssl_zeroize( buf, n + 1 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200133 polarssl_free( buf );
134
135 return( ret );
136}
137
138/*
139 * Load and parse a public key
140 */
141int pk_parse_public_keyfile( pk_context *ctx, const char *path )
142{
143 int ret;
144 size_t n;
145 unsigned char *buf;
146
Paul Bakker66d5d072014-06-17 16:39:18 +0200147 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200148 return( ret );
149
150 ret = pk_parse_public_key( ctx, buf, n );
151
Paul Bakker34617722014-06-13 17:20:13 +0200152 polarssl_zeroize( buf, n + 1 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200153 polarssl_free( buf );
154
155 return( ret );
156}
157#endif /* POLARSSL_FS_IO */
158
159#if defined(POLARSSL_ECP_C)
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100160/* Minimally parse an ECParameters buffer to and asn1_buf
Paul Bakker1a7550a2013-09-15 13:01:22 +0200161 *
162 * ECParameters ::= CHOICE {
163 * namedCurve OBJECT IDENTIFIER
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100164 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200165 * -- implicitCurve NULL
Paul Bakker1a7550a2013-09-15 13:01:22 +0200166 * }
167 */
168static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
169 asn1_buf *params )
170{
171 int ret;
172
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100173 /* Tag may be either OID or SEQUENCE */
Paul Bakker1a7550a2013-09-15 13:01:22 +0200174 params->tag = **p;
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100175 if( params->tag != ASN1_OID
176#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
177 && params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE )
178#endif
179 )
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100180 {
181 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
182 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
183 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200184
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100185 if( ( ret = asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
186 {
Paul Bakker1a7550a2013-09-15 13:01:22 +0200187 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100188 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200189
190 params->p = *p;
191 *p += params->len;
192
193 if( *p != end )
194 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
195 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
196
197 return( 0 );
198}
199
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100200#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
Paul Bakker1a7550a2013-09-15 13:01:22 +0200201/*
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100202 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
203 * WARNING: the resulting group should only be used with
204 * pk_group_id_from_specified(), since its base point may not be set correctly
205 * if it was encoded compressed.
206 *
207 * SpecifiedECDomain ::= SEQUENCE {
208 * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
209 * fieldID FieldID {{FieldTypes}},
210 * curve Curve,
211 * base ECPoint,
212 * order INTEGER,
213 * cofactor INTEGER OPTIONAL,
214 * hash HashAlgorithm OPTIONAL,
215 * ...
216 * }
217 *
218 * We only support prime-field as field type, and ignore hash and cofactor.
219 */
220static int pk_group_from_specified( const asn1_buf *params, ecp_group *grp )
221{
222 int ret;
223 unsigned char *p = params->p;
224 const unsigned char * const end = params->p + params->len;
225 const unsigned char *end_field, *end_curve;
226 size_t len;
227 int ver;
228
229 /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
230 if( ( ret = asn1_get_int( &p, end, &ver ) ) != 0 )
231 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
232
233 if( ver < 1 || ver > 3 )
234 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
235
236 /*
237 * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
238 * fieldType FIELD-ID.&id({IOSet}),
239 * parameters FIELD-ID.&Type({IOSet}{@fieldType})
240 * }
241 */
242 if( ( ret = asn1_get_tag( &p, end, &len,
243 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
244 return( ret );
245
246 end_field = p + len;
247
248 /*
249 * FIELD-ID ::= TYPE-IDENTIFIER
250 * FieldTypes FIELD-ID ::= {
251 * { Prime-p IDENTIFIED BY prime-field } |
252 * { Characteristic-two IDENTIFIED BY characteristic-two-field }
253 * }
254 * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
255 */
256 if( ( ret = asn1_get_tag( &p, end_field, &len, ASN1_OID ) ) != 0 )
257 return( ret );
258
259 if( len != OID_SIZE( OID_ANSI_X9_62_PRIME_FIELD ) ||
260 memcmp( p, OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
261 {
262 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
263 }
264
265 p += len;
266
267 /* Prime-p ::= INTEGER -- Field of size p. */
268 if( ( ret = asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
269 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
270
271 grp->pbits = mpi_msb( &grp->P );
272
273 if( p != end_field )
274 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
275 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
276
277 /*
278 * Curve ::= SEQUENCE {
279 * a FieldElement,
280 * b FieldElement,
281 * seed BIT STRING OPTIONAL
282 * -- Shall be present if used in SpecifiedECDomain
283 * -- with version equal to ecdpVer2 or ecdpVer3
284 * }
285 */
286 if( ( ret = asn1_get_tag( &p, end, &len,
287 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
288 return( ret );
289
290 end_curve = p + len;
291
292 /*
293 * FieldElement ::= OCTET STRING
294 * containing an integer in the case of a prime field
295 */
296 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
297 ( ret = mpi_read_binary( &grp->A, p, len ) ) != 0 )
298 {
299 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
300 }
301
302 p += len;
303
304 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
305 ( ret = mpi_read_binary( &grp->B, p, len ) ) != 0 )
306 {
307 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
308 }
309
310 p += len;
311
312 /* Ignore seed BIT STRING OPTIONAL */
313 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_BIT_STRING ) ) == 0 )
314 p += len;
315
316 if( p != end_curve )
317 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
318 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
319
320 /*
321 * ECPoint ::= OCTET STRING
322 */
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100323 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100324 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
325
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100326 if( ( ret = ecp_point_read_binary( grp, &grp->G,
327 ( const unsigned char *) p, len ) ) != 0 )
328 {
329 /*
330 * If we can't read the point because it's compressed, cheat by
331 * reading only the X coordinate and the parity bit of Y.
332 */
333 if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ||
334 ( p[0] != 0x02 && p[0] != 0x03 ) ||
335 len != mpi_size( &grp->P ) + 1 ||
336 mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
337 mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
338 mpi_lset( &grp->G.Z, 1 ) != 0 )
339 {
340 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
341 }
342 }
343
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100344 p += len;
345
346 /*
347 * order INTEGER
348 */
349 if( ( ret = asn1_get_mpi( &p, end, &grp->N ) ) )
350 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
351
352 grp->nbits = mpi_msb( &grp->N );
353
354 /*
355 * Allow optional elements by purposefully not enforcing p == end here.
356 */
357
358 return( 0 );
359}
360
361/*
362 * Find the group id associated with an (almost filled) group as generated by
363 * pk_group_from_specified(), or return an error if unknown.
364 */
365static int pk_group_id_from_group( const ecp_group *grp, ecp_group_id *grp_id )
366{
Manuel Pégourié-Gonnard5b8c4092014-03-27 14:59:42 +0100367 int ret = 0;
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100368 ecp_group ref;
369 const ecp_group_id *id;
370
371 ecp_group_init( &ref );
372
373 for( id = ecp_grp_id_list(); *id != POLARSSL_ECP_DP_NONE; id++ )
374 {
375 /* Load the group associated to that id */
376 ecp_group_free( &ref );
377 MPI_CHK( ecp_use_known_dp( &ref, *id ) );
378
379 /* Compare to the group we were given, starting with easy tests */
380 if( grp->pbits == ref.pbits && grp->nbits == ref.nbits &&
381 mpi_cmp_mpi( &grp->P, &ref.P ) == 0 &&
382 mpi_cmp_mpi( &grp->A, &ref.A ) == 0 &&
383 mpi_cmp_mpi( &grp->B, &ref.B ) == 0 &&
384 mpi_cmp_mpi( &grp->N, &ref.N ) == 0 &&
385 mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 &&
386 mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 &&
387 /* For Y we may only know the parity bit, so compare only that */
388 mpi_get_bit( &grp->G.Y, 0 ) == mpi_get_bit( &ref.G.Y, 0 ) )
389 {
390 break;
391 }
392
393 }
394
395cleanup:
396 ecp_group_free( &ref );
397
398 *grp_id = *id;
399
400 if( ret == 0 && *id == POLARSSL_ECP_DP_NONE )
401 ret = POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE;
402
403 return( ret );
404}
405
406/*
407 * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
408 */
409static int pk_group_id_from_specified( const asn1_buf *params,
410 ecp_group_id *grp_id )
411{
412 int ret;
413 ecp_group grp;
414
415 ecp_group_init( &grp );
416
417 if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 )
418 goto cleanup;
419
420 ret = pk_group_id_from_group( &grp, grp_id );
421
422cleanup:
423 ecp_group_free( &grp );
424
425 return( ret );
426}
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100427#endif /* POLARSSL_PK_PARSE_EC_EXTENDED */
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100428
429/*
Paul Bakker1a7550a2013-09-15 13:01:22 +0200430 * Use EC parameters to initialise an EC group
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100431 *
432 * ECParameters ::= CHOICE {
433 * namedCurve OBJECT IDENTIFIER
434 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
435 * -- implicitCurve NULL
Paul Bakker1a7550a2013-09-15 13:01:22 +0200436 */
437static int pk_use_ecparams( const asn1_buf *params, ecp_group *grp )
438{
439 int ret;
440 ecp_group_id grp_id;
441
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100442 if( params->tag == ASN1_OID )
443 {
444 if( oid_get_ec_grp( params, &grp_id ) != 0 )
445 return( POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE );
446 }
447 else
448 {
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100449#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100450 if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 )
451 return( ret );
Manuel Pégourié-Gonnard6fac3512014-03-19 16:39:52 +0100452#else
453 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
454#endif
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100455 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200456
457 /*
458 * grp may already be initilialized; if so, make sure IDs match
459 */
460 if( grp->id != POLARSSL_ECP_DP_NONE && grp->id != grp_id )
461 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
462
463 if( ( ret = ecp_use_known_dp( grp, grp_id ) ) != 0 )
464 return( ret );
465
466 return( 0 );
467}
468
469/*
470 * EC public key is an EC point
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100471 *
472 * The caller is responsible for clearing the structure upon failure if
473 * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
474 * return code of ecp_point_read_binary() and leave p in a usable state.
Paul Bakker1a7550a2013-09-15 13:01:22 +0200475 */
476static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
477 ecp_keypair *key )
478{
479 int ret;
480
481 if( ( ret = ecp_point_read_binary( &key->grp, &key->Q,
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100482 (const unsigned char *) *p, end - *p ) ) == 0 )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200483 {
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100484 ret = ecp_check_pubkey( &key->grp, &key->Q );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200485 }
486
487 /*
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100488 * We know ecp_point_read_binary consumed all bytes or failed
Paul Bakker1a7550a2013-09-15 13:01:22 +0200489 */
490 *p = (unsigned char *) end;
491
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100492 return( ret );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200493}
494#endif /* POLARSSL_ECP_C */
495
496#if defined(POLARSSL_RSA_C)
497/*
498 * RSAPublicKey ::= SEQUENCE {
499 * modulus INTEGER, -- n
500 * publicExponent INTEGER -- e
501 * }
502 */
503static int pk_get_rsapubkey( unsigned char **p,
504 const unsigned char *end,
505 rsa_context *rsa )
506{
507 int ret;
508 size_t len;
509
510 if( ( ret = asn1_get_tag( p, end, &len,
511 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
512 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
513
514 if( *p + len != end )
515 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
516 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
517
518 if( ( ret = asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
519 ( ret = asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
520 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
521
522 if( *p != end )
523 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
524 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
525
526 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
Manuel Pégourié-Gonnard387a2112013-09-18 18:54:01 +0200527 return( POLARSSL_ERR_PK_INVALID_PUBKEY );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200528
529 rsa->len = mpi_size( &rsa->N );
530
531 return( 0 );
532}
533#endif /* POLARSSL_RSA_C */
534
535/* Get a PK algorithm identifier
536 *
537 * AlgorithmIdentifier ::= SEQUENCE {
538 * algorithm OBJECT IDENTIFIER,
539 * parameters ANY DEFINED BY algorithm OPTIONAL }
540 */
541static int pk_get_pk_alg( unsigned char **p,
542 const unsigned char *end,
543 pk_type_t *pk_alg, asn1_buf *params )
544{
545 int ret;
546 asn1_buf alg_oid;
547
548 memset( params, 0, sizeof(asn1_buf) );
549
550 if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
551 return( POLARSSL_ERR_PK_INVALID_ALG + ret );
552
553 if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
554 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
555
556 /*
557 * No parameters with RSA (only for EC)
558 */
559 if( *pk_alg == POLARSSL_PK_RSA &&
560 ( ( params->tag != ASN1_NULL && params->tag != 0 ) ||
561 params->len != 0 ) )
562 {
563 return( POLARSSL_ERR_PK_INVALID_ALG );
564 }
565
566 return( 0 );
567}
568
569/*
570 * SubjectPublicKeyInfo ::= SEQUENCE {
571 * algorithm AlgorithmIdentifier,
572 * subjectPublicKey BIT STRING }
573 */
Paul Bakkerda771152013-09-16 22:45:03 +0200574int pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
575 pk_context *pk )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200576{
577 int ret;
578 size_t len;
579 asn1_buf alg_params;
580 pk_type_t pk_alg = POLARSSL_PK_NONE;
581 const pk_info_t *pk_info;
582
583 if( ( ret = asn1_get_tag( p, end, &len,
584 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
585 {
586 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
587 }
588
589 end = *p + len;
590
591 if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
592 return( ret );
593
594 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
595 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
596
597 if( *p + len != end )
598 return( POLARSSL_ERR_PK_INVALID_PUBKEY +
599 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
600
601 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
602 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
603
604 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
605 return( ret );
606
607#if defined(POLARSSL_RSA_C)
608 if( pk_alg == POLARSSL_PK_RSA )
609 {
610 ret = pk_get_rsapubkey( p, end, pk_rsa( *pk ) );
611 } else
612#endif /* POLARSSL_RSA_C */
613#if defined(POLARSSL_ECP_C)
614 if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY )
615 {
616 ret = pk_use_ecparams( &alg_params, &pk_ec( *pk )->grp );
617 if( ret == 0 )
618 ret = pk_get_ecpubkey( p, end, pk_ec( *pk ) );
619 } else
620#endif /* POLARSSL_ECP_C */
621 ret = POLARSSL_ERR_PK_UNKNOWN_PK_ALG;
622
623 if( ret == 0 && *p != end )
624 ret = POLARSSL_ERR_PK_INVALID_PUBKEY
625 POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
626
627 if( ret != 0 )
628 pk_free( pk );
629
630 return( ret );
631}
632
633#if defined(POLARSSL_RSA_C)
634/*
635 * Parse a PKCS#1 encoded private RSA key
636 */
637static int pk_parse_key_pkcs1_der( rsa_context *rsa,
638 const unsigned char *key,
639 size_t keylen )
640{
641 int ret;
642 size_t len;
643 unsigned char *p, *end;
644
645 p = (unsigned char *) key;
646 end = p + keylen;
647
648 /*
649 * This function parses the RSAPrivateKey (PKCS#1)
650 *
651 * RSAPrivateKey ::= SEQUENCE {
652 * version Version,
653 * modulus INTEGER, -- n
654 * publicExponent INTEGER, -- e
655 * privateExponent INTEGER, -- d
656 * prime1 INTEGER, -- p
657 * prime2 INTEGER, -- q
658 * exponent1 INTEGER, -- d mod (p-1)
659 * exponent2 INTEGER, -- d mod (q-1)
660 * coefficient INTEGER, -- (inverse of q) mod p
661 * otherPrimeInfos OtherPrimeInfos OPTIONAL
662 * }
663 */
664 if( ( ret = asn1_get_tag( &p, end, &len,
665 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
666 {
667 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
668 }
669
670 end = p + len;
671
672 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
673 {
674 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
675 }
676
677 if( rsa->ver != 0 )
678 {
679 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
680 }
681
682 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
683 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
684 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
685 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
686 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
687 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
688 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
689 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
690 {
691 rsa_free( rsa );
692 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
693 }
694
695 rsa->len = mpi_size( &rsa->N );
696
697 if( p != end )
698 {
699 rsa_free( rsa );
700 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
701 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
702 }
703
704 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
705 {
706 rsa_free( rsa );
707 return( ret );
708 }
709
710 return( 0 );
711}
712#endif /* POLARSSL_RSA_C */
713
714#if defined(POLARSSL_ECP_C)
715/*
716 * Parse a SEC1 encoded private EC key
717 */
718static int pk_parse_key_sec1_der( ecp_keypair *eck,
719 const unsigned char *key,
720 size_t keylen )
721{
722 int ret;
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100723 int version, pubkey_done;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200724 size_t len;
725 asn1_buf params;
726 unsigned char *p = (unsigned char *) key;
727 unsigned char *end = p + keylen;
728 unsigned char *end2;
729
730 /*
731 * RFC 5915, or SEC1 Appendix C.4
732 *
733 * ECPrivateKey ::= SEQUENCE {
734 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
735 * privateKey OCTET STRING,
736 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
737 * publicKey [1] BIT STRING OPTIONAL
738 * }
739 */
740 if( ( ret = asn1_get_tag( &p, end, &len,
741 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
742 {
743 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
744 }
745
746 end = p + len;
747
748 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
749 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
750
751 if( version != 1 )
752 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
753
754 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
755 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
756
757 if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 )
758 {
759 ecp_keypair_free( eck );
760 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
761 }
762
763 p += len;
764
765 /*
766 * Is 'parameters' present?
767 */
768 if( ( ret = asn1_get_tag( &p, end, &len,
769 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
770 {
771 if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
772 ( ret = pk_use_ecparams( &params, &eck->grp ) ) != 0 )
773 {
774 ecp_keypair_free( eck );
775 return( ret );
776 }
777 }
778 else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
779 {
780 ecp_keypair_free( eck );
781 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
782 }
783
784 /*
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100785 * Is 'publickey' present? If not, or if we can't read it (eg because it
786 * is compressed), create it from the private key.
Paul Bakker1a7550a2013-09-15 13:01:22 +0200787 */
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100788 pubkey_done = 0;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200789 if( ( ret = asn1_get_tag( &p, end, &len,
790 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
791 {
792 end2 = p + len;
793
794 if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
795 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
796
797 if( p + len != end2 )
798 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
799 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
800
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100801 if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
802 pubkey_done = 1;
Manuel Pégourié-Gonnard5246ee52014-03-19 16:18:38 +0100803 else
804 {
805 /*
806 * The only acceptable failure mode of pk_get_ecpubkey() above
807 * is if the point format is not recognized.
808 */
809 if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE )
810 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
811 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200812 }
Paul Bakker66d5d072014-06-17 16:39:18 +0200813 else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
Paul Bakker1a7550a2013-09-15 13:01:22 +0200814 {
815 ecp_keypair_free( eck );
816 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
817 }
Manuel Pégourié-Gonnardeab20d22014-03-14 17:58:42 +0100818
819 if( ! pubkey_done &&
820 ( ret = ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
821 NULL, NULL ) ) != 0 )
Manuel Pégourié-Gonnardff29f9c2013-09-18 16:13:02 +0200822 {
823 ecp_keypair_free( eck );
824 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
825 }
Paul Bakker1a7550a2013-09-15 13:01:22 +0200826
827 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
828 {
829 ecp_keypair_free( eck );
830 return( ret );
831 }
832
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200833 return( 0 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200834}
835#endif /* POLARSSL_ECP_C */
836
837/*
838 * Parse an unencrypted PKCS#8 encoded private key
839 */
840static int pk_parse_key_pkcs8_unencrypted_der(
841 pk_context *pk,
842 const unsigned char* key,
843 size_t keylen )
844{
845 int ret, version;
846 size_t len;
847 asn1_buf params;
848 unsigned char *p = (unsigned char *) key;
849 unsigned char *end = p + keylen;
850 pk_type_t pk_alg = POLARSSL_PK_NONE;
851 const pk_info_t *pk_info;
852
853 /*
854 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
855 *
856 * PrivateKeyInfo ::= SEQUENCE {
857 * version Version,
858 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
859 * privateKey PrivateKey,
860 * attributes [0] IMPLICIT Attributes OPTIONAL }
861 *
862 * Version ::= INTEGER
863 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
864 * PrivateKey ::= OCTET STRING
865 *
866 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
867 */
868
869 if( ( ret = asn1_get_tag( &p, end, &len,
870 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
871 {
872 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
873 }
874
875 end = p + len;
876
877 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
878 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
879
880 if( version != 0 )
881 return( POLARSSL_ERR_PK_KEY_INVALID_VERSION + ret );
882
883 if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
884 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
885
886 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
887 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
888
889 if( len < 1 )
890 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
891 POLARSSL_ERR_ASN1_OUT_OF_DATA );
892
893 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
894 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
895
896 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
897 return( ret );
898
899#if defined(POLARSSL_RSA_C)
900 if( pk_alg == POLARSSL_PK_RSA )
901 {
902 if( ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), p, len ) ) != 0 )
903 {
904 pk_free( pk );
905 return( ret );
906 }
907 } else
908#endif /* POLARSSL_RSA_C */
909#if defined(POLARSSL_ECP_C)
910 if( pk_alg == POLARSSL_PK_ECKEY || pk_alg == POLARSSL_PK_ECKEY_DH )
911 {
912 if( ( ret = pk_use_ecparams( &params, &pk_ec( *pk )->grp ) ) != 0 ||
913 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), p, len ) ) != 0 )
914 {
915 pk_free( pk );
916 return( ret );
917 }
918 } else
919#endif /* POLARSSL_ECP_C */
920 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
921
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200922 return( 0 );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200923}
924
925/*
926 * Parse an encrypted PKCS#8 encoded private key
927 */
928static int pk_parse_key_pkcs8_encrypted_der(
929 pk_context *pk,
930 const unsigned char *key, size_t keylen,
931 const unsigned char *pwd, size_t pwdlen )
932{
Paul Bakkerf4cf80b2014-04-17 17:19:56 +0200933 int ret, decrypted = 0;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200934 size_t len;
935 unsigned char buf[2048];
936 unsigned char *p, *end;
937 asn1_buf pbe_alg_oid, pbe_params;
938#if defined(POLARSSL_PKCS12_C)
939 cipher_type_t cipher_alg;
940 md_type_t md_alg;
941#endif
942
943 memset( buf, 0, sizeof( buf ) );
944
945 p = (unsigned char *) key;
946 end = p + keylen;
947
948 if( pwdlen == 0 )
949 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
950
951 /*
952 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
953 *
954 * EncryptedPrivateKeyInfo ::= SEQUENCE {
955 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
956 * encryptedData EncryptedData
957 * }
958 *
959 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
960 *
961 * EncryptedData ::= OCTET STRING
962 *
963 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
964 */
965 if( ( ret = asn1_get_tag( &p, end, &len,
966 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
967 {
968 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
969 }
970
971 end = p + len;
972
973 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
974 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
975
976 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
977 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
978
979 if( len > sizeof( buf ) )
980 return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
981
982 /*
983 * Decrypt EncryptedData with appropriate PDE
984 */
985#if defined(POLARSSL_PKCS12_C)
986 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
987 {
988 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
989 cipher_alg, md_alg,
990 pwd, pwdlen, p, len, buf ) ) != 0 )
991 {
992 if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
993 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
994
995 return( ret );
996 }
Paul Bakkerf4cf80b2014-04-17 17:19:56 +0200997
998 decrypted = 1;
Paul Bakker1a7550a2013-09-15 13:01:22 +0200999 }
1000 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
1001 {
1002 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
1003 PKCS12_PBE_DECRYPT,
1004 pwd, pwdlen,
1005 p, len, buf ) ) != 0 )
1006 {
1007 return( ret );
1008 }
1009
1010 // Best guess for password mismatch when using RC4. If first tag is
1011 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
1012 //
1013 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
1014 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001015
1016 decrypted = 1;
Paul Bakker1a7550a2013-09-15 13:01:22 +02001017 }
1018 else
1019#endif /* POLARSSL_PKCS12_C */
1020#if defined(POLARSSL_PKCS5_C)
1021 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
1022 {
1023 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
1024 p, len, buf ) ) != 0 )
1025 {
1026 if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
1027 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
1028
1029 return( ret );
1030 }
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001031
1032 decrypted = 1;
Paul Bakker1a7550a2013-09-15 13:01:22 +02001033 }
1034 else
1035#endif /* POLARSSL_PKCS5_C */
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001036 {
1037 ((void) pwd);
Manuel Pégourié-Gonnard1032c1d2013-09-18 17:18:34 +02001038 }
Paul Bakker1a7550a2013-09-15 13:01:22 +02001039
Paul Bakkerf4cf80b2014-04-17 17:19:56 +02001040 if( decrypted == 0 )
1041 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
1042
Paul Bakker1a7550a2013-09-15 13:01:22 +02001043 return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
1044}
1045
1046/*
1047 * Parse a private key
1048 */
1049int pk_parse_key( pk_context *pk,
1050 const unsigned char *key, size_t keylen,
1051 const unsigned char *pwd, size_t pwdlen )
1052{
1053 int ret;
1054 const pk_info_t *pk_info;
1055
Paul Bakkercff68422013-09-15 20:43:33 +02001056#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001057 size_t len;
1058 pem_context pem;
1059
1060 pem_init( &pem );
1061
1062#if defined(POLARSSL_RSA_C)
1063 ret = pem_read_buffer( &pem,
1064 "-----BEGIN RSA PRIVATE KEY-----",
1065 "-----END RSA PRIVATE KEY-----",
1066 key, pwd, pwdlen, &len );
1067 if( ret == 0 )
1068 {
1069 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
1070 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
1071
1072 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1073 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ),
1074 pem.buf, pem.buflen ) ) != 0 )
1075 {
1076 pk_free( pk );
1077 }
1078
1079 pem_free( &pem );
1080 return( ret );
1081 }
1082 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
1083 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
1084 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
1085 return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
1086 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1087 return( ret );
1088#endif /* POLARSSL_RSA_C */
1089
1090#if defined(POLARSSL_ECP_C)
1091 ret = pem_read_buffer( &pem,
1092 "-----BEGIN EC PRIVATE KEY-----",
1093 "-----END EC PRIVATE KEY-----",
1094 key, pwd, pwdlen, &len );
1095 if( ret == 0 )
1096 {
1097 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
1098 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
1099
1100 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1101 ( 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
1136 ret = pem_read_buffer( &pem,
1137 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
1138 "-----END ENCRYPTED PRIVATE KEY-----",
1139 key, NULL, 0, &len );
1140 if( ret == 0 )
1141 {
1142 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
1143 pem.buf, pem.buflen,
1144 pwd, pwdlen ) ) != 0 )
1145 {
1146 pk_free( pk );
1147 }
1148
1149 pem_free( &pem );
1150 return( ret );
1151 }
1152 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1153 return( ret );
1154#else
1155 ((void) pwd);
1156 ((void) pwdlen);
Paul Bakkercff68422013-09-15 20:43:33 +02001157#endif /* POLARSSL_PEM_PARSE_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001158
1159 /*
1160 * At this point we only know it's not a PEM formatted key. Could be any
1161 * of the known DER encoded private key formats
1162 *
1163 * We try the different DER format parsers to see if one passes without
1164 * error
1165 */
1166 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
1167 pwd, pwdlen ) ) == 0 )
1168 {
1169 return( 0 );
1170 }
1171
1172 pk_free( pk );
1173
1174 if( ret == POLARSSL_ERR_PK_PASSWORD_MISMATCH )
1175 {
1176 return( ret );
1177 }
1178
1179 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
1180 return( 0 );
1181
1182 pk_free( pk );
1183
1184#if defined(POLARSSL_RSA_C)
1185 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
1186 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
1187
1188 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1189 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), key, keylen ) ) == 0 )
1190 {
1191 return( 0 );
1192 }
1193
1194 pk_free( pk );
1195#endif /* POLARSSL_RSA_C */
1196
1197#if defined(POLARSSL_ECP_C)
1198 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
1199 return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
1200
1201 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1202 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), key, keylen ) ) == 0 )
1203 {
1204 return( 0 );
1205 }
1206
1207 pk_free( pk );
1208#endif /* POLARSSL_ECP_C */
1209
1210 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
1211}
1212
1213/*
1214 * Parse a public key
1215 */
1216int pk_parse_public_key( pk_context *ctx,
1217 const unsigned char *key, size_t keylen )
1218{
1219 int ret;
1220 unsigned char *p;
Paul Bakkercff68422013-09-15 20:43:33 +02001221#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001222 size_t len;
1223 pem_context pem;
1224
1225 pem_init( &pem );
1226 ret = pem_read_buffer( &pem,
1227 "-----BEGIN PUBLIC KEY-----",
1228 "-----END PUBLIC KEY-----",
1229 key, NULL, 0, &len );
1230
1231 if( ret == 0 )
1232 {
1233 /*
1234 * Was PEM encoded
1235 */
1236 key = pem.buf;
1237 keylen = pem.buflen;
1238 }
1239 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1240 {
1241 pem_free( &pem );
1242 return( ret );
1243 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001244#endif /* POLARSSL_PEM_PARSE_C */
Paul Bakker1a7550a2013-09-15 13:01:22 +02001245 p = (unsigned char *) key;
1246
Paul Bakkerda771152013-09-16 22:45:03 +02001247 ret = pk_parse_subpubkey( &p, p + keylen, ctx );
Paul Bakker1a7550a2013-09-15 13:01:22 +02001248
Paul Bakkercff68422013-09-15 20:43:33 +02001249#if defined(POLARSSL_PEM_PARSE_C)
Paul Bakker1a7550a2013-09-15 13:01:22 +02001250 pem_free( &pem );
1251#endif
1252
1253 return( ret );
1254}
1255
Paul Bakker4606c732013-09-15 17:04:23 +02001256#endif /* POLARSSL_PK_PARSE_C */