Browse Source

Only compute length of OID data once.

Signed-off-by: Steffen Jaeckel <[email protected]>
Steffen Jaeckel 3 weeks ago
parent
commit
ae50082c0f

+ 2 - 1
src/headers/tomcrypt_private.h

@@ -588,7 +588,8 @@ int der_length_asn1_length(unsigned long len, unsigned long *outlen);
 int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
 int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
                            unsigned long *outlen, unsigned long *payloadlen);
                            unsigned long *outlen, unsigned long *payloadlen);
 
 
-unsigned long der_object_identifier_bits(unsigned long x);
+int der_length_object_identifier_full(const unsigned long *words,  unsigned long  nwords,
+                                            unsigned long *outlen, unsigned long *datalen);
 
 
 int der_ia5_char_encode(int c);
 int der_ia5_char_encode(int c);
 int der_ia5_value_decode(int v);
 int der_ia5_value_decode(int v);

+ 1 - 12
src/pk/asn1/der/object_identifier/der_encode_object_identifier.c

@@ -27,7 +27,7 @@ int der_encode_object_identifier(const unsigned long *words, unsigned long  nwor
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(outlen != NULL);
 
 
    /* check length */
    /* check length */
-   if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) {
+   if ((err = der_length_object_identifier_full(words, nwords, &x, &z)) != CRYPT_OK) {
       return err;
       return err;
    }
    }
    if (x > *outlen) {
    if (x > *outlen) {
@@ -35,17 +35,6 @@ int der_encode_object_identifier(const unsigned long *words, unsigned long  nwor
       return CRYPT_BUFFER_OVERFLOW;
       return CRYPT_BUFFER_OVERFLOW;
    }
    }
 
 
-   /* compute length to store OID data */
-   z = 0;
-   wordbuf = words[0] * 40 + words[1];
-   for (y = 1; y < nwords; y++) {
-       t = der_object_identifier_bits(wordbuf);
-       z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
-       if (y < nwords - 1) {
-          wordbuf = words[y + 1];
-       }
-   }
-
    /* store header + length */
    /* store header + length */
    x = 0;
    x = 0;
    out[x++] = 0x06;
    out[x++] = 0x06;

+ 18 - 10
src/pk/asn1/der/object_identifier/der_length_object_identifier.c

@@ -9,7 +9,7 @@
 
 
 #ifdef LTC_DER
 #ifdef LTC_DER
 
 
-unsigned long der_object_identifier_bits(unsigned long x)
+static LTC_INLINE unsigned long s_der_object_identifier_bits(unsigned long x)
 {
 {
 #if defined(LTC_HAVE_CLZL_BUILTIN)
 #if defined(LTC_HAVE_CLZL_BUILTIN)
    if (x == 0)
    if (x == 0)
@@ -26,14 +26,7 @@ unsigned long der_object_identifier_bits(unsigned long x)
 #endif
 #endif
 }
 }
 
 
-/**
-  Gets length of DER encoding of Object Identifier
-  @param nwords   The number of OID words
-  @param words    The actual OID words to get the size of
-  @param outlen   [out] The length of the DER encoding for the given string
-  @return CRYPT_OK if successful
-*/
-int der_length_object_identifier(const unsigned long *words, unsigned long nwords, unsigned long *outlen)
+int der_length_object_identifier_full(const unsigned long *words, unsigned long nwords, unsigned long *outlen, unsigned long *datalen)
 {
 {
    unsigned long y, z, t, wordbuf;
    unsigned long y, z, t, wordbuf;
 
 
@@ -55,7 +48,7 @@ int der_length_object_identifier(const unsigned long *words, unsigned long nword
    z = 0;
    z = 0;
    wordbuf = words[0] * 40 + words[1];
    wordbuf = words[0] * 40 + words[1];
    for (y = 1; y < nwords; y++) {
    for (y = 1; y < nwords; y++) {
-       t = der_object_identifier_bits(wordbuf);
+       t = s_der_object_identifier_bits(wordbuf);
        z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
        z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
        if (y < nwords - 1) {
        if (y < nwords - 1) {
           /* grab next word */
           /* grab next word */
@@ -63,6 +56,9 @@ int der_length_object_identifier(const unsigned long *words, unsigned long nword
        }
        }
    }
    }
 
 
+   if (datalen) {
+      *datalen = z;
+   }
    /* now depending on the length our length encoding changes */
    /* now depending on the length our length encoding changes */
    if (z < 128) {
    if (z < 128) {
       z += 2;
       z += 2;
@@ -78,4 +74,16 @@ int der_length_object_identifier(const unsigned long *words, unsigned long nword
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 
+/**
+  Gets length of DER encoding of Object Identifier
+  @param nwords   The number of OID words
+  @param words    The actual OID words to get the size of
+  @param outlen   [out] The length of the DER encoding for the given string
+  @return CRYPT_OK if successful
+*/
+int der_length_object_identifier(const unsigned long *words, unsigned long nwords, unsigned long *outlen)
+{
+   return der_length_object_identifier_full(words, nwords, outlen, NULL);
+}
+
 #endif
 #endif