mbedtls ported to mbed-classic
Fork of mbedtls by
Embed:
(wiki syntax)
Show/hide line numbers
pkparse.c
00001 /* 00002 * Public Key layer for parsing key files and structures 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 #if !defined(MBEDTLS_CONFIG_FILE) 00023 #include "mbedtls/config.h" 00024 #else 00025 #include MBEDTLS_CONFIG_FILE 00026 #endif 00027 00028 #if defined(MBEDTLS_PK_PARSE_C) 00029 00030 #include "mbedtls/pk.h" 00031 #include "mbedtls/asn1.h" 00032 #include "mbedtls/oid.h" 00033 00034 #include <string.h> 00035 00036 #if defined(MBEDTLS_RSA_C) 00037 #include "mbedtls/rsa.h" 00038 #endif 00039 #if defined(MBEDTLS_ECP_C) 00040 #include "mbedtls/ecp.h" 00041 #endif 00042 #if defined(MBEDTLS_ECDSA_C) 00043 #include "mbedtls/ecdsa.h" 00044 #endif 00045 #if defined(MBEDTLS_PEM_PARSE_C) 00046 #include "mbedtls/pem.h" 00047 #endif 00048 #if defined(MBEDTLS_PKCS5_C) 00049 #include "mbedtls/pkcs5.h" 00050 #endif 00051 #if defined(MBEDTLS_PKCS12_C) 00052 #include "mbedtls/pkcs12.h" 00053 #endif 00054 00055 #if defined(MBEDTLS_PLATFORM_C) 00056 #include "mbedtls/platform.h" 00057 #else 00058 #include <stdlib.h> 00059 #define mbedtls_calloc calloc 00060 #define mbedtls_free free 00061 #endif 00062 00063 #if defined(MBEDTLS_FS_IO) 00064 /* Implementation that should never be optimized out by the compiler */ 00065 static void mbedtls_zeroize( void *v, size_t n ) { 00066 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00067 } 00068 00069 /* 00070 * Load all data from a file into a given buffer. 00071 * 00072 * The file is expected to contain either PEM or DER encoded data. 00073 * A terminating null byte is always appended. It is included in the announced 00074 * length only if the data looks like it is PEM encoded. 00075 */ 00076 int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ) 00077 { 00078 FILE *f; 00079 long size; 00080 00081 if( ( f = fopen( path, "rb" ) ) == NULL ) 00082 return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); 00083 00084 fseek( f, 0, SEEK_END ); 00085 if( ( size = ftell( f ) ) == -1 ) 00086 { 00087 fclose( f ); 00088 return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); 00089 } 00090 fseek( f, 0, SEEK_SET ); 00091 00092 *n = (size_t) size; 00093 00094 if( *n + 1 == 0 || 00095 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) 00096 { 00097 fclose( f ); 00098 return( MBEDTLS_ERR_PK_ALLOC_FAILED ); 00099 } 00100 00101 if( fread( *buf, 1, *n, f ) != *n ) 00102 { 00103 fclose( f ); 00104 mbedtls_free( *buf ); 00105 return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); 00106 } 00107 00108 fclose( f ); 00109 00110 (*buf)[*n] = '\0'; 00111 00112 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) 00113 ++*n; 00114 00115 return( 0 ); 00116 } 00117 00118 /* 00119 * Load and parse a private key 00120 */ 00121 int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, 00122 const char *path, const char *pwd ) 00123 { 00124 int ret; 00125 size_t n; 00126 unsigned char *buf; 00127 00128 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) 00129 return( ret ); 00130 00131 if( pwd == NULL ) 00132 ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 ); 00133 else 00134 ret = mbedtls_pk_parse_key( ctx, buf, n, 00135 (const unsigned char *) pwd, strlen( pwd ) ); 00136 00137 mbedtls_zeroize( buf, n ); 00138 mbedtls_free( buf ); 00139 00140 return( ret ); 00141 } 00142 00143 /* 00144 * Load and parse a public key 00145 */ 00146 int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ) 00147 { 00148 int ret; 00149 size_t n; 00150 unsigned char *buf; 00151 00152 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) 00153 return( ret ); 00154 00155 ret = mbedtls_pk_parse_public_key( ctx, buf, n ); 00156 00157 mbedtls_zeroize( buf, n ); 00158 mbedtls_free( buf ); 00159 00160 return( ret ); 00161 } 00162 #endif /* MBEDTLS_FS_IO */ 00163 00164 #if defined(MBEDTLS_ECP_C) 00165 /* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf 00166 * 00167 * ECParameters ::= CHOICE { 00168 * namedCurve OBJECT IDENTIFIER 00169 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } 00170 * -- implicitCurve NULL 00171 * } 00172 */ 00173 static int pk_get_ecparams( unsigned char **p, const unsigned char *end, 00174 mbedtls_asn1_buf *params ) 00175 { 00176 int ret; 00177 00178 /* Tag may be either OID or SEQUENCE */ 00179 params->tag = **p; 00180 if( params->tag != MBEDTLS_ASN1_OID 00181 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) 00182 && params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) 00183 #endif 00184 ) 00185 { 00186 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + 00187 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00188 } 00189 00190 if( ( ret = mbedtls_asn1_get_tag( p, end, ¶ms->len, params->tag ) ) != 0 ) 00191 { 00192 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00193 } 00194 00195 params->p = *p; 00196 *p += params->len; 00197 00198 if( *p != end ) 00199 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + 00200 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00201 00202 return( 0 ); 00203 } 00204 00205 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) 00206 /* 00207 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. 00208 * WARNING: the resulting group should only be used with 00209 * pk_group_id_from_specified(), since its base point may not be set correctly 00210 * if it was encoded compressed. 00211 * 00212 * SpecifiedECDomain ::= SEQUENCE { 00213 * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), 00214 * fieldID FieldID {{FieldTypes}}, 00215 * curve Curve, 00216 * base ECPoint, 00217 * order INTEGER, 00218 * cofactor INTEGER OPTIONAL, 00219 * hash HashAlgorithm OPTIONAL, 00220 * ... 00221 * } 00222 * 00223 * We only support prime-field as field type, and ignore hash and cofactor. 00224 */ 00225 static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) 00226 { 00227 int ret; 00228 unsigned char *p = params->p; 00229 const unsigned char * const end = params->p + params->len; 00230 const unsigned char *end_field, *end_curve; 00231 size_t len; 00232 int ver; 00233 00234 /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ 00235 if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 ) 00236 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00237 00238 if( ver < 1 || ver > 3 ) 00239 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); 00240 00241 /* 00242 * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field 00243 * fieldType FIELD-ID.&id({IOSet}), 00244 * parameters FIELD-ID.&Type({IOSet}{@fieldType}) 00245 * } 00246 */ 00247 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00248 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00249 return( ret ); 00250 00251 end_field = p + len; 00252 00253 /* 00254 * FIELD-ID ::= TYPE-IDENTIFIER 00255 * FieldTypes FIELD-ID ::= { 00256 * { Prime-p IDENTIFIED BY prime-field } | 00257 * { Characteristic-two IDENTIFIED BY characteristic-two-field } 00258 * } 00259 * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } 00260 */ 00261 if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 ) 00262 return( ret ); 00263 00264 if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) || 00265 memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) 00266 { 00267 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 00268 } 00269 00270 p += len; 00271 00272 /* Prime-p ::= INTEGER -- Field of size p. */ 00273 if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 ) 00274 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00275 00276 grp->pbits = mbedtls_mpi_bitlen( &grp->P ); 00277 00278 if( p != end_field ) 00279 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + 00280 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00281 00282 /* 00283 * Curve ::= SEQUENCE { 00284 * a FieldElement, 00285 * b FieldElement, 00286 * seed BIT STRING OPTIONAL 00287 * -- Shall be present if used in SpecifiedECDomain 00288 * -- with version equal to ecdpVer2 or ecdpVer3 00289 * } 00290 */ 00291 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00292 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00293 return( ret ); 00294 00295 end_curve = p + len; 00296 00297 /* 00298 * FieldElement ::= OCTET STRING 00299 * containing an integer in the case of a prime field 00300 */ 00301 if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || 00302 ( ret = mbedtls_mpi_read_binary( &grp->A , p, len ) ) != 0 ) 00303 { 00304 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00305 } 00306 00307 p += len; 00308 00309 if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || 00310 ( ret = mbedtls_mpi_read_binary( &grp->B , p, len ) ) != 0 ) 00311 { 00312 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00313 } 00314 00315 p += len; 00316 00317 /* Ignore seed BIT STRING OPTIONAL */ 00318 if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 ) 00319 p += len; 00320 00321 if( p != end_curve ) 00322 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + 00323 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00324 00325 /* 00326 * ECPoint ::= OCTET STRING 00327 */ 00328 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) 00329 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00330 00331 if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G , 00332 ( const unsigned char *) p, len ) ) != 0 ) 00333 { 00334 /* 00335 * If we can't read the point because it's compressed, cheat by 00336 * reading only the X coordinate and the parity bit of Y. 00337 */ 00338 if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE || 00339 ( p[0] != 0x02 && p[0] != 0x03 ) || 00340 len != mbedtls_mpi_size( &grp->P ) + 1 || 00341 mbedtls_mpi_read_binary( &grp->G .X , p + 1, len - 1 ) != 0 || 00342 mbedtls_mpi_lset( &grp->G .Y , p[0] - 2 ) != 0 || 00343 mbedtls_mpi_lset( &grp->G .Z , 1 ) != 0 ) 00344 { 00345 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); 00346 } 00347 } 00348 00349 p += len; 00350 00351 /* 00352 * order INTEGER 00353 */ 00354 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 ) 00355 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00356 00357 grp->nbits = mbedtls_mpi_bitlen( &grp->N ); 00358 00359 /* 00360 * Allow optional elements by purposefully not enforcing p == end here. 00361 */ 00362 00363 return( 0 ); 00364 } 00365 00366 /* 00367 * Find the group id associated with an (almost filled) group as generated by 00368 * pk_group_from_specified(), or return an error if unknown. 00369 */ 00370 static int pk_group_id_from_group( const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id ) 00371 { 00372 int ret = 0; 00373 mbedtls_ecp_group ref; 00374 const mbedtls_ecp_group_id *id; 00375 00376 mbedtls_ecp_group_init( &ref ); 00377 00378 for( id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++ ) 00379 { 00380 /* Load the group associated to that id */ 00381 mbedtls_ecp_group_free( &ref ); 00382 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref, *id ) ); 00383 00384 /* Compare to the group we were given, starting with easy tests */ 00385 if( grp->pbits == ref.pbits && grp->nbits == ref.nbits && 00386 mbedtls_mpi_cmp_mpi( &grp->P , &ref.P ) == 0 && 00387 mbedtls_mpi_cmp_mpi( &grp->A , &ref.A ) == 0 && 00388 mbedtls_mpi_cmp_mpi( &grp->B , &ref.B ) == 0 && 00389 mbedtls_mpi_cmp_mpi( &grp->N , &ref.N ) == 0 && 00390 mbedtls_mpi_cmp_mpi( &grp->G .X , &ref.G .X ) == 0 && 00391 mbedtls_mpi_cmp_mpi( &grp->G .Z , &ref.G .Z ) == 0 && 00392 /* For Y we may only know the parity bit, so compare only that */ 00393 mbedtls_mpi_get_bit( &grp->G .Y , 0 ) == mbedtls_mpi_get_bit( &ref.G .Y , 0 ) ) 00394 { 00395 break; 00396 } 00397 00398 } 00399 00400 cleanup: 00401 mbedtls_ecp_group_free( &ref ); 00402 00403 *grp_id = *id; 00404 00405 if( ret == 0 && *id == MBEDTLS_ECP_DP_NONE ) 00406 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; 00407 00408 return( ret ); 00409 } 00410 00411 /* 00412 * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID 00413 */ 00414 static int pk_group_id_from_specified( const mbedtls_asn1_buf *params, 00415 mbedtls_ecp_group_id *grp_id ) 00416 { 00417 int ret; 00418 mbedtls_ecp_group grp; 00419 00420 mbedtls_ecp_group_init( &grp ); 00421 00422 if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 ) 00423 goto cleanup; 00424 00425 ret = pk_group_id_from_group( &grp, grp_id ); 00426 00427 cleanup: 00428 mbedtls_ecp_group_free( &grp ); 00429 00430 return( ret ); 00431 } 00432 #endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ 00433 00434 /* 00435 * Use EC parameters to initialise an EC group 00436 * 00437 * ECParameters ::= CHOICE { 00438 * namedCurve OBJECT IDENTIFIER 00439 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } 00440 * -- implicitCurve NULL 00441 */ 00442 static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) 00443 { 00444 int ret; 00445 mbedtls_ecp_group_id grp_id; 00446 00447 if( params->tag == MBEDTLS_ASN1_OID ) 00448 { 00449 if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 ) 00450 return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); 00451 } 00452 else 00453 { 00454 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) 00455 if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 ) 00456 return( ret ); 00457 #else 00458 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); 00459 #endif 00460 } 00461 00462 /* 00463 * grp may already be initilialized; if so, make sure IDs match 00464 */ 00465 if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id ) 00466 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); 00467 00468 if( ( ret = mbedtls_ecp_group_load( grp, grp_id ) ) != 0 ) 00469 return( ret ); 00470 00471 return( 0 ); 00472 } 00473 00474 /* 00475 * EC public key is an EC point 00476 * 00477 * The caller is responsible for clearing the structure upon failure if 00478 * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE 00479 * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state. 00480 */ 00481 static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end, 00482 mbedtls_ecp_keypair *key ) 00483 { 00484 int ret; 00485 00486 if( ( ret = mbedtls_ecp_point_read_binary( &key->grp , &key->Q , 00487 (const unsigned char *) *p, end - *p ) ) == 0 ) 00488 { 00489 ret = mbedtls_ecp_check_pubkey( &key->grp , &key->Q ); 00490 } 00491 00492 /* 00493 * We know mbedtls_ecp_point_read_binary consumed all bytes or failed 00494 */ 00495 *p = (unsigned char *) end; 00496 00497 return( ret ); 00498 } 00499 #endif /* MBEDTLS_ECP_C */ 00500 00501 #if defined(MBEDTLS_RSA_C) 00502 /* 00503 * RSAPublicKey ::= SEQUENCE { 00504 * modulus INTEGER, -- n 00505 * publicExponent INTEGER -- e 00506 * } 00507 */ 00508 static int pk_get_rsapubkey( unsigned char **p, 00509 const unsigned char *end, 00510 mbedtls_rsa_context *rsa ) 00511 { 00512 int ret; 00513 size_t len; 00514 00515 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00516 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00517 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); 00518 00519 if( *p + len != end ) 00520 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + 00521 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00522 00523 if( ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->N ) ) != 0 || 00524 ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->E ) ) != 0 ) 00525 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); 00526 00527 if( *p != end ) 00528 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + 00529 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00530 00531 if( ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 ) 00532 return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); 00533 00534 rsa->len = mbedtls_mpi_size( &rsa->N ); 00535 00536 return( 0 ); 00537 } 00538 #endif /* MBEDTLS_RSA_C */ 00539 00540 /* Get a PK algorithm identifier 00541 * 00542 * AlgorithmIdentifier ::= SEQUENCE { 00543 * algorithm OBJECT IDENTIFIER, 00544 * parameters ANY DEFINED BY algorithm OPTIONAL } 00545 */ 00546 static int pk_get_pk_alg( unsigned char **p, 00547 const unsigned char *end, 00548 mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params ) 00549 { 00550 int ret; 00551 mbedtls_asn1_buf alg_oid; 00552 00553 memset( params, 0, sizeof(mbedtls_asn1_buf) ); 00554 00555 if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 ) 00556 return( MBEDTLS_ERR_PK_INVALID_ALG + ret ); 00557 00558 if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 ) 00559 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); 00560 00561 /* 00562 * No parameters with RSA (only for EC) 00563 */ 00564 if( *pk_alg == MBEDTLS_PK_RSA && 00565 ( ( params->tag != MBEDTLS_ASN1_NULL && params->tag != 0 ) || 00566 params->len != 0 ) ) 00567 { 00568 return( MBEDTLS_ERR_PK_INVALID_ALG ); 00569 } 00570 00571 return( 0 ); 00572 } 00573 00574 /* 00575 * SubjectPublicKeyInfo ::= SEQUENCE { 00576 * algorithm AlgorithmIdentifier, 00577 * subjectPublicKey BIT STRING } 00578 */ 00579 int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, 00580 mbedtls_pk_context *pk ) 00581 { 00582 int ret; 00583 size_t len; 00584 mbedtls_asn1_buf alg_params; 00585 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; 00586 const mbedtls_pk_info_t *pk_info; 00587 00588 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00589 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00590 { 00591 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00592 } 00593 00594 end = *p + len; 00595 00596 if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 ) 00597 return( ret ); 00598 00599 if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) 00600 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); 00601 00602 if( *p + len != end ) 00603 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + 00604 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00605 00606 if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) 00607 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); 00608 00609 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) 00610 return( ret ); 00611 00612 #if defined(MBEDTLS_RSA_C) 00613 if( pk_alg == MBEDTLS_PK_RSA ) 00614 { 00615 ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) ); 00616 } else 00617 #endif /* MBEDTLS_RSA_C */ 00618 #if defined(MBEDTLS_ECP_C) 00619 if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY ) 00620 { 00621 ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp ); 00622 if( ret == 0 ) 00623 ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) ); 00624 } else 00625 #endif /* MBEDTLS_ECP_C */ 00626 ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; 00627 00628 if( ret == 0 && *p != end ) 00629 ret = MBEDTLS_ERR_PK_INVALID_PUBKEY 00630 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 00631 00632 if( ret != 0 ) 00633 mbedtls_pk_free( pk ); 00634 00635 return( ret ); 00636 } 00637 00638 #if defined(MBEDTLS_RSA_C) 00639 /* 00640 * Parse a PKCS#1 encoded private RSA key 00641 */ 00642 static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, 00643 const unsigned char *key, 00644 size_t keylen ) 00645 { 00646 int ret; 00647 size_t len; 00648 unsigned char *p, *end; 00649 00650 p = (unsigned char *) key; 00651 end = p + keylen; 00652 00653 /* 00654 * This function parses the RSAPrivateKey (PKCS#1) 00655 * 00656 * RSAPrivateKey ::= SEQUENCE { 00657 * version Version, 00658 * modulus INTEGER, -- n 00659 * publicExponent INTEGER, -- e 00660 * privateExponent INTEGER, -- d 00661 * prime1 INTEGER, -- p 00662 * prime2 INTEGER, -- q 00663 * exponent1 INTEGER, -- d mod (p-1) 00664 * exponent2 INTEGER, -- d mod (q-1) 00665 * coefficient INTEGER, -- (inverse of q) mod p 00666 * otherPrimeInfos OtherPrimeInfos OPTIONAL 00667 * } 00668 */ 00669 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00670 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00671 { 00672 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00673 } 00674 00675 end = p + len; 00676 00677 if( ( ret = mbedtls_asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) 00678 { 00679 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00680 } 00681 00682 if( rsa->ver != 0 ) 00683 { 00684 return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); 00685 } 00686 00687 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->N ) ) != 0 || 00688 ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->E ) ) != 0 || 00689 ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->D ) ) != 0 || 00690 ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->P ) ) != 0 || 00691 ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 || 00692 ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 || 00693 ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 || 00694 ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 ) 00695 { 00696 mbedtls_rsa_free( rsa ); 00697 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00698 } 00699 00700 rsa->len = mbedtls_mpi_size( &rsa->N ); 00701 00702 if( p != end ) 00703 { 00704 mbedtls_rsa_free( rsa ); 00705 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + 00706 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00707 } 00708 00709 if( ( ret = mbedtls_rsa_check_privkey( rsa ) ) != 0 ) 00710 { 00711 mbedtls_rsa_free( rsa ); 00712 return( ret ); 00713 } 00714 00715 return( 0 ); 00716 } 00717 #endif /* MBEDTLS_RSA_C */ 00718 00719 #if defined(MBEDTLS_ECP_C) 00720 /* 00721 * Parse a SEC1 encoded private EC key 00722 */ 00723 static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck, 00724 const unsigned char *key, 00725 size_t keylen ) 00726 { 00727 int ret; 00728 int version, pubkey_done; 00729 size_t len; 00730 mbedtls_asn1_buf params; 00731 unsigned char *p = (unsigned char *) key; 00732 unsigned char *end = p + keylen; 00733 unsigned char *end2; 00734 00735 /* 00736 * RFC 5915, or SEC1 Appendix C.4 00737 * 00738 * ECPrivateKey ::= SEQUENCE { 00739 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), 00740 * privateKey OCTET STRING, 00741 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 00742 * publicKey [1] BIT STRING OPTIONAL 00743 * } 00744 */ 00745 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00746 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00747 { 00748 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00749 } 00750 00751 end = p + len; 00752 00753 if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) 00754 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00755 00756 if( version != 1 ) 00757 return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); 00758 00759 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) 00760 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00761 00762 if( ( ret = mbedtls_mpi_read_binary( &eck->d , p, len ) ) != 0 ) 00763 { 00764 mbedtls_ecp_keypair_free( eck ); 00765 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00766 } 00767 00768 p += len; 00769 00770 pubkey_done = 0; 00771 if( p != end ) 00772 { 00773 /* 00774 * Is 'parameters' present? 00775 */ 00776 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00777 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) 00778 { 00779 if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || 00780 ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) 00781 { 00782 mbedtls_ecp_keypair_free( eck ); 00783 return( ret ); 00784 } 00785 } 00786 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00787 { 00788 mbedtls_ecp_keypair_free( eck ); 00789 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00790 } 00791 00792 /* 00793 * Is 'publickey' present? If not, or if we can't read it (eg because it 00794 * is compressed), create it from the private key. 00795 */ 00796 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00797 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) 00798 { 00799 end2 = p + len; 00800 00801 if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) 00802 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00803 00804 if( p + len != end2 ) 00805 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + 00806 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00807 00808 if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 ) 00809 pubkey_done = 1; 00810 else 00811 { 00812 /* 00813 * The only acceptable failure mode of pk_get_ecpubkey() above 00814 * is if the point format is not recognized. 00815 */ 00816 if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ) 00817 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); 00818 } 00819 } 00820 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00821 { 00822 mbedtls_ecp_keypair_free( eck ); 00823 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00824 } 00825 } 00826 00827 if( ! pubkey_done && 00828 ( ret = mbedtls_ecp_mul( &eck->grp , &eck->Q , &eck->d , &eck->grp .G , 00829 NULL, NULL ) ) != 0 ) 00830 { 00831 mbedtls_ecp_keypair_free( eck ); 00832 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00833 } 00834 00835 if( ( ret = mbedtls_ecp_check_privkey( &eck->grp , &eck->d ) ) != 0 ) 00836 { 00837 mbedtls_ecp_keypair_free( eck ); 00838 return( ret ); 00839 } 00840 00841 return( 0 ); 00842 } 00843 #endif /* MBEDTLS_ECP_C */ 00844 00845 /* 00846 * Parse an unencrypted PKCS#8 encoded private key 00847 */ 00848 static int pk_parse_key_pkcs8_unencrypted_der( 00849 mbedtls_pk_context *pk, 00850 const unsigned char* key, 00851 size_t keylen ) 00852 { 00853 int ret, version; 00854 size_t len; 00855 mbedtls_asn1_buf params; 00856 unsigned char *p = (unsigned char *) key; 00857 unsigned char *end = p + keylen; 00858 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; 00859 const mbedtls_pk_info_t *pk_info; 00860 00861 /* 00862 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208) 00863 * 00864 * PrivateKeyInfo ::= SEQUENCE { 00865 * version Version, 00866 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, 00867 * privateKey PrivateKey, 00868 * attributes [0] IMPLICIT Attributes OPTIONAL } 00869 * 00870 * Version ::= INTEGER 00871 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier 00872 * PrivateKey ::= OCTET STRING 00873 * 00874 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey 00875 */ 00876 00877 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00878 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00879 { 00880 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00881 } 00882 00883 end = p + len; 00884 00885 if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) 00886 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00887 00888 if( version != 0 ) 00889 return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret ); 00890 00891 if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, ¶ms ) ) != 0 ) 00892 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00893 00894 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) 00895 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00896 00897 if( len < 1 ) 00898 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + 00899 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00900 00901 if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) 00902 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); 00903 00904 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) 00905 return( ret ); 00906 00907 #if defined(MBEDTLS_RSA_C) 00908 if( pk_alg == MBEDTLS_PK_RSA ) 00909 { 00910 if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 ) 00911 { 00912 mbedtls_pk_free( pk ); 00913 return( ret ); 00914 } 00915 } else 00916 #endif /* MBEDTLS_RSA_C */ 00917 #if defined(MBEDTLS_ECP_C) 00918 if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH ) 00919 { 00920 if( ( ret = pk_use_ecparams( ¶ms, &mbedtls_pk_ec( *pk )->grp ) ) != 0 || 00921 ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len ) ) != 0 ) 00922 { 00923 mbedtls_pk_free( pk ); 00924 return( ret ); 00925 } 00926 } else 00927 #endif /* MBEDTLS_ECP_C */ 00928 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); 00929 00930 return( 0 ); 00931 } 00932 00933 /* 00934 * Parse an encrypted PKCS#8 encoded private key 00935 */ 00936 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) 00937 static int pk_parse_key_pkcs8_encrypted_der( 00938 mbedtls_pk_context *pk, 00939 const unsigned char *key, size_t keylen, 00940 const unsigned char *pwd, size_t pwdlen ) 00941 { 00942 int ret, decrypted = 0; 00943 size_t len; 00944 unsigned char buf[2048]; 00945 unsigned char *p, *end; 00946 mbedtls_asn1_buf pbe_alg_oid, pbe_params; 00947 #if defined(MBEDTLS_PKCS12_C) 00948 mbedtls_cipher_type_t cipher_alg; 00949 mbedtls_md_type_t md_alg; 00950 #endif 00951 00952 memset( buf, 0, sizeof( buf ) ); 00953 00954 p = (unsigned char *) key; 00955 end = p + keylen; 00956 00957 if( pwdlen == 0 ) 00958 return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); 00959 00960 /* 00961 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8) 00962 * 00963 * EncryptedPrivateKeyInfo ::= SEQUENCE { 00964 * encryptionAlgorithm EncryptionAlgorithmIdentifier, 00965 * encryptedData EncryptedData 00966 * } 00967 * 00968 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier 00969 * 00970 * EncryptedData ::= OCTET STRING 00971 * 00972 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo 00973 */ 00974 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00975 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00976 { 00977 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00978 } 00979 00980 end = p + len; 00981 00982 if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 ) 00983 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00984 00985 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) 00986 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); 00987 00988 if( len > sizeof( buf ) ) 00989 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 00990 00991 /* 00992 * Decrypt EncryptedData with appropriate PDE 00993 */ 00994 #if defined(MBEDTLS_PKCS12_C) 00995 if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 ) 00996 { 00997 if( ( ret = mbedtls_pkcs12_pbe( &pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT, 00998 cipher_alg, md_alg, 00999 pwd, pwdlen, p, len, buf ) ) != 0 ) 01000 { 01001 if( ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH ) 01002 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); 01003 01004 return( ret ); 01005 } 01006 01007 decrypted = 1; 01008 } 01009 else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 ) 01010 { 01011 if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params, 01012 MBEDTLS_PKCS12_PBE_DECRYPT, 01013 pwd, pwdlen, 01014 p, len, buf ) ) != 0 ) 01015 { 01016 return( ret ); 01017 } 01018 01019 // Best guess for password mismatch when using RC4. If first tag is 01020 // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE 01021 // 01022 if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) 01023 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); 01024 01025 decrypted = 1; 01026 } 01027 else 01028 #endif /* MBEDTLS_PKCS12_C */ 01029 #if defined(MBEDTLS_PKCS5_C) 01030 if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid ) == 0 ) 01031 { 01032 if( ( ret = mbedtls_pkcs5_pbes2( &pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen, 01033 p, len, buf ) ) != 0 ) 01034 { 01035 if( ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH ) 01036 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); 01037 01038 return( ret ); 01039 } 01040 01041 decrypted = 1; 01042 } 01043 else 01044 #endif /* MBEDTLS_PKCS5_C */ 01045 { 01046 ((void) pwd); 01047 } 01048 01049 if( decrypted == 0 ) 01050 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 01051 01052 return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) ); 01053 } 01054 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ 01055 01056 /* 01057 * Parse a private key 01058 */ 01059 int mbedtls_pk_parse_key( mbedtls_pk_context *pk, 01060 const unsigned char *key, size_t keylen, 01061 const unsigned char *pwd, size_t pwdlen ) 01062 { 01063 int ret; 01064 const mbedtls_pk_info_t *pk_info; 01065 01066 #if defined(MBEDTLS_PEM_PARSE_C) 01067 size_t len; 01068 mbedtls_pem_context pem; 01069 01070 mbedtls_pem_init( &pem ); 01071 01072 #if defined(MBEDTLS_RSA_C) 01073 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ 01074 if( keylen == 0 || key[keylen - 1] != '\0' ) 01075 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; 01076 else 01077 ret = mbedtls_pem_read_buffer( &pem, 01078 "-----BEGIN RSA PRIVATE KEY-----", 01079 "-----END RSA PRIVATE KEY-----", 01080 key, pwd, pwdlen, &len ); 01081 01082 if( ret == 0 ) 01083 { 01084 if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) 01085 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); 01086 01087 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || 01088 ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), 01089 pem.buf , pem.buflen ) ) != 0 ) 01090 { 01091 mbedtls_pk_free( pk ); 01092 } 01093 01094 mbedtls_pem_free( &pem ); 01095 return( ret ); 01096 } 01097 else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) 01098 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); 01099 else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) 01100 return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); 01101 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 01102 return( ret ); 01103 #endif /* MBEDTLS_RSA_C */ 01104 01105 #if defined(MBEDTLS_ECP_C) 01106 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ 01107 if( keylen == 0 || key[keylen - 1] != '\0' ) 01108 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; 01109 else 01110 ret = mbedtls_pem_read_buffer( &pem, 01111 "-----BEGIN EC PRIVATE KEY-----", 01112 "-----END EC PRIVATE KEY-----", 01113 key, pwd, pwdlen, &len ); 01114 if( ret == 0 ) 01115 { 01116 if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL ) 01117 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); 01118 01119 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || 01120 ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), 01121 pem.buf , pem.buflen ) ) != 0 ) 01122 { 01123 mbedtls_pk_free( pk ); 01124 } 01125 01126 mbedtls_pem_free( &pem ); 01127 return( ret ); 01128 } 01129 else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) 01130 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); 01131 else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) 01132 return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); 01133 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 01134 return( ret ); 01135 #endif /* MBEDTLS_ECP_C */ 01136 01137 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ 01138 if( keylen == 0 || key[keylen - 1] != '\0' ) 01139 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; 01140 else 01141 ret = mbedtls_pem_read_buffer( &pem, 01142 "-----BEGIN PRIVATE KEY-----", 01143 "-----END PRIVATE KEY-----", 01144 key, NULL, 0, &len ); 01145 if( ret == 0 ) 01146 { 01147 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, 01148 pem.buf , pem.buflen ) ) != 0 ) 01149 { 01150 mbedtls_pk_free( pk ); 01151 } 01152 01153 mbedtls_pem_free( &pem ); 01154 return( ret ); 01155 } 01156 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 01157 return( ret ); 01158 01159 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) 01160 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ 01161 if( keylen == 0 || key[keylen - 1] != '\0' ) 01162 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; 01163 else 01164 ret = mbedtls_pem_read_buffer( &pem, 01165 "-----BEGIN ENCRYPTED PRIVATE KEY-----", 01166 "-----END ENCRYPTED PRIVATE KEY-----", 01167 key, NULL, 0, &len ); 01168 if( ret == 0 ) 01169 { 01170 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, 01171 pem.buf , pem.buflen , 01172 pwd, pwdlen ) ) != 0 ) 01173 { 01174 mbedtls_pk_free( pk ); 01175 } 01176 01177 mbedtls_pem_free( &pem ); 01178 return( ret ); 01179 } 01180 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 01181 return( ret ); 01182 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ 01183 #else 01184 ((void) ret); 01185 ((void) pwd); 01186 ((void) pwdlen); 01187 #endif /* MBEDTLS_PEM_PARSE_C */ 01188 01189 /* 01190 * At this point we only know it's not a PEM formatted key. Could be any 01191 * of the known DER encoded private key formats 01192 * 01193 * We try the different DER format parsers to see if one passes without 01194 * error 01195 */ 01196 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) 01197 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen, 01198 pwd, pwdlen ) ) == 0 ) 01199 { 01200 return( 0 ); 01201 } 01202 01203 mbedtls_pk_free( pk ); 01204 01205 if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH ) 01206 { 01207 return( ret ); 01208 } 01209 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ 01210 01211 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 ) 01212 return( 0 ); 01213 01214 mbedtls_pk_free( pk ); 01215 01216 #if defined(MBEDTLS_RSA_C) 01217 if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) 01218 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); 01219 01220 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || 01221 ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) ) == 0 ) 01222 { 01223 return( 0 ); 01224 } 01225 01226 mbedtls_pk_free( pk ); 01227 #endif /* MBEDTLS_RSA_C */ 01228 01229 #if defined(MBEDTLS_ECP_C) 01230 if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL ) 01231 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); 01232 01233 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || 01234 ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), key, keylen ) ) == 0 ) 01235 { 01236 return( 0 ); 01237 } 01238 01239 mbedtls_pk_free( pk ); 01240 #endif /* MBEDTLS_ECP_C */ 01241 01242 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); 01243 } 01244 01245 /* 01246 * Parse a public key 01247 */ 01248 int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, 01249 const unsigned char *key, size_t keylen ) 01250 { 01251 int ret; 01252 unsigned char *p; 01253 #if defined(MBEDTLS_PEM_PARSE_C) 01254 size_t len; 01255 mbedtls_pem_context pem; 01256 01257 mbedtls_pem_init( &pem ); 01258 01259 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ 01260 if( keylen == 0 || key[keylen - 1] != '\0' ) 01261 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; 01262 else 01263 ret = mbedtls_pem_read_buffer( &pem, 01264 "-----BEGIN PUBLIC KEY-----", 01265 "-----END PUBLIC KEY-----", 01266 key, NULL, 0, &len ); 01267 01268 if( ret == 0 ) 01269 { 01270 /* 01271 * Was PEM encoded 01272 */ 01273 key = pem.buf ; 01274 keylen = pem.buflen ; 01275 } 01276 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 01277 { 01278 mbedtls_pem_free( &pem ); 01279 return( ret ); 01280 } 01281 #endif /* MBEDTLS_PEM_PARSE_C */ 01282 p = (unsigned char *) key; 01283 01284 ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx ); 01285 01286 #if defined(MBEDTLS_PEM_PARSE_C) 01287 mbedtls_pem_free( &pem ); 01288 #endif 01289 01290 return( ret ); 01291 } 01292 01293 #endif /* MBEDTLS_PK_PARSE_C */
Generated on Tue Jul 12 2022 12:52:45 by 1.7.2