summaryrefslogtreecommitdiff
path: root/crypto/heimdal/lib/ntlm/ntlm.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/lib/ntlm/ntlm.c')
-rw-r--r--crypto/heimdal/lib/ntlm/ntlm.c152
1 files changed, 103 insertions, 49 deletions
diff --git a/crypto/heimdal/lib/ntlm/ntlm.c b/crypto/heimdal/lib/ntlm/ntlm.c
index 7aafc8c0aa7a..3ce8d28e5271 100644
--- a/crypto/heimdal/lib/ntlm/ntlm.c
+++ b/crypto/heimdal/lib/ntlm/ntlm.c
@@ -1011,12 +1011,12 @@ out:
*
*/
-static void
+static int
splitandenc(unsigned char *hash,
unsigned char *challenge,
unsigned char *answer)
{
- EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX *ctx;
unsigned char key[8];
key[0] = hash[0];
@@ -1028,12 +1028,15 @@ splitandenc(unsigned char *hash,
key[6] = (hash[5] << 2) | (hash[6] >> 6);
key[7] = (hash[6] << 1);
- EVP_CIPHER_CTX_init(&ctx);
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL)
+ return ENOMEM;
- EVP_CipherInit_ex(&ctx, EVP_des_cbc(), NULL, key, NULL, 1);
- EVP_Cipher(&ctx, answer, challenge, 8);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CipherInit_ex(ctx, EVP_des_cbc(), NULL, key, NULL, 1);
+ EVP_Cipher(ctx, answer, challenge, 8);
+ EVP_CIPHER_CTX_free(ctx);
memset(key, 0, sizeof(key));
+ return 0;
}
/**
@@ -1102,6 +1105,7 @@ heim_ntlm_calculate_ntlm1(void *key, size_t len,
struct ntlm_buf *answer)
{
unsigned char res[21];
+ int ret;
if (len != MD4_DIGEST_LENGTH)
return HNTLM_ERR_INVALID_LENGTH;
@@ -1114,11 +1118,21 @@ heim_ntlm_calculate_ntlm1(void *key, size_t len,
return ENOMEM;
answer->length = 24;
- splitandenc(&res[0], challenge, ((unsigned char *)answer->data) + 0);
- splitandenc(&res[7], challenge, ((unsigned char *)answer->data) + 8);
- splitandenc(&res[14], challenge, ((unsigned char *)answer->data) + 16);
+ ret = splitandenc(&res[0], challenge, ((unsigned char *)answer->data) + 0);
+ if (ret)
+ goto out;
+ ret = splitandenc(&res[7], challenge, ((unsigned char *)answer->data) + 8);
+ if (ret)
+ goto out;
+ ret = splitandenc(&res[14], challenge, ((unsigned char *)answer->data) + 16);
+ if (ret)
+ goto out;
return 0;
+
+out:
+ heim_ntlm_free_buf(answer);
+ return ret;
}
int
@@ -1153,7 +1167,7 @@ heim_ntlm_v2_base_session(void *key, size_t len,
struct ntlm_buf *session)
{
unsigned int hmaclen;
- HMAC_CTX c;
+ HMAC_CTX *c;
if (ntlmResponse->length <= 16)
return HNTLM_ERR_INVALID_LENGTH;
@@ -1164,11 +1178,15 @@ heim_ntlm_v2_base_session(void *key, size_t len,
session->length = 16;
/* Note: key is the NTLMv2 key */
- HMAC_CTX_init(&c);
- HMAC_Init_ex(&c, key, len, EVP_md5(), NULL);
- HMAC_Update(&c, ntlmResponse->data, 16);
- HMAC_Final(&c, session->data, &hmaclen);
- HMAC_CTX_cleanup(&c);
+ c = HMAC_CTX_new();
+ if (c == NULL) {
+ heim_ntlm_free_buf(session);
+ return ENOMEM;
+ }
+ HMAC_Init_ex(c, key, len, EVP_md5(), NULL);
+ HMAC_Update(c, ntlmResponse->data, 16);
+ HMAC_Final(c, session->data, &hmaclen);
+ HMAC_CTX_free(c);
return 0;
}
@@ -1179,7 +1197,7 @@ heim_ntlm_keyex_wrap(struct ntlm_buf *base_session,
struct ntlm_buf *session,
struct ntlm_buf *encryptedSession)
{
- EVP_CIPHER_CTX c;
+ EVP_CIPHER_CTX *c;
int ret;
session->length = MD4_DIGEST_LENGTH;
@@ -1196,25 +1214,30 @@ heim_ntlm_keyex_wrap(struct ntlm_buf *base_session,
return ENOMEM;
}
- EVP_CIPHER_CTX_init(&c);
+ c = EVP_CIPHER_CTX_new();
+ if (c == NULL) {
+ heim_ntlm_free_buf(encryptedSession);
+ heim_ntlm_free_buf(session);
+ return ENOMEM;
+ }
- ret = EVP_CipherInit_ex(&c, EVP_rc4(), NULL, base_session->data, NULL, 1);
+ ret = EVP_CipherInit_ex(c, EVP_rc4(), NULL, base_session->data, NULL, 1);
if (ret != 1) {
- EVP_CIPHER_CTX_cleanup(&c);
+ EVP_CIPHER_CTX_free(c);
heim_ntlm_free_buf(encryptedSession);
heim_ntlm_free_buf(session);
return HNTLM_ERR_CRYPTO;
}
if (RAND_bytes(session->data, session->length) != 1) {
- EVP_CIPHER_CTX_cleanup(&c);
+ EVP_CIPHER_CTX_free(c);
heim_ntlm_free_buf(encryptedSession);
heim_ntlm_free_buf(session);
return HNTLM_ERR_RAND;
}
- EVP_Cipher(&c, encryptedSession->data, session->data, encryptedSession->length);
- EVP_CIPHER_CTX_cleanup(&c);
+ EVP_Cipher(c, encryptedSession->data, session->data, encryptedSession->length);
+ EVP_CIPHER_CTX_free(c);
return 0;
@@ -1309,7 +1332,7 @@ heim_ntlm_keyex_unwrap(struct ntlm_buf *baseKey,
struct ntlm_buf *encryptedSession,
struct ntlm_buf *session)
{
- EVP_CIPHER_CTX c;
+ EVP_CIPHER_CTX *c;
memset(session, 0, sizeof(*session));
@@ -1322,16 +1345,20 @@ heim_ntlm_keyex_unwrap(struct ntlm_buf *baseKey,
session->length = 0;
return ENOMEM;
}
- EVP_CIPHER_CTX_init(&c);
+ c = EVP_CIPHER_CTX_new();
+ if (c == NULL) {
+ heim_ntlm_free_buf(session);
+ return ENOMEM;
+ }
- if (EVP_CipherInit_ex(&c, EVP_rc4(), NULL, baseKey->data, NULL, 0) != 1) {
- EVP_CIPHER_CTX_cleanup(&c);
+ if (EVP_CipherInit_ex(c, EVP_rc4(), NULL, baseKey->data, NULL, 0) != 1) {
+ EVP_CIPHER_CTX_free(c);
heim_ntlm_free_buf(session);
return HNTLM_ERR_CRYPTO;
}
- EVP_Cipher(&c, session->data, encryptedSession->data, session->length);
- EVP_CIPHER_CTX_cleanup(&c);
+ EVP_Cipher(c, session->data, encryptedSession->data, session->length);
+ EVP_CIPHER_CTX_free(c);
return 0;
}
@@ -1359,28 +1386,30 @@ heim_ntlm_ntlmv2_key(const void *key, size_t len,
{
int ret;
unsigned int hmaclen;
- HMAC_CTX c;
+ HMAC_CTX *c;
- HMAC_CTX_init(&c);
- HMAC_Init_ex(&c, key, len, EVP_md5(), NULL);
+ c = HMAC_CTX_new();
+ if (c == NULL)
+ return ENOMEM;
+ HMAC_Init_ex(c, key, len, EVP_md5(), NULL);
{
struct ntlm_buf buf;
/* uppercase username and turn it into ucs2-le */
ret = ascii2ucs2le(username, 1, &buf);
if (ret)
goto out;
- HMAC_Update(&c, buf.data, buf.length);
+ HMAC_Update(c, buf.data, buf.length);
free(buf.data);
/* uppercase target and turn into ucs2-le */
ret = ascii2ucs2le(target, 1, &buf);
if (ret)
goto out;
- HMAC_Update(&c, buf.data, buf.length);
+ HMAC_Update(c, buf.data, buf.length);
free(buf.data);
}
- HMAC_Final(&c, ntlmv2, &hmaclen);
+ HMAC_Final(c, ntlmv2, &hmaclen);
out:
- HMAC_CTX_cleanup(&c);
+ HMAC_CTX_free(c);
return ret;
}
@@ -1434,6 +1463,7 @@ heim_ntlm_calculate_lm2(const void *key, size_t len,
struct ntlm_buf *answer)
{
unsigned char clientchallenge[8];
+ int ret;
if (RAND_bytes(clientchallenge, sizeof(clientchallenge)) != 1)
return HNTLM_ERR_RAND;
@@ -1447,8 +1477,10 @@ heim_ntlm_calculate_lm2(const void *key, size_t len,
return ENOMEM;
answer->length = 24;
- heim_ntlm_derive_ntlm2_sess(ntlmv2, clientchallenge, 8,
+ ret = heim_ntlm_derive_ntlm2_sess(ntlmv2, clientchallenge, 8,
serverchallenge, answer->data);
+ if (ret)
+ return ret;
memcpy(((uint8_t *)answer->data) + 16, clientchallenge, 8);
@@ -1489,6 +1521,7 @@ heim_ntlm_calculate_ntlm2(const void *key, size_t len,
krb5_storage *sp;
unsigned char clientchallenge[8];
uint64_t t;
+ int code;
t = unix2nttime(time(NULL));
@@ -1523,7 +1556,11 @@ heim_ntlm_calculate_ntlm2(const void *key, size_t len,
krb5_storage_free(sp);
sp = NULL;
- heim_ntlm_derive_ntlm2_sess(ntlmv2, data.data, data.length, serverchallenge, ntlmv2answer);
+ code = heim_ntlm_derive_ntlm2_sess(ntlmv2, data.data, data.length, serverchallenge, ntlmv2answer);
+ if (code) {
+ krb5_data_free(&data);
+ return code;
+ }
sp = krb5_storage_emem();
if (sp == NULL) {
@@ -1588,6 +1625,7 @@ heim_ntlm_verify_ntlm2(const void *key, size_t len,
time_t authtime;
uint32_t temp;
uint64_t t;
+ int code;
infotarget->length = 0;
infotarget->data = NULL;
@@ -1651,10 +1689,12 @@ heim_ntlm_verify_ntlm2(const void *key, size_t len,
goto out;
}
- heim_ntlm_derive_ntlm2_sess(ntlmv2,
+ ret = heim_ntlm_derive_ntlm2_sess(ntlmv2,
((unsigned char *)answer->data) + 16, answer->length - 16,
serverchallenge,
serveranswer);
+ if (ret)
+ goto out;
if (memcmp(serveranswer, clientanswer, 16) != 0) {
heim_ntlm_free_buf(infotarget);
@@ -1724,11 +1764,22 @@ heim_ntlm_calculate_ntlm2_sess(const unsigned char clnt_nonce[8],
memcpy(res, ntlm_hash, 16);
resp = ntlm->data;
- splitandenc(&res[0], ntlm2_sess_hash, resp + 0);
- splitandenc(&res[7], ntlm2_sess_hash, resp + 8);
- splitandenc(&res[14], ntlm2_sess_hash, resp + 16);
+ code = splitandenc(&res[0], ntlm2_sess_hash, resp + 0);
+ if (code)
+ goto out;
+ code = splitandenc(&res[7], ntlm2_sess_hash, resp + 8);
+ if (code)
+ goto out;
+ code = splitandenc(&res[14], ntlm2_sess_hash, resp + 16);
+ if (code)
+ goto out;
return 0;
+
+out:
+ heim_ntlm_free_buf(ntlm);
+ heim_ntlm_free_buf(lm);
+ return code;
}
@@ -1783,21 +1834,24 @@ heim_ntlm_calculate_ntlm2_sess_hash(const unsigned char clnt_nonce[8],
* @ingroup ntlm_core
*/
-void
+int
heim_ntlm_derive_ntlm2_sess(const unsigned char sessionkey[16],
const unsigned char *clnt_nonce, size_t clnt_nonce_length,
const unsigned char svr_chal[8],
unsigned char derivedkey[16])
{
unsigned int hmaclen;
- HMAC_CTX c;
+ HMAC_CTX *c;
/* HMAC(Ksession, serverchallenge || clientchallenge) */
- HMAC_CTX_init(&c);
- HMAC_Init_ex(&c, sessionkey, 16, EVP_md5(), NULL);
- HMAC_Update(&c, svr_chal, 8);
- HMAC_Update(&c, clnt_nonce, clnt_nonce_length);
- HMAC_Final(&c, derivedkey, &hmaclen);
- HMAC_CTX_cleanup(&c);
+ c = HMAC_CTX_new();
+ if (c == NULL)
+ return ENOMEM;
+ HMAC_Init_ex(c, sessionkey, 16, EVP_md5(), NULL);
+ HMAC_Update(c, svr_chal, 8);
+ HMAC_Update(c, clnt_nonce, clnt_nonce_length);
+ HMAC_Final(c, derivedkey, &hmaclen);
+ HMAC_CTX_free(c);
+ return 0;
}