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.
Fork of mbedtls by
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 17:25:42 by
