From e6c8366b46c2d767ad2e724f6d4281f59d65dfa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 14 Apr 2015 11:18:04 +0200 Subject: [PATCH] Fix bug in pk_parse_key() --- ChangeLog | 2 + library/pkparse.c | 97 ++++++++++++++------------- tests/data_files/ec_prv.noopt.der | Bin 0 -> 67 bytes tests/suites/test_suite_pkparse.data | 4 ++ 4 files changed, 56 insertions(+), 47 deletions(-) create mode 100644 tests/data_files/ec_prv.noopt.der diff --git a/ChangeLog b/ChangeLog index b24b2d688..09d7c7b89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,8 @@ Features errors on use of deprecated functions. Bugfix + * Fix bug in pk_parse_key() that caused some valid private EC keys to be + rejected. * Fix bug in Via Padlock support (found by Nikos Mavrogiannopoulos). * Fix thread safety bug in RSA operations (found by Fredrik Axelsson). * Fix hardclock() (only used in the benchmarking program) with some diff --git a/library/pkparse.c b/library/pkparse.c index 06fb2929f..39c51f648 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -761,58 +761,61 @@ static int pk_parse_key_sec1_der( ecp_keypair *eck, p += len; - /* - * Is 'parameters' present? - */ - if( ( ret = asn1_get_tag( &p, end, &len, - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 ) + pubkey_done = 0; + if( p != end ) { - if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || - ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) + /* + * Is 'parameters' present? + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 ) + { + if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || + ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) + { + ecp_keypair_free( eck ); + return( ret ); + } + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + { + ecp_keypair_free( eck ); + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + /* + * 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 = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) + { + end2 = p + len; + + if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( p + len != end2 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 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 != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); + } + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) { ecp_keypair_free( eck ); - return( ret ); - } - } - else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) - { - ecp_keypair_free( eck ); - return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); - } - - /* - * Is 'publickey' present? If not, or if we can't read it (eg because it - * is compressed), create it from the private key. - */ - pubkey_done = 0; - if( ( ret = asn1_get_tag( &p, end, &len, - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) - { - end2 = p + len; - - if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); - - if( p + len != end2 ) - return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + - POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); - - if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 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 != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ) - return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); } - } - else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) - { - ecp_keypair_free( eck ); - return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); } if( ! pubkey_done && diff --git a/tests/data_files/ec_prv.noopt.der b/tests/data_files/ec_prv.noopt.der new file mode 100644 index 0000000000000000000000000000000000000000..fde16a17a7551d655f8cb0e66febe4809a664845 GIT binary patch literal 67 zcmXqTWMX765N2c7YV$Z}%f!gW0cJ2Wva_fgs4_7!vM9Vh?a{s>m+gy*#G)C0*3J3b V_^ST