Update the existing heimdal implementation for OpenSSL 1.1.
Existing work is underway to import a newer version of heimdal, but this patchset gets us to a fully working tree to enable more wide spread testing of OpenSSL 1.1 for now. I've also enabled WARNS=1 for kerberos (which is the reason for the change in libroken). Having -Werror enabled was useful during the 1.1 updates and we probably should have warnings enabled by default for kerberos anyway. This passes make tinderbox, and I have also done some very light runtime testing on amd64. Reviewed by: bjk, jkim, emaste Differential Revision: https://reviews.freebsd.org/D17276
This commit is contained in:
parent
4b6d416b32
commit
e4456411a8
@ -375,8 +375,8 @@ _kdc_do_digest(krb5_context context,
|
||||
case choice_DigestReqInner_init: {
|
||||
unsigned char server_nonce[16], identifier;
|
||||
|
||||
RAND_pseudo_bytes(&identifier, sizeof(identifier));
|
||||
RAND_pseudo_bytes(server_nonce, sizeof(server_nonce));
|
||||
RAND_bytes(&identifier, sizeof(identifier));
|
||||
RAND_bytes(server_nonce, sizeof(server_nonce));
|
||||
|
||||
server_nonce[0] = kdc_time & 0xff;
|
||||
server_nonce[1] = (kdc_time >> 8) & 0xff;
|
||||
@ -1333,7 +1333,7 @@ _kdc_do_digest(krb5_context context,
|
||||
|
||||
if (ireq.u.ntlmRequest.sessionkey) {
|
||||
unsigned char masterkey[MD4_DIGEST_LENGTH];
|
||||
EVP_CIPHER_CTX rc4;
|
||||
EVP_CIPHER_CTX *rc4;
|
||||
size_t len;
|
||||
|
||||
if ((flags & NTLM_NEG_KEYEX) == 0) {
|
||||
@ -1354,12 +1354,18 @@ _kdc_do_digest(krb5_context context,
|
||||
}
|
||||
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4);
|
||||
EVP_CipherInit_ex(&rc4, EVP_rc4(), NULL, sessionkey, NULL, 1);
|
||||
EVP_Cipher(&rc4,
|
||||
rc4 = EVP_CIPHER_CTX_new();
|
||||
if (rc4 == NULL) {
|
||||
ret = ENOMEM;
|
||||
krb5_set_error_message(context, ret,
|
||||
"NTLM failed to malloc cipher context");
|
||||
goto failed;
|
||||
}
|
||||
EVP_CipherInit_ex(rc4, EVP_rc4(), NULL, sessionkey, NULL, 1);
|
||||
EVP_Cipher(rc4,
|
||||
masterkey, ireq.u.ntlmRequest.sessionkey->data,
|
||||
sizeof(masterkey));
|
||||
EVP_CIPHER_CTX_cleanup(&rc4);
|
||||
EVP_CIPHER_CTX_free(rc4);
|
||||
|
||||
r.u.ntlmResponse.sessionkey =
|
||||
malloc(sizeof(*r.u.ntlmResponse.sessionkey));
|
||||
|
@ -64,7 +64,7 @@ verify_req_hash(krb5_context context,
|
||||
krb5_keyblock *key)
|
||||
{
|
||||
unsigned char digest[SHA_DIGEST_LENGTH];
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX *ctx;
|
||||
|
||||
if (req->pk_hash.length != sizeof(digest)) {
|
||||
krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
|
||||
@ -73,16 +73,21 @@ verify_req_hash(krb5_context context,
|
||||
return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
}
|
||||
|
||||
HMAC_CTX_init(&ctx);
|
||||
HMAC_Init_ex(&ctx,
|
||||
ctx = HMAC_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
krb5_set_error_message(context, ENOMEM,
|
||||
"HMAC context malloc failed");
|
||||
return ENOMEM;
|
||||
}
|
||||
HMAC_Init_ex(ctx,
|
||||
key->keyvalue.data, key->keyvalue.length,
|
||||
EVP_sha1(), NULL);
|
||||
if (sizeof(digest) != HMAC_size(&ctx))
|
||||
if (sizeof(digest) != HMAC_size(ctx))
|
||||
krb5_abortx(context, "runtime error, hmac buffer wrong size in kx509");
|
||||
HMAC_Update(&ctx, version_2_0, sizeof(version_2_0));
|
||||
HMAC_Update(&ctx, req->pk_key.data, req->pk_key.length);
|
||||
HMAC_Final(&ctx, digest, 0);
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
HMAC_Update(ctx, version_2_0, sizeof(version_2_0));
|
||||
HMAC_Update(ctx, req->pk_key.data, req->pk_key.length);
|
||||
HMAC_Final(ctx, digest, 0);
|
||||
HMAC_CTX_free(ctx);
|
||||
|
||||
if (memcmp(req->pk_hash.data, digest, sizeof(digest)) != 0) {
|
||||
krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
|
||||
@ -98,35 +103,40 @@ calculate_reply_hash(krb5_context context,
|
||||
Kx509Response *rep)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX *ctx;
|
||||
|
||||
HMAC_CTX_init(&ctx);
|
||||
ctx = HMAC_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
krb5_set_error_message(context, ENOMEM,
|
||||
"HMAC context malloc failed");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
HMAC_Init_ex(&ctx, key->keyvalue.data, key->keyvalue.length,
|
||||
HMAC_Init_ex(ctx, key->keyvalue.data, key->keyvalue.length,
|
||||
EVP_sha1(), NULL);
|
||||
ret = krb5_data_alloc(rep->hash, HMAC_size(&ctx));
|
||||
ret = krb5_data_alloc(rep->hash, HMAC_size(ctx));
|
||||
if (ret) {
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
HMAC_CTX_free(ctx);
|
||||
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
HMAC_Update(&ctx, version_2_0, sizeof(version_2_0));
|
||||
HMAC_Update(ctx, version_2_0, sizeof(version_2_0));
|
||||
if (rep->error_code) {
|
||||
int32_t t = *rep->error_code;
|
||||
do {
|
||||
unsigned char p = (t & 0xff);
|
||||
HMAC_Update(&ctx, &p, 1);
|
||||
HMAC_Update(ctx, &p, 1);
|
||||
t >>= 8;
|
||||
} while (t);
|
||||
}
|
||||
if (rep->certificate)
|
||||
HMAC_Update(&ctx, rep->certificate->data, rep->certificate->length);
|
||||
HMAC_Update(ctx, rep->certificate->data, rep->certificate->length);
|
||||
if (rep->e_text)
|
||||
HMAC_Update(&ctx, (unsigned char *)*rep->e_text, strlen(*rep->e_text));
|
||||
HMAC_Update(ctx, (unsigned char *)*rep->e_text, strlen(*rep->e_text));
|
||||
|
||||
HMAC_Final(&ctx, rep->hash->data, 0);
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
HMAC_Final(ctx, rep->hash->data, 0);
|
||||
HMAC_CTX_free(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -331,6 +331,7 @@ get_dh_param(krb5_context context,
|
||||
{
|
||||
DomainParameters dhparam;
|
||||
DH *dh = NULL;
|
||||
BIGNUM *p, *q, *g;
|
||||
krb5_error_code ret;
|
||||
|
||||
memset(&dhparam, 0, sizeof(dhparam));
|
||||
@ -375,15 +376,21 @@ get_dh_param(krb5_context context,
|
||||
goto out;
|
||||
}
|
||||
ret = KRB5_BADMSGTYPE;
|
||||
dh->p = integer_to_BN(context, "DH prime", &dhparam.p);
|
||||
if (dh->p == NULL)
|
||||
p = integer_to_BN(context, "DH prime", &dhparam.p);
|
||||
g = integer_to_BN(context, "DH base", &dhparam.g);
|
||||
q = integer_to_BN(context, "DH p-1 factor", &dhparam.q);
|
||||
if (p == NULL || g == NULL || q == NULL) {
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
BN_free(q);
|
||||
goto out;
|
||||
dh->g = integer_to_BN(context, "DH base", &dhparam.g);
|
||||
if (dh->g == NULL)
|
||||
goto out;
|
||||
dh->q = integer_to_BN(context, "DH p-1 factor", &dhparam.q);
|
||||
if (dh->g == NULL)
|
||||
}
|
||||
if (DH_set0_pqg(dh, p, g, q) != 1) {
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
BN_free(q);
|
||||
goto out;
|
||||
}
|
||||
|
||||
{
|
||||
heim_integer glue;
|
||||
@ -895,7 +902,7 @@ _kdc_pk_rd_padata(krb5_context context,
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer)
|
||||
BN_to_integer(krb5_context context, const BIGNUM *bn, heim_integer *integer)
|
||||
{
|
||||
integer->length = BN_num_bytes(bn);
|
||||
integer->data = malloc(integer->length);
|
||||
@ -1112,9 +1119,11 @@ pk_mk_pa_reply_dh(krb5_context context,
|
||||
|
||||
if (cp->keyex == USE_DH) {
|
||||
DH *kdc_dh = cp->u.dh.key;
|
||||
const BIGNUM *pub_key;
|
||||
heim_integer i;
|
||||
|
||||
ret = BN_to_integer(context, kdc_dh->pub_key, &i);
|
||||
DH_get0_key(kdc_dh, &pub_key, NULL);
|
||||
ret = BN_to_integer(context, pub_key, &i);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -173,7 +173,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
|
||||
int32_t seq_number;
|
||||
size_t len, total_len;
|
||||
u_char k6_data[16], *p0, *p;
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
_gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
|
||||
@ -235,10 +235,16 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
|
||||
|
||||
memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4);
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
rc4_key = EVP_CIPHER_CTX_new();
|
||||
if (rc4_key == NULL) {
|
||||
_gsskrb5_release_buffer(minor_status, message_token);
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(rc4_key, p, p, 8);
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
|
||||
@ -308,12 +314,16 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);
|
||||
EVP_Cipher(&rc4_key, SND_SEQ, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
rc4_key = EVP_CIPHER_CTX_new();
|
||||
if (rc4_key == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);
|
||||
EVP_Cipher(rc4_key, SND_SEQ, p, 8);
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
}
|
||||
@ -461,12 +471,17 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
|
||||
|
||||
|
||||
if(conf_req_flag) {
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
rc4_key = EVP_CIPHER_CTX_new();
|
||||
if (rc4_key == NULL) {
|
||||
_gsskrb5_release_buffer(minor_status, output_message_buffer);
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen);
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
}
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
|
||||
@ -480,12 +495,17 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
rc4_key = EVP_CIPHER_CTX_new();
|
||||
if (rc4_key == NULL) {
|
||||
_gsskrb5_release_buffer(minor_status, output_message_buffer);
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8);
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
}
|
||||
|
||||
@ -580,12 +600,16 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
rc4_key = EVP_CIPHER_CTX_new();
|
||||
if (rc4_key == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8);
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
}
|
||||
|
||||
@ -628,13 +652,18 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
|
||||
output_message_buffer->length = datalen;
|
||||
|
||||
if(conf_flag) {
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
|
||||
EVP_Cipher(&rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
rc4_key = EVP_CIPHER_CTX_new();
|
||||
if (rc4_key == NULL) {
|
||||
_gsskrb5_release_buffer(minor_status, output_message_buffer);
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CipherInit_ex(rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8);
|
||||
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen);
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
} else {
|
||||
memcpy(Confounder, p0 + 24, 8); /* Confounder */
|
||||
memcpy(output_message_buffer->value,
|
||||
|
@ -50,7 +50,7 @@ mic_des
|
||||
EVP_MD_CTX *md5;
|
||||
u_char hash[16];
|
||||
DES_key_schedule schedule;
|
||||
EVP_CIPHER_CTX des_ctx;
|
||||
EVP_CIPHER_CTX *des_ctx;
|
||||
DES_cblock deskey;
|
||||
DES_cblock zero;
|
||||
int32_t seq_number;
|
||||
@ -96,6 +96,17 @@ mic_des
|
||||
&schedule, &zero);
|
||||
memcpy (p - 8, hash, 8); /* SGN_CKSUM */
|
||||
|
||||
des_ctx = EVP_CIPHER_CTX_new();
|
||||
if (des_ctx == NULL) {
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
/* sequence number */
|
||||
krb5_auth_con_getlocalseqnumber (context,
|
||||
@ -111,10 +122,9 @@ mic_des
|
||||
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
|
||||
4);
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
|
||||
EVP_Cipher(&des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
|
||||
EVP_Cipher(des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_free(des_ctx);
|
||||
|
||||
krb5_auth_con_setlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
|
@ -50,7 +50,7 @@ unwrap_des
|
||||
size_t len;
|
||||
EVP_MD_CTX *md5;
|
||||
u_char hash[16];
|
||||
EVP_CIPHER_CTX des_ctx;
|
||||
EVP_CIPHER_CTX *des_ctx;
|
||||
DES_key_schedule schedule;
|
||||
DES_cblock deskey;
|
||||
DES_cblock zero;
|
||||
@ -104,12 +104,17 @@ unwrap_des
|
||||
deskey[i] ^= 0xf0;
|
||||
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 0);
|
||||
EVP_Cipher(&des_ctx, p, p, input_message_buffer->length - len);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
des_ctx = EVP_CIPHER_CTX_new();
|
||||
if (des_ctx == NULL) {
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, deskey, zero, 0);
|
||||
EVP_Cipher(des_ctx, p, p, input_message_buffer->length - len);
|
||||
EVP_CIPHER_CTX_free(des_ctx);
|
||||
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
}
|
||||
|
||||
if (IS_DCE_STYLE(context_handle)) {
|
||||
@ -135,19 +140,29 @@ unwrap_des
|
||||
DES_set_key_unchecked (&deskey, &schedule);
|
||||
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
|
||||
&schedule, &zero);
|
||||
if (ct_memcmp (p - 8, hash, 8) != 0)
|
||||
if (ct_memcmp (p - 8, hash, 8) != 0) {
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
/* verify sequence number */
|
||||
|
||||
des_ctx = EVP_CIPHER_CTX_new();
|
||||
if (des_ctx == NULL) {
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
|
||||
p -= 16;
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
|
||||
EVP_Cipher(&des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
|
||||
EVP_Cipher(des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_free(des_ctx);
|
||||
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
|
@ -51,7 +51,7 @@ verify_mic_des
|
||||
EVP_MD_CTX *md5;
|
||||
u_char hash[16], *seq;
|
||||
DES_key_schedule schedule;
|
||||
EVP_CIPHER_CTX des_ctx;
|
||||
EVP_CIPHER_CTX *des_ctx;
|
||||
DES_cblock zero;
|
||||
DES_cblock deskey;
|
||||
uint32_t seq_number;
|
||||
@ -96,14 +96,21 @@ verify_mic_des
|
||||
|
||||
/* verify sequence number */
|
||||
|
||||
des_ctx = EVP_CIPHER_CTX_new();
|
||||
if (des_ctx == NULL) {
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
|
||||
p -= 16;
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
|
||||
EVP_Cipher(&des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
|
||||
EVP_Cipher(des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_free(des_ctx);
|
||||
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
|
@ -211,7 +211,7 @@ wrap_des
|
||||
EVP_MD_CTX *md5;
|
||||
u_char hash[16];
|
||||
DES_key_schedule schedule;
|
||||
EVP_CIPHER_CTX des_ctx;
|
||||
EVP_CIPHER_CTX *des_ctx;
|
||||
DES_cblock deskey;
|
||||
DES_cblock zero;
|
||||
size_t i;
|
||||
@ -283,6 +283,17 @@ wrap_des
|
||||
&schedule, &zero);
|
||||
memcpy (p - 8, hash, 8);
|
||||
|
||||
des_ctx = EVP_CIPHER_CTX_new();
|
||||
if (des_ctx == NULL) {
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
free(output_message_buffer->value);
|
||||
output_message_buffer->value = NULL;
|
||||
output_message_buffer->length = 0;
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/* sequence number */
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
krb5_auth_con_getlocalseqnumber (context,
|
||||
@ -298,10 +309,8 @@ wrap_des
|
||||
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
|
||||
4);
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
|
||||
EVP_Cipher(&des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
|
||||
EVP_Cipher(des_ctx, p, p, 8);
|
||||
|
||||
krb5_auth_con_setlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
@ -317,11 +326,11 @@ wrap_des
|
||||
for (i = 0; i < sizeof(deskey); ++i)
|
||||
deskey[i] ^= 0xf0;
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 1);
|
||||
EVP_Cipher(&des_ctx, p, p, datalen);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
EVP_CIPHER_CTX_reset(des_ctx);
|
||||
EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, deskey, zero, 1);
|
||||
EVP_Cipher(des_ctx, p, p, datalen);
|
||||
}
|
||||
EVP_CIPHER_CTX_free(des_ctx);
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
|
||||
|
@ -148,16 +148,18 @@ v2_sign_message(gss_buffer_t in,
|
||||
{
|
||||
unsigned char hmac[16];
|
||||
unsigned int hmaclen;
|
||||
HMAC_CTX c;
|
||||
HMAC_CTX *c;
|
||||
|
||||
HMAC_CTX_init(&c);
|
||||
HMAC_Init_ex(&c, signkey, 16, EVP_md5(), NULL);
|
||||
c = HMAC_CTX_new();
|
||||
if (c == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
HMAC_Init_ex(c, signkey, 16, EVP_md5(), NULL);
|
||||
|
||||
encode_le_uint32(seq, hmac);
|
||||
HMAC_Update(&c, hmac, 4);
|
||||
HMAC_Update(&c, in->value, in->length);
|
||||
HMAC_Final(&c, hmac, &hmaclen);
|
||||
HMAC_CTX_cleanup(&c);
|
||||
HMAC_Update(c, hmac, 4);
|
||||
HMAC_Update(c, in->value, in->length);
|
||||
HMAC_Final(c, hmac, &hmaclen);
|
||||
HMAC_CTX_free(c);
|
||||
|
||||
encode_le_uint32(1, &out[0]);
|
||||
if (sealkey)
|
||||
|
@ -226,7 +226,8 @@ heim_int2BN(const heim_integer *i)
|
||||
BIGNUM *bn;
|
||||
|
||||
bn = BN_bin2bn(i->data, i->length, NULL);
|
||||
BN_set_negative(bn, i->negative);
|
||||
if (bn != NULL)
|
||||
BN_set_negative(bn, i->negative);
|
||||
return bn;
|
||||
}
|
||||
|
||||
@ -899,12 +900,15 @@ rsa_get_internal(hx509_context context,
|
||||
hx509_private_key key,
|
||||
const char *type)
|
||||
{
|
||||
const BIGNUM *n;
|
||||
|
||||
if (strcasecmp(type, "rsa-modulus") == 0) {
|
||||
return BN_dup(key->private_key.rsa->n);
|
||||
RSA_get0_key(key->private_key.rsa, &n, NULL, NULL);
|
||||
} else if (strcasecmp(type, "rsa-exponent") == 0) {
|
||||
return BN_dup(key->private_key.rsa->e);
|
||||
RSA_get0_key(key->private_key.rsa, NULL, &n, NULL);
|
||||
} else
|
||||
return NULL;
|
||||
return BN_dup(n);
|
||||
}
|
||||
|
||||
|
||||
@ -1045,6 +1049,7 @@ dsa_verify_signature(hx509_context context,
|
||||
DSAPublicKey pk;
|
||||
DSAParams param;
|
||||
size_t size;
|
||||
BIGNUM *key, *p, *q, *g;
|
||||
DSA *dsa;
|
||||
int ret;
|
||||
|
||||
@ -1062,16 +1067,25 @@ dsa_verify_signature(hx509_context context,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
dsa->pub_key = heim_int2BN(&pk);
|
||||
key = heim_int2BN(&pk);
|
||||
|
||||
free_DSAPublicKey(&pk);
|
||||
|
||||
if (dsa->pub_key == NULL) {
|
||||
if (key == NULL) {
|
||||
ret = ENOMEM;
|
||||
hx509_set_error_string(context, 0, ret, "out of memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = DSA_set0_key(dsa, key, NULL);
|
||||
|
||||
if (ret != 1) {
|
||||
BN_free(key);
|
||||
ret = EINVAL;
|
||||
hx509_set_error_string(context, 0, ret, "failed to set DSA key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (spi->algorithm.parameters == NULL) {
|
||||
ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
|
||||
hx509_set_error_string(context, 0, ret, "DSA parameters missing");
|
||||
@ -1087,18 +1101,32 @@ dsa_verify_signature(hx509_context context,
|
||||
goto out;
|
||||
}
|
||||
|
||||
dsa->p = heim_int2BN(¶m.p);
|
||||
dsa->q = heim_int2BN(¶m.q);
|
||||
dsa->g = heim_int2BN(¶m.g);
|
||||
p = heim_int2BN(¶m.p);
|
||||
q = heim_int2BN(¶m.q);
|
||||
g = heim_int2BN(¶m.g);
|
||||
|
||||
free_DSAParams(¶m);
|
||||
|
||||
if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
|
||||
if (p == NULL || q == NULL || g == NULL) {
|
||||
BN_free(p);
|
||||
BN_free(q);
|
||||
BN_free(g);
|
||||
ret = ENOMEM;
|
||||
hx509_set_error_string(context, 0, ret, "out of memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = DSA_set0_pqg(dsa, p, q, g);
|
||||
|
||||
if (ret != 1) {
|
||||
BN_free(p);
|
||||
BN_free(q);
|
||||
BN_free(g);
|
||||
ret = EINVAL;
|
||||
hx509_set_error_string(context, 0, ret, "failed to set DSA parameters");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = DSA_verify(-1, data->data, data->length,
|
||||
(unsigned char*)sig->data, sig->length,
|
||||
dsa);
|
||||
@ -2562,7 +2590,7 @@ hx509_crypto_encrypt(hx509_crypto crypto,
|
||||
const heim_octet_string *ivec,
|
||||
heim_octet_string **ciphertext)
|
||||
{
|
||||
EVP_CIPHER_CTX evp;
|
||||
EVP_CIPHER_CTX *evp;
|
||||
size_t padsize, bsize;
|
||||
int ret;
|
||||
|
||||
@ -2574,12 +2602,13 @@ hx509_crypto_encrypt(hx509_crypto crypto,
|
||||
|
||||
assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length);
|
||||
|
||||
EVP_CIPHER_CTX_init(&evp);
|
||||
evp = EVP_CIPHER_CTX_new();
|
||||
if (evp == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
|
||||
ret = EVP_CipherInit_ex(evp, crypto->c, NULL,
|
||||
crypto->key.data, ivec->data, 1);
|
||||
if (ret != 1) {
|
||||
EVP_CIPHER_CTX_cleanup(&evp);
|
||||
ret = HX509_CRYPTO_INTERNAL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
@ -2619,7 +2648,7 @@ hx509_crypto_encrypt(hx509_crypto crypto,
|
||||
*p++ = padsize;
|
||||
}
|
||||
|
||||
ret = EVP_Cipher(&evp, (*ciphertext)->data,
|
||||
ret = EVP_Cipher(evp, (*ciphertext)->data,
|
||||
(*ciphertext)->data,
|
||||
length + padsize);
|
||||
if (ret != 1) {
|
||||
@ -2638,7 +2667,7 @@ hx509_crypto_encrypt(hx509_crypto crypto,
|
||||
*ciphertext = NULL;
|
||||
}
|
||||
}
|
||||
EVP_CIPHER_CTX_cleanup(&evp);
|
||||
EVP_CIPHER_CTX_free(evp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2650,7 +2679,7 @@ hx509_crypto_decrypt(hx509_crypto crypto,
|
||||
heim_octet_string *ivec,
|
||||
heim_octet_string *clear)
|
||||
{
|
||||
EVP_CIPHER_CTX evp;
|
||||
EVP_CIPHER_CTX *evp;
|
||||
void *idata = NULL;
|
||||
int ret;
|
||||
|
||||
@ -2670,27 +2699,30 @@ hx509_crypto_decrypt(hx509_crypto crypto,
|
||||
if (ivec)
|
||||
idata = ivec->data;
|
||||
|
||||
EVP_CIPHER_CTX_init(&evp);
|
||||
evp = EVP_CIPHER_CTX_new();
|
||||
if (evp == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
|
||||
ret = EVP_CipherInit_ex(evp, crypto->c, NULL,
|
||||
crypto->key.data, idata, 0);
|
||||
if (ret != 1) {
|
||||
EVP_CIPHER_CTX_cleanup(&evp);
|
||||
EVP_CIPHER_CTX_free(evp);
|
||||
return HX509_CRYPTO_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
clear->length = length;
|
||||
clear->data = malloc(length);
|
||||
if (clear->data == NULL) {
|
||||
EVP_CIPHER_CTX_cleanup(&evp);
|
||||
EVP_CIPHER_CTX_free(evp);
|
||||
clear->length = 0;
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (EVP_Cipher(&evp, clear->data, data, length) != 1) {
|
||||
if (EVP_Cipher(evp, clear->data, data, length) != 1) {
|
||||
EVP_CIPHER_CTX_free(evp);
|
||||
return HX509_CRYPTO_INTERNAL_ERROR;
|
||||
}
|
||||
EVP_CIPHER_CTX_cleanup(&evp);
|
||||
EVP_CIPHER_CTX_free(evp);
|
||||
|
||||
if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) {
|
||||
int padsize;
|
||||
@ -2949,6 +2981,8 @@ match_keys_rsa(hx509_cert c, hx509_private_key private_key)
|
||||
const SubjectPublicKeyInfo *spi;
|
||||
RSAPublicKey pk;
|
||||
RSA *rsa;
|
||||
const BIGNUM *d, *p, *q, *dmp1, *dmq1, *iqmp;
|
||||
BIGNUM *new_d, *new_p, *new_q, *new_dmp1, *new_dmq1, *new_iqmp, *n, *e;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
@ -2956,7 +2990,10 @@ match_keys_rsa(hx509_cert c, hx509_private_key private_key)
|
||||
return 0;
|
||||
|
||||
rsa = private_key->private_key.rsa;
|
||||
if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)
|
||||
RSA_get0_key(rsa, NULL, NULL, &d);
|
||||
RSA_get0_factors(rsa, &p, &q);
|
||||
RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
|
||||
if (d == NULL || p == NULL || q == NULL)
|
||||
return 0;
|
||||
|
||||
cert = _hx509_get_cert(c);
|
||||
@ -2973,21 +3010,66 @@ match_keys_rsa(hx509_cert c, hx509_private_key private_key)
|
||||
RSA_free(rsa);
|
||||
return 0;
|
||||
}
|
||||
rsa->n = heim_int2BN(&pk.modulus);
|
||||
rsa->e = heim_int2BN(&pk.publicExponent);
|
||||
n = heim_int2BN(&pk.modulus);
|
||||
e = heim_int2BN(&pk.publicExponent);
|
||||
|
||||
free_RSAPublicKey(&pk);
|
||||
|
||||
rsa->d = BN_dup(private_key->private_key.rsa->d);
|
||||
rsa->p = BN_dup(private_key->private_key.rsa->p);
|
||||
rsa->q = BN_dup(private_key->private_key.rsa->q);
|
||||
rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);
|
||||
rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);
|
||||
rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);
|
||||
new_d = BN_dup(d);
|
||||
new_p = BN_dup(p);
|
||||
new_q = BN_dup(q);
|
||||
new_dmp1 = BN_dup(dmp1);
|
||||
new_dmq1 = BN_dup(dmq1);
|
||||
new_iqmp = BN_dup(iqmp);
|
||||
|
||||
if (rsa->n == NULL || rsa->e == NULL ||
|
||||
rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||
|
||||
rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
|
||||
if (n == NULL || e == NULL ||
|
||||
new_d == NULL || new_p == NULL|| new_q == NULL ||
|
||||
new_dmp1 == NULL || new_dmq1 == NULL || new_iqmp == NULL) {
|
||||
BN_free(n);
|
||||
BN_free(e);
|
||||
BN_free(new_d);
|
||||
BN_free(new_p);
|
||||
BN_free(new_q);
|
||||
BN_free(new_dmp1);
|
||||
BN_free(new_dmq1);
|
||||
BN_free(new_iqmp);
|
||||
RSA_free(rsa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = RSA_set0_key(rsa, new_d, n, e);
|
||||
|
||||
if (ret != 1) {
|
||||
BN_free(n);
|
||||
BN_free(e);
|
||||
BN_free(new_d);
|
||||
BN_free(new_p);
|
||||
BN_free(new_q);
|
||||
BN_free(new_dmp1);
|
||||
BN_free(new_dmq1);
|
||||
BN_free(new_iqmp);
|
||||
RSA_free(rsa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = RSA_set0_factors(rsa, new_p, new_q);
|
||||
|
||||
if (ret != 1) {
|
||||
BN_free(new_p);
|
||||
BN_free(new_q);
|
||||
BN_free(new_dmp1);
|
||||
BN_free(new_dmq1);
|
||||
BN_free(new_iqmp);
|
||||
RSA_free(rsa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = RSA_set0_crt_params(rsa, new_dmp1, new_dmq1, new_iqmp);
|
||||
|
||||
if (ret != 1) {
|
||||
BN_free(new_dmp1);
|
||||
BN_free(new_dmq1);
|
||||
BN_free(new_iqmp);
|
||||
RSA_free(rsa);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1387,12 +1387,12 @@ info(void *opt, int argc, char **argv)
|
||||
{
|
||||
const RSA_METHOD *m = RSA_get_default_method();
|
||||
if (m != NULL)
|
||||
printf("rsa: %s\n", m->name);
|
||||
printf("rsa: %s\n", RSA_meth_get0_name(m));
|
||||
}
|
||||
{
|
||||
const DH_METHOD *m = DH_get_default_method();
|
||||
if (m != NULL)
|
||||
printf("dh: %s\n", m->name);
|
||||
printf("dh: %s\n", DH_meth_get0_name(m));
|
||||
}
|
||||
#ifdef HAVE_OPENSSL
|
||||
{
|
||||
|
@ -107,11 +107,18 @@ try_decrypt(hx509_context context,
|
||||
clear.length = len;
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_CipherInit_ex(&ctx, c, NULL, key, ivdata, 0);
|
||||
EVP_Cipher(&ctx, clear.data, cipher, len);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
hx509_set_error_string(context, 0, ENOMEM,
|
||||
"Out of memory to decrypt for private key");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
EVP_CipherInit_ex(ctx, c, NULL, key, ivdata, 0);
|
||||
EVP_Cipher(ctx, clear.data, cipher, len);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
|
||||
ret = _hx509_collector_private_key_add(context,
|
||||
@ -122,8 +129,8 @@ try_decrypt(hx509_context context,
|
||||
NULL);
|
||||
|
||||
memset(clear.data, 0, clear.length);
|
||||
free(clear.data);
|
||||
out:
|
||||
free(clear.data);
|
||||
memset(key, 0, keylen);
|
||||
free(key);
|
||||
return ret;
|
||||
|
@ -213,21 +213,47 @@ p11_rsa_finish(RSA *rsa)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const RSA_METHOD p11_rsa_pkcs1_method = {
|
||||
"hx509 PKCS11 PKCS#1 RSA",
|
||||
p11_rsa_public_encrypt,
|
||||
p11_rsa_public_decrypt,
|
||||
p11_rsa_private_encrypt,
|
||||
p11_rsa_private_decrypt,
|
||||
NULL,
|
||||
NULL,
|
||||
p11_rsa_init,
|
||||
p11_rsa_finish,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
static const RSA_METHOD *
|
||||
get_p11_rsa_pkcs1_method(void)
|
||||
{
|
||||
static const RSA_METHOD *p11_rsa_pkcs1_method;
|
||||
RSA_METHOD *new_method;
|
||||
|
||||
if (p11_rsa_pkcs1_method != NULL)
|
||||
return p11_rsa_pkcs1_method;
|
||||
|
||||
new_method = RSA_meth_new("hx509 PKCS11 PKCS#1 RSA", 0);
|
||||
if (new_method == NULL)
|
||||
return NULL;
|
||||
|
||||
if (RSA_meth_set_pub_enc(new_method, p11_rsa_public_encrypt) != 1)
|
||||
goto out;
|
||||
|
||||
if (RSA_meth_set_pub_dec(new_method, p11_rsa_public_decrypt) != 1)
|
||||
goto out;
|
||||
|
||||
if (RSA_meth_set_priv_enc(new_method, p11_rsa_private_encrypt) != 1)
|
||||
goto out;
|
||||
|
||||
if (RSA_meth_set_priv_dec(new_method, p11_rsa_private_decrypt) != 1)
|
||||
goto out;
|
||||
|
||||
if (RSA_meth_set_init(new_method, p11_rsa_init) != 1)
|
||||
goto out;
|
||||
|
||||
if (RSA_meth_set_finish(new_method, p11_rsa_finish) != 1)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* This might overwrite a previously-created method if multiple
|
||||
* threads invoke this concurrently which will leak memory.
|
||||
*/
|
||||
p11_rsa_pkcs1_method = new_method;
|
||||
return p11_rsa_pkcs1_method;
|
||||
out:
|
||||
RSA_meth_free(new_method);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
@ -607,6 +633,8 @@ collect_private_key(hx509_context context,
|
||||
hx509_private_key key;
|
||||
heim_octet_string localKeyId;
|
||||
int ret;
|
||||
const RSA_METHOD *meth;
|
||||
BIGNUM *n, *e;
|
||||
RSA *rsa;
|
||||
struct p11_rsa *p11rsa;
|
||||
|
||||
@ -626,8 +654,15 @@ collect_private_key(hx509_context context,
|
||||
* the pkcs11 specification, but some smartcards leaves it out,
|
||||
* let ignore any failure to fetch it.
|
||||
*/
|
||||
rsa->n = getattr_bn(p, slot, session, object, CKA_MODULUS);
|
||||
rsa->e = getattr_bn(p, slot, session, object, CKA_PUBLIC_EXPONENT);
|
||||
n = getattr_bn(p, slot, session, object, CKA_MODULUS);
|
||||
e = getattr_bn(p, slot, session, object, CKA_PUBLIC_EXPONENT);
|
||||
if (RSA_set0_key(rsa, n, e, NULL) != 1) {
|
||||
BN_free(n);
|
||||
BN_free(e);
|
||||
RSA_free(rsa);
|
||||
hx509_private_key_free(&key);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
p11rsa = calloc(1, sizeof(*p11rsa));
|
||||
if (p11rsa == NULL)
|
||||
@ -643,7 +678,10 @@ collect_private_key(hx509_context context,
|
||||
if (p->ref == UINT_MAX)
|
||||
_hx509_abort("pkcs11 ref == UINT_MAX on alloc");
|
||||
|
||||
RSA_set_method(rsa, &p11_rsa_pkcs1_method);
|
||||
meth = get_p11_rsa_pkcs1_method();
|
||||
if (meth == NULL)
|
||||
_hx509_abort("failed to create RSA method");
|
||||
RSA_set_method(rsa, meth);
|
||||
ret = RSA_set_app_data(rsa, p11rsa);
|
||||
if (ret != 1)
|
||||
_hx509_abort("RSA_set_app_data");
|
||||
|
@ -124,13 +124,15 @@ AES_PRF(krb5_context context,
|
||||
|
||||
{
|
||||
const EVP_CIPHER *c = (*crypto->et->keytype->evp)();
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx); /* ivec all zero */
|
||||
EVP_CipherInit_ex(&ctx, c, NULL, derived->keyvalue.data, NULL, 1);
|
||||
EVP_Cipher(&ctx, out->data, result.checksum.data,
|
||||
ctx = EVP_CIPHER_CTX_new(); /* ivec all zero */
|
||||
if (ctx == NULL)
|
||||
krb5_abortx(context, "malloc failed");
|
||||
EVP_CipherInit_ex(ctx, c, NULL, derived->keyvalue.data, NULL, 1);
|
||||
EVP_Cipher(ctx, out->data, result.checksum.data,
|
||||
crypto->et->blocksize);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
|
||||
krb5_data_free(&result.checksum);
|
||||
|
@ -129,7 +129,7 @@ ARCFOUR_subencrypt(krb5_context context,
|
||||
unsigned usage,
|
||||
void *ivec)
|
||||
{
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
struct _krb5_checksum_type *c = _krb5_find_checksum (CKSUMTYPE_RSA_MD5);
|
||||
Checksum k1_c, k2_c, k3_c, cksum;
|
||||
struct _krb5_key_data ke;
|
||||
@ -176,11 +176,13 @@ ARCFOUR_subencrypt(krb5_context context,
|
||||
if (ret)
|
||||
krb5_abortx(context, "hmac failed");
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL)
|
||||
krb5_abortx(context, "malloc failed");
|
||||
|
||||
EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 1);
|
||||
EVP_Cipher(&ctx, cdata + 16, cdata + 16, len - 16);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 1);
|
||||
EVP_Cipher(ctx, cdata + 16, cdata + 16, len - 16);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
memset (k1_c_data, 0, sizeof(k1_c_data));
|
||||
memset (k2_c_data, 0, sizeof(k2_c_data));
|
||||
@ -196,7 +198,7 @@ ARCFOUR_subdecrypt(krb5_context context,
|
||||
unsigned usage,
|
||||
void *ivec)
|
||||
{
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
struct _krb5_checksum_type *c = _krb5_find_checksum (CKSUMTYPE_RSA_MD5);
|
||||
Checksum k1_c, k2_c, k3_c, cksum;
|
||||
struct _krb5_key_data ke;
|
||||
@ -234,10 +236,12 @@ ARCFOUR_subdecrypt(krb5_context context,
|
||||
if (ret)
|
||||
krb5_abortx(context, "hmac failed");
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 0);
|
||||
EVP_Cipher(&ctx, cdata + 16, cdata + 16, len - 16);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL)
|
||||
krb5_abortx(context, "malloc failed");
|
||||
EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 0);
|
||||
EVP_Cipher(ctx, cdata + 16, cdata + 16, len - 16);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
ke.key = &kb;
|
||||
kb.keyvalue = k2_c.checksum;
|
||||
|
@ -81,8 +81,8 @@ _krb5_des_checksum(krb5_context context,
|
||||
EVP_DigestFinal_ex (m, p + 8, NULL);
|
||||
EVP_MD_CTX_destroy(m);
|
||||
memset (&ivec, 0, sizeof(ivec));
|
||||
EVP_CipherInit_ex(&ctx->ectx, NULL, NULL, NULL, (void *)&ivec, -1);
|
||||
EVP_Cipher(&ctx->ectx, p, p, 24);
|
||||
EVP_CipherInit_ex(ctx->ectx, NULL, NULL, NULL, (void *)&ivec, -1);
|
||||
EVP_Cipher(ctx->ectx, p, p, 24);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -109,8 +109,8 @@ _krb5_des_verify(krb5_context context,
|
||||
}
|
||||
|
||||
memset(&ivec, 0, sizeof(ivec));
|
||||
EVP_CipherInit_ex(&ctx->dctx, NULL, NULL, NULL, (void *)&ivec, -1);
|
||||
EVP_Cipher(&ctx->dctx, tmp, C->checksum.data, 24);
|
||||
EVP_CipherInit_ex(ctx->dctx, NULL, NULL, NULL, (void *)&ivec, -1);
|
||||
EVP_Cipher(ctx->dctx, tmp, C->checksum.data, 24);
|
||||
|
||||
EVP_DigestInit_ex(m, evp_md, NULL);
|
||||
EVP_DigestUpdate(m, tmp, 8); /* confounder */
|
||||
|
@ -225,7 +225,7 @@ evp_des_encrypt_null_ivec(krb5_context context,
|
||||
EVP_CIPHER_CTX *c;
|
||||
DES_cblock ivec;
|
||||
memset(&ivec, 0, sizeof(ivec));
|
||||
c = encryptp ? &ctx->ectx : &ctx->dctx;
|
||||
c = encryptp ? ctx->ectx : ctx->dctx;
|
||||
EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1);
|
||||
EVP_Cipher(c, data, data, len);
|
||||
return 0;
|
||||
@ -244,7 +244,7 @@ evp_des_encrypt_key_ivec(krb5_context context,
|
||||
EVP_CIPHER_CTX *c;
|
||||
DES_cblock ivec;
|
||||
memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
|
||||
c = encryptp ? &ctx->ectx : &ctx->dctx;
|
||||
c = encryptp ? ctx->ectx : ctx->dctx;
|
||||
EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1);
|
||||
EVP_Cipher(c, data, data, len);
|
||||
return 0;
|
||||
|
@ -41,19 +41,21 @@ _krb5_evp_schedule(krb5_context context,
|
||||
struct _krb5_evp_schedule *key = kd->schedule->data;
|
||||
const EVP_CIPHER *c = (*kt->evp)();
|
||||
|
||||
EVP_CIPHER_CTX_init(&key->ectx);
|
||||
EVP_CIPHER_CTX_init(&key->dctx);
|
||||
key->ectx = EVP_CIPHER_CTX_new();
|
||||
key->dctx = EVP_CIPHER_CTX_new();
|
||||
if (key->ectx == NULL || key->dctx == NULL)
|
||||
krb5_abort(context, ENOMEM, "malloc failed");
|
||||
|
||||
EVP_CipherInit_ex(&key->ectx, c, NULL, kd->key->keyvalue.data, NULL, 1);
|
||||
EVP_CipherInit_ex(&key->dctx, c, NULL, kd->key->keyvalue.data, NULL, 0);
|
||||
EVP_CipherInit_ex(key->ectx, c, NULL, kd->key->keyvalue.data, NULL, 1);
|
||||
EVP_CipherInit_ex(key->dctx, c, NULL, kd->key->keyvalue.data, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
_krb5_evp_cleanup(krb5_context context, struct _krb5_key_data *kd)
|
||||
{
|
||||
struct _krb5_evp_schedule *key = kd->schedule->data;
|
||||
EVP_CIPHER_CTX_cleanup(&key->ectx);
|
||||
EVP_CIPHER_CTX_cleanup(&key->dctx);
|
||||
EVP_CIPHER_CTX_free(key->ectx);
|
||||
EVP_CIPHER_CTX_free(key->dctx);
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@ -67,7 +69,7 @@ _krb5_evp_encrypt(krb5_context context,
|
||||
{
|
||||
struct _krb5_evp_schedule *ctx = key->schedule->data;
|
||||
EVP_CIPHER_CTX *c;
|
||||
c = encryptp ? &ctx->ectx : &ctx->dctx;
|
||||
c = encryptp ? ctx->ectx : ctx->dctx;
|
||||
if (ivec == NULL) {
|
||||
/* alloca ? */
|
||||
size_t len2 = EVP_CIPHER_CTX_iv_length(c);
|
||||
@ -102,7 +104,7 @@ _krb5_evp_encrypt_cts(krb5_context context,
|
||||
EVP_CIPHER_CTX *c;
|
||||
unsigned char *p;
|
||||
|
||||
c = encryptp ? &ctx->ectx : &ctx->dctx;
|
||||
c = encryptp ? ctx->ectx : ctx->dctx;
|
||||
|
||||
blocksize = EVP_CIPHER_CTX_block_size(c);
|
||||
|
||||
|
@ -63,6 +63,7 @@ seed_something(void)
|
||||
we do not have to deal with it. */
|
||||
if (RAND_status() != 1) {
|
||||
#ifndef _WIN32
|
||||
#ifndef OPENSSL_NO_EGD
|
||||
krb5_context context;
|
||||
const char *p;
|
||||
|
||||
@ -74,6 +75,7 @@ seed_something(void)
|
||||
RAND_egd_bytes(p, ENTROPY_NEEDED);
|
||||
krb5_free_context(context);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
/* TODO: Once a Windows CryptoAPI RAND method is defined, we
|
||||
can use that and failover to another method. */
|
||||
|
@ -174,6 +174,6 @@ extern int _krb5_num_etypes;
|
||||
|
||||
/* Interface to the EVP crypto layer provided by hcrypto */
|
||||
struct _krb5_evp_schedule {
|
||||
EVP_CIPHER_CTX ectx;
|
||||
EVP_CIPHER_CTX dctx;
|
||||
EVP_CIPHER_CTX *ectx;
|
||||
EVP_CIPHER_CTX *dctx;
|
||||
};
|
||||
|
@ -101,7 +101,7 @@ _krb5_pk_cert_free(struct krb5_pk_cert *cert)
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer)
|
||||
BN_to_integer(krb5_context context, const BIGNUM *bn, heim_integer *integer)
|
||||
{
|
||||
integer->length = BN_num_bytes(bn);
|
||||
integer->data = malloc(integer->length);
|
||||
@ -134,6 +134,7 @@ select_dh_group(krb5_context context, DH *dh, unsigned long bits,
|
||||
struct krb5_dh_moduli **moduli)
|
||||
{
|
||||
const struct krb5_dh_moduli *m;
|
||||
BIGNUM *p, *g, *q;
|
||||
|
||||
if (bits == 0) {
|
||||
m = moduli[1]; /* XXX */
|
||||
@ -155,15 +156,22 @@ select_dh_group(krb5_context context, DH *dh, unsigned long bits,
|
||||
m = moduli[i];
|
||||
}
|
||||
|
||||
dh->p = integer_to_BN(context, "p", &m->p);
|
||||
if (dh->p == NULL)
|
||||
return ENOMEM;
|
||||
dh->g = integer_to_BN(context, "g", &m->g);
|
||||
if (dh->g == NULL)
|
||||
return ENOMEM;
|
||||
dh->q = integer_to_BN(context, "q", &m->q);
|
||||
if (dh->q == NULL)
|
||||
p = integer_to_BN(context, "p", &m->p);
|
||||
g = integer_to_BN(context, "g", &m->g);
|
||||
q = integer_to_BN(context, "q", &m->q);
|
||||
if (p == NULL || g == NULL || q == NULL) {
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
BN_free(q);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (DH_set0_pqg(dh, p, q, g) != 1) {
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
BN_free(q);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -477,6 +485,7 @@ build_auth_pack(krb5_context context,
|
||||
|
||||
if (ctx->keyex == USE_DH) {
|
||||
DH *dh = ctx->u.dh;
|
||||
const BIGNUM *p, *g, *q, *pub_key;
|
||||
DomainParameters dp;
|
||||
heim_integer dh_pub_key;
|
||||
|
||||
@ -487,17 +496,18 @@ build_auth_pack(krb5_context context,
|
||||
|
||||
memset(&dp, 0, sizeof(dp));
|
||||
|
||||
ret = BN_to_integer(context, dh->p, &dp.p);
|
||||
DH_get0_pqg(dh, &p, &q, &g);
|
||||
ret = BN_to_integer(context, p, &dp.p);
|
||||
if (ret) {
|
||||
free_DomainParameters(&dp);
|
||||
return ret;
|
||||
}
|
||||
ret = BN_to_integer(context, dh->g, &dp.g);
|
||||
ret = BN_to_integer(context, g, &dp.g);
|
||||
if (ret) {
|
||||
free_DomainParameters(&dp);
|
||||
return ret;
|
||||
}
|
||||
ret = BN_to_integer(context, dh->q, &dp.q);
|
||||
ret = BN_to_integer(context, q, &dp.q);
|
||||
if (ret) {
|
||||
free_DomainParameters(&dp);
|
||||
return ret;
|
||||
@ -522,7 +532,8 @@ build_auth_pack(krb5_context context,
|
||||
if (size != a->clientPublicValue->algorithm.parameters->length)
|
||||
krb5_abortx(context, "Internal ASN1 encoder error");
|
||||
|
||||
ret = BN_to_integer(context, dh->pub_key, &dh_pub_key);
|
||||
DH_get0_key(dh, &pub_key, NULL);
|
||||
ret = BN_to_integer(context, pub_key, &dh_pub_key);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -87,7 +87,7 @@ heim_ntlm_decode_type3 (
|
||||
int /*ucs2*/,
|
||||
struct ntlm_type3 */*type3*/);
|
||||
|
||||
void
|
||||
int
|
||||
heim_ntlm_derive_ntlm2_sess (
|
||||
const unsigned char sessionkey[16],
|
||||
const unsigned char */*clnt_nonce*/,
|
||||
|
@ -1011,12 +1011,12 @@ heim_ntlm_encode_type3(const struct ntlm_type3 *type3, struct ntlm_buf *data)
|
||||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -498,7 +498,7 @@ xyzprintf (struct snprintf_state *state, const char *char_format, va_list ap)
|
||||
break;
|
||||
}
|
||||
case 'p' : {
|
||||
u_longest arg = (u_longest)va_arg(ap, void*);
|
||||
u_longest arg = (uintptr_t)va_arg(ap, void*);
|
||||
|
||||
len += append_number (state, arg, 0x10, "0123456789ABCDEF",
|
||||
width, prec, flags, 0);
|
||||
|
@ -8,6 +8,10 @@ KRB5DIR= ${SRCTOP}/crypto/heimdal
|
||||
|
||||
CFLAGS+= -DHAVE_CONFIG_H -I${.CURDIR:H:H}/include
|
||||
|
||||
WARNS?= 1
|
||||
CWARNFLAGS.clang+= -Wno-error=absolute-value
|
||||
CWARNFLAGS+= -Wno-error=deprecated-declarations
|
||||
|
||||
.if ${MK_OPENLDAP} != "no" && !defined(COMPAT_32BIT)
|
||||
OPENLDAPBASE?= /usr/local
|
||||
LDAPLDADD= -lldap -llber
|
||||
|
@ -18,9 +18,5 @@
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#ifndef BN_is_negative
|
||||
#define BN_set_negative(bn, flag) ((bn)->neg=(flag)?1:0)
|
||||
#define BN_is_negative(bn) ((bn)->neg != 0)
|
||||
#endif
|
||||
|
||||
#endif /* __crypto_headers_h__ */
|
||||
|
Loading…
Reference in New Issue
Block a user