cyrus-sasl/cyrus-sasl-2.1.27-openssl-1...

436 lines
13 KiB
Diff

diff -up cyrus-sasl-2.1.26/plugins/ntlm.c.openssl110 cyrus-sasl-2.1.26/plugins/ntlm.c
--- cyrus-sasl-2.1.26/plugins/ntlm.c.openssl110 2012-01-28 00:31:36.000000000 +0100
+++ cyrus-sasl-2.1.26/plugins/ntlm.c 2016-11-07 16:15:57.498259304 +0100
@@ -417,6 +417,29 @@ static unsigned char *P24(unsigned char
return P24;
}
+static HMAC_CTX *_plug_HMAC_CTX_new(const sasl_utils_t *utils)
+{
+ utils->log(NULL, SASL_LOG_DEBUG, "_plug_HMAC_CTX_new()");
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ return HMAC_CTX_new();
+#else
+ return utils->malloc(sizeof(HMAC_CTX));
+#endif
+}
+
+static void _plug_HMAC_CTX_free(HMAC_CTX *ctx, const sasl_utils_t *utils)
+{
+ utils->log(NULL, SASL_LOG_DEBUG, "_plug_HMAC_CTX_free()");
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ HMAC_CTX_free(ctx);
+#else
+ HMAC_cleanup(ctx);
+ utils->free(ctx);
+#endif
+}
+
static unsigned char *V2(unsigned char *V2, sasl_secret_t *passwd,
const char *authid, const char *target,
const unsigned char *challenge,
@@ -424,7 +447,7 @@ static unsigned char *V2(unsigned char *
const sasl_utils_t *utils,
char **buf, unsigned *buflen, int *result)
{
- HMAC_CTX ctx;
+ HMAC_CTX *ctx = NULL;
unsigned char hash[EVP_MAX_MD_SIZE];
char *upper;
unsigned int len;
@@ -435,6 +458,10 @@ static unsigned char *V2(unsigned char *
SETERROR(utils, "cannot allocate NTLMv2 hash");
*result = SASL_NOMEM;
}
+ else if ((ctx = _plug_HMAC_CTX_new(utils)) == NULL) {
+ SETERROR(utils, "cannot allocate HMAC CTX");
+ *result = SASL_NOMEM;
+ }
else {
/* NTLMv2hash = HMAC-MD5(NTLMhash, unicode(ucase(authid + domain))) */
P16_nt(hash, passwd, utils, buf, buflen, result);
@@ -449,17 +476,18 @@ static unsigned char *V2(unsigned char *
HMAC(EVP_md5(), hash, MD4_DIGEST_LENGTH, *buf, 2 * len, hash, &len);
/* V2 = HMAC-MD5(NTLMv2hash, challenge + blob) + blob */
- HMAC_Init(&ctx, hash, len, EVP_md5());
- HMAC_Update(&ctx, challenge, NTLM_NONCE_LENGTH);
- HMAC_Update(&ctx, blob, bloblen);
- HMAC_Final(&ctx, V2, &len);
- HMAC_cleanup(&ctx);
+ HMAC_Init_ex(ctx, hash, len, EVP_md5(), NULL);
+ HMAC_Update(ctx, challenge, NTLM_NONCE_LENGTH);
+ HMAC_Update(ctx, blob, bloblen);
+ HMAC_Final(ctx, V2, &len);
/* the blob is concatenated outside of this function */
*result = SASL_OK;
}
+ if (ctx) _plug_HMAC_CTX_free(ctx, utils);
+
return V2;
}
diff -up cyrus-sasl-2.1.26/plugins/otp.c.openssl110 cyrus-sasl-2.1.26/plugins/otp.c
--- cyrus-sasl-2.1.26/plugins/otp.c.openssl110 2012-10-12 16:05:48.000000000 +0200
+++ cyrus-sasl-2.1.26/plugins/otp.c 2016-11-07 16:13:54.374327601 +0100
@@ -96,6 +96,28 @@ static algorithm_option_t algorithm_opti
{NULL, 0, NULL}
};
+static EVP_MD_CTX *_plug_EVP_MD_CTX_new(const sasl_utils_t *utils)
+{
+ utils->log(NULL, SASL_LOG_DEBUG, "_plug_EVP_MD_CTX_new()");
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ return EVP_MD_CTX_new();
+#else
+ return utils->malloc(sizeof(EVP_MD_CTX));
+#endif
+}
+
+static void _plug_EVP_MD_CTX_free(EVP_MD_CTX *ctx, const sasl_utils_t *utils)
+{
+ utils->log(NULL, SASL_LOG_DEBUG, "_plug_EVP_MD_CTX_free()");
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ EVP_MD_CTX_free(ctx);
+#else
+ utils->free(ctx);
+#endif
+}
+
/* Convert the binary data into ASCII hex */
void bin2hex(unsigned char *bin, int binlen, char *hex)
{
@@ -116,17 +138,16 @@ void bin2hex(unsigned char *bin, int bin
* swabbing bytes if necessary.
*/
static void otp_hash(const EVP_MD *md, char *in, size_t inlen,
- unsigned char *out, int swab)
+ unsigned char *out, int swab, EVP_MD_CTX *mdctx)
{
- EVP_MD_CTX mdctx;
- char hash[EVP_MAX_MD_SIZE];
+ unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int i;
int j;
unsigned hashlen;
- EVP_DigestInit(&mdctx, md);
- EVP_DigestUpdate(&mdctx, in, inlen);
- EVP_DigestFinal(&mdctx, hash, &hashlen);
+ EVP_DigestInit(mdctx, md);
+ EVP_DigestUpdate(mdctx, in, inlen);
+ EVP_DigestFinal(mdctx, hash, &hashlen);
/* Fold the result into 64 bits */
for (i = OTP_HASH_SIZE; i < hashlen; i++) {
@@ -149,7 +170,9 @@ static int generate_otp(const sasl_utils
char *secret, char *otp)
{
const EVP_MD *md;
- char *key;
+ EVP_MD_CTX *mdctx = NULL;
+ char *key = NULL;
+ int r = SASL_OK;
if (!(md = EVP_get_digestbyname(alg->evp_name))) {
utils->seterror(utils->conn, 0,
@@ -157,23 +180,32 @@ static int generate_otp(const sasl_utils
return SASL_FAIL;
}
+ if ((mdctx = _plug_EVP_MD_CTX_new(utils)) == NULL) {
+ SETERROR(utils, "cannot allocate MD CTX");
+ r = SASL_NOMEM;
+ goto done;
+ }
+
if ((key = utils->malloc(strlen(seed) + strlen(secret) + 1)) == NULL) {
SETERROR(utils, "cannot allocate OTP key");
- return SASL_NOMEM;
+ r = SASL_NOMEM;
+ goto done;
}
/* initial step */
strcpy(key, seed);
strcat(key, secret);
- otp_hash(md, key, strlen(key), otp, alg->swab);
+ otp_hash(md, key, strlen(key), otp, alg->swab, mdctx);
/* computation step */
while (seq-- > 0)
- otp_hash(md, otp, OTP_HASH_SIZE, otp, alg->swab);
-
- utils->free(key);
+ otp_hash(md, otp, OTP_HASH_SIZE, otp, alg->swab, mdctx);
+
+ done:
+ if (key) utils->free(key);
+ if (mdctx) _plug_EVP_MD_CTX_free(mdctx, utils);
- return SASL_OK;
+ return r;
}
static int parse_challenge(const sasl_utils_t *utils,
@@ -693,7 +725,8 @@ static int strptrcasecmp(const void *arg
/* Convert the 6 words into binary data */
static int word2bin(const sasl_utils_t *utils,
- char *words, unsigned char *bin, const EVP_MD *md)
+ char *words, unsigned char *bin, const EVP_MD *md,
+ EVP_MD_CTX *mdctx)
{
int i, j;
char *c, *word, buf[OTP_RESPONSE_MAX+1];
@@ -752,13 +785,12 @@ static int word2bin(const sasl_utils_t *
/* alternate dictionary */
if (alt_dict) {
- EVP_MD_CTX mdctx;
- char hash[EVP_MAX_MD_SIZE];
- int hashlen;
+ unsigned char hash[EVP_MAX_MD_SIZE];
+ unsigned hashlen;
- EVP_DigestInit(&mdctx, md);
- EVP_DigestUpdate(&mdctx, word, strlen(word));
- EVP_DigestFinal(&mdctx, hash, &hashlen);
+ EVP_DigestInit(mdctx, md);
+ EVP_DigestUpdate(mdctx, word, strlen(word));
+ EVP_DigestFinal(mdctx, hash, &hashlen);
/* use lowest 11 bits */
x = ((hash[hashlen-2] & 0x7) << 8) | hash[hashlen-1];
@@ -802,6 +834,7 @@ static int verify_response(server_contex
char *response)
{
const EVP_MD *md;
+ EVP_MD_CTX *mdctx = NULL;
char *c;
int do_init = 0;
unsigned char cur_otp[OTP_HASH_SIZE], prev_otp[OTP_HASH_SIZE];
@@ -815,6 +848,11 @@ static int verify_response(server_contex
return SASL_FAIL;
}
+ if ((mdctx = _plug_EVP_MD_CTX_new(utils)) == NULL) {
+ SETERROR(utils, "cannot allocate MD CTX");
+ return SASL_NOMEM;
+ }
+
/* eat leading whitespace */
c = response;
while (isspace((int) *c)) c++;
@@ -824,7 +862,7 @@ static int verify_response(server_contex
r = hex2bin(c+strlen(OTP_HEX_TYPE), cur_otp, OTP_HASH_SIZE);
}
else if (!strncasecmp(c, OTP_WORD_TYPE, strlen(OTP_WORD_TYPE))) {
- r = word2bin(utils, c+strlen(OTP_WORD_TYPE), cur_otp, md);
+ r = word2bin(utils, c+strlen(OTP_WORD_TYPE), cur_otp, md, mdctx);
}
else if (!strncasecmp(c, OTP_INIT_HEX_TYPE,
strlen(OTP_INIT_HEX_TYPE))) {
@@ -834,7 +872,7 @@ static int verify_response(server_contex
else if (!strncasecmp(c, OTP_INIT_WORD_TYPE,
strlen(OTP_INIT_WORD_TYPE))) {
do_init = 1;
- r = word2bin(utils, c+strlen(OTP_INIT_WORD_TYPE), cur_otp, md);
+ r = word2bin(utils, c+strlen(OTP_INIT_WORD_TYPE), cur_otp, md, mdctx);
}
else {
SETERROR(utils, "unknown OTP extended response type");
@@ -843,14 +881,15 @@ static int verify_response(server_contex
}
else {
/* standard response, try word first, and then hex */
- r = word2bin(utils, c, cur_otp, md);
+ r = word2bin(utils, c, cur_otp, md, mdctx);
if (r != SASL_OK)
r = hex2bin(c, cur_otp, OTP_HASH_SIZE);
}
if (r == SASL_OK) {
/* do one more hash (previous otp) and compare to stored otp */
- otp_hash(md, cur_otp, OTP_HASH_SIZE, prev_otp, text->alg->swab);
+ otp_hash(md, (char *) cur_otp, OTP_HASH_SIZE,
+ prev_otp, text->alg->swab, mdctx);
if (!memcmp(prev_otp, text->otp, OTP_HASH_SIZE)) {
/* update the secret with this seq/otp */
@@ -879,23 +918,28 @@ static int verify_response(server_contex
*new_resp++ = '\0';
}
- if (!(new_chal && new_resp))
- return SASL_BADAUTH;
+ if (!(new_chal && new_resp)) {
+ r = SASL_BADAUTH;
+ goto done;
+ }
if ((r = parse_challenge(utils, new_chal, &alg, &seq, seed, 1))
!= SASL_OK) {
- return r;
+ goto done;
}
- if (seq < 1 || !strcasecmp(seed, text->seed))
- return SASL_BADAUTH;
+ if (seq < 1 || !strcasecmp(seed, text->seed)) {
+ r = SASL_BADAUTH;
+ goto done;
+ }
/* find the MDA */
if (!(md = EVP_get_digestbyname(alg->evp_name))) {
utils->seterror(utils->conn, 0,
"OTP algorithm %s is not available",
alg->evp_name);
- return SASL_BADAUTH;
+ r = SASL_BADAUTH;
+ goto done;
}
if (!strncasecmp(c, OTP_INIT_HEX_TYPE, strlen(OTP_INIT_HEX_TYPE))) {
@@ -903,7 +947,7 @@ static int verify_response(server_contex
}
else if (!strncasecmp(c, OTP_INIT_WORD_TYPE,
strlen(OTP_INIT_WORD_TYPE))) {
- r = word2bin(utils, new_resp, new_otp, md);
+ r = word2bin(utils, new_resp, new_otp, md, mdctx);
}
if (r == SASL_OK) {
@@ -914,7 +958,10 @@ static int verify_response(server_contex
memcpy(text->otp, new_otp, OTP_HASH_SIZE);
}
}
-
+
+ done:
+ if (mdctx) _plug_EVP_MD_CTX_free(mdctx, utils);
+
return r;
}
diff -up cyrus-sasl-2.1.26/saslauthd/lak.c.openssl110 cyrus-sasl-2.1.26/saslauthd/lak.c
--- cyrus-sasl-2.1.26/saslauthd/lak.c.openssl110 2016-11-07 16:13:54.347327616 +0100
+++ cyrus-sasl-2.1.26/saslauthd/lak.c 2016-11-07 16:18:42.283167898 +0100
@@ -61,6 +61,35 @@
#include <sasl.h>
#include "lak.h"
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static EVP_MD_CTX *EVP_MD_CTX_new(void)
+{
+ return EVP_MD_CTX_create();
+}
+static void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ EVP_MD_CTX_destroy(ctx);
+}
+
+static EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void)
+{
+ EVP_ENCODE_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
+
+ if (ctx != NULL) {
+ memset(ctx, 0, sizeof(*ctx));
+ }
+ return ctx;
+}
+static void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
+{
+ OPENSSL_free(ctx);
+ return;
+}
+#endif
+
typedef struct lak_auth_method {
int method;
int (*check) (LAK *lak, const char *user, const char *service, const char *realm, const char *password) ;
@@ -1720,20 +1749,28 @@ static int lak_base64_decode(
int rc, i, tlen = 0;
char *text;
- EVP_ENCODE_CTX EVP_ctx;
+ EVP_ENCODE_CTX *enc_ctx = EVP_ENCODE_CTX_new();
- text = (char *)malloc(((strlen(src)+3)/4 * 3) + 1);
if (text == NULL)
return LAK_NOMEM;
- EVP_DecodeInit(&EVP_ctx);
- rc = EVP_DecodeUpdate(&EVP_ctx, text, &i, (char *)src, strlen(src));
+ text = (char *)malloc(((strlen(src)+3)/4 * 3) + 1);
+ if (text == NULL) {
+ EVP_ENCODE_CTX_free(enc_ctx);
+ return LAK_NOMEM;
+ }
+
+ EVP_DecodeInit(enc_ctx);
+ rc = EVP_DecodeUpdate(enc_ctx, (unsigned char *) text, &i, (const unsigned char *)src, strlen(src));
if (rc < 0) {
+ EVP_ENCODE_CTX_free(enc_ctx);
free(text);
return LAK_FAIL;
}
tlen += i;
- EVP_DecodeFinal(&EVP_ctx, text, &i);
+ EVP_DecodeFinal(enc_ctx, (unsigned char *) text, &i);
+
+ EVP_ENCODE_CTX_free(enc_ctx);
*ret = text;
if (rlen != NULL)
@@ -1749,7 +1786,7 @@ static int lak_check_hashed(
{
int rc, clen;
LAK_HASH_ROCK *hrock = (LAK_HASH_ROCK *) rock;
- EVP_MD_CTX mdctx;
+ EVP_MD_CTX *mdctx;
const EVP_MD *md;
unsigned char digest[EVP_MAX_MD_SIZE];
char *cred;
@@ -1758,17 +1795,24 @@ static int lak_check_hashed(
if (!md)
return LAK_FAIL;
+ mdctx = EVP_MD_CTX_new();
+ if (!mdctx)
+ return LAK_NOMEM;
+
rc = lak_base64_decode(hash, &cred, &clen);
- if (rc != LAK_OK)
+ if (rc != LAK_OK) {
+ EVP_MD_CTX_free(mdctx);
return rc;
+ }
- EVP_DigestInit(&mdctx, md);
- EVP_DigestUpdate(&mdctx, passwd, strlen(passwd));
+ EVP_DigestInit(mdctx, md);
+ EVP_DigestUpdate(mdctx, passwd, strlen(passwd));
if (hrock->salted) {
- EVP_DigestUpdate(&mdctx, &cred[EVP_MD_size(md)],
+ EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)],
clen - EVP_MD_size(md));
}
- EVP_DigestFinal(&mdctx, digest, NULL);
+ EVP_DigestFinal(mdctx, digest, NULL);
+ EVP_MD_CTX_free(mdctx);
rc = memcmp((char *)cred, (char *)digest, EVP_MD_size(md));
free(cred);