diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h index 5a9ed7dce..9d3218d58 100644 --- a/include/polarssl/x509.h +++ b/include/polarssl/x509.h @@ -278,6 +278,8 @@ int x509_get_alg_null( unsigned char **p, const unsigned char *end, x509_buf *alg ); int x509_get_alg( unsigned char **p, const unsigned char *end, x509_buf *alg, x509_buf *params ); +int x509_get_rsassa_pss_params( const x509_buf *params, md_type_t *md_alg, + int *salt_len, int *trailer_field ); int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig ); int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg, pk_type_t *pk_alg ); diff --git a/library/x509.c b/library/x509.c index 991551865..45dcea0fd 100644 --- a/library/x509.c +++ b/library/x509.c @@ -137,6 +137,92 @@ int x509_get_alg( unsigned char **p, const unsigned char *end, 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. + */ +int x509_get_rsassa_pss_params( const x509_buf *params, + md_type_t *md_alg, + int *salt_len, + int *trailer_field ) +{ + int ret; + unsigned char *p; + const unsigned char *end; + size_t len; + x509_buf alg_id; + + /* First set everything to defaults */ + *md_alg = POLARSSL_MD_SHA1; + *salt_len = 20; + *trailer_field = 1; + + /* 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 ); + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 ) + { + /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ + // TODO: WIP + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) + { + /* MaskGenAlgorithm ::= AlgorithmIdentifier */ + // TODO: WIP + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2 ) ) == 0 ) + { + /* salt_len */ + if( ( ret = asn1_get_int( &p, p + len, salt_len ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) == 0 ) + { + /* trailer_field */ + if( ( ret = asn1_get_int( &p, p + len, trailer_field ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + } + 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 ); +} + /* * AttributeTypeAndValue ::= SEQUENCE { * type AttributeType, diff --git a/library/x509_crt.c b/library/x509_crt.c index b9f226b07..6d206a3cd 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -622,6 +622,22 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, return( ret ); } + if( crt->sig_pk == POLARSSL_PK_RSASSA_PSS ) + { + int salt_len, trailer_field; + + if( ( ret = x509_get_rsassa_pss_params( &crt->sig_params, + &crt->sig_md, &salt_len, &trailer_field ) ) != 0 ) + return( ret ); + } + else + { + /* Make sure parameters were absent or NULL */ + if( ( crt->sig_params.tag != ASN1_NULL && crt->sig_params.tag != 0 ) || + crt->sig_params.len != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG ); + } + /* * issuer Name */ @@ -1300,6 +1316,21 @@ int x509_crt_info( char *buf, size_t size, const char *prefix, ret = snprintf( p, n, "%s", desc ); SAFE_SNPRINTF(); + if( crt->sig_pk == POLARSSL_PK_RSASSA_PSS ) + { + md_type_t md_alg; + int salt_len, trailer_field; + + if( ( ret = x509_get_rsassa_pss_params( &crt->sig_params, + &md_alg, &salt_len, &trailer_field ) ) != 0 ) + return( ret ); + + // TODO: SHA1 harcoded twice (WIP) + ret = snprintf( p, n, " (SHA1, MGF1-SHA1, %d, %d)", + salt_len, trailer_field ); + SAFE_SNPRINTF(); + } + /* Key size */ if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON, pk_get_name( &crt->pk ) ) ) != 0 ) diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 7531587d1..057c353a4 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -44,7 +44,7 @@ x509_cert_info:"data_files/cert_sha512.crt":"cert. version \: 3\nserial numb X509 Certificate information RSA-PSS, SHA1 Digest depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_RSA_C -x509_cert_info:"data_files/server9.crt":"cert. version \: 3\nserial number \: 16\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2014-01-20 13\:38\:16\nexpires on \: 2024-01-18 13\:38\:16\nsigned using \: RSASSA-PSS\nRSA key size \: 1024 bits\n" +x509_cert_info:"data_files/server9.crt":"cert. version \: 3\nserial number \: 16\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2014-01-20 13\:38\:16\nexpires on \: 2024-01-18 13\:38\:16\nsigned using \: RSASSA-PSS (SHA1, MGF1-SHA1, 234, 1)\nRSA key size \: 1024 bits\n" X509 Certificate information EC, SHA1 Digest depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED