From 0eab41fb78cf4d7c76e563fd677ab6c32fc28bb0 Mon Sep 17 00:00:00 2001 From: Ben Laurie Date: Mon, 29 Dec 2008 16:11:58 +0000 Subject: [PATCH] If we're going to return errors (no matter how stupid), then we should test for them! --- apps/ts.c | 2 ++ crypto/evp/evp.h | 2 ++ crypto/evp/evp_err.c | 4 +++- crypto/evp/evp_lib.c | 3 +++ crypto/evp/m_sigver.c | 15 +++++++++------ crypto/evp/p5_crpt.c | 6 +++++- crypto/evp/p5_crpt2.c | 7 +++++-- crypto/hmac/hm_pmeth.c | 6 +++++- crypto/ocsp/ocsp_vfy.c | 2 ++ crypto/pkcs12/p12_key.c | 5 +++++ crypto/pkcs12/p12_mutl.c | 8 ++++++-- crypto/rsa/rsa.h | 1 - crypto/rsa/rsa_err.c | 1 - crypto/rsa/rsa_oaep.c | 19 +++++++++++++------ crypto/rsa/rsa_pss.c | 16 ++++++++-------- crypto/ts/ts_rsp_verify.c | 5 ++++- ssl/d1_enc.c | 8 ++++++++ ssl/d1_pkt.c | 14 +++++++++++--- ssl/s2_lib.c | 11 +++++++---- ssl/s2_pkt.c | 14 ++++++++++---- ssl/s3_enc.c | 21 ++++++++++++++++----- ssl/s3_lib.c | 2 +- ssl/s3_pkt.c | 10 ++++++++-- ssl/s3_srvr.c | 11 ++++++++++- ssl/ssl_ciph.c | 3 +++ ssl/ssl_locl.h | 2 +- ssl/t1_enc.c | 20 ++++++++++++++++---- ssl/t1_lib.c | 5 +++++ 28 files changed, 168 insertions(+), 55 deletions(-) diff --git a/apps/ts.c b/apps/ts.c index 08b8c4a9e1..74e7e932b3 100644 --- a/apps/ts.c +++ b/apps/ts.c @@ -598,6 +598,8 @@ static int create_digest(BIO *input, char *digest, const EVP_MD *md, int md_value_len; md_value_len = EVP_MD_size(md); + if (md_value_len < 0) + goto err; if (input) { /* Digest must be computed from an input file. */ diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 985ff2f5a9..df54409f10 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -1183,6 +1183,7 @@ void ERR_load_EVP_strings(void); #define EVP_F_EVP_DIGESTINIT_EX 128 #define EVP_F_EVP_ENCRYPTFINAL_EX 127 #define EVP_F_EVP_MD_CTX_COPY_EX 110 +#define EVP_F_EVP_MD_SIZE 162 #define EVP_F_EVP_OPENINIT 102 #define EVP_F_EVP_PBE_ALG_ADD 115 #define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 @@ -1262,6 +1263,7 @@ void ERR_load_EVP_strings(void); #define EVP_R_INVALID_OPERATION 148 #define EVP_R_IV_TOO_LARGE 102 #define EVP_R_KEYGEN_FAILURE 120 +#define EVP_R_MESSAGE_DIGEST_IS_NULL 159 #define EVP_R_METHOD_NOT_SUPPORTED 144 #define EVP_R_MISSING_PARAMETERS 103 #define EVP_R_NO_CIPHER_SET 131 diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 25a8ad7cdc..04485f0162 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* crypto/evp/evp_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -85,6 +85,7 @@ static ERR_STRING_DATA EVP_str_functs[]= {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, +{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_SIZE"}, {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"}, {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"}, {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"}, @@ -167,6 +168,7 @@ static ERR_STRING_DATA EVP_str_reasons[]= {ERR_REASON(EVP_R_INVALID_OPERATION) ,"invalid operation"}, {ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"}, {ERR_REASON(EVP_R_KEYGEN_FAILURE) ,"keygen failure"}, +{ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL),"message digest is null"}, {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED) ,"method not supported"}, {ERR_REASON(EVP_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(EVP_R_NO_CIPHER_SET) ,"no cipher set"}, diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index daccb66820..d815bc6d6f 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -256,7 +256,10 @@ int EVP_MD_pkey_type(const EVP_MD *md) int EVP_MD_size(const EVP_MD *md) { if (!md) + { + EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); return -1; + } return md->md_size; } diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index c6d257fc08..d98455eaad 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -128,7 +128,6 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, return do_sigver_init(ctx, pctx, type, e, pkey, 1); } - int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) { int sctx, r = 0; @@ -159,13 +158,15 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) { if (sctx) { - if (ctx->pctx->pmeth->signctx(ctx->pctx, - sigret, siglen, ctx) <= 0) + if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx) <= 0) + return 0; + } + else + { + int s = EVP_MD_size(ctx->digest); + if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, s) <= 0) return 0; } - else if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, - EVP_MD_size(ctx->digest)) <= 0) - return 0; } return 1; } @@ -177,6 +178,8 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen) int r; unsigned int mdlen; int vctx; + + /* FIXME: surely this should test verifyctx? (Ben 29/12/08) */ if (ctx->pctx->pmeth->signctx) vctx = 1; else diff --git a/crypto/evp/p5_crpt.c b/crypto/evp/p5_crpt.c index 9c6e07b706..7ecfa8dad9 100644 --- a/crypto/evp/p5_crpt.c +++ b/crypto/evp/p5_crpt.c @@ -81,6 +81,7 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, int saltlen, iter; unsigned char *salt; const unsigned char *pbuf; + int mdsize; /* Extract useful info from parameter */ if (param == NULL || param->type != V_ASN1_SEQUENCE || @@ -109,9 +110,12 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, EVP_DigestUpdate(&ctx, salt, saltlen); PBEPARAM_free(pbe); EVP_DigestFinal_ex(&ctx, md_tmp, NULL); + mdsize = EVP_MD_size(md); + if (mdsize < 0) + return 0; for (i = 1; i < iter; i++) { EVP_DigestInit_ex(&ctx, md, NULL); - EVP_DigestUpdate(&ctx, md_tmp, EVP_MD_size(md)); + EVP_DigestUpdate(&ctx, md_tmp, mdsize); EVP_DigestFinal_ex (&ctx, md_tmp, NULL); } EVP_MD_CTX_cleanup(&ctx); diff --git a/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c index 70fd48aed0..334379f310 100644 --- a/crypto/evp/p5_crpt2.c +++ b/crypto/evp/p5_crpt2.c @@ -87,6 +87,8 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, HMAC_CTX hctx; mdlen = EVP_MD_size(digest); + if (mdlen < 0) + return 0; HMAC_CTX_init(&hctx); p = out; @@ -273,8 +275,9 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, salt = kdf->salt->value.octet_string->data; saltlen = kdf->salt->value.octet_string->length; iter = ASN1_INTEGER_get(kdf->iter); - PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, - keylen, key); + if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, + keylen, key)) + goto err; EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); OPENSSL_cleanse(key, keylen); PBKDF2PARAM_free(kdf); diff --git a/crypto/hmac/hm_pmeth.c b/crypto/hmac/hm_pmeth.c index aff7013b76..985921ca1a 100644 --- a/crypto/hmac/hm_pmeth.c +++ b/crypto/hmac/hm_pmeth.c @@ -157,7 +157,11 @@ static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, { unsigned int hlen; HMAC_PKEY_CTX *hctx = ctx->data; - *siglen = EVP_MD_CTX_size(mctx); + int l = EVP_MD_CTX_size(mctx); + + if (l < 0) + return 0; + *siglen = l; if (!sig) return 1; diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c index be9bf5b0f0..415d67e61c 100644 --- a/crypto/ocsp/ocsp_vfy.c +++ b/crypto/ocsp/ocsp_vfy.c @@ -308,6 +308,8 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, } mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + return -1; if ((cid->issuerNameHash->length != mdlen) || (cid->issuerKeyHash->length != mdlen)) return 0; diff --git a/crypto/pkcs12/p12_key.c b/crypto/pkcs12/p12_key.c index 9e57eee4a4..b72cf1638b 100644 --- a/crypto/pkcs12/p12_key.c +++ b/crypto/pkcs12/p12_key.c @@ -81,6 +81,7 @@ int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, int ret; unsigned char *unipass; int uniplen; + if(!pass) { unipass = NULL; uniplen = 0; @@ -90,6 +91,8 @@ int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, } ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, id, iter, n, out, md_type); + if (ret <= 0) + return 0; if(unipass) { OPENSSL_cleanse(unipass, uniplen); /* Clear password from memory */ OPENSSL_free(unipass); @@ -129,6 +132,8 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, #endif v = EVP_MD_block_size (md_type); u = EVP_MD_size (md_type); + if (u < 0) + return 0; D = OPENSSL_malloc (v); Ai = OPENSSL_malloc (u); B = OPENSSL_malloc (v + 1); diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c index 70bfef6e5d..9ab740d51f 100644 --- a/crypto/pkcs12/p12_mutl.c +++ b/crypto/pkcs12/p12_mutl.c @@ -71,6 +71,7 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, HMAC_CTX hmac; unsigned char key[EVP_MAX_MD_SIZE], *salt; int saltlen, iter; + int md_size; if (!PKCS7_type_is_data(p12->authsafes)) { @@ -87,13 +88,16 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); return 0; } + md_size = EVP_MD_size(md_type); + if (md_size < 0) + return 0; if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, - EVP_MD_size(md_type), key, md_type)) { + md_size, key, md_type)) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR); return 0; } HMAC_CTX_init(&hmac); - HMAC_Init_ex(&hmac, key, EVP_MD_size(md_type), md_type, NULL); + HMAC_Init_ex(&hmac, key, md_size, md_type, NULL); HMAC_Update(&hmac, p12->authsafes->d.data->data, p12->authsafes->d.data->length); HMAC_Final(&hmac, mac, maclen); diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h index 91cd4198c7..cf74343657 100644 --- a/crypto/rsa/rsa.h +++ b/crypto/rsa/rsa.h @@ -448,7 +448,6 @@ void ERR_load_RSA_strings(void); /* Reason codes. */ #define RSA_R_ALGORITHM_MISMATCH 100 -#define RSA_R_BAD_ARGUMENT 149 #define RSA_R_BAD_E_VALUE 101 #define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 #define RSA_R_BAD_PAD_BYTE_COUNT 103 diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c index a53c5f6bff..cf9f1106b0 100644 --- a/crypto/rsa/rsa_err.c +++ b/crypto/rsa/rsa_err.c @@ -124,7 +124,6 @@ static ERR_STRING_DATA RSA_str_functs[]= static ERR_STRING_DATA RSA_str_reasons[]= { {ERR_REASON(RSA_R_ALGORITHM_MISMATCH) ,"algorithm mismatch"}, -{ERR_REASON(RSA_R_BAD_ARGUMENT) ,"bad argument"}, {ERR_REASON(RSA_R_BAD_E_VALUE) ,"bad e value"}, {ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT),"bad fixed header decrypt"}, {ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT) ,"bad pad byte count"}, diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c index 3652677a99..70bacf850e 100644 --- a/crypto/rsa/rsa_oaep.c +++ b/crypto/rsa/rsa_oaep.c @@ -28,7 +28,7 @@ #include #include -int MGF1(unsigned char *mask, long len, +static int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen); int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, @@ -76,11 +76,13 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, 20); #endif - MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH); + if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH) < 0) + return 0; for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++) db[i] ^= dbmask[i]; - MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH); + if (MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH) < 0) + return 0; for (i = 0; i < SHA_DIGEST_LENGTH; i++) seed[i] ^= seedmask[i]; @@ -133,11 +135,13 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, maskeddb = padded_from + SHA_DIGEST_LENGTH; - MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen); + if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen)) + return -1; for (i = 0; i < SHA_DIGEST_LENGTH; i++) seed[i] ^= padded_from[i]; - MGF1(db, dblen, seed, SHA_DIGEST_LENGTH); + if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH)) + return -1; for (i = 0; i < dblen; i++) db[i] ^= maskeddb[i]; @@ -188,6 +192,8 @@ int PKCS1_MGF1(unsigned char *mask, long len, EVP_MD_CTX_init(&c); mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + return -1; for (i = 0; outlen < len; i++) { cnt[0] = (unsigned char)((i >> 24) & 255); @@ -213,7 +219,8 @@ int PKCS1_MGF1(unsigned char *mask, long len, return 0; } -int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen) +static int MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen) { return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1()); } diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c index 2e44194bdc..775c36114f 100644 --- a/crypto/rsa/rsa_pss.c +++ b/crypto/rsa/rsa_pss.c @@ -81,13 +81,9 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, EVP_MD_CTX ctx; unsigned char H_[EVP_MAX_MD_SIZE]; - if (Hash == NULL) - { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_BAD_ARGUMENT); - goto err; - } - hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; /* * Negative sLen has special meanings: * -1 sLen == hLen @@ -132,7 +128,8 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE); goto err; } - PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash); + if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0) + goto err; for (i = 0; i < maskedDBLen; i++) DB[i] ^= EM[i]; if (MSBits) @@ -183,6 +180,8 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, EVP_MD_CTX ctx; hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; /* * Negative sLen has special meanings: * -1 sLen == hLen @@ -238,7 +237,8 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, EVP_MD_CTX_cleanup(&ctx); /* Generate dbMask in place then perform XOR on it */ - PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash); + if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash)) + goto err; p = EM; diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c index 6acacac6c1..e1f3b534af 100644 --- a/crypto/ts/ts_rsp_verify.c +++ b/crypto/ts/ts_rsp_verify.c @@ -604,7 +604,10 @@ static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, } /* Compute message digest. */ - *imprint_len = EVP_MD_size(md); + length = EVP_MD_size(md); + if (length < 0) + goto err; + *imprint_len = length; if (!(*imprint = OPENSSL_malloc(*imprint_len))) { TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); diff --git a/ssl/d1_enc.c b/ssl/d1_enc.c index ea5e12ee07..9de787e8f6 100644 --- a/ssl/d1_enc.c +++ b/ssl/d1_enc.c @@ -135,7 +135,11 @@ int dtls1_enc(SSL *s, int send) if (send) { if (EVP_MD_CTX_md(s->write_hash)) + { n=EVP_MD_CTX_size(s->write_hash); + if (n < 0) + return -1; + } ds=s->enc_write_ctx; rec= &(s->s3->wrec); if (s->enc_write_ctx == NULL) @@ -157,7 +161,11 @@ int dtls1_enc(SSL *s, int send) else { if (EVP_MD_CTX_md(s->read_hash)) + { n=EVP_MD_CTX_size(s->read_hash); + if (n < 0) + return -1; + } ds=s->enc_read_ctx; rec= &(s->s3->rrec); if (s->enc_read_ctx == NULL) diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index daf1fee881..dea63d694a 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -428,7 +428,10 @@ printf("\n"); if (!clear) { /* !clear => s->read_hash != NULL => mac_size != -1 */ - mac_size=EVP_MD_CTX_size(s->read_hash); + int t; + t=EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(t >= 0); + mac_size=t; if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) { @@ -453,7 +456,7 @@ printf("\n"); } rr->length-=mac_size; i=s->method->ssl3_enc->mac(s,md,0); - if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) + if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0) { goto decryption_failed_or_bad_record_mac; } @@ -1341,7 +1344,11 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, if (clear) mac_size=0; else + { mac_size=EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } /* DTLS implements explicit IV, so no need for empty fragments */ #if 0 @@ -1428,7 +1435,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, if (mac_size != 0) { - s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1); + if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0) + goto err; wr->length+=mac_size; } diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c index 4cfafcedf1..907e305259 100644 --- a/ssl/s2_lib.c +++ b/ssl/s2_lib.c @@ -455,6 +455,7 @@ int ssl2_generate_key_material(SSL *s) unsigned char *km; unsigned char c='0'; const EVP_MD *md5; + int md_size; md5 = EVP_md5(); @@ -471,10 +472,12 @@ int ssl2_generate_key_material(SSL *s) SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); return 0; } - - for (i=0; is2->key_material_length; i += EVP_MD_size(md5)) + md_size = EVP_MD_size(md5); + if (md_size < 0) + return 0; + for (i=0; is2->key_material_length; i += md_size) { - if (((km - s->s2->key_material) + EVP_MD_size(md5)) > + if (((km - s->s2->key_material) + md_size) > (int)sizeof(s->s2->key_material)) { /* EVP_DigestFinal_ex() below would write beyond buffer */ @@ -493,7 +496,7 @@ int ssl2_generate_key_material(SSL *s) EVP_DigestUpdate(&ctx,s->s2->challenge,s->s2->challenge_length); EVP_DigestUpdate(&ctx,s->s2->conn_id,s->s2->conn_id_length); EVP_DigestFinal_ex(&ctx,km,NULL); - km += EVP_MD_size(md5); + km += md_size; } EVP_MD_CTX_cleanup(&ctx); diff --git a/ssl/s2_pkt.c b/ssl/s2_pkt.c index e6d5d09643..9c1d1313c1 100644 --- a/ssl/s2_pkt.c +++ b/ssl/s2_pkt.c @@ -116,7 +116,7 @@ #define USE_SOCKETS static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend); -static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); static int write_pending(SSL *s, const unsigned char *buf, unsigned int len); static int ssl_mt_error(int n); @@ -130,7 +130,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) unsigned char mac[MAX_MAC_SIZE]; unsigned char *p; int i; - unsigned int mac_size; + int mac_size; ssl2_read_again: if (SSL_in_init(s) && !s->in_handshake) @@ -247,6 +247,8 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) else { mac_size=EVP_MD_CTX_size(s->read_hash); + if (mac_size < 0) + return -1; OPENSSL_assert(mac_size <= MAX_MAC_SIZE); s->s2->mac_data=p; s->s2->ract_data= &p[mac_size]; @@ -447,7 +449,7 @@ int ssl2_write(SSL *s, const void *_buf, int len) n=(len-tot); for (;;) { - i=do_ssl_write(s,&(buf[tot]),n); + i=n_do_ssl_write(s,&(buf[tot]),n); if (i <= 0) { s->s2->wnum=tot; @@ -511,7 +513,7 @@ static int write_pending(SSL *s, const unsigned char *buf, unsigned int len) } } -static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) { unsigned int j,k,olen,p,mac_size,bs; register unsigned char *pp; @@ -529,7 +531,11 @@ static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) if (s->s2->clear_text) mac_size=0; else + { mac_size=EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + return -1; + } /* lets set the pad p */ if (s->s2->clear_text) diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 96e59f678f..00fad17b9a 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -315,6 +315,8 @@ int ssl3_change_cipher_state(SSL *s, int which) p=s->s3->tmp.key_block; i=EVP_MD_size(m); + if (i < 0) + goto err2; cl=EVP_CIPHER_key_length(c); j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; @@ -409,7 +411,11 @@ int ssl3_setup_key_block(SSL *s) s->s3->tmp.new_compression=comp; #endif - num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); + num=EVP_MD_size(hash); + if (num < 0) + return 0; + + num=EVP_CIPHER_key_length(c)+num+EVP_CIPHER_iv_length(c); num*=2; ssl3_cleanup_key_block(s); @@ -666,6 +672,9 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, EVP_MD_CTX_init(&ctx); EVP_MD_CTX_copy_ex(&ctx,d); n=EVP_MD_CTX_size(&ctx); + if (n < 0) + return 0; + npad=(48/n)*n; if (sender != NULL) EVP_DigestUpdate(&ctx,sender,len); @@ -686,7 +695,7 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, return((int)ret); } -int ssl3_mac(SSL *ssl, unsigned char *md, int send) +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send) { SSL3_RECORD *rec; unsigned char *mac_sec,*seq; @@ -695,6 +704,7 @@ int ssl3_mac(SSL *ssl, unsigned char *md, int send) unsigned char *p,rec_char; unsigned int md_size; int npad; + int t; if (send) { @@ -711,9 +721,10 @@ int ssl3_mac(SSL *ssl, unsigned char *md, int send) hash=ssl->read_hash; } - /* If hash is NULL, then a crash will follow anyway */ - OPENSSL_assert(hash); - md_size=EVP_MD_CTX_size(hash); + t=EVP_MD_CTX_size(hash); + if (t < 0) + return -1; + md_size=t; npad=(48/md_size)*md_size; /* Chop the digest off the end :-) */ diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 54c0540493..727827f91d 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -2077,7 +2077,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL3_ENC_METHOD SSLv3_enc_data={ ssl3_enc, - ssl3_mac, + n_ssl3_mac, ssl3_setup_key_block, ssl3_generate_master_secret, ssl3_change_cipher_state, diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index 330918a78a..e6c68b339b 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -414,6 +414,7 @@ printf("\n"); { /* !clear => s->read_hash != NULL => mac_size != -1 */ mac_size=EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size >= 0); if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) { @@ -444,7 +445,7 @@ printf("\n"); #endif } i=s->method->ssl3_enc->mac(s,md,0); - if (mac == NULL || memcmp(md, mac, mac_size) != 0) + if (i < 0 || mac == NULL || memcmp(md, mac, mac_size) != 0) { decryption_failed_or_bad_record_mac = 1; } @@ -649,7 +650,11 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (clear) mac_size=0; else + { mac_size=EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } /* 'create_empty_fragment' is true only when this function calls itself */ if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) @@ -747,7 +752,8 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (mac_size != 0) { - s->method->ssl3_enc->mac(s,&(p[wr->length]),1); + if (s->method->ssl3_enc->mac(s,&(p[wr->length]),1) < 0) + goto err; wr->length+=mac_size; wr->input=p; wr->data=p; diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 5cc3a196d7..d7327649d5 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -522,6 +522,7 @@ int ssl3_accept(SSL *s) { int offset=0; int dgst_num; + s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; @@ -536,8 +537,16 @@ int ssl3_accept(SSL *s) for (dgst_num=0; dgst_nums3->handshake_dgst[dgst_num]) { + int dgst_size; + s->method->ssl3_enc->cert_verify_mac(s,EVP_MD_CTX_type(s->s3->handshake_dgst[dgst_num]),&(s->s3->tmp.cert_verify_md[offset])); - offset+=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); + dgst_size=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); + if (dgst_size < 0) + { + ret = -1; + goto end; + } + offset+=dgst_size; } } break; diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 02cf181aad..8858dcb8c6 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -381,16 +381,19 @@ void ssl_load_ciphers(void) EVP_get_digestbyname(SN_md5); ssl_mac_secret_size[SSL_MD_MD5_IDX]= EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0); ssl_digest_methods[SSL_MD_SHA1_IDX]= EVP_get_digestbyname(SN_sha1); ssl_mac_secret_size[SSL_MD_SHA1_IDX]= EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0); ssl_digest_methods[SSL_MD_GOST94_IDX]= EVP_get_digestbyname(SN_id_GostR3411_94); if (ssl_digest_methods[SSL_MD_GOST94_IDX]) { ssl_mac_secret_size[SSL_MD_GOST94_IDX]= EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0); } ssl_digest_methods[SSL_MD_GOST89MAC_IDX]= EVP_get_digestbyname(SN_id_Gost28147_89_MAC); diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 9df4be54c6..2e6e98fc32 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -870,7 +870,7 @@ int ssl3_final_finish_mac(SSL *s, const char *sender, int slen,unsigned char *p) int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len); int ssl3_enc(SSL *s, int send_data); -int ssl3_mac(SSL *ssl, unsigned char *md, int send_data); +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data); void ssl3_free_digest_list(SSL *s); unsigned long ssl3_output_cert_chain(SSL *s, X509 *x); SSL_CIPHER *ssl3_choose_cipher(SSL *ssl,STACK_OF(SSL_CIPHER) *clnt, diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 4d9a18e3a6..ea3cd710e5 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -163,6 +163,7 @@ static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, unsigned int A1_len; chunk=EVP_MD_size(md); + OPENSSL_assert(chunk >= 0); HMAC_CTX_init(&ctx); HMAC_CTX_init(&ctx_tmp); @@ -605,7 +606,10 @@ int tls1_enc(SSL *s, int send) if (send) { if (EVP_MD_CTX_md(s->write_hash)) + { n=EVP_MD_CTX_size(s->write_hash); + OPENSSL_assert(n >= 0); + } ds=s->enc_write_ctx; rec= &(s->s3->wrec); if (s->enc_write_ctx == NULL) @@ -616,7 +620,10 @@ int tls1_enc(SSL *s, int send) else { if (EVP_MD_CTX_md(s->read_hash)) + { n=EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(n >= 0); + } ds=s->enc_read_ctx; rec= &(s->s3->rrec); if (s->enc_read_ctx == NULL) @@ -796,8 +803,8 @@ int tls1_final_finish_mac(SSL *s, { if (mask & s->s3->tmp.new_cipher->algorithm2) { - unsigned int hashsize = EVP_MD_size(md); - if (hashsize > (sizeof buf - (size_t)(q-buf))) + int hashsize = EVP_MD_size(md); + if (hashsize < 0 || hashsize > (sizeof buf - (size_t)(q-buf))) { /* internal error: 'buf' is too small for this cipersuite! */ err = 1; @@ -835,6 +842,7 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) EVP_MD_CTX hmac, *mac_ctx; unsigned char buf[5]; int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM)); + int t; if (send) { @@ -851,7 +859,9 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) hash=ssl->read_hash; } - md_size=EVP_MD_CTX_size(hash); + t=EVP_MD_CTX_size(hash); + OPENSSL_assert(t >= 0); + md_size=t; buf[0]=rec->type; buf[1]=(unsigned char)(ssl->version>>8); @@ -884,7 +894,9 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) EVP_DigestSignUpdate(mac_ctx,buf,5); EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length); - EVP_DigestSignFinal(mac_ctx,md,&md_size); + t=EVP_DigestSignFinal(mac_ctx,md,&md_size); + OPENSSL_assert(t > 0); + if (!stream_mac) EVP_MD_CTX_cleanup(&hmac); #ifdef TLS_DEBUG printf("sec="); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index e6ba33d85b..c1d4173b5e 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1532,6 +1532,11 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, * integrity checks on ticket. */ mlen = HMAC_size(&hctx); + if (mlen < 0) + { + EVP_CIPHER_CTX_cleanup(&ctx); + return -1; + } eticklen -= mlen; /* Check HMAC of encrypted ticket */ HMAC_Update(&hctx, etick, eticklen); -- 2.25.1