Skip to content

Commit

Permalink
kdc: decrypt b->enc_authorization_data in tgs_build_reply()
Browse files Browse the repository at this point in the history
We need to do this after checking for constraint delegation (S4U2Proxy).

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13131

Signed-off-by: Stefan Metzmacher <metze@samba.org>

MR: heimdal#1156
  • Loading branch information
metze-samba authored and jsutton24 committed Feb 26, 2024
1 parent 80acfba commit b16cc20
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 57 deletions.
1 change: 1 addition & 0 deletions kdc/kdc_locl.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ struct astgs_request_desc {
unsigned int rk_is_subkey : 1;
unsigned int fast_asserted : 1;
unsigned int explicit_armor_present : 1;
krb5_keyblock enc_ad_key;

krb5_crypto armor_crypto;
hdb_entry *armor_server;
Expand Down
1 change: 1 addition & 0 deletions kdc/kerberos5.c
Original file line number Diff line number Diff line change
Expand Up @@ -3040,6 +3040,7 @@ _kdc_as_rep(astgs_request_t r)
if (r->armor_server)
_kdc_free_ent(r->context, r->armor_serverdb, r->armor_server);
krb5_free_keyblock_contents(r->context, &r->reply_key);
krb5_free_keyblock_contents(r->context, &r->enc_ad_key);
krb5_free_keyblock_contents(r->context, &r->session_key);
krb5_free_keyblock_contents(r->context, &r->strengthen_key);
krb5_pac_free(r->context, r->pac);
Expand Down
126 changes: 69 additions & 57 deletions kdc/krb5tgs.c
Original file line number Diff line number Diff line change
Expand Up @@ -931,8 +931,7 @@ tgs_parse_request(astgs_request_t r,
const char *from,
const struct sockaddr *from_addr,
time_t **csec,
int **cusec,
AuthorizationData **auth_data)
int **cusec)
{
krb5_kdc_configuration *config = r->config;
KDC_REQ_BODY *b = &r->req.req_body;
Expand All @@ -943,16 +942,13 @@ tgs_parse_request(astgs_request_t r,
krb5_auth_context ac = NULL;
krb5_flags ap_req_options;
krb5_flags verify_ap_req_flags = 0;
krb5_crypto crypto;
krb5uint32 krbtgt_kvno; /* kvno used for the PA-TGS-REQ AP-REQ Ticket */
krb5uint32 krbtgt_kvno_try;
int kvno_search_tries = 4; /* number of kvnos to try when tkt_vno == 0 */
const Keys *krbtgt_keys;/* keyset for TGT tkt_vno */
Key *tkey;
krb5_keyblock *subkey = NULL;
unsigned usage;

*auth_data = NULL;
*csec = NULL;
*cusec = NULL;

Expand Down Expand Up @@ -1135,7 +1131,6 @@ tgs_parse_request(astgs_request_t r,
goto out;
}

usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
r->rk_is_subkey = 1;

ret = krb5_auth_con_getremotesubkey(r->context, ac, &subkey);
Expand All @@ -1147,7 +1142,6 @@ tgs_parse_request(astgs_request_t r,
goto out;
}
if(subkey == NULL){
usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
r->rk_is_subkey = 0;

ret = krb5_auth_con_getkey(r->context, ac, &subkey);
Expand All @@ -1173,47 +1167,13 @@ tgs_parse_request(astgs_request_t r,
if (ret)
goto out;

krb5_free_keyblock_contents(r->context, &r->enc_ad_key);
if (b->enc_authorization_data) {
krb5_data ad;

ret = krb5_crypto_init(r->context, &r->reply_key, 0, &crypto);
if (ret) {
const char *msg = krb5_get_error_message(r->context, ret);
krb5_auth_con_free(r->context, ac);
kdc_log(r->context, config, 4, "krb5_crypto_init failed: %s", msg);
krb5_free_error_message(r->context, msg);
goto out;
}
ret = krb5_decrypt_EncryptedData (r->context,
crypto,
usage,
b->enc_authorization_data,
&ad);
krb5_crypto_destroy(r->context, crypto);
if(ret){
krb5_auth_con_free(r->context, ac);
kdc_log(r->context, config, 4,
"Failed to decrypt enc-authorization-data");
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out;
}
ALLOC(*auth_data);
if (*auth_data == NULL) {
krb5_data_free(&ad);
krb5_auth_con_free(r->context, ac);
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out;
}
ret = decode_AuthorizationData(ad.data, ad.length, *auth_data, NULL);
krb5_data_free(&ad);
if(ret){
krb5_auth_con_free(r->context, ac);
free(*auth_data);
*auth_data = NULL;
kdc_log(r->context, config, 4, "Failed to decode authorization data");
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
ret = krb5_copy_keyblock_contents(r->context,
&r->reply_key,
&r->enc_ad_key);
if (ret)
goto out;
}
}

ret = validate_fast_ad(r, r->ticket->ticket.authorization_data);
Expand Down Expand Up @@ -1372,7 +1332,6 @@ _kdc_db_fetch_client(krb5_context context,
static krb5_error_code
tgs_build_reply(astgs_request_t priv,
krb5_enctype krbtgt_etype,
AuthorizationData **auth_data,
const struct sockaddr *from_addr)
{
krb5_context context = priv->context;
Expand Down Expand Up @@ -1402,6 +1361,7 @@ tgs_build_reply(astgs_request_t priv,
krb5_principal_get_comp_string(context, priv->krbtgt->principal, 1);
char **capath = NULL;
size_t num_capath = 0;
AuthorizationData *auth_data = NULL;

HDB *krbtgt_outdb;
hdb_entry *krbtgt_out = NULL;
Expand Down Expand Up @@ -1933,6 +1893,60 @@ tgs_build_reply(astgs_request_t priv,
if (ret)
goto out;

if (b->enc_authorization_data) {
unsigned auth_data_usage;
krb5_crypto crypto;
krb5_data ad;

if (priv->rk_is_subkey != 0) {
auth_data_usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
} else {
auth_data_usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
}

ret = krb5_crypto_init(context, &priv->enc_ad_key, 0, &crypto);
if (ret) {
const char *msg = krb5_get_error_message(context, ret);
kdc_audit_addreason((kdc_request_t)priv,
"krb5_crypto_init() failed for "
"enc_authorization_data");
kdc_log(context, config, 4, "krb5_crypto_init failed: %s", msg);
krb5_free_error_message(context, msg);
goto out;
}
ret = krb5_decrypt_EncryptedData(context,
crypto,
auth_data_usage,
b->enc_authorization_data,
&ad);
krb5_crypto_destroy(context, crypto);
if(ret){
kdc_audit_addreason((kdc_request_t)priv,
"Failed to decrypt enc-authorization-data");
kdc_log(context, config, 4,
"Failed to decrypt enc-authorization-data");
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out;
}
ALLOC(auth_data);
if (auth_data == NULL) {
krb5_data_free(&ad);
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out;
}
ret = decode_AuthorizationData(ad.data, ad.length, auth_data, NULL);
krb5_data_free(&ad);
if(ret){
free(auth_data);
auth_data = NULL;
kdc_audit_addreason((kdc_request_t)priv,
"Failed to decode authorization data");
kdc_log(context, config, 4, "Failed to decode authorization data");
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out;
}
}

/*
* Check flags
*/
Expand Down Expand Up @@ -2044,7 +2058,7 @@ tgs_build_reply(astgs_request_t priv,
&tkey_sign->key,
&sessionkey,
kvno,
*auth_data,
auth_data,
tgt_realm,
rodc_id,
add_ticket_sig);
Expand All @@ -2064,6 +2078,11 @@ tgs_build_reply(astgs_request_t priv,
krb5_free_principal(context, krbtgt_out_principal);
free(ref_realm);

if (auth_data) {
free_AuthorizationData(auth_data);
free(auth_data);
}

free_EncTicketPart(&adtkt);

krb5_pac_free(context, user2user_pac);
Expand All @@ -2084,7 +2103,6 @@ _kdc_tgs_rep(astgs_request_t r)
const char *from = r->from;
struct sockaddr *from_addr = r->addr;
int datagram_reply = r->datagram_reply;
AuthorizationData *auth_data = NULL;
krb5_error_code ret;
int i = 0;
const PA_DATA *tgs_req, *pa;
Expand Down Expand Up @@ -2122,8 +2140,7 @@ _kdc_tgs_rep(astgs_request_t r)
ret = tgs_parse_request(r, tgs_req,
&krbtgt_etype,
from, from_addr,
&csec, &cusec,
&auth_data);
&csec, &cusec);
if (ret == HDB_ERR_NOT_FOUND_HERE) {
/* kdc_log() is called in tgs_parse_request() */
goto out;
Expand All @@ -2147,7 +2164,6 @@ _kdc_tgs_rep(astgs_request_t r)

ret = tgs_build_reply(r,
krbtgt_etype,
&auth_data,
from_addr);
if (ret) {
kdc_log(r->context, config, 4,
Expand Down Expand Up @@ -2227,6 +2243,7 @@ _kdc_tgs_rep(astgs_request_t r)
if (r->explicit_armor_pac)
krb5_pac_free(r->context, r->explicit_armor_pac);
krb5_free_keyblock_contents(r->context, &r->reply_key);
krb5_free_keyblock_contents(r->context, &r->enc_ad_key);
krb5_free_keyblock_contents(r->context, &r->strengthen_key);

if (r->ticket)
Expand All @@ -2243,10 +2260,5 @@ _kdc_tgs_rep(astgs_request_t r)
_kdc_free_fast_state(&r->fast);
krb5_pac_free(r->context, r->pac);

if (auth_data) {
free_AuthorizationData(auth_data);
free(auth_data);
}

return ret;
}

0 comments on commit b16cc20

Please sign in to comment.