|
@@ -94,11 +94,25 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* handle context specific tags - just skip the tag + len bytes */
|
|
|
|
+ z = 0;
|
|
|
|
+ if (list[i].tag > 0 && list[i].tag == in[x + z++]) {
|
|
|
|
+ if (in[x+z] & 0x80) {
|
|
|
|
+ y = in[x + z++] & 0x7F;
|
|
|
|
+ if (y == 0 || y > 2) { return CRYPT_INVALID_PACKET; }
|
|
|
|
+ z += y;
|
|
|
|
+ } else {
|
|
|
|
+ z++;
|
|
|
|
+ }
|
|
|
|
+ x += z;
|
|
|
|
+ inlen -= z;
|
|
|
|
+ }
|
|
|
|
+
|
|
switch (type) {
|
|
switch (type) {
|
|
case LTC_ASN1_BOOLEAN:
|
|
case LTC_ASN1_BOOLEAN:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
|
|
if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
if ((err = der_length_boolean(&z)) != CRYPT_OK) {
|
|
if ((err = der_length_boolean(&z)) != CRYPT_OK) {
|
|
@@ -109,7 +123,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_INTEGER:
|
|
case LTC_ASN1_INTEGER:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
|
|
if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
|
|
if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
|
|
@@ -120,7 +134,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_SHORT_INTEGER:
|
|
case LTC_ASN1_SHORT_INTEGER:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
|
|
if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
|
|
if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
|
|
@@ -132,7 +146,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_BIT_STRING:
|
|
case LTC_ASN1_BIT_STRING:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
list[i].size = size;
|
|
list[i].size = size;
|
|
@@ -144,7 +158,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_RAW_BIT_STRING:
|
|
case LTC_ASN1_RAW_BIT_STRING:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
list[i].size = size;
|
|
list[i].size = size;
|
|
@@ -156,7 +170,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_OCTET_STRING:
|
|
case LTC_ASN1_OCTET_STRING:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
list[i].size = size;
|
|
list[i].size = size;
|
|
@@ -167,7 +181,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
|
|
|
|
case LTC_ASN1_NULL:
|
|
case LTC_ASN1_NULL:
|
|
if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
|
|
if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
err = CRYPT_INVALID_PACKET;
|
|
err = CRYPT_INVALID_PACKET;
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
@@ -177,7 +191,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_OBJECT_IDENTIFIER:
|
|
case LTC_ASN1_OBJECT_IDENTIFIER:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
|
|
if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
list[i].size = size;
|
|
list[i].size = size;
|
|
@@ -189,7 +203,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_TELETEX_STRING:
|
|
case LTC_ASN1_TELETEX_STRING:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
list[i].size = size;
|
|
list[i].size = size;
|
|
@@ -201,7 +215,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_IA5_STRING:
|
|
case LTC_ASN1_IA5_STRING:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
list[i].size = size;
|
|
list[i].size = size;
|
|
@@ -214,7 +228,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_PRINTABLE_STRING:
|
|
case LTC_ASN1_PRINTABLE_STRING:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
list[i].size = size;
|
|
list[i].size = size;
|
|
@@ -226,7 +240,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_UTF8_STRING:
|
|
case LTC_ASN1_UTF8_STRING:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
list[i].size = size;
|
|
list[i].size = size;
|
|
@@ -238,7 +252,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_UTCTIME:
|
|
case LTC_ASN1_UTCTIME:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
|
|
if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -254,7 +268,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_SET:
|
|
case LTC_ASN1_SET:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
|
|
if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
|
|
if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
|
|
@@ -272,7 +286,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
|
|
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
|
|
if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
|
|
if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
|
|
@@ -284,7 +298,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
case LTC_ASN1_CHOICE:
|
|
case LTC_ASN1_CHOICE:
|
|
z = inlen;
|
|
z = inlen;
|
|
if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
|
|
if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
|
|
- if (!ordered) { continue; }
|
|
|
|
|
|
+ if (!ordered || list[i].optional) { continue; }
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -305,7 +319,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|
}
|
|
}
|
|
|
|
|
|
for (i = 0; i < (int)outlen; i++) {
|
|
for (i = 0; i < (int)outlen; i++) {
|
|
- if (list[i].used == 0) {
|
|
|
|
|
|
+ if (list[i].used == 0 && list[i].optional == 0) {
|
|
err = CRYPT_INVALID_PACKET;
|
|
err = CRYPT_INVALID_PACKET;
|
|
goto LBL_ERR;
|
|
goto LBL_ERR;
|
|
}
|
|
}
|