From ccc7cf4af2b99bc85fe752ebb9a808d2839faaef Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Mon, 19 Feb 2018 13:28:25 +0100 Subject: [PATCH] improve/fix `x509_decode_subject_public_key_info()` 1. only pass in as many alg_id sequence elements as used 2. we weren't able to import into exactly sized public_key buffers 3. fix types in API signature 4. make `public_key` arg a `const*` --- src/headers/tomcrypt_pk.h | 6 ++--- .../x509_decode_subject_public_key_info.c | 25 +++++++++++++------ .../x509_encode_subject_public_key_info.c | 6 ++--- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index 54b9967a..d9062784 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -847,12 +847,12 @@ int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen /* internal helper functions */ /* SUBJECT PUBLIC KEY INFO */ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, - unsigned int algorithm, void* public_key, unsigned long public_key_len, - unsigned long parameters_type, void* parameters, unsigned long parameters_len); + unsigned int algorithm, const void* public_key, unsigned long public_key_len, + ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len); int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, unsigned int algorithm, void* public_key, unsigned long* public_key_len, - unsigned long parameters_type, void* parameters, unsigned long *parameters_len); + ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); #endif /* LTC_SOURCE */ #endif diff --git a/src/pk/asn1/x509/x509_decode_subject_public_key_info.c b/src/pk/asn1/x509/x509_decode_subject_public_key_info.c index c68b4a3b..8fef4e2a 100644 --- a/src/pk/asn1/x509/x509_decode_subject_public_key_info.c +++ b/src/pk/asn1/x509/x509_decode_subject_public_key_info.c @@ -39,10 +39,10 @@ */ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, unsigned int algorithm, void* public_key, unsigned long* public_key_len, - unsigned long parameters_type, void* parameters, unsigned long *parameters_len) + ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len) { int err; - unsigned long len; + unsigned long len, alg_id_num; oid_st oid; unsigned char *tmpbuf; unsigned long tmpoid[16]; @@ -52,7 +52,9 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen != 0); LTC_ARGCHK(public_key_len != NULL); - LTC_ARGCHK(parameters_len != NULL); + if (parameters_type != LTC_ASN1_EOL) { + LTC_ARGCHK(parameters_len != NULL); + } err = pk_get_oid(algorithm, &oid); if (err != CRYPT_OK) { @@ -68,20 +70,27 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i /* this includes the internal hash ID and optional params (NULL in this case) */ LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); - LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, *parameters_len); + if (parameters_type == LTC_ASN1_EOL) { + alg_id_num = 1; + } + else { + LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, *parameters_len); + alg_id_num = 2; + } /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet */ - LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2); + LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, alg_id_num); LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, inlen*8U); err=der_decode_sequence(in, inlen, subject_pubkey, 2UL); if (err != CRYPT_OK) { goto LBL_ERR; } - - *parameters_len = alg_id[1].size; + if (parameters_type != LTC_ASN1_EOL) { + *parameters_len = alg_id[1].size; + } if ((alg_id[0].size != oid.OIDlen) || XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) { @@ -91,7 +100,7 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i } len = subject_pubkey[1].size/8; - if (*public_key_len > len) { + if (*public_key_len >= len) { XMEMCPY(public_key, subject_pubkey[1].data, len); *public_key_len = len; } else { diff --git a/src/pk/asn1/x509/x509_encode_subject_public_key_info.c b/src/pk/asn1/x509/x509_encode_subject_public_key_info.c index 8148a185..25c1195d 100644 --- a/src/pk/asn1/x509/x509_encode_subject_public_key_info.c +++ b/src/pk/asn1/x509/x509_encode_subject_public_key_info.c @@ -38,8 +38,8 @@ @return CRYPT_OK on success */ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, - unsigned int algorithm, void* public_key, unsigned long public_key_len, - unsigned long parameters_type, void* parameters, unsigned long parameters_len) + unsigned int algorithm, const void* public_key, unsigned long public_key_len, + ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len) { int err; ltc_asn1_list alg_id[2]; @@ -54,7 +54,7 @@ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outle } LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen); - LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, parameters_len); + LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len); return der_encode_sequence_multi(out, outlen, LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,