Browse Source

Merge pull request #298 from libtom/strict_der_decoding

initialize 'flags' etc. to invalid values before trying to decode
Steffen Jaeckel 8 years ago
parent
commit
5f89a5ce2c

+ 2 - 1
src/headers/tomcrypt.h

@@ -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 */
 
 

+ 1 - 1
src/misc/crypt/crypt_constants.c

@@ -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),

+ 2 - 1
src/misc/error_to_string.c

@@ -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.",
 
 

+ 1 - 1
src/pk/asn1/der/sequence/der_decode_sequence_ex.c

@@ -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:

+ 6 - 2
src/pk/dh/dh_import.c

@@ -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;

+ 3 - 2
src/pk/dsa/dsa_decrypt_key.c

@@ -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;
    }
    }
 
 

+ 7 - 3
src/pk/dsa/dsa_import.c

@@ -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,

+ 3 - 2
src/pk/ecc/ecc_decrypt_key.c

@@ -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;
    }
    }
 
 

+ 6 - 2
src/pk/ecc/ecc_import.c

@@ -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 */

+ 1 - 1
src/pk/rsa/rsa_import.c

@@ -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;
    }
    }