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