Browse Source

use new ASN.1 functionality

Steffen Jaeckel 7 years ago
parent
commit
756bc7fa21
26 changed files with 138 additions and 436 deletions
  1. 5 18
      src/pk/asn1/der/bit/der_decode_bit_string.c
  2. 5 18
      src/pk/asn1/der/bit/der_decode_raw_bit_string.c
  3. 4 9
      src/pk/asn1/der/bit/der_encode_bit_string.c
  4. 4 9
      src/pk/asn1/der/bit/der_encode_raw_bit_string.c
  5. 6 12
      src/pk/asn1/der/bit/der_length_bit_string.c
  6. 6 17
      src/pk/asn1/der/ia5/der_decode_ia5_string.c
  7. 4 16
      src/pk/asn1/der/ia5/der_encode_ia5_string.c
  8. 4 14
      src/pk/asn1/der/ia5/der_length_ia5_string.c
  9. 9 39
      src/pk/asn1/der/integer/der_decode_integer.c
  10. 5 18
      src/pk/asn1/der/integer/der_encode_integer.c
  11. 6 20
      src/pk/asn1/der/integer/der_length_integer.c
  12. 5 12
      src/pk/asn1/der/object_identifier/der_decode_object_identifier.c
  13. 4 11
      src/pk/asn1/der/object_identifier/der_encode_object_identifier.c
  14. 6 16
      src/pk/asn1/der/octet/der_decode_octet_string.c
  15. 4 16
      src/pk/asn1/der/octet/der_encode_octet_string.c
  16. 6 14
      src/pk/asn1/der/octet/der_length_octet_string.c
  17. 6 17
      src/pk/asn1/der/printable_string/der_decode_printable_string.c
  18. 4 16
      src/pk/asn1/der/printable_string/der_encode_printable_string.c
  19. 4 14
      src/pk/asn1/der/printable_string/der_length_printable_string.c
  20. 1 23
      src/pk/asn1/der/set/der_encode_set.c
  21. 9 15
      src/pk/asn1/der/short_integer/der_length_short_integer.c
  22. 6 17
      src/pk/asn1/der/teletex_string/der_decode_teletex_string.c
  23. 4 14
      src/pk/asn1/der/teletex_string/der_length_teletex_string.c
  24. 5 16
      src/pk/asn1/der/utf8/der_decode_utf8_string.c
  25. 12 31
      src/pk/asn1/der/utf8/der_encode_utf8_string.c
  26. 4 14
      src/pk/asn1/der/utf8/der_length_utf8_string.c

+ 5 - 18
src/pk/asn1/der/bit/der_decode_bit_string.c

@@ -28,6 +28,7 @@ int der_decode_bit_string(const unsigned char *in,  unsigned long inlen,
                                 unsigned char *out, unsigned long *outlen)
                                 unsigned char *out, unsigned long *outlen)
 {
 {
    unsigned long dlen, blen, x, y;
    unsigned long dlen, blen, x, y;
+   int err;
 
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(out    != NULL);
@@ -47,25 +48,11 @@ int der_decode_bit_string(const unsigned char *in,  unsigned long inlen,
    x = 1;
    x = 1;
 
 
    /* get the length of the data */
    /* get the length of the data */
-   if (in[x] & 0x80) {
-      /* long format get number of length bytes */
-      y = in[x++] & 0x7F;
-
-      /* invalid if 0 or > 2 */
-      if (y == 0 || y > 2) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* read the data len */
-      dlen = 0;
-      while (y--) {
-         dlen = (dlen << 8) | (unsigned long)in[x++];
-      }
-   } else {
-      /* short format */
-      dlen = in[x++] & 0x7F;
+   y = inlen - 1;
+   if ((err = der_decode_asn1_length(in + x, &y, &dlen)) != CRYPT_OK) {
+      return err;
    }
    }
-
+   x += y;
    /* is the data len too long or too short? */
    /* is the data len too long or too short? */
    if ((dlen == 0) || (dlen + x > inlen)) {
    if ((dlen == 0) || (dlen + x > inlen)) {
        return CRYPT_INVALID_PACKET;
        return CRYPT_INVALID_PACKET;

+ 5 - 18
src/pk/asn1/der/bit/der_decode_raw_bit_string.c

@@ -31,6 +31,7 @@ int der_decode_raw_bit_string(const unsigned char *in,  unsigned long inlen,
                                 unsigned char *out, unsigned long *outlen)
                                 unsigned char *out, unsigned long *outlen)
 {
 {
    unsigned long dlen, blen, x, y;
    unsigned long dlen, blen, x, y;
+   int err;
 
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(out    != NULL);
@@ -50,25 +51,11 @@ int der_decode_raw_bit_string(const unsigned char *in,  unsigned long inlen,
    x = 1;
    x = 1;
 
 
    /* get the length of the data */
    /* get the length of the data */
-   if (in[x] & 0x80) {
-      /* long format get number of length bytes */
-      y = in[x++] & 0x7F;
-
-      /* invalid if 0 or > 2 */
-      if (y == 0 || y > 2) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* read the data len */
-      dlen = 0;
-      while (y--) {
-         dlen = (dlen << 8) | (unsigned long)in[x++];
-      }
-   } else {
-      /* short format */
-      dlen = in[x++] & 0x7F;
+   y = inlen - 1;
+   if ((err = der_decode_asn1_length(in + x, &y, &dlen)) != CRYPT_OK) {
+      return err;
    }
    }
-
+   x += y;
    /* is the data len too long or too short? */
    /* is the data len too long or too short? */
    if ((dlen == 0) || (dlen + x > inlen)) {
    if ((dlen == 0) || (dlen + x > inlen)) {
        return CRYPT_INVALID_PACKET;
        return CRYPT_INVALID_PACKET;

+ 4 - 9
src/pk/asn1/der/bit/der_encode_bit_string.c

@@ -50,16 +50,11 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
    y = ((inlen + 7) >> 3) + 1;
    y = ((inlen + 7) >> 3) + 1;
 
 
    out[x++] = 0x03;
    out[x++] = 0x03;
-   if (y < 128) {
-      out[x++] = (unsigned char)y;
-   } else if (y < 256) {
-      out[x++] = 0x81;
-      out[x++] = (unsigned char)y;
-   } else if (y < 65536) {
-      out[x++] = 0x82;
-      out[x++] = (unsigned char)((y>>8)&255);
-      out[x++] = (unsigned char)(y&255);
+   len = *outlen - x;
+   if ((err = der_encode_asn1_length(y, out + x, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += len;
 
 
    /* store number of zero padding bits */
    /* store number of zero padding bits */
    out[x++] = (unsigned char)((8 - inlen) & 7);
    out[x++] = (unsigned char)((8 - inlen) & 7);

+ 4 - 9
src/pk/asn1/der/bit/der_encode_raw_bit_string.c

@@ -52,16 +52,11 @@ int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
    y = ((inlen + 7) >> 3) + 1;
    y = ((inlen + 7) >> 3) + 1;
 
 
    out[x++] = 0x03;
    out[x++] = 0x03;
-   if (y < 128) {
-      out[x++] = (unsigned char)y;
-   } else if (y < 256) {
-      out[x++] = 0x81;
-      out[x++] = (unsigned char)y;
-   } else if (y < 65536) {
-      out[x++] = 0x82;
-      out[x++] = (unsigned char)((y>>8)&255);
-      out[x++] = (unsigned char)(y&255);
+   len = *outlen - x;
+   if ((err = der_encode_asn1_length(y, out + x, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += len;
 
 
    /* store number of zero padding bits */
    /* store number of zero padding bits */
    out[x++] = (unsigned char)((8 - inlen) & 7);
    out[x++] = (unsigned char)((8 - inlen) & 7);

+ 6 - 12
src/pk/asn1/der/bit/der_length_bit_string.c

@@ -22,24 +22,18 @@
 */
 */
 int der_length_bit_string(unsigned long nbits, unsigned long *outlen)
 int der_length_bit_string(unsigned long nbits, unsigned long *outlen)
 {
 {
-   unsigned long nbytes;
+   unsigned long nbytes, x;
+   int err;
+
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(outlen != NULL);
 
 
    /* get the number of the bytes */
    /* get the number of the bytes */
    nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1;
    nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1;
 
 
-   if (nbytes < 128) {
-      /* 03 LL PP DD DD DD ... */
-      *outlen = 2 + nbytes;
-   } else if (nbytes < 256) {
-      /* 03 81 LL PP DD DD DD ... */
-      *outlen = 3 + nbytes;
-   } else if (nbytes < 65536) {
-      /* 03 82 LL LL PP DD DD DD ... */
-      *outlen = 4 + nbytes;
-   } else {
-      return CRYPT_INVALID_ARG;
+   if ((err = der_length_asn1_length(nbytes, &x)) != CRYPT_OK) {
+      return err;
    }
    }
+   *outlen = 1 + x + nbytes;
 
 
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }

+ 6 - 17
src/pk/asn1/der/ia5/der_decode_ia5_string.c

@@ -28,7 +28,7 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
                                 unsigned char *out, unsigned long *outlen)
                                 unsigned char *out, unsigned long *outlen)
 {
 {
    unsigned long x, y, len;
    unsigned long x, y, len;
-   int           t;
+   int           t, err;
 
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(out    != NULL);
@@ -45,23 +45,12 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
    }
    }
    x = 1;
    x = 1;
 
 
-   /* decode the length */
-   if (in[x] & 0x80) {
-      /* valid # of bytes in length are 1,2,3 */
-      y = in[x] & 0x7F;
-      if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* read the length in */
-      len = 0;
-      ++x;
-      while (y--) {
-         len = (len << 8) | in[x++];
-      }
-   } else {
-      len = in[x++] & 0x7F;
+   /* get the length of the data */
+   y = inlen - x;
+   if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += y;
 
 
    /* is it too long? */
    /* is it too long? */
    if (len > *outlen) {
    if (len > *outlen) {

+ 4 - 16
src/pk/asn1/der/ia5/der_encode_ia5_string.c

@@ -47,23 +47,11 @@ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
    /* encode the header+len */
    /* encode the header+len */
    x = 0;
    x = 0;
    out[x++] = 0x16;
    out[x++] = 0x16;
-   if (inlen < 128) {
-      out[x++] = (unsigned char)inlen;
-   } else if (inlen < 256) {
-      out[x++] = 0x81;
-      out[x++] = (unsigned char)inlen;
-   } else if (inlen < 65536UL) {
-      out[x++] = 0x82;
-      out[x++] = (unsigned char)((inlen>>8)&255);
-      out[x++] = (unsigned char)(inlen&255);
-   } else if (inlen < 16777216UL) {
-      out[x++] = 0x83;
-      out[x++] = (unsigned char)((inlen>>16)&255);
-      out[x++] = (unsigned char)((inlen>>8)&255);
-      out[x++] = (unsigned char)(inlen&255);
-   } else {
-      return CRYPT_INVALID_ARG;
+   len = *outlen - x;
+   if ((err = der_encode_asn1_length(inlen, out + x, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += len;
 
 
    /* store octets */
    /* store octets */
    for (y = 0; y < inlen; y++) {
    for (y = 0; y < inlen; y++) {

+ 4 - 14
src/pk/asn1/der/ia5/der_length_ia5_string.c

@@ -154,6 +154,7 @@ int der_ia5_value_decode(int v)
 int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
 int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
 {
 {
    unsigned long x;
    unsigned long x;
+   int err;
 
 
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(octets != NULL);
    LTC_ARGCHK(octets != NULL);
@@ -165,21 +166,10 @@ int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, un
        }
        }
    }
    }
 
 
-   if (noctets < 128) {
-      /* 16 LL DD DD DD ... */
-      *outlen = 2 + noctets;
-   } else if (noctets < 256) {
-      /* 16 81 LL DD DD DD ... */
-      *outlen = 3 + noctets;
-   } else if (noctets < 65536UL) {
-      /* 16 82 LL LL DD DD DD ... */
-      *outlen = 4 + noctets;
-   } else if (noctets < 16777216UL) {
-      /* 16 83 LL LL LL DD DD DD ... */
-      *outlen = 5 + noctets;
-   } else {
-      return CRYPT_INVALID_ARG;
+   if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) {
+      return err;
    }
    }
+   *outlen = 1 + x + noctets;
 
 
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }

+ 9 - 39
src/pk/asn1/der/integer/der_decode_integer.c

@@ -25,7 +25,7 @@
 */
 */
 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num)
 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num)
 {
 {
-   unsigned long x, y, z;
+   unsigned long x, y;
    int           err;
    int           err;
 
 
    LTC_ARGCHK(num    != NULL);
    LTC_ARGCHK(num    != NULL);
@@ -42,45 +42,15 @@ int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num)
       return CRYPT_INVALID_PACKET;
       return CRYPT_INVALID_PACKET;
    }
    }
 
 
-   /* now decode the len stuff */
-   z = in[x++];
-
-   if ((z & 0x80) == 0x00) {
-      /* short form */
-
-      /* will it overflow? */
-      if (x + z > inlen) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* no so read it */
-      if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) {
-         return err;
-      }
-   } else {
-      /* long form */
-      z &= 0x7F;
-
-      /* will number of length bytes overflow? (or > 4) */
-      if (((x + z) > inlen) || (z > 4) || (z == 0)) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* now read it in */
-      y = 0;
-      while (z--) {
-         y = ((unsigned long)(in[x++])) | (y << 8);
-      }
-
-      /* now will reading y bytes overrun? */
-      if ((x + y) > inlen) {
-         return CRYPT_INVALID_PACKET;
-      }
+   /* get the length of the data */
+   inlen -= x;
+   if ((err = der_decode_asn1_length(in + x, &inlen, &y)) != CRYPT_OK) {
+      return err;
+   }
+   x += inlen;
 
 
-      /* no so read it */
-      if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) {
-         return err;
-      }
+   if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) {
+      return err;
    }
    }
 
 
    /* see if it's negative */
    /* see if it's negative */

+ 5 - 18
src/pk/asn1/der/integer/der_encode_integer.c

@@ -26,7 +26,7 @@
 */
 */
 int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen)
 int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen)
 {
 {
-   unsigned long tmplen, y;
+   unsigned long tmplen, y, len;
    int           err, leading_zero;
    int           err, leading_zero;
 
 
    LTC_ARGCHK(num    != NULL);
    LTC_ARGCHK(num    != NULL);
@@ -63,24 +63,11 @@ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen)
 
 
    /* now store initial data */
    /* now store initial data */
    *out++ = 0x02;
    *out++ = 0x02;
-   if (y < 128) {
-      /* short form */
-      *out++ = (unsigned char)y;
-   } else if (y < 256) {
-      *out++ = 0x81;
-      *out++ = (unsigned char)y;
-   } else if (y < 65536UL) {
-      *out++ = 0x82;
-      *out++ = (unsigned char)((y>>8)&255);
-      *out++ = (unsigned char)y;
-   } else if (y < 16777216UL) {
-      *out++ = 0x83;
-      *out++ = (unsigned char)((y>>16)&255);
-      *out++ = (unsigned char)((y>>8)&255);
-      *out++ = (unsigned char)y;
-   } else {
-      return CRYPT_INVALID_ARG;
+   len = *outlen - 1;
+   if ((err = der_encode_asn1_length(y, out, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   out += len;
 
 
    /* now store msbyte of zero if num is non-zero */
    /* now store msbyte of zero if num is non-zero */
    if (leading_zero) {
    if (leading_zero) {

+ 6 - 20
src/pk/asn1/der/integer/der_length_integer.c

@@ -24,7 +24,7 @@
 int der_length_integer(void *num, unsigned long *outlen)
 int der_length_integer(void *num, unsigned long *outlen)
 {
 {
    unsigned long z, len;
    unsigned long z, len;
-   int           leading_zero;
+   int           leading_zero, err;
 
 
    LTC_ARGCHK(num     != NULL);
    LTC_ARGCHK(num     != NULL);
    LTC_ARGCHK(outlen  != NULL);
    LTC_ARGCHK(outlen  != NULL);
@@ -40,35 +40,21 @@ int der_length_integer(void *num, unsigned long *outlen)
       }
       }
 
 
       /* size for bignum */
       /* size for bignum */
-      z = len = leading_zero + mp_unsigned_bin_size(num);
+      len = leading_zero + mp_unsigned_bin_size(num);
    } else {
    } else {
       /* it's negative */
       /* it's negative */
       /* find power of 2 that is a multiple of eight and greater than count bits */
       /* find power of 2 that is a multiple of eight and greater than count bits */
       z = mp_count_bits(num);
       z = mp_count_bits(num);
       z = z + (8 - (z & 7));
       z = z + (8 - (z & 7));
       if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z;
       if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z;
-      len = z = z >> 3;
+      len = z >> 3;
    }
    }
 
 
-   /* now we need a length */
-   if (z < 128) {
-      /* short form */
-      ++len;
-   } else {
-      /* long form (relies on z != 0), assumes length bytes < 128 */
-      ++len;
-
-      while (z) {
-         ++len;
-         z >>= 8;
-      }
+   if ((err = der_length_asn1_length(len, &z)) != CRYPT_OK) {
+      return err;
    }
    }
+   *outlen = 1 + z + len;
 
 
-   /* we need a 0x02 to indicate it's INTEGER */
-   ++len;
-
-   /* return length */
-   *outlen = len;
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 

+ 5 - 12
src/pk/asn1/der/object_identifier/der_decode_object_identifier.c

@@ -49,19 +49,12 @@ int der_decode_object_identifier(const unsigned char *in,    unsigned long  inle
       return CRYPT_INVALID_PACKET;
       return CRYPT_INVALID_PACKET;
    }
    }
 
 
-   /* get the length */
-   if (in[x] < 128) {
-      len = in[x++];
-   } else {
-      if (in[x] < 0x81 || in[x] > 0x82) {
-         return CRYPT_INVALID_PACKET;
-      }
-      y   = in[x++] & 0x7F;
-      len = 0;
-      while (y--) {
-         len = (len << 8) | (unsigned long)in[x++];
-      }
+   /* get the length of the data */
+   y = inlen - x;
+   if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += y;
 
 
    if (len < 1 || (len + x) > inlen) {
    if (len < 1 || (len + x) > inlen) {
       return CRYPT_INVALID_PACKET;
       return CRYPT_INVALID_PACKET;

+ 4 - 11
src/pk/asn1/der/object_identifier/der_encode_object_identifier.c

@@ -55,18 +55,11 @@ int der_encode_object_identifier(unsigned long *words, unsigned long  nwords,
    /* store header + length */
    /* store header + length */
    x = 0;
    x = 0;
    out[x++] = 0x06;
    out[x++] = 0x06;
-   if (z < 128) {
-      out[x++] = (unsigned char)z;
-   } else if (z < 256) {
-      out[x++] = 0x81;
-      out[x++] = (unsigned char)z;
-   } else if (z < 65536UL) {
-      out[x++] = 0x82;
-      out[x++] = (unsigned char)((z>>8)&255);
-      out[x++] = (unsigned char)(z&255);
-   } else {
-      return CRYPT_INVALID_ARG;
+   y = *outlen - x;
+   if ((err = der_encode_asn1_length(z, out + x, &y)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += y;
 
 
    /* store first byte */
    /* store first byte */
    wordbuf = words[0] * 40 + words[1];
    wordbuf = words[0] * 40 + words[1];

+ 6 - 16
src/pk/asn1/der/octet/der_decode_octet_string.c

@@ -28,6 +28,7 @@ int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
                                   unsigned char *out, unsigned long *outlen)
                                   unsigned char *out, unsigned long *outlen)
 {
 {
    unsigned long x, y, len;
    unsigned long x, y, len;
+   int err;
 
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(out    != NULL);
@@ -44,23 +45,12 @@ int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
    }
    }
    x = 1;
    x = 1;
 
 
-   /* decode the length */
-   if (in[x] & 0x80) {
-      /* valid # of bytes in length are 1,2,3 */
-      y = in[x] & 0x7F;
-      if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* read the length in */
-      len = 0;
-      ++x;
-      while (y--) {
-         len = (len << 8) | in[x++];
-      }
-   } else {
-      len = in[x++] & 0x7F;
+   /* get the length of the data */
+   y = inlen - x;
+   if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += y;
 
 
    /* is it too long? */
    /* is it too long? */
    if (len > *outlen) {
    if (len > *outlen) {

+ 4 - 16
src/pk/asn1/der/octet/der_encode_octet_string.c

@@ -48,23 +48,11 @@ int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
    /* encode the header+len */
    /* encode the header+len */
    x = 0;
    x = 0;
    out[x++] = 0x04;
    out[x++] = 0x04;
-   if (inlen < 128) {
-      out[x++] = (unsigned char)inlen;
-   } else if (inlen < 256) {
-      out[x++] = 0x81;
-      out[x++] = (unsigned char)inlen;
-   } else if (inlen < 65536UL) {
-      out[x++] = 0x82;
-      out[x++] = (unsigned char)((inlen>>8)&255);
-      out[x++] = (unsigned char)(inlen&255);
-   } else if (inlen < 16777216UL) {
-      out[x++] = 0x83;
-      out[x++] = (unsigned char)((inlen>>16)&255);
-      out[x++] = (unsigned char)((inlen>>8)&255);
-      out[x++] = (unsigned char)(inlen&255);
-   } else {
-      return CRYPT_INVALID_ARG;
+   len = *outlen - x;
+   if ((err = der_encode_asn1_length(inlen, out + x, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += len;
 
 
    /* store octets */
    /* store octets */
    for (y = 0; y < inlen; y++) {
    for (y = 0; y < inlen; y++) {

+ 6 - 14
src/pk/asn1/der/octet/der_length_octet_string.c

@@ -22,23 +22,15 @@
 */
 */
 int der_length_octet_string(unsigned long noctets, unsigned long *outlen)
 int der_length_octet_string(unsigned long noctets, unsigned long *outlen)
 {
 {
+   unsigned long x;
+   int err;
+
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(outlen != NULL);
 
 
-   if (noctets < 128) {
-      /* 04 LL DD DD DD ... */
-      *outlen = 2 + noctets;
-   } else if (noctets < 256) {
-      /* 04 81 LL DD DD DD ... */
-      *outlen = 3 + noctets;
-   } else if (noctets < 65536UL) {
-      /* 04 82 LL LL DD DD DD ... */
-      *outlen = 4 + noctets;
-   } else if (noctets < 16777216UL) {
-      /* 04 83 LL LL LL DD DD DD ... */
-      *outlen = 5 + noctets;
-   } else {
-      return CRYPT_INVALID_ARG;
+   if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) {
+      return err;
    }
    }
+   *outlen = 1 + x + noctets;
 
 
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }

+ 6 - 17
src/pk/asn1/der/printable_string/der_decode_printable_string.c

@@ -28,7 +28,7 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
                                 unsigned char *out, unsigned long *outlen)
                                 unsigned char *out, unsigned long *outlen)
 {
 {
    unsigned long x, y, len;
    unsigned long x, y, len;
-   int           t;
+   int           t, err;
 
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(out    != NULL);
@@ -45,23 +45,12 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
    }
    }
    x = 1;
    x = 1;
 
 
-   /* decode the length */
-   if (in[x] & 0x80) {
-      /* valid # of bytes in length are 1,2,3 */
-      y = in[x] & 0x7F;
-      if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* read the length in */
-      len = 0;
-      ++x;
-      while (y--) {
-         len = (len << 8) | in[x++];
-      }
-   } else {
-      len = in[x++] & 0x7F;
+   /* get the length of the data */
+   y = inlen - x;
+   if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += y;
 
 
    /* is it too long? */
    /* is it too long? */
    if (len > *outlen) {
    if (len > *outlen) {

+ 4 - 16
src/pk/asn1/der/printable_string/der_encode_printable_string.c

@@ -47,23 +47,11 @@ int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
    /* encode the header+len */
    /* encode the header+len */
    x = 0;
    x = 0;
    out[x++] = 0x13;
    out[x++] = 0x13;
-   if (inlen < 128) {
-      out[x++] = (unsigned char)inlen;
-   } else if (inlen < 256) {
-      out[x++] = 0x81;
-      out[x++] = (unsigned char)inlen;
-   } else if (inlen < 65536UL) {
-      out[x++] = 0x82;
-      out[x++] = (unsigned char)((inlen>>8)&255);
-      out[x++] = (unsigned char)(inlen&255);
-   } else if (inlen < 16777216UL) {
-      out[x++] = 0x83;
-      out[x++] = (unsigned char)((inlen>>16)&255);
-      out[x++] = (unsigned char)((inlen>>8)&255);
-      out[x++] = (unsigned char)(inlen&255);
-   } else {
-      return CRYPT_INVALID_ARG;
+   len = *outlen - x;
+   if ((err = der_encode_asn1_length(inlen, out + x, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += len;
 
 
    /* store octets */
    /* store octets */
    for (y = 0; y < inlen; y++) {
    for (y = 0; y < inlen; y++) {

+ 4 - 14
src/pk/asn1/der/printable_string/der_length_printable_string.c

@@ -126,6 +126,7 @@ int der_printable_value_decode(int v)
 int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
 int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
 {
 {
    unsigned long x;
    unsigned long x;
+   int err;
 
 
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(octets != NULL);
    LTC_ARGCHK(octets != NULL);
@@ -137,21 +138,10 @@ int der_length_printable_string(const unsigned char *octets, unsigned long nocte
        }
        }
    }
    }
 
 
-   if (noctets < 128) {
-      /* 16 LL DD DD DD ... */
-      *outlen = 2 + noctets;
-   } else if (noctets < 256) {
-      /* 16 81 LL DD DD DD ... */
-      *outlen = 3 + noctets;
-   } else if (noctets < 65536UL) {
-      /* 16 82 LL LL DD DD DD ... */
-      *outlen = 4 + noctets;
-   } else if (noctets < 16777216UL) {
-      /* 16 83 LL LL LL DD DD DD ... */
-      *outlen = 5 + noctets;
-   } else {
-      return CRYPT_INVALID_ARG;
+   if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) {
+      return err;
    }
    }
+   *outlen = 1 + x + noctets;
 
 
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }

+ 1 - 23
src/pk/asn1/der/set/der_encode_set.c

@@ -18,29 +18,7 @@
 /* LTC define to ASN.1 TAG */
 /* LTC define to ASN.1 TAG */
 static int _ltc_to_asn1(ltc_asn1_type v)
 static int _ltc_to_asn1(ltc_asn1_type v)
 {
 {
-   switch (v) {
-      case LTC_ASN1_BOOLEAN:                 return 0x01;
-      case LTC_ASN1_INTEGER:
-      case LTC_ASN1_SHORT_INTEGER:           return 0x02;
-      case LTC_ASN1_RAW_BIT_STRING:
-      case LTC_ASN1_BIT_STRING:              return 0x03;
-      case LTC_ASN1_OCTET_STRING:            return 0x04;
-      case LTC_ASN1_NULL:                    return 0x05;
-      case LTC_ASN1_OBJECT_IDENTIFIER:       return 0x06;
-      case LTC_ASN1_UTF8_STRING:             return 0x0C;
-      case LTC_ASN1_PRINTABLE_STRING:        return 0x13;
-      case LTC_ASN1_TELETEX_STRING:          return 0x14;
-      case LTC_ASN1_IA5_STRING:              return 0x16;
-      case LTC_ASN1_UTCTIME:                 return 0x17;
-      case LTC_ASN1_GENERALIZEDTIME:         return 0x18;
-      case LTC_ASN1_SEQUENCE:                return 0x30;
-      case LTC_ASN1_SET:
-      case LTC_ASN1_SETOF:                   return 0x31;
-      case LTC_ASN1_CHOICE:
-      case LTC_ASN1_CUSTOM_TYPE:
-      case LTC_ASN1_EOL:                     return -1;
-   }
-   return -1;
+   return der_asn1_type_to_identifier_map[v];
 }
 }
 
 
 
 

+ 9 - 15
src/pk/asn1/der/short_integer/der_length_short_integer.c

@@ -23,7 +23,8 @@
 */
 */
 int der_length_short_integer(unsigned long num, unsigned long *outlen)
 int der_length_short_integer(unsigned long num, unsigned long *outlen)
 {
 {
-   unsigned long z, y, len;
+   unsigned long z, y;
+   int err;
 
 
    LTC_ARGCHK(outlen  != NULL);
    LTC_ARGCHK(outlen  != NULL);
 
 
@@ -41,22 +42,15 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen)
    /* handle zero */
    /* handle zero */
    if (z == 0) {
    if (z == 0) {
       z = 1;
       z = 1;
+   } else if ((num&(1UL<<((z<<3) - 1))) != 0) {
+      /* in case msb is set */
+      ++z;
    }
    }
 
 
-   /* we need a 0x02 to indicate it's INTEGER */
-   len = 1;
-
-   /* length byte */
-   ++len;
-
-   /* bytes in value */
-   len += z;
-
-   /* see if msb is set */
-   len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
-
-   /* return length */
-   *outlen = len;
+   if ((err = der_length_asn1_length(z, &y)) != CRYPT_OK) {
+      return err;
+   }
+   *outlen = 1 + y + z;
 
 
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }

+ 6 - 17
src/pk/asn1/der/teletex_string/der_decode_teletex_string.c

@@ -27,7 +27,7 @@ int der_decode_teletex_string(const unsigned char *in, unsigned long inlen,
                                 unsigned char *out, unsigned long *outlen)
                                 unsigned char *out, unsigned long *outlen)
 {
 {
    unsigned long x, y, len;
    unsigned long x, y, len;
-   int           t;
+   int           t, err;
 
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(out    != NULL);
@@ -44,23 +44,12 @@ int der_decode_teletex_string(const unsigned char *in, unsigned long inlen,
    }
    }
    x = 1;
    x = 1;
 
 
-   /* decode the length */
-   if (in[x] & 0x80) {
-      /* valid # of bytes in length are 1,2,3 */
-      y = in[x] & 0x7F;
-      if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* read the length in */
-      len = 0;
-      ++x;
-      while (y--) {
-         len = (len << 8) | in[x++];
-      }
-   } else {
-      len = in[x++] & 0x7F;
+   /* get the length of the data */
+   y = inlen - x;
+   if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += y;
 
 
    /* is it too long? */
    /* is it too long? */
    if (len > *outlen) {
    if (len > *outlen) {

+ 4 - 14
src/pk/asn1/der/teletex_string/der_length_teletex_string.c

@@ -170,6 +170,7 @@ int der_teletex_value_decode(int v)
 int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
 int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
 {
 {
    unsigned long x;
    unsigned long x;
+   int err;
 
 
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(octets != NULL);
    LTC_ARGCHK(octets != NULL);
@@ -181,21 +182,10 @@ int der_length_teletex_string(const unsigned char *octets, unsigned long noctets
        }
        }
    }
    }
 
 
-   if (noctets < 128) {
-      /* 16 LL DD DD DD ... */
-      *outlen = 2 + noctets;
-   } else if (noctets < 256) {
-      /* 16 81 LL DD DD DD ... */
-      *outlen = 3 + noctets;
-   } else if (noctets < 65536UL) {
-      /* 16 82 LL LL DD DD DD ... */
-      *outlen = 4 + noctets;
-   } else if (noctets < 16777216UL) {
-      /* 16 83 LL LL LL DD DD DD ... */
-      *outlen = 5 + noctets;
-   } else {
-      return CRYPT_INVALID_ARG;
+   if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) {
+      return err;
    }
    }
+   *outlen = 1 + x + noctets;
 
 
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }

+ 5 - 16
src/pk/asn1/der/utf8/der_decode_utf8_string.c

@@ -46,23 +46,12 @@ int der_decode_utf8_string(const unsigned char *in,  unsigned long inlen,
    }
    }
    x = 1;
    x = 1;
 
 
-   /* decode the length */
-   if (in[x] & 0x80) {
-      /* valid # of bytes in length are 1,2,3 */
-      y = in[x] & 0x7F;
-      if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* read the length in */
-      len = 0;
-      ++x;
-      while (y--) {
-         len = (len << 8) | in[x++];
-      }
-   } else {
-      len = in[x++] & 0x7F;
+   /* get the length of the data */
+   y = inlen - x;
+   if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += y;
 
 
    if (len + x > inlen) {
    if (len + x > inlen) {
       return CRYPT_INVALID_PACKET;
       return CRYPT_INVALID_PACKET;

+ 12 - 31
src/pk/asn1/der/utf8/der_encode_utf8_string.c

@@ -28,6 +28,7 @@ int der_encode_utf8_string(const wchar_t *in,  unsigned long inlen,
                            unsigned char *out, unsigned long *outlen)
                            unsigned char *out, unsigned long *outlen)
 {
 {
    unsigned long x, y, len;
    unsigned long x, y, len;
+   int err;
 
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(out    != NULL);
@@ -38,46 +39,26 @@ int der_encode_utf8_string(const wchar_t *in,  unsigned long inlen,
        if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG;
        if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG;
        len += der_utf8_charsize(in[x]);
        len += der_utf8_charsize(in[x]);
    }
    }
-
-   if (len < 128) {
-      y = 2 + len;
-   } else if (len < 256) {
-      y = 3 + len;
-   } else if (len < 65536UL) {
-      y = 4 + len;
-   } else if (len < 16777216UL) {
-      y = 5 + len;
-   } else {
-      return CRYPT_INVALID_ARG;
+   if ((err = der_length_asn1_length(len, &x)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += len + 1;
 
 
    /* too big? */
    /* too big? */
-   if (y > *outlen) {
-      *outlen = y;
+   if (x > *outlen) {
+      *outlen = x;
       return CRYPT_BUFFER_OVERFLOW;
       return CRYPT_BUFFER_OVERFLOW;
    }
    }
 
 
    /* encode the header+len */
    /* encode the header+len */
    x = 0;
    x = 0;
    out[x++] = 0x0C;
    out[x++] = 0x0C;
-   if (len < 128) {
-      out[x++] = (unsigned char)len;
-   } else if (len < 256) {
-      out[x++] = 0x81;
-      out[x++] = (unsigned char)len;
-   } else if (len < 65536UL) {
-      out[x++] = 0x82;
-      out[x++] = (unsigned char)((len>>8)&255);
-      out[x++] = (unsigned char)(len&255);
-   } else if (len < 16777216UL) {
-      out[x++] = 0x83;
-      out[x++] = (unsigned char)((len>>16)&255);
-      out[x++] = (unsigned char)((len>>8)&255);
-      out[x++] = (unsigned char)(len&255);
-   } else {
-       /* coverity[dead_error_line] */
-      return CRYPT_INVALID_ARG;
+
+   y = *outlen - x;
+   if ((err = der_encode_asn1_length(len, out + x, &y)) != CRYPT_OK) {
+      return err;
    }
    }
+   x += y;
 
 
    /* store UTF8 */
    /* store UTF8 */
    for (y = 0; y < inlen; y++) {
    for (y = 0; y < inlen; y++) {
@@ -91,7 +72,7 @@ int der_encode_utf8_string(const wchar_t *in,  unsigned long inlen,
        }
        }
    }
    }
 
 
-   /* retun length */
+   /* return length */
    *outlen = x;
    *outlen = x;
 
 
    return CRYPT_OK;
    return CRYPT_OK;

+ 4 - 14
src/pk/asn1/der/utf8/der_length_utf8_string.c

@@ -65,6 +65,7 @@ int der_utf8_valid_char(const wchar_t c)
 int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen)
 int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen)
 {
 {
    unsigned long x, len;
    unsigned long x, len;
+   int err;
 
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(outlen != NULL);
@@ -75,21 +76,10 @@ int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned lo
       len += der_utf8_charsize(in[x]);
       len += der_utf8_charsize(in[x]);
    }
    }
 
 
-   if (len < 128) {
-      /* 0C LL DD DD DD ... */
-      *outlen = 2 + len;
-   } else if (len < 256) {
-      /* 0C 81 LL DD DD DD ... */
-      *outlen = 3 + len;
-   } else if (len < 65536UL) {
-      /* 0C 82 LL LL DD DD DD ... */
-      *outlen = 4 + len;
-   } else if (len < 16777216UL) {
-      /* 0C 83 LL LL LL DD DD DD ... */
-      *outlen = 5 + len;
-   } else {
-      return CRYPT_INVALID_ARG;
+   if ((err = der_length_asn1_length(len, &x)) != CRYPT_OK) {
+      return err;
    }
    }
+   *outlen = 1 + x + len;
 
 
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }