diff options
Diffstat (limited to 'src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c')
-rw-r--r-- | src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c b/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c index d857ce95..c86d6603 100644 --- a/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c +++ b/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c @@ -29,6 +29,7 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, { wchar_t tmp; unsigned long x, y, z, len; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -45,25 +46,14 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, } 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 > (inlen - x)) { return CRYPT_INVALID_PACKET; } @@ -91,15 +81,19 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); } - if (y > *outlen) { - *outlen = y; - return CRYPT_BUFFER_OVERFLOW; + if (y < *outlen) { + out[y] = tmp; } - out[y++] = tmp; + y++; + } + if (y > *outlen) { + err = CRYPT_BUFFER_OVERFLOW; + } else { + err = CRYPT_OK; } *outlen = y; - return CRYPT_OK; + return err; } #endif |