Browse Source

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*`
Steffen Jaeckel 7 years ago
parent
commit
ccc7cf4af2

+ 3 - 3
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

+ 17 - 8
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 {

+ 3 - 3
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,