mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-02-02 11:21:08 +00:00
Parse private key in uecc format
Parse the private key from cert in uecc format. Accept only P-256 curve.
This commit is contained in:
parent
42b83db1eb
commit
b176092656
|
@ -471,6 +471,18 @@ int mbedtls_oid_get_pk_alg( const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_a
|
||||||
int mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_type_t pk_alg,
|
int mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_type_t pk_alg,
|
||||||
const char **oid, size_t *olen );
|
const char **oid, size_t *olen );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_TINYCRYPT)
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MBEDTLS_UECC_DP_NONE = 0, /*!< Curve not defined. */
|
||||||
|
MBEDTLS_UECC_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */
|
||||||
|
} mbedtls_uecc_group_id;
|
||||||
|
|
||||||
|
int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_uecc_group_id *grp_id );
|
||||||
|
|
||||||
|
int mbedtls_oid_get_oid_by_ec_grp( mbedtls_uecc_group_id grp_id,
|
||||||
|
const char **oid, size_t *olen);
|
||||||
|
#else
|
||||||
#if defined(MBEDTLS_ECP_C)
|
#if defined(MBEDTLS_ECP_C)
|
||||||
/**
|
/**
|
||||||
* \brief Translate NamedCurve OID into an EC group identifier
|
* \brief Translate NamedCurve OID into an EC group identifier
|
||||||
|
@ -494,6 +506,7 @@ int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *g
|
||||||
int mbedtls_oid_get_oid_by_ec_grp( mbedtls_ecp_group_id grp_id,
|
int mbedtls_oid_get_oid_by_ec_grp( mbedtls_ecp_group_id grp_id,
|
||||||
const char **oid, size_t *olen );
|
const char **oid, size_t *olen );
|
||||||
#endif /* MBEDTLS_ECP_C */
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD_C)
|
#if defined(MBEDTLS_MD_C)
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
#include "ecdsa.h"
|
#include "ecdsa.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_TINYCRYPT)
|
||||||
|
#include "ecc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
||||||
!defined(inline) && !defined(__cplusplus)
|
!defined(inline) && !defined(__cplusplus)
|
||||||
#define inline __inline
|
#define inline __inline
|
||||||
|
@ -133,6 +137,14 @@ typedef struct mbedtls_pk_context
|
||||||
void * pk_ctx; /**< Underlying public key context */
|
void * pk_ctx; /**< Underlying public key context */
|
||||||
} mbedtls_pk_context;
|
} mbedtls_pk_context;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_TINYCRYPT)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t private_key[NUM_ECC_BYTES];
|
||||||
|
uint8_t public_key[2*NUM_ECC_BYTES];
|
||||||
|
} mbedtls_uecc_keypair;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
/**
|
/**
|
||||||
* \brief Context for resuming operations
|
* \brief Context for resuming operations
|
||||||
|
|
|
@ -467,6 +467,12 @@ FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg)
|
||||||
FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg)
|
FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg)
|
||||||
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg)
|
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg)
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_TINYCRYPT)
|
||||||
|
typedef struct {
|
||||||
|
mbedtls_oid_descriptor_t descriptor;
|
||||||
|
mbedtls_uecc_group_id grp_id;
|
||||||
|
} oid_ecp_grp_t;
|
||||||
|
#else
|
||||||
#if defined(MBEDTLS_ECP_C)
|
#if defined(MBEDTLS_ECP_C)
|
||||||
/*
|
/*
|
||||||
* For namedCurve (RFC 5480)
|
* For namedCurve (RFC 5480)
|
||||||
|
@ -475,7 +481,26 @@ typedef struct {
|
||||||
mbedtls_oid_descriptor_t descriptor;
|
mbedtls_oid_descriptor_t descriptor;
|
||||||
mbedtls_ecp_group_id grp_id;
|
mbedtls_ecp_group_id grp_id;
|
||||||
} oid_ecp_grp_t;
|
} oid_ecp_grp_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_TINYCRYPT)
|
||||||
|
static const oid_ecp_grp_t oid_ecp_grp[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" },
|
||||||
|
MBEDTLS_UECC_DP_SECP256R1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ NULL, 0, NULL, NULL },
|
||||||
|
MBEDTLS_UECC_DP_NONE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp)
|
||||||
|
FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_uecc_group_id, grp_id)
|
||||||
|
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_uecc_group_id, grp_id)
|
||||||
|
#else
|
||||||
|
#if defined(MBEDTLS_ECP_C)
|
||||||
static const oid_ecp_grp_t oid_ecp_grp[] =
|
static const oid_ecp_grp_t oid_ecp_grp[] =
|
||||||
{
|
{
|
||||||
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
|
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
|
||||||
|
@ -554,6 +579,7 @@ FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp)
|
||||||
FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id)
|
FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id)
|
||||||
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id)
|
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id)
|
||||||
#endif /* MBEDTLS_ECP_C */
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_C)
|
#if defined(MBEDTLS_CIPHER_C)
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -179,7 +179,28 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_FS_IO */
|
#endif /* MBEDTLS_FS_IO */
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_C)
|
#if defined(MBEDTLS_USE_TINYCRYPT)
|
||||||
|
static int pk_use_ecparams( const mbedtls_asn1_buf *params )
|
||||||
|
{
|
||||||
|
uint32_t grp_id;
|
||||||
|
|
||||||
|
if( params->tag == MBEDTLS_ASN1_OID )
|
||||||
|
{
|
||||||
|
if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only P-256 is supported
|
||||||
|
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_C) || \
|
||||||
|
defined(MBEDTLS_USE_TINYCRYPT)
|
||||||
/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
|
/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
|
||||||
*
|
*
|
||||||
* ECParameters ::= CHOICE {
|
* ECParameters ::= CHOICE {
|
||||||
|
@ -223,7 +244,9 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_C)
|
||||||
#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
|
#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
|
||||||
/*
|
/*
|
||||||
* Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
|
* Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
|
||||||
|
@ -524,7 +547,7 @@ static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
|
||||||
/*
|
/*
|
||||||
* Import a point from unsigned binary data (SEC1 2.3.4)
|
* Import a point from unsigned binary data (SEC1 2.3.4)
|
||||||
*/
|
*/
|
||||||
static int uecc_public_key_read_binary( uint8_t **pt,
|
static int uecc_public_key_read_binary( uint8_t *pt,
|
||||||
const unsigned char *buf, size_t ilen )
|
const unsigned char *buf, size_t ilen )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -539,7 +562,7 @@ static int uecc_public_key_read_binary( uint8_t **pt,
|
||||||
if( ilen != 2 * NUM_ECC_BYTES + 1 )
|
if( ilen != 2 * NUM_ECC_BYTES + 1 )
|
||||||
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
|
return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
|
||||||
|
|
||||||
*pt = (uint8_t *) buf + 1;
|
memcpy( pt, buf + 1, ilen - 1);
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
@ -550,7 +573,7 @@ static int pk_get_ueccpubkey( unsigned char **p,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = uecc_public_key_read_binary( &pk_context,
|
ret = uecc_public_key_read_binary( pk_context,
|
||||||
(const unsigned char *) *p, end - *p );
|
(const unsigned char *) *p, end - *p );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -854,6 +877,114 @@ cleanup:
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_RSA_C */
|
#endif /* MBEDTLS_RSA_C */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_USE_TINYCRYPT)
|
||||||
|
static int pk_parse_key_sec1_der( mbedtls_uecc_keypair *keypair,
|
||||||
|
const unsigned char *key,
|
||||||
|
size_t keylen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int version, pubkey_done;
|
||||||
|
size_t len;
|
||||||
|
mbedtls_asn1_buf params;
|
||||||
|
unsigned char *p = (unsigned char *) key;
|
||||||
|
unsigned char *end = p + keylen;
|
||||||
|
unsigned char *end2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC 5915, or SEC1 Appendix C.4
|
||||||
|
*
|
||||||
|
* ECPrivateKey ::= SEQUENCE {
|
||||||
|
* version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
|
||||||
|
* privateKey OCTET STRING,
|
||||||
|
* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
|
||||||
|
* publicKey [1] BIT STRING OPTIONAL
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||||
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
end = p + len;
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
|
||||||
|
|
||||||
|
if( version != 1 )
|
||||||
|
return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
|
||||||
|
|
||||||
|
memcpy(keypair->private_key, p, len);
|
||||||
|
|
||||||
|
p += len;
|
||||||
|
|
||||||
|
pubkey_done = 0;
|
||||||
|
if( p != end )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Is 'parameters' present?
|
||||||
|
*/
|
||||||
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||||
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
|
||||||
|
{
|
||||||
|
if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 ||
|
||||||
|
( ret = pk_use_ecparams( ¶ms ) ) != 0 )
|
||||||
|
{
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||||
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
|
||||||
|
{
|
||||||
|
end2 = p + len;
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
|
||||||
|
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
|
||||||
|
|
||||||
|
if( p + len != end2 )
|
||||||
|
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
|
||||||
|
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||||
|
|
||||||
|
if( ( ret = uecc_public_key_read_binary( keypair->public_key,
|
||||||
|
(const unsigned char *) p, end2 - p ) ) == 0 )
|
||||||
|
pubkey_done = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The only acceptable failure mode of pk_get_ecpubkey() above
|
||||||
|
* is if the point format is not recognized.
|
||||||
|
*/
|
||||||
|
if( ret != MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE )
|
||||||
|
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
|
||||||
|
{
|
||||||
|
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Do we need to support derived public keys with uecc?
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_C)
|
#if defined(MBEDTLS_ECP_C)
|
||||||
/*
|
/*
|
||||||
* Parse a SEC1 encoded private EC key
|
* Parse a SEC1 encoded private EC key
|
||||||
|
@ -982,6 +1113,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_ECP_C */
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
#endif /* MBEDTLS_USE_TINYCRYPT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse an unencrypted PKCS#8 encoded private key
|
* Parse an unencrypted PKCS#8 encoded private key
|
||||||
|
|
Loading…
Reference in a new issue