mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-07-29 11:41:15 +03:00
Merge parsing and verification of RSASSA-PSS in X.509 modules
This commit is contained in:
@ -363,6 +363,10 @@ static const oid_sig_alg_t oid_sig_alg[] =
|
||||
{ ADD_LEN( OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" },
|
||||
POLARSSL_MD_SHA512, POLARSSL_PK_ECDSA,
|
||||
},
|
||||
{
|
||||
{ ADD_LEN( OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" },
|
||||
POLARSSL_MD_NONE, POLARSSL_PK_RSASSA_PSS,
|
||||
},
|
||||
{
|
||||
{ NULL, 0, NULL, NULL },
|
||||
0, 0,
|
||||
|
53
library/pk.c
53
library/pk.c
@ -188,6 +188,59 @@ int pk_verify( pk_context *ctx, md_type_t md_alg,
|
||||
sig, sig_len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify a signature with options
|
||||
*/
|
||||
int pk_verify_ext( pk_type_t type, const void *options,
|
||||
pk_context *ctx, md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len )
|
||||
{
|
||||
if( ctx == NULL || ctx->pk_info == NULL )
|
||||
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
if( ! pk_can_do( ctx, type ) )
|
||||
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
|
||||
|
||||
if( type == POLARSSL_PK_RSASSA_PSS )
|
||||
{
|
||||
#if defined(POLARSSL_RSA_C) && defined(POLARSSL_PKCS1_V21)
|
||||
int ret;
|
||||
const pk_rsassa_pss_options *pss_opts;
|
||||
|
||||
if( options == NULL )
|
||||
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
pss_opts = (const pk_rsassa_pss_options *) options;
|
||||
|
||||
if( sig_len < pk_get_len( ctx ) )
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
|
||||
ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ),
|
||||
NULL, NULL, RSA_PUBLIC,
|
||||
md_alg, hash_len, hash,
|
||||
pss_opts->mgf1_hash_id,
|
||||
pss_opts->expected_salt_len,
|
||||
sig );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
if( sig_len > pk_get_len( ctx ) )
|
||||
return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
#else
|
||||
return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* General case: no options */
|
||||
if( options != NULL )
|
||||
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
return( pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a signature
|
||||
*/
|
||||
|
@ -52,13 +52,13 @@
|
||||
#define polarssl_free free
|
||||
#endif
|
||||
|
||||
/* Used by RSA-alt too */
|
||||
#if defined(POLARSSL_RSA_C)
|
||||
static int rsa_can_do( pk_type_t type )
|
||||
{
|
||||
return( type == POLARSSL_PK_RSA );
|
||||
return( type == POLARSSL_PK_RSA ||
|
||||
type == POLARSSL_PK_RSASSA_PSS );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_RSA_C)
|
||||
static size_t rsa_get_size( const void *ctx )
|
||||
{
|
||||
return( 8 * ((const rsa_context *) ctx)->len );
|
||||
@ -372,6 +372,11 @@ const pk_info_t ecdsa_info = {
|
||||
* Support for alternative RSA-private implementations
|
||||
*/
|
||||
|
||||
static int rsa_alt_can_do( pk_type_t type )
|
||||
{
|
||||
return( type == POLARSSL_PK_RSA );
|
||||
}
|
||||
|
||||
static size_t rsa_alt_get_size( const void *ctx )
|
||||
{
|
||||
const rsa_alt_context *rsa_alt = (const rsa_alt_context *) ctx;
|
||||
@ -428,7 +433,7 @@ const pk_info_t rsa_alt_info = {
|
||||
POLARSSL_PK_RSA_ALT,
|
||||
"RSA-alt",
|
||||
rsa_alt_get_size,
|
||||
rsa_can_do,
|
||||
rsa_alt_can_do,
|
||||
NULL,
|
||||
rsa_alt_sign_wrap,
|
||||
rsa_alt_decrypt_wrap,
|
||||
|
@ -505,7 +505,10 @@ int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
|
||||
const md_info_t *md_info;
|
||||
md_context_t md_ctx;
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
|
||||
if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
md_info = md_info_from_type( ctx->hash_id );
|
||||
@ -515,7 +518,7 @@ int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
|
||||
olen = ctx->len;
|
||||
hlen = md_get_size( md_info );
|
||||
|
||||
if( olen < ilen + 2 * hlen + 2 || f_rng == NULL )
|
||||
if( olen < ilen + 2 * hlen + 2 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
memset( output, 0, olen );
|
||||
@ -572,7 +575,10 @@ int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
|
||||
int ret;
|
||||
unsigned char *p = output;
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V15 || f_rng == NULL )
|
||||
if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
olen = ctx->len;
|
||||
@ -675,7 +681,7 @@ int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
|
||||
/*
|
||||
* Parameters sanity checks
|
||||
*/
|
||||
if( ctx->padding != RSA_PKCS_V21 )
|
||||
if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
ilen = ctx->len;
|
||||
@ -780,7 +786,7 @@ int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
|
||||
unsigned char *p, bad, pad_done = 0;
|
||||
unsigned char buf[POLARSSL_MPI_MAX_SIZE];
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V15 )
|
||||
if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
ilen = ctx->len;
|
||||
@ -901,7 +907,10 @@ int rsa_rsassa_pss_sign( rsa_context *ctx,
|
||||
const md_info_t *md_info;
|
||||
md_context_t md_ctx;
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
|
||||
if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
olen = ctx->len;
|
||||
@ -995,7 +1004,7 @@ int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
|
||||
unsigned char *p = sig;
|
||||
const char *oid;
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V15 )
|
||||
if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
olen = ctx->len;
|
||||
@ -1097,14 +1106,16 @@ int rsa_pkcs1_sign( rsa_context *ctx,
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
|
||||
*/
|
||||
int rsa_rsassa_pss_verify( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
const unsigned char *sig )
|
||||
int rsa_rsassa_pss_verify_ext( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
md_type_t mgf1_hash_id,
|
||||
int expected_salt_len,
|
||||
const unsigned char *sig )
|
||||
{
|
||||
int ret;
|
||||
size_t siglen;
|
||||
@ -1117,7 +1128,7 @@ int rsa_rsassa_pss_verify( rsa_context *ctx,
|
||||
const md_info_t *md_info;
|
||||
md_context_t md_ctx;
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V21 )
|
||||
if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
siglen = ctx->len;
|
||||
@ -1148,12 +1159,12 @@ int rsa_rsassa_pss_verify( rsa_context *ctx,
|
||||
hashlen = md_get_size( md_info );
|
||||
}
|
||||
|
||||
md_info = md_info_from_type( ctx->hash_id );
|
||||
md_info = md_info_from_type( mgf1_hash_id );
|
||||
if( md_info == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
hlen = md_get_size( md_info );
|
||||
slen = siglen - hlen - 1;
|
||||
slen = siglen - hlen - 1; /* Currently length of salt + padding */
|
||||
|
||||
memset( zeros, 0, 8 );
|
||||
|
||||
@ -1187,8 +1198,16 @@ int rsa_rsassa_pss_verify( rsa_context *ctx,
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
/* Actual salt len */
|
||||
slen -= p - buf;
|
||||
|
||||
if( expected_salt_len != RSA_SALT_LEN_ANY &&
|
||||
slen != (size_t) expected_salt_len )
|
||||
{
|
||||
md_free_ctx( &md_ctx );
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
// Generate H = Hash( M' )
|
||||
//
|
||||
md_starts( &md_ctx );
|
||||
@ -1204,6 +1223,29 @@ int rsa_rsassa_pss_verify( rsa_context *ctx,
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
/*
|
||||
* Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
|
||||
*/
|
||||
int rsa_rsassa_pss_verify( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
const unsigned char *sig )
|
||||
{
|
||||
md_type_t mgf1_hash_id = ( ctx->hash_id != POLARSSL_MD_NONE )
|
||||
? (md_type_t) ctx->hash_id
|
||||
: md_alg;
|
||||
|
||||
return( rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
|
||||
md_alg, hashlen, hash,
|
||||
mgf1_hash_id, RSA_SALT_LEN_ANY,
|
||||
sig ) );
|
||||
|
||||
}
|
||||
#endif /* POLARSSL_PKCS1_V21 */
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V15)
|
||||
@ -1227,7 +1269,7 @@ int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
|
||||
const md_info_t *md_info;
|
||||
asn1_buf oid;
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V15 )
|
||||
if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
siglen = ctx->len;
|
||||
|
307
library/x509.c
307
library/x509.c
@ -123,6 +123,223 @@ int x509_get_alg_null( unsigned char **p, const unsigned char *end,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse an algorithm identifier with (optional) paramaters
|
||||
*/
|
||||
int x509_get_alg( unsigned char **p, const unsigned char *end,
|
||||
x509_buf *alg, x509_buf *params )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ( ret = asn1_get_alg( p, end, alg, params ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
|
||||
/*
|
||||
* HashAlgorithm ::= AlgorithmIdentifier
|
||||
*
|
||||
* AlgorithmIdentifier ::= SEQUENCE {
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm OPTIONAL }
|
||||
*
|
||||
* For HashAlgorithm, parameters MUST be NULL or absent.
|
||||
*/
|
||||
static int x509_get_hash_alg( const x509_buf *alg, md_type_t *md_alg )
|
||||
{
|
||||
int ret;
|
||||
unsigned char *p;
|
||||
const unsigned char *end;
|
||||
x509_buf md_oid;
|
||||
size_t len;
|
||||
|
||||
/* Make sure we got a SEQUENCE and setup bounds */
|
||||
if( alg->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG +
|
||||
POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
|
||||
|
||||
p = (unsigned char *) alg->p;
|
||||
end = p + alg->len;
|
||||
|
||||
if( p >= end )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG +
|
||||
POLARSSL_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
/* Parse md_oid */
|
||||
md_oid.tag = *p;
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end, &md_oid.len, ASN1_OID ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
md_oid.p = p;
|
||||
p += md_oid.len;
|
||||
|
||||
/* Get md_alg from md_oid */
|
||||
if( ( ret = oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
/* Make sure params is absent of NULL */
|
||||
if( p == end )
|
||||
return( 0 );
|
||||
|
||||
if( ( ret = asn1_get_tag( &p, end, &len, ASN1_NULL ) ) != 0 || len != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
if( p != end )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* RSASSA-PSS-params ::= SEQUENCE {
|
||||
* hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
|
||||
* maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
|
||||
* saltLength [2] INTEGER DEFAULT 20,
|
||||
* trailerField [3] INTEGER DEFAULT 1 }
|
||||
* -- Note that the tags in this Sequence are explicit.
|
||||
*
|
||||
* RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
|
||||
* of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
|
||||
* option. Enfore this at parsing time.
|
||||
*/
|
||||
int x509_get_rsassa_pss_params( const x509_buf *params,
|
||||
md_type_t *md_alg, md_type_t *mgf_md,
|
||||
int *salt_len )
|
||||
{
|
||||
int ret;
|
||||
unsigned char *p;
|
||||
const unsigned char *end, *end2;
|
||||
size_t len;
|
||||
x509_buf alg_id, alg_params;
|
||||
|
||||
/* First set everything to defaults */
|
||||
*md_alg = POLARSSL_MD_SHA1;
|
||||
*mgf_md = POLARSSL_MD_SHA1;
|
||||
*salt_len = 20;
|
||||
|
||||
/* Make sure params is a SEQUENCE and setup bounds */
|
||||
if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG +
|
||||
POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
|
||||
|
||||
p = (unsigned char *) params->p;
|
||||
end = p + params->len;
|
||||
|
||||
if( p == end )
|
||||
return( 0 );
|
||||
|
||||
/*
|
||||
* HashAlgorithm
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
|
||||
{
|
||||
end2 = p + len;
|
||||
|
||||
/* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
|
||||
if( ( ret = x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
if( p != end2 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
if( p == end )
|
||||
return( 0 );
|
||||
|
||||
/*
|
||||
* MaskGenAlgorithm
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
|
||||
{
|
||||
end2 = p + len;
|
||||
|
||||
/* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
|
||||
if( ( ret = x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Only MFG1 is recognised for now */
|
||||
if( ! OID_CMP( OID_MGF1, &alg_id ) )
|
||||
return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE +
|
||||
POLARSSL_ERR_OID_NOT_FOUND );
|
||||
|
||||
/* Parse HashAlgorithm */
|
||||
if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( p != end2 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
if( p == end )
|
||||
return( 0 );
|
||||
|
||||
/*
|
||||
* salt_len
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2 ) ) == 0 )
|
||||
{
|
||||
end2 = p + len;
|
||||
|
||||
if( ( ret = asn1_get_int( &p, end2, salt_len ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
if( p != end2 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
if( p == end )
|
||||
return( 0 );
|
||||
|
||||
/*
|
||||
* trailer_field (if present, must be 1)
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) == 0 )
|
||||
{
|
||||
int trailer_field;
|
||||
|
||||
end2 = p + len;
|
||||
|
||||
if( ( ret = asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
if( p != end2 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
if( trailer_field != 1 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG );
|
||||
}
|
||||
else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
if( p != end )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
|
||||
|
||||
/*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
@ -338,14 +555,51 @@ int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
|
||||
pk_type_t *pk_alg )
|
||||
/*
|
||||
* Get signature algorithm from alg OID and optional parameters
|
||||
*/
|
||||
int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params,
|
||||
md_type_t *md_alg, pk_type_t *pk_alg,
|
||||
void **sig_opts )
|
||||
{
|
||||
int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
|
||||
int ret;
|
||||
|
||||
if( ret != 0 )
|
||||
if( *sig_opts != NULL )
|
||||
return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
|
||||
|
||||
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
|
||||
if( *pk_alg == POLARSSL_PK_RSASSA_PSS )
|
||||
{
|
||||
pk_rsassa_pss_options *pss_opts;
|
||||
|
||||
pss_opts = polarssl_malloc( sizeof( pk_rsassa_pss_options ) );
|
||||
if( pss_opts == NULL )
|
||||
return( POLARSSL_ERR_X509_MALLOC_FAILED );
|
||||
|
||||
ret = x509_get_rsassa_pss_params( sig_params,
|
||||
md_alg,
|
||||
&pss_opts->mgf1_hash_id,
|
||||
&pss_opts->expected_salt_len );
|
||||
if( ret != 0 )
|
||||
{
|
||||
polarssl_free( pss_opts );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*sig_opts = (void *) pss_opts;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Make sure parameters are absent or NULL */
|
||||
if( ( sig_params->tag != ASN1_NULL && sig_params->tag != 0 ) ||
|
||||
sig_params->len != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_ALG );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -581,6 +835,51 @@ int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
|
||||
return( (int) ( size - n ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper for writing signature algorithms
|
||||
*/
|
||||
int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid,
|
||||
pk_type_t pk_alg, md_type_t md_alg,
|
||||
const void *sig_opts )
|
||||
{
|
||||
int ret;
|
||||
char *p = buf;
|
||||
size_t n = size;
|
||||
const char *desc = NULL;
|
||||
|
||||
ret = oid_get_sig_alg_desc( sig_oid, &desc );
|
||||
if( ret != 0 )
|
||||
ret = snprintf( p, n, "???" );
|
||||
else
|
||||
ret = snprintf( p, n, "%s", desc );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
|
||||
if( pk_alg == POLARSSL_PK_RSASSA_PSS )
|
||||
{
|
||||
const pk_rsassa_pss_options *pss_opts;
|
||||
const md_info_t *md_info, *mgf_md_info;
|
||||
|
||||
pss_opts = (const pk_rsassa_pss_options *) sig_opts;
|
||||
|
||||
md_info = md_info_from_type( md_alg );
|
||||
mgf_md_info = md_info_from_type( pss_opts->mgf1_hash_id );
|
||||
|
||||
ret = snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
|
||||
md_info ? md_info->name : "???",
|
||||
mgf_md_info ? mgf_md_info->name : "???",
|
||||
pss_opts->expected_salt_len );
|
||||
SAFE_SNPRINTF();
|
||||
}
|
||||
#else
|
||||
((void) pk_alg);
|
||||
((void) md_alg);
|
||||
((void) sig_opts);
|
||||
#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
|
||||
|
||||
return( (int) size - n );
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper for writing "RSA key size", "EC key size", etc
|
||||
*/
|
||||
|
@ -256,11 +256,16 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
|
||||
size_t len;
|
||||
unsigned char *p, *end;
|
||||
x509_crl *crl;
|
||||
x509_buf sig_params1, sig_params2;
|
||||
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
size_t use_len;
|
||||
pem_context pem;
|
||||
#endif
|
||||
|
||||
memset( &sig_params1, 0, sizeof( x509_buf ) );
|
||||
memset( &sig_params2, 0, sizeof( x509_buf ) );
|
||||
|
||||
crl = chain;
|
||||
|
||||
/*
|
||||
@ -379,7 +384,7 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
|
||||
* signature AlgorithmIdentifier
|
||||
*/
|
||||
if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
|
||||
( ret = x509_get_alg_null( &p, end, &crl->sig_oid1 ) ) != 0 )
|
||||
( ret = x509_get_alg( &p, end, &crl->sig_oid1, &sig_params1 ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
@ -393,8 +398,9 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
|
||||
return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
|
||||
&crl->sig_pk ) ) != 0 )
|
||||
if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &sig_params1,
|
||||
&crl->sig_md, &crl->sig_pk,
|
||||
&crl->sig_opts ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
|
||||
@ -484,14 +490,16 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signatureValue BIT STRING
|
||||
*/
|
||||
if( ( ret = x509_get_alg_null( &p, end, &crl->sig_oid2 ) ) != 0 )
|
||||
if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, &sig_params2 ) ) != 0 )
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( crl->sig_oid1.len != crl->sig_oid2.len ||
|
||||
memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
|
||||
memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 ||
|
||||
sig_params1.len != sig_params2.len ||
|
||||
memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0)
|
||||
{
|
||||
x509_crl_free( crl );
|
||||
return( POLARSSL_ERR_X509_SIG_MISMATCH );
|
||||
@ -617,7 +625,6 @@ int x509_crl_info( char *buf, size_t size, const char *prefix,
|
||||
int ret;
|
||||
size_t n;
|
||||
char *p;
|
||||
const char *desc;
|
||||
const x509_crl_entry *entry;
|
||||
|
||||
p = buf;
|
||||
@ -674,11 +681,8 @@ int x509_crl_info( char *buf, size_t size, const char *prefix,
|
||||
ret = snprintf( p, n, "\n%ssigned using : ", prefix );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
|
||||
if( ret != 0 )
|
||||
ret = snprintf( p, n, "???" );
|
||||
else
|
||||
ret = snprintf( p, n, "%s", desc );
|
||||
ret = x509_sig_alg_gets( p, n, &crl->sig_oid1, crl->sig_pk, crl->sig_md,
|
||||
crl->sig_opts );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = snprintf( p, n, "\n" );
|
||||
@ -712,6 +716,10 @@ void x509_crl_free( x509_crl *crl )
|
||||
|
||||
do
|
||||
{
|
||||
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
|
||||
polarssl_free( crl_cur->sig_opts );
|
||||
#endif
|
||||
|
||||
name_cur = crl_cur->issuer.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
|
@ -534,6 +534,10 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
|
||||
int ret;
|
||||
size_t len;
|
||||
unsigned char *p, *end, *crt_end;
|
||||
x509_buf sig_params1, sig_params2;
|
||||
|
||||
memset( &sig_params1, 0, sizeof( x509_buf ) );
|
||||
memset( &sig_params2, 0, sizeof( x509_buf ) );
|
||||
|
||||
/*
|
||||
* Check for valid input
|
||||
@ -597,7 +601,8 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
|
||||
*/
|
||||
if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
|
||||
( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
|
||||
( ret = x509_get_alg_null( &p, end, &crt->sig_oid1 ) ) != 0 )
|
||||
( ret = x509_get_alg( &p, end, &crt->sig_oid1,
|
||||
&sig_params1 ) ) != 0 )
|
||||
{
|
||||
x509_crt_free( crt );
|
||||
return( ret );
|
||||
@ -611,8 +616,9 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
|
||||
return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
|
||||
&crt->sig_pk ) ) != 0 )
|
||||
if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &sig_params1,
|
||||
&crt->sig_md, &crt->sig_pk,
|
||||
&crt->sig_opts ) ) != 0 )
|
||||
{
|
||||
x509_crt_free( crt );
|
||||
return( ret );
|
||||
@ -738,14 +744,16 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signatureValue BIT STRING
|
||||
*/
|
||||
if( ( ret = x509_get_alg_null( &p, end, &crt->sig_oid2 ) ) != 0 )
|
||||
if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, &sig_params2 ) ) != 0 )
|
||||
{
|
||||
x509_crt_free( crt );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( crt->sig_oid1.len != crt->sig_oid2.len ||
|
||||
memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
|
||||
memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 ||
|
||||
sig_params1.len != sig_params2.len ||
|
||||
memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0)
|
||||
{
|
||||
x509_crt_free( crt );
|
||||
return( POLARSSL_ERR_X509_SIG_MISMATCH );
|
||||
@ -1244,7 +1252,6 @@ int x509_crt_info( char *buf, size_t size, const char *prefix,
|
||||
int ret;
|
||||
size_t n;
|
||||
char *p;
|
||||
const char *desc = NULL;
|
||||
char key_size_str[BEFORE_COLON];
|
||||
|
||||
p = buf;
|
||||
@ -1287,11 +1294,8 @@ int x509_crt_info( char *buf, size_t size, const char *prefix,
|
||||
ret = snprintf( p, n, "\n%ssigned using : ", prefix );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
|
||||
if( ret != 0 )
|
||||
ret = snprintf( p, n, "???" );
|
||||
else
|
||||
ret = snprintf( p, n, "%s", desc );
|
||||
ret = x509_sig_alg_gets( p, n, &crt->sig_oid1, crt->sig_pk,
|
||||
crt->sig_md, crt->sig_opts );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
/* Key size */
|
||||
@ -1488,9 +1492,9 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
|
||||
|
||||
md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
|
||||
|
||||
if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 ||
|
||||
pk_verify( &ca->pk, crl_list->sig_md, hash, md_info->size,
|
||||
crl_list->sig.p, crl_list->sig.len ) != 0 )
|
||||
if( pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
|
||||
crl_list->sig_md, hash, md_info->size,
|
||||
crl_list->sig.p, crl_list->sig.len ) != 0 )
|
||||
{
|
||||
flags |= BADCRL_NOT_TRUSTED;
|
||||
break;
|
||||
@ -1655,9 +1659,9 @@ static int x509_crt_verify_top(
|
||||
continue;
|
||||
}
|
||||
|
||||
if( pk_can_do( &trust_ca->pk, child->sig_pk ) == 0 ||
|
||||
pk_verify( &trust_ca->pk, child->sig_md, hash, md_info->size,
|
||||
child->sig.p, child->sig.len ) != 0 )
|
||||
if( pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
|
||||
child->sig_md, hash, md_info->size,
|
||||
child->sig.p, child->sig.len ) != 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1744,9 +1748,9 @@ static int x509_crt_verify_child(
|
||||
{
|
||||
md( md_info, child->tbs.p, child->tbs.len, hash );
|
||||
|
||||
if( pk_can_do( &parent->pk, child->sig_pk ) == 0 ||
|
||||
pk_verify( &parent->pk, child->sig_md, hash, md_info->size,
|
||||
child->sig.p, child->sig.len ) != 0 )
|
||||
if( pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
|
||||
child->sig_md, hash, md_info->size,
|
||||
child->sig.p, child->sig.len ) != 0 )
|
||||
{
|
||||
*flags |= BADCERT_NOT_TRUSTED;
|
||||
}
|
||||
@ -1917,6 +1921,10 @@ void x509_crt_free( x509_crt *crt )
|
||||
{
|
||||
pk_free( &cert_cur->pk );
|
||||
|
||||
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
|
||||
polarssl_free( cert_cur->sig_opts );
|
||||
#endif
|
||||
|
||||
name_cur = cert_cur->issuer.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
|
@ -93,11 +93,14 @@ int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen )
|
||||
int ret;
|
||||
size_t len;
|
||||
unsigned char *p, *end;
|
||||
x509_buf sig_params;
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
size_t use_len;
|
||||
pem_context pem;
|
||||
#endif
|
||||
|
||||
memset( &sig_params, 0, sizeof( x509_buf ) );
|
||||
|
||||
/*
|
||||
* Check for valid input
|
||||
*/
|
||||
@ -247,14 +250,15 @@ int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen )
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signature BIT STRING
|
||||
*/
|
||||
if( ( ret = x509_get_alg_null( &p, end, &csr->sig_oid ) ) != 0 )
|
||||
if( ( ret = x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_sig_alg( &csr->sig_oid, &csr->sig_md,
|
||||
&csr->sig_pk ) ) != 0 )
|
||||
if( ( ret = x509_get_sig_alg( &csr->sig_oid, &sig_params,
|
||||
&csr->sig_md, &csr->sig_pk,
|
||||
&csr->sig_opts ) ) != 0 )
|
||||
{
|
||||
x509_csr_free( csr );
|
||||
return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
|
||||
@ -361,7 +365,6 @@ int x509_csr_info( char *buf, size_t size, const char *prefix,
|
||||
int ret;
|
||||
size_t n;
|
||||
char *p;
|
||||
const char *desc;
|
||||
char key_size_str[BEFORE_COLON];
|
||||
|
||||
p = buf;
|
||||
@ -379,11 +382,8 @@ int x509_csr_info( char *buf, size_t size, const char *prefix,
|
||||
ret = snprintf( p, n, "\n%ssigned using : ", prefix );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
ret = oid_get_sig_alg_desc( &csr->sig_oid, &desc );
|
||||
if( ret != 0 )
|
||||
ret = snprintf( p, n, "???" );
|
||||
else
|
||||
ret = snprintf( p, n, "%s", desc );
|
||||
ret = x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
|
||||
csr->sig_opts );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
|
||||
@ -420,6 +420,10 @@ void x509_csr_free( x509_csr *csr )
|
||||
|
||||
pk_free( &csr->pk );
|
||||
|
||||
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
|
||||
polarssl_free( csr->sig_opts );
|
||||
#endif
|
||||
|
||||
name_cur = csr->subject.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
|
Reference in New Issue
Block a user