mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 07:09:48 -06:00
Externals: Update mbedtls to 2.16.1
On a few of our buildbot instances, we get warnings about the usage of deprecated functions. We should correct these, especially if we're delegating to system versions of the libraries if they're available. However, in order to do that, we need to update our library variant from 2.1.1 so that the non-deprecated alternatives are actually available.
This commit is contained in:
361
Externals/mbedtls/library/pkparse.c
vendored
361
Externals/mbedtls/library/pkparse.c
vendored
@ -30,6 +30,7 @@
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -60,12 +61,13 @@
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
|
||||
}
|
||||
/* Parameter validation macros based on platform_util.h */
|
||||
#define PK_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
|
||||
#define PK_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/*
|
||||
* Load all data from a file into a given buffer.
|
||||
*
|
||||
@ -78,6 +80,10 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
|
||||
FILE *f;
|
||||
long size;
|
||||
|
||||
PK_VALIDATE_RET( path != NULL );
|
||||
PK_VALIDATE_RET( buf != NULL );
|
||||
PK_VALIDATE_RET( n != NULL );
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
|
||||
|
||||
@ -101,7 +107,10 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
|
||||
if( fread( *buf, 1, *n, f ) != *n )
|
||||
{
|
||||
fclose( f );
|
||||
|
||||
mbedtls_platform_zeroize( *buf, *n );
|
||||
mbedtls_free( *buf );
|
||||
|
||||
return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
|
||||
}
|
||||
|
||||
@ -125,6 +134,9 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
|
||||
size_t n;
|
||||
unsigned char *buf;
|
||||
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
PK_VALIDATE_RET( path != NULL );
|
||||
|
||||
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
@ -134,7 +146,7 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
|
||||
ret = mbedtls_pk_parse_key( ctx, buf, n,
|
||||
(const unsigned char *) pwd, strlen( pwd ) );
|
||||
|
||||
mbedtls_zeroize( buf, n );
|
||||
mbedtls_platform_zeroize( buf, n );
|
||||
mbedtls_free( buf );
|
||||
|
||||
return( ret );
|
||||
@ -149,12 +161,15 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
|
||||
size_t n;
|
||||
unsigned char *buf;
|
||||
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
PK_VALIDATE_RET( path != NULL );
|
||||
|
||||
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_pk_parse_public_key( ctx, buf, n );
|
||||
|
||||
mbedtls_zeroize( buf, n );
|
||||
mbedtls_platform_zeroize( buf, n );
|
||||
mbedtls_free( buf );
|
||||
|
||||
return( ret );
|
||||
@ -175,6 +190,10 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ( end - *p < 1 )
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
|
||||
MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
/* Tag may be either OID or SEQUENCE */
|
||||
params->tag = **p;
|
||||
if( params->tag != MBEDTLS_ASN1_OID
|
||||
@ -520,19 +539,36 @@ static int pk_get_rsapubkey( unsigned char **p,
|
||||
return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
|
||||
/* Import N */
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
|
||||
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
|
||||
|
||||
if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0,
|
||||
NULL, 0, NULL, 0 ) ) != 0 )
|
||||
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
|
||||
|
||||
*p += len;
|
||||
|
||||
/* Import E */
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
|
||||
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
|
||||
|
||||
if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
|
||||
NULL, 0, *p, len ) ) != 0 )
|
||||
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
|
||||
|
||||
*p += len;
|
||||
|
||||
if( mbedtls_rsa_complete( rsa ) != 0 ||
|
||||
mbedtls_rsa_check_pubkey( rsa ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
|
||||
}
|
||||
|
||||
if( *p != end )
|
||||
return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
if( ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 )
|
||||
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
|
||||
|
||||
rsa->len = mbedtls_mpi_size( &rsa->N );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
@ -585,6 +621,11 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
|
||||
const mbedtls_pk_info_t *pk_info;
|
||||
|
||||
PK_VALIDATE_RET( p != NULL );
|
||||
PK_VALIDATE_RET( *p != NULL );
|
||||
PK_VALIDATE_RET( end != NULL );
|
||||
PK_VALIDATE_RET( pk != NULL );
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
@ -643,10 +684,13 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
|
||||
const unsigned char *key,
|
||||
size_t keylen )
|
||||
{
|
||||
int ret;
|
||||
int ret, version;
|
||||
size_t len;
|
||||
unsigned char *p, *end;
|
||||
|
||||
mbedtls_mpi T;
|
||||
mbedtls_mpi_init( &T );
|
||||
|
||||
p = (unsigned char *) key;
|
||||
end = p + keylen;
|
||||
|
||||
@ -674,45 +718,88 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
|
||||
|
||||
end = p + len;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
|
||||
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
if( rsa->ver != 0 )
|
||||
if( version != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
|
||||
{
|
||||
mbedtls_rsa_free( rsa );
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
|
||||
}
|
||||
/* Import N */
|
||||
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||
MBEDTLS_ASN1_INTEGER ) ) != 0 ||
|
||||
( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0,
|
||||
NULL, 0, NULL, 0 ) ) != 0 )
|
||||
goto cleanup;
|
||||
p += len;
|
||||
|
||||
rsa->len = mbedtls_mpi_size( &rsa->N );
|
||||
/* Import E */
|
||||
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||
MBEDTLS_ASN1_INTEGER ) ) != 0 ||
|
||||
( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
|
||||
NULL, 0, p, len ) ) != 0 )
|
||||
goto cleanup;
|
||||
p += len;
|
||||
|
||||
/* Import D */
|
||||
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||
MBEDTLS_ASN1_INTEGER ) ) != 0 ||
|
||||
( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
|
||||
p, len, NULL, 0 ) ) != 0 )
|
||||
goto cleanup;
|
||||
p += len;
|
||||
|
||||
/* Import P */
|
||||
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||
MBEDTLS_ASN1_INTEGER ) ) != 0 ||
|
||||
( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, p, len, NULL, 0,
|
||||
NULL, 0, NULL, 0 ) ) != 0 )
|
||||
goto cleanup;
|
||||
p += len;
|
||||
|
||||
/* Import Q */
|
||||
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||
MBEDTLS_ASN1_INTEGER ) ) != 0 ||
|
||||
( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, p, len,
|
||||
NULL, 0, NULL, 0 ) ) != 0 )
|
||||
goto cleanup;
|
||||
p += len;
|
||||
|
||||
/* Complete the RSA private key */
|
||||
if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 )
|
||||
goto cleanup;
|
||||
|
||||
/* Check optional parameters */
|
||||
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
|
||||
( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 )
|
||||
goto cleanup;
|
||||
|
||||
if( p != end )
|
||||
{
|
||||
mbedtls_rsa_free( rsa );
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ;
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_rsa_check_privkey( rsa ) ) != 0 )
|
||||
cleanup:
|
||||
|
||||
mbedtls_mpi_free( &T );
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
/* Wrap error code if it's coming from a lower level */
|
||||
if( ( ret & 0xff80 ) == 0 )
|
||||
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
|
||||
else
|
||||
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
|
||||
mbedtls_rsa_free( rsa );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
@ -788,7 +875,10 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
|
||||
mbedtls_ecp_keypair_free( eck );
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
|
||||
}
|
||||
}
|
||||
|
||||
if( p != end )
|
||||
{
|
||||
/*
|
||||
* Is 'publickey' present? If not, or if we can't read it (eg because it
|
||||
* is compressed), create it from the private key.
|
||||
@ -844,6 +934,16 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
|
||||
|
||||
/*
|
||||
* Parse an unencrypted PKCS#8 encoded private key
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* - This function does not own the key buffer. It is the
|
||||
* responsibility of the caller to take care of zeroizing
|
||||
* and freeing it after use.
|
||||
*
|
||||
* - The function is responsible for freeing the provided
|
||||
* PK context on failure.
|
||||
*
|
||||
*/
|
||||
static int pk_parse_key_pkcs8_unencrypted_der(
|
||||
mbedtls_pk_context *pk,
|
||||
@ -859,7 +959,7 @@ static int pk_parse_key_pkcs8_unencrypted_der(
|
||||
const mbedtls_pk_info_t *pk_info;
|
||||
|
||||
/*
|
||||
* This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
|
||||
* This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
|
||||
*
|
||||
* PrivateKeyInfo ::= SEQUENCE {
|
||||
* version Version,
|
||||
@ -932,16 +1032,22 @@ static int pk_parse_key_pkcs8_unencrypted_der(
|
||||
|
||||
/*
|
||||
* Parse an encrypted PKCS#8 encoded private key
|
||||
*
|
||||
* To save space, the decryption happens in-place on the given key buffer.
|
||||
* Also, while this function may modify the keybuffer, it doesn't own it,
|
||||
* and instead it is the responsibility of the caller to zeroize and properly
|
||||
* free it after use.
|
||||
*
|
||||
*/
|
||||
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
|
||||
static int pk_parse_key_pkcs8_encrypted_der(
|
||||
mbedtls_pk_context *pk,
|
||||
const unsigned char *key, size_t keylen,
|
||||
unsigned char *key, size_t keylen,
|
||||
const unsigned char *pwd, size_t pwdlen )
|
||||
{
|
||||
int ret, decrypted = 0;
|
||||
size_t len;
|
||||
unsigned char buf[2048];
|
||||
unsigned char *buf;
|
||||
unsigned char *p, *end;
|
||||
mbedtls_asn1_buf pbe_alg_oid, pbe_params;
|
||||
#if defined(MBEDTLS_PKCS12_C)
|
||||
@ -949,16 +1055,14 @@ static int pk_parse_key_pkcs8_encrypted_der(
|
||||
mbedtls_md_type_t md_alg;
|
||||
#endif
|
||||
|
||||
memset( buf, 0, sizeof( buf ) );
|
||||
|
||||
p = (unsigned char *) key;
|
||||
p = key;
|
||||
end = p + keylen;
|
||||
|
||||
if( pwdlen == 0 )
|
||||
return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
|
||||
|
||||
/*
|
||||
* This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
|
||||
* This function parses the EncryptedPrivateKeyInfo object (PKCS#8)
|
||||
*
|
||||
* EncryptedPrivateKeyInfo ::= SEQUENCE {
|
||||
* encryptionAlgorithm EncryptionAlgorithmIdentifier,
|
||||
@ -970,6 +1074,7 @@ static int pk_parse_key_pkcs8_encrypted_der(
|
||||
* EncryptedData ::= OCTET STRING
|
||||
*
|
||||
* The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
|
||||
*
|
||||
*/
|
||||
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
@ -985,11 +1090,10 @@ static int pk_parse_key_pkcs8_encrypted_der(
|
||||
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
|
||||
|
||||
if( len > sizeof( buf ) )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
buf = p;
|
||||
|
||||
/*
|
||||
* Decrypt EncryptedData with appropriate PDE
|
||||
* Decrypt EncryptedData with appropriate PBE
|
||||
*/
|
||||
#if defined(MBEDTLS_PKCS12_C)
|
||||
if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
|
||||
@ -1062,16 +1166,22 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
||||
{
|
||||
int ret;
|
||||
const mbedtls_pk_info_t *pk_info;
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
size_t len;
|
||||
mbedtls_pem_context pem;
|
||||
#endif
|
||||
|
||||
mbedtls_pem_init( &pem );
|
||||
PK_VALIDATE_RET( pk != NULL );
|
||||
if( keylen == 0 )
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
|
||||
PK_VALIDATE_RET( key != NULL );
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_pem_init( &pem );
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
if( keylen == 0 || key[keylen - 1] != '\0' )
|
||||
if( key[keylen - 1] != '\0' )
|
||||
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
else
|
||||
ret = mbedtls_pem_read_buffer( &pem,
|
||||
@ -1081,10 +1191,8 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
||||
|
||||
if( ret == 0 )
|
||||
{
|
||||
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
|
||||
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
|
||||
|
||||
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
|
||||
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
|
||||
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
|
||||
( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
|
||||
pem.buf, pem.buflen ) ) != 0 )
|
||||
{
|
||||
@ -1104,7 +1212,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
if( keylen == 0 || key[keylen - 1] != '\0' )
|
||||
if( key[keylen - 1] != '\0' )
|
||||
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
else
|
||||
ret = mbedtls_pem_read_buffer( &pem,
|
||||
@ -1113,10 +1221,9 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
||||
key, pwd, pwdlen, &len );
|
||||
if( ret == 0 )
|
||||
{
|
||||
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL )
|
||||
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
|
||||
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
|
||||
|
||||
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
|
||||
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
|
||||
( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
|
||||
pem.buf, pem.buflen ) ) != 0 )
|
||||
{
|
||||
@ -1135,7 +1242,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
if( keylen == 0 || key[keylen - 1] != '\0' )
|
||||
if( key[keylen - 1] != '\0' )
|
||||
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
else
|
||||
ret = mbedtls_pem_read_buffer( &pem,
|
||||
@ -1158,7 +1265,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
||||
|
||||
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
if( keylen == 0 || key[keylen - 1] != '\0' )
|
||||
if( key[keylen - 1] != '\0' )
|
||||
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
else
|
||||
ret = mbedtls_pem_read_buffer( &pem,
|
||||
@ -1181,26 +1288,38 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
|
||||
#else
|
||||
((void) ret);
|
||||
((void) pwd);
|
||||
((void) pwdlen);
|
||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||
|
||||
/*
|
||||
* At this point we only know it's not a PEM formatted key. Could be any
|
||||
* of the known DER encoded private key formats
|
||||
*
|
||||
* We try the different DER format parsers to see if one passes without
|
||||
* error
|
||||
*/
|
||||
* At this point we only know it's not a PEM formatted key. Could be any
|
||||
* of the known DER encoded private key formats
|
||||
*
|
||||
* We try the different DER format parsers to see if one passes without
|
||||
* error
|
||||
*/
|
||||
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
|
||||
if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
|
||||
pwd, pwdlen ) ) == 0 )
|
||||
{
|
||||
return( 0 );
|
||||
unsigned char *key_copy;
|
||||
|
||||
if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL )
|
||||
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
|
||||
|
||||
memcpy( key_copy, key, keylen );
|
||||
|
||||
ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
|
||||
pwd, pwdlen );
|
||||
|
||||
mbedtls_platform_zeroize( key_copy, keylen );
|
||||
mbedtls_free( key_copy );
|
||||
}
|
||||
|
||||
if( ret == 0 )
|
||||
return( 0 );
|
||||
|
||||
mbedtls_pk_free( pk );
|
||||
mbedtls_pk_init( pk );
|
||||
|
||||
if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH )
|
||||
{
|
||||
@ -1212,33 +1331,42 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
||||
return( 0 );
|
||||
|
||||
mbedtls_pk_free( pk );
|
||||
mbedtls_pk_init( pk );
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
|
||||
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
|
||||
|
||||
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
|
||||
( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) ) == 0 )
|
||||
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
|
||||
if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
|
||||
pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) == 0 )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
mbedtls_pk_free( pk );
|
||||
mbedtls_pk_init( pk );
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL )
|
||||
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
|
||||
|
||||
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
|
||||
( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), key, keylen ) ) == 0 )
|
||||
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
|
||||
if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
|
||||
pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
|
||||
key, keylen ) == 0 )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
mbedtls_pk_free( pk );
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
/* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
|
||||
* it is ok to leave the PK context initialized but not
|
||||
* freed: It is the caller's responsibility to call pk_init()
|
||||
* before calling this function, and to call pk_free()
|
||||
* when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C
|
||||
* isn't, this leads to mbedtls_pk_free() being called
|
||||
* twice, once here and once by the caller, but this is
|
||||
* also ok and in line with the mbedtls_pk_free() calls
|
||||
* on failed PEM parsing attempts. */
|
||||
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
|
||||
}
|
||||
|
||||
@ -1250,14 +1378,55 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
|
||||
{
|
||||
int ret;
|
||||
unsigned char *p;
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
const mbedtls_pk_info_t *pk_info;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
size_t len;
|
||||
mbedtls_pem_context pem;
|
||||
#endif
|
||||
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
if( keylen == 0 )
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
|
||||
PK_VALIDATE_RET( key != NULL || keylen == 0 );
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_pem_init( &pem );
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
if( key[keylen - 1] != '\0' )
|
||||
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
else
|
||||
ret = mbedtls_pem_read_buffer( &pem,
|
||||
"-----BEGIN RSA PUBLIC KEY-----",
|
||||
"-----END RSA PUBLIC KEY-----",
|
||||
key, NULL, 0, &len );
|
||||
|
||||
if( ret == 0 )
|
||||
{
|
||||
p = pem.buf;
|
||||
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
|
||||
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
|
||||
|
||||
if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 )
|
||||
mbedtls_pk_free( ctx );
|
||||
|
||||
mbedtls_pem_free( &pem );
|
||||
return( ret );
|
||||
}
|
||||
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
|
||||
{
|
||||
mbedtls_pem_free( &pem );
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
if( keylen == 0 || key[keylen - 1] != '\0' )
|
||||
if( key[keylen - 1] != '\0' )
|
||||
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
else
|
||||
ret = mbedtls_pem_read_buffer( &pem,
|
||||
@ -1270,23 +1439,43 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
|
||||
/*
|
||||
* Was PEM encoded
|
||||
*/
|
||||
key = pem.buf;
|
||||
keylen = pem.buflen;
|
||||
p = pem.buf;
|
||||
|
||||
ret = mbedtls_pk_parse_subpubkey( &p, p + pem.buflen, ctx );
|
||||
mbedtls_pem_free( &pem );
|
||||
return( ret );
|
||||
}
|
||||
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
|
||||
{
|
||||
mbedtls_pem_free( &pem );
|
||||
return( ret );
|
||||
}
|
||||
mbedtls_pem_free( &pem );
|
||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
|
||||
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
|
||||
|
||||
if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
p = (unsigned char *)key;
|
||||
ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) );
|
||||
if( ret == 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
mbedtls_pk_free( ctx );
|
||||
if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
p = (unsigned char *) key;
|
||||
|
||||
ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx );
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_pem_free( &pem );
|
||||
#endif
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user