use ASN1_MALLOC_ENCODE
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@11375 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
113
kdc/kerberos5.c
113
kdc/kerberos5.c
@@ -156,51 +156,68 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
|
|||||||
krb5_enctype etype,
|
krb5_enctype etype,
|
||||||
int skvno, EncryptionKey *skey,
|
int skvno, EncryptionKey *skey,
|
||||||
int ckvno, EncryptionKey *ckey,
|
int ckvno, EncryptionKey *ckey,
|
||||||
|
const char **e_text,
|
||||||
krb5_data *reply)
|
krb5_data *reply)
|
||||||
{
|
{
|
||||||
unsigned char buf[8192]; /* XXX The data could be indefinite */
|
unsigned char *buf;
|
||||||
|
size_t buf_size;
|
||||||
size_t len;
|
size_t len;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_crypto crypto;
|
krb5_crypto crypto;
|
||||||
|
|
||||||
ret = encode_EncTicketPart(buf + sizeof(buf) - 1, sizeof(buf), et, &len);
|
ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
kdc_log(0, "Failed to encode ticket: %s",
|
kdc_log(0, "Failed to encode ticket: %s",
|
||||||
krb5_get_err_text(context, ret));
|
krb5_get_err_text(context, ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if(buf_size != len) {
|
||||||
|
free(buf);
|
||||||
|
kdc_log(0, "Internal error in ASN.1 encoder");
|
||||||
|
*e_text = "KDC internal error";
|
||||||
|
return KRB5KRB_ERR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
ret = krb5_crypto_init(context, skey, etype, &crypto);
|
ret = krb5_crypto_init(context, skey, etype, &crypto);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
free(buf);
|
||||||
kdc_log(0, "krb5_crypto_init failed: %s",
|
kdc_log(0, "krb5_crypto_init failed: %s",
|
||||||
krb5_get_err_text(context, ret));
|
krb5_get_err_text(context, ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
krb5_encrypt_EncryptedData(context,
|
ret = krb5_encrypt_EncryptedData(context,
|
||||||
crypto,
|
crypto,
|
||||||
KRB5_KU_TICKET,
|
KRB5_KU_TICKET,
|
||||||
buf + sizeof(buf) - len,
|
buf,
|
||||||
len,
|
len,
|
||||||
skvno,
|
skvno,
|
||||||
&rep->ticket.enc_part);
|
&rep->ticket.enc_part);
|
||||||
|
free(buf);
|
||||||
krb5_crypto_destroy(context, crypto);
|
krb5_crypto_destroy(context, crypto);
|
||||||
|
if(ret) {
|
||||||
|
kdc_log(0, "Failed to encrypt data", krb5_get_err_text(context, ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep)
|
if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep)
|
||||||
ret = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf),
|
ASN1_MALLOC_ENCODE(EncASRepPart, buf, buf_size, ek, &len, ret);
|
||||||
ek, &len);
|
|
||||||
else
|
else
|
||||||
ret = encode_EncTGSRepPart(buf + sizeof(buf) - 1, sizeof(buf),
|
ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret);
|
||||||
ek, &len);
|
|
||||||
if(ret) {
|
if(ret) {
|
||||||
kdc_log(0, "Failed to encode KDC-REP: %s",
|
kdc_log(0, "Failed to encode KDC-REP: %s",
|
||||||
krb5_get_err_text(context, ret));
|
krb5_get_err_text(context, ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if(buf_size != len) {
|
||||||
|
free(buf);
|
||||||
|
kdc_log(0, "Internal error in ASN.1 encoder");
|
||||||
|
*e_text = "KDC internal error";
|
||||||
|
return KRB5KRB_ERR_GENERIC;
|
||||||
|
}
|
||||||
ret = krb5_crypto_init(context, ckey, 0, &crypto);
|
ret = krb5_crypto_init(context, ckey, 0, &crypto);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
free(buf);
|
||||||
kdc_log(0, "krb5_crypto_init failed: %s",
|
kdc_log(0, "krb5_crypto_init failed: %s",
|
||||||
krb5_get_err_text(context, ret));
|
krb5_get_err_text(context, ret));
|
||||||
return ret;
|
return ret;
|
||||||
@@ -209,20 +226,22 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
|
|||||||
krb5_encrypt_EncryptedData(context,
|
krb5_encrypt_EncryptedData(context,
|
||||||
crypto,
|
crypto,
|
||||||
KRB5_KU_AS_REP_ENC_PART,
|
KRB5_KU_AS_REP_ENC_PART,
|
||||||
buf + sizeof(buf) - len,
|
buf,
|
||||||
len,
|
len,
|
||||||
ckvno,
|
ckvno,
|
||||||
&rep->enc_part);
|
&rep->enc_part);
|
||||||
ret = encode_AS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
|
free(buf);
|
||||||
|
ASN1_MALLOC_ENCODE(AS_REP, buf, buf_size, rep, &len, ret);
|
||||||
} else {
|
} else {
|
||||||
krb5_encrypt_EncryptedData(context,
|
krb5_encrypt_EncryptedData(context,
|
||||||
crypto,
|
crypto,
|
||||||
KRB5_KU_TGS_REP_ENC_PART_SESSION,
|
KRB5_KU_TGS_REP_ENC_PART_SESSION,
|
||||||
buf + sizeof(buf) - len,
|
buf,
|
||||||
len,
|
len,
|
||||||
ckvno,
|
ckvno,
|
||||||
&rep->enc_part);
|
&rep->enc_part);
|
||||||
ret = encode_TGS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
|
free(buf);
|
||||||
|
ASN1_MALLOC_ENCODE(TGS_REP, buf, buf_size, rep, &len, ret);
|
||||||
}
|
}
|
||||||
krb5_crypto_destroy(context, crypto);
|
krb5_crypto_destroy(context, crypto);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
@@ -230,7 +249,14 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
|
|||||||
krb5_get_err_text(context, ret));
|
krb5_get_err_text(context, ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
krb5_data_copy(reply, buf + sizeof(buf) - len, len);
|
if(buf_size != len) {
|
||||||
|
free(buf);
|
||||||
|
kdc_log(0, "Internal error in ASN.1 encoder");
|
||||||
|
*e_text = "KDC internal error";
|
||||||
|
return KRB5KRB_ERR_GENERIC;
|
||||||
|
}
|
||||||
|
reply->data = buf;
|
||||||
|
reply->length = buf_size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,18 +359,10 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client,
|
|||||||
pa.len = n;
|
pa.len = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = length_ETYPE_INFO(&pa);
|
ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret);
|
||||||
buf = malloc(len);
|
|
||||||
if (buf == NULL) {
|
|
||||||
free_ETYPE_INFO(&pa);
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
ret = encode_ETYPE_INFO(buf + len - 1, len, &pa, &len);
|
|
||||||
free_ETYPE_INFO(&pa);
|
free_ETYPE_INFO(&pa);
|
||||||
if(ret) {
|
if(ret)
|
||||||
free(buf);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
ret = realloc_method_data(md);
|
ret = realloc_method_data(md);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
free(buf);
|
free(buf);
|
||||||
@@ -657,15 +675,10 @@ as_rep(KDC_REQ *req,
|
|||||||
ret = get_pa_etype_info(&method_data, client,
|
ret = get_pa_etype_info(&method_data, client,
|
||||||
b->etype.val, b->etype.len); /* XXX check ret */
|
b->etype.val, b->etype.len); /* XXX check ret */
|
||||||
|
|
||||||
len = length_METHOD_DATA(&method_data);
|
ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
|
||||||
buf = malloc(len);
|
|
||||||
encode_METHOD_DATA(buf + len - 1,
|
|
||||||
len,
|
|
||||||
&method_data,
|
|
||||||
&len);
|
|
||||||
free_METHOD_DATA(&method_data);
|
free_METHOD_DATA(&method_data);
|
||||||
foo_data.length = len;
|
|
||||||
foo_data.data = buf;
|
foo_data.data = buf;
|
||||||
|
foo_data.length = len;
|
||||||
|
|
||||||
ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
|
ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
|
||||||
krb5_mk_error(context,
|
krb5_mk_error(context,
|
||||||
@@ -895,7 +908,7 @@ as_rep(KDC_REQ *req,
|
|||||||
|
|
||||||
set_salt_padata (&rep.padata, ckey->salt);
|
set_salt_padata (&rep.padata, ckey->salt);
|
||||||
ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key,
|
ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key,
|
||||||
client->kvno, &ckey->key, reply);
|
client->kvno, &ckey->key, &e_text, reply);
|
||||||
free_EncTicketPart(&et);
|
free_EncTicketPart(&et);
|
||||||
free_EncKDCRepPart(&ek);
|
free_EncKDCRepPart(&ek);
|
||||||
free_AS_REP(&rep);
|
free_AS_REP(&rep);
|
||||||
@@ -1101,6 +1114,7 @@ tgs_make_reply(KDC_REQ_BODY *b,
|
|||||||
krb5_principal client_principal,
|
krb5_principal client_principal,
|
||||||
hdb_entry *krbtgt,
|
hdb_entry *krbtgt,
|
||||||
krb5_enctype cetype,
|
krb5_enctype cetype,
|
||||||
|
const char **e_text,
|
||||||
krb5_data *reply)
|
krb5_data *reply)
|
||||||
{
|
{
|
||||||
KDC_REP rep;
|
KDC_REP rep;
|
||||||
@@ -1256,7 +1270,7 @@ tgs_make_reply(KDC_REQ_BODY *b,
|
|||||||
etype list, even if we don't want a session key with
|
etype list, even if we don't want a session key with
|
||||||
DES3? */
|
DES3? */
|
||||||
ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
|
ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
|
||||||
0, &tgt->key, reply);
|
0, &tgt->key, e_text, reply);
|
||||||
out:
|
out:
|
||||||
free_TGS_REP(&rep);
|
free_TGS_REP(&rep);
|
||||||
free_TransitedEncoding(&et.transited);
|
free_TransitedEncoding(&et.transited);
|
||||||
@@ -1273,11 +1287,13 @@ out:
|
|||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
tgs_check_authenticator(krb5_auth_context ac,
|
tgs_check_authenticator(krb5_auth_context ac,
|
||||||
KDC_REQ_BODY *b,
|
KDC_REQ_BODY *b,
|
||||||
|
const char **e_text,
|
||||||
krb5_keyblock *key)
|
krb5_keyblock *key)
|
||||||
{
|
{
|
||||||
krb5_authenticator auth;
|
krb5_authenticator auth;
|
||||||
size_t len;
|
size_t len;
|
||||||
unsigned char buf[8192];
|
unsigned char *buf;
|
||||||
|
size_t buf_size;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_crypto crypto;
|
krb5_crypto crypto;
|
||||||
|
|
||||||
@@ -1304,15 +1320,22 @@ tgs_check_authenticator(krb5_auth_context ac,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX should not re-encode this */
|
/* XXX should not re-encode this */
|
||||||
ret = encode_KDC_REQ_BODY(buf + sizeof(buf) - 1, sizeof(buf),
|
ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret);
|
||||||
b, &len);
|
|
||||||
if(ret){
|
if(ret){
|
||||||
kdc_log(0, "Failed to encode KDC-REQ-BODY: %s",
|
kdc_log(0, "Failed to encode KDC-REQ-BODY: %s",
|
||||||
krb5_get_err_text(context, ret));
|
krb5_get_err_text(context, ret));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if(buf_size != len) {
|
||||||
|
free(buf);
|
||||||
|
kdc_log(0, "Internal error in ASN.1 encoder");
|
||||||
|
*e_text = "KDC internal error";
|
||||||
|
ret = KRB5KRB_ERR_GENERIC;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
ret = krb5_crypto_init(context, key, 0, &crypto);
|
ret = krb5_crypto_init(context, key, 0, &crypto);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
free(buf);
|
||||||
kdc_log(0, "krb5_crypto_init failed: %s",
|
kdc_log(0, "krb5_crypto_init failed: %s",
|
||||||
krb5_get_err_text(context, ret));
|
krb5_get_err_text(context, ret));
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1320,9 +1343,10 @@ tgs_check_authenticator(krb5_auth_context ac,
|
|||||||
ret = krb5_verify_checksum(context,
|
ret = krb5_verify_checksum(context,
|
||||||
crypto,
|
crypto,
|
||||||
KRB5_KU_TGS_REQ_AUTH_CKSUM,
|
KRB5_KU_TGS_REQ_AUTH_CKSUM,
|
||||||
buf + sizeof(buf) - len,
|
buf,
|
||||||
len,
|
len,
|
||||||
auth->cksum);
|
auth->cksum);
|
||||||
|
free(buf);
|
||||||
krb5_crypto_destroy(context, crypto);
|
krb5_crypto_destroy(context, crypto);
|
||||||
if(ret){
|
if(ret){
|
||||||
kdc_log(0, "Failed to verify checksum: %s",
|
kdc_log(0, "Failed to verify checksum: %s",
|
||||||
@@ -1506,7 +1530,7 @@ tgs_rep2(KDC_REQ_BODY *b,
|
|||||||
|
|
||||||
tgt = &ticket->ticket;
|
tgt = &ticket->ticket;
|
||||||
|
|
||||||
ret = tgs_check_authenticator(ac, b, &tgt->key);
|
ret = tgs_check_authenticator(ac, b, &e_text, &tgt->key);
|
||||||
|
|
||||||
if (b->enc_authorization_data) {
|
if (b->enc_authorization_data) {
|
||||||
krb5_keyblock *subkey;
|
krb5_keyblock *subkey;
|
||||||
@@ -1723,6 +1747,7 @@ tgs_rep2(KDC_REQ_BODY *b,
|
|||||||
cp,
|
cp,
|
||||||
krbtgt,
|
krbtgt,
|
||||||
cetype,
|
cetype,
|
||||||
|
&e_text,
|
||||||
reply);
|
reply);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999 - 2001, PADL Software Pty Ltd.
|
* Copyright (c) 1999-2001, PADL Software Pty Ltd.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -451,29 +451,10 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent,
|
|||||||
for (i = 0; i < ent->keys.len; i++) {
|
for (i = 0; i < ent->keys.len; i++) {
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
Key new;
|
|
||||||
|
|
||||||
ret = copy_Key(&ent->keys.val[i], &new);
|
ASN1_MALLOC_ENCODE(Key, buf, len, &ent->keys.val[i], &len, ret);
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
len = length_Key(&new);
|
|
||||||
buf = malloc(len);
|
|
||||||
if (buf == NULL) {
|
|
||||||
krb5_set_error_string(context, "malloc: out of memory");
|
|
||||||
ret = ENOMEM;
|
|
||||||
free_Key(&new);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = encode_Key(buf + len - 1, len, &new, &len);
|
|
||||||
if (ret != 0) {
|
|
||||||
free(buf);
|
|
||||||
free_Key(&new);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
free_Key(&new);
|
|
||||||
|
|
||||||
/* addmod_len _owns_ the key, doesn't need to copy it */
|
/* addmod_len _owns_ the key, doesn't need to copy it */
|
||||||
ret = LDAP_addmod_len(&mods, LDAP_MOD_ADD, "krb5Key", buf, len);
|
ret = LDAP_addmod_len(&mods, LDAP_MOD_ADD, "krb5Key", buf, len);
|
||||||
|
Reference in New Issue
Block a user