Merge pull request #298 from libtom/strict_der_decoding

initialize 'flags' etc. to invalid values before trying to decode
This commit is contained in:
Steffen Jaeckel 2017-09-27 21:34:30 +02:00 committed by GitHub
commit 5f89a5ce2c
10 changed files with 32 additions and 16 deletions

View File

@ -68,7 +68,8 @@ enum {
CRYPT_OVERFLOW, /* An overflow of a value was detected/prevented */ CRYPT_OVERFLOW, /* An overflow of a value was detected/prevented */
CRYPT_UNUSED1, /* UNUSED1 */ CRYPT_UNUSED1, /* UNUSED1 */
CRYPT_UNUSED2, /* UNUSED2 */
CRYPT_INPUT_TOO_LONG, /* The input was longer than expected. */
CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */

View File

@ -48,7 +48,7 @@ static const crypt_constant _crypt_constants[] = {
_C_STRINGIFY(CRYPT_PK_INVALID_TYPE), _C_STRINGIFY(CRYPT_PK_INVALID_TYPE),
_C_STRINGIFY(CRYPT_OVERFLOW), _C_STRINGIFY(CRYPT_OVERFLOW),
_C_STRINGIFY(CRYPT_UNUSED1), _C_STRINGIFY(CRYPT_UNUSED1),
_C_STRINGIFY(CRYPT_UNUSED2), _C_STRINGIFY(CRYPT_INPUT_TOO_LONG),
_C_STRINGIFY(CRYPT_PK_INVALID_SIZE), _C_STRINGIFY(CRYPT_PK_INVALID_SIZE),
_C_STRINGIFY(CRYPT_INVALID_PRIME_SIZE), _C_STRINGIFY(CRYPT_INVALID_PRIME_SIZE),
_C_STRINGIFY(CRYPT_PK_INVALID_PADDING), _C_STRINGIFY(CRYPT_PK_INVALID_PADDING),

View File

@ -47,7 +47,8 @@ static const char * const err_2_str[] =
"An overflow of a value was detected/prevented.", "An overflow of a value was detected/prevented.",
"UNUSED1.", "UNUSED1.",
"UNUSED2.",
"The input was longer than expected.",
"Invalid sized parameter.", "Invalid sized parameter.",

View File

@ -314,7 +314,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
if (inlen == 0) { if (inlen == 0) {
err = CRYPT_OK; err = CRYPT_OK;
} else { } else {
err = CRYPT_PK_INVALID_SIZE; err = CRYPT_INPUT_TOO_LONG;
} }
LBL_ERR: LBL_ERR:

View File

@ -37,7 +37,7 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
LTC_ASN1_SHORT_INTEGER, 1UL, &version, LTC_ASN1_SHORT_INTEGER, 1UL, &version,
LTC_ASN1_BIT_STRING, 1UL, &flags, LTC_ASN1_BIT_STRING, 1UL, &flags,
LTC_ASN1_EOL, 0UL, NULL); LTC_ASN1_EOL, 0UL, NULL);
if (err != CRYPT_OK && err != CRYPT_PK_INVALID_SIZE) { if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
goto error; goto error;
} }
@ -58,7 +58,7 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
goto error; goto error;
} }
} }
else { else if (flags[0] == 0) {
key->type = PK_PUBLIC; key->type = PK_PUBLIC;
if ((err = der_decode_sequence_multi(in, inlen, if ((err = der_decode_sequence_multi(in, inlen,
LTC_ASN1_SHORT_INTEGER, 1UL, &version, LTC_ASN1_SHORT_INTEGER, 1UL, &version,
@ -70,6 +70,10 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
goto error; goto error;
} }
} }
else {
err = CRYPT_INVALID_PACKET;
goto error;
}
} }
else { else {
err = CRYPT_INVALID_PACKET; err = CRYPT_INVALID_PACKET;

View File

@ -30,7 +30,8 @@ int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
{ {
unsigned char *skey, *expt; unsigned char *skey, *expt;
void *g_pub; void *g_pub;
unsigned long x, y, hashOID[32]; unsigned long x, y;
unsigned long hashOID[32] = { 0 };
int hash, err; int hash, err;
ltc_asn1_list decode[3]; ltc_asn1_list decode[3];
@ -47,7 +48,7 @@ int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
/* decode to find out hash */ /* decode to find out hash */
LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
err = der_decode_sequence(in, inlen, decode, 1); err = der_decode_sequence(in, inlen, decode, 1);
if (err != CRYPT_OK && err != CRYPT_PK_INVALID_SIZE) { if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
return err; return err;
} }

View File

@ -42,9 +42,9 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags,
LTC_ASN1_EOL, 0UL, NULL); LTC_ASN1_EOL, 0UL, NULL);
if (err == CRYPT_OK || err == CRYPT_PK_INVALID_SIZE) { if (err == CRYPT_OK || err == CRYPT_INPUT_TOO_LONG) {
/* private key */ /* private key */
if (flags[0]) { if (flags[0] == 1) {
if ((err = der_decode_sequence_multi(in, inlen, if ((err = der_decode_sequence_multi(in, inlen,
LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_BIT_STRING, 1UL, flags,
LTC_ASN1_INTEGER, 1UL, key->g, LTC_ASN1_INTEGER, 1UL, key->g,
@ -59,7 +59,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
goto LBL_OK; goto LBL_OK;
} }
/* public key */ /* public key */
else { else if (flags[0] == 0) {
if ((err = der_decode_sequence_multi(in, inlen, if ((err = der_decode_sequence_multi(in, inlen,
LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_BIT_STRING, 1UL, flags,
LTC_ASN1_INTEGER, 1UL, key->g, LTC_ASN1_INTEGER, 1UL, key->g,
@ -72,6 +72,10 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
key->type = PK_PUBLIC; key->type = PK_PUBLIC;
goto LBL_OK; goto LBL_OK;
} }
else {
err = CRYPT_INVALID_PACKET;
goto LBL_ERR;
}
} }
/* get key type */ /* get key type */
if ((err = der_decode_sequence_multi(in, inlen, if ((err = der_decode_sequence_multi(in, inlen,

View File

@ -35,7 +35,8 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
ecc_key *key) ecc_key *key)
{ {
unsigned char *ecc_shared, *skey, *pub_expt; unsigned char *ecc_shared, *skey, *pub_expt;
unsigned long x, y, hashOID[32]; unsigned long x, y;
unsigned long hashOID[32] = { 0 };
int hash, err; int hash, err;
ecc_key pubkey; ecc_key pubkey;
ltc_asn1_list decode[3]; ltc_asn1_list decode[3];
@ -53,7 +54,7 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
/* decode to find out hash */ /* decode to find out hash */
LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
err = der_decode_sequence(in, inlen, decode, 1); err = der_decode_sequence(in, inlen, decode, 1);
if (err != CRYPT_OK && err != CRYPT_PK_INVALID_SIZE) { if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
return err; return err;
} }

View File

@ -107,7 +107,7 @@ int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, co
/* find out what type of key it is */ /* find out what type of key it is */
err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags,
LTC_ASN1_EOL, 0UL, NULL); LTC_ASN1_EOL, 0UL, NULL);
if (err != CRYPT_OK && err != CRYPT_PK_INVALID_SIZE) { if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
goto done; goto done;
} }
@ -124,7 +124,7 @@ int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, co
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
goto done; goto done;
} }
} else { } else if (flags[0] == 0) {
/* public key */ /* public key */
key->type = PK_PUBLIC; key->type = PK_PUBLIC;
if ((err = der_decode_sequence_multi(in, inlen, if ((err = der_decode_sequence_multi(in, inlen,
@ -136,6 +136,10 @@ int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, co
goto done; goto done;
} }
} }
else {
err = CRYPT_INVALID_PACKET;
goto done;
}
if (dp == NULL) { if (dp == NULL) {
/* find the idx */ /* find the idx */

View File

@ -69,7 +69,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, key->N, err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, key->N,
LTC_ASN1_EOL, 0UL, NULL); LTC_ASN1_EOL, 0UL, NULL);
if (err != CRYPT_OK && err != CRYPT_PK_INVALID_SIZE) { if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
goto LBL_ERR; goto LBL_ERR;
} }