Implement KERB_AP_OPTIONS_CBT (server side)
if the client asserted knowledge of channel-bindings by passing KERB_AP_OPTIONS_CBT, and the server passed bindings, require the bindings to match.
This commit is contained in:

committed by
Luke Howard

parent
51ce4c8d15
commit
a4527a28a3
@@ -163,6 +163,50 @@ _gsskrb5_create_8003_checksum (
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
check_ap_options_cbt(void *ad_data, size_t ad_len,
|
||||
krb5_boolean *client_asserted_cb)
|
||||
{
|
||||
uint32_t ad_ap_options;
|
||||
|
||||
*client_asserted_cb = FALSE;
|
||||
|
||||
if (ad_len != sizeof(uint32_t))
|
||||
return KRB5KRB_AP_ERR_MSG_TYPE;
|
||||
|
||||
_gss_mg_decode_le_uint32(ad_data, &ad_ap_options);
|
||||
|
||||
if (ad_ap_options & KERB_AP_OPTIONS_CBT)
|
||||
*client_asserted_cb = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
find_ap_options(krb5_context context,
|
||||
krb5_authenticator authenticator,
|
||||
krb5_boolean *client_asserted_cb)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_authdata *ad;
|
||||
krb5_data data;
|
||||
|
||||
*client_asserted_cb = FALSE;
|
||||
|
||||
ad = authenticator->authorization_data;
|
||||
if (ad == NULL)
|
||||
return 0;
|
||||
|
||||
ret = _krb5_get_ad(context, ad, NULL, KRB5_AUTHDATA_AP_OPTIONS, &data);
|
||||
if (ret)
|
||||
return ret == ENOENT ? 0 : ret;
|
||||
|
||||
ret = check_ap_options_cbt(data.data, data.length, client_asserted_cb);
|
||||
krb5_data_free(&data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* verify the checksum in `cksum' over `input_chan_bindings'
|
||||
* returning `flags' and `fwd_data'
|
||||
@@ -170,9 +214,10 @@ _gsskrb5_create_8003_checksum (
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_verify_8003_checksum(
|
||||
krb5_context context,
|
||||
OM_uint32 *minor_status,
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
const Checksum *cksum,
|
||||
krb5_authenticator authenticator,
|
||||
OM_uint32 *flags,
|
||||
krb5_data *fwd_data)
|
||||
{
|
||||
@@ -182,6 +227,9 @@ _gsskrb5_verify_8003_checksum(
|
||||
int DlgOpt;
|
||||
static unsigned char zeros[16];
|
||||
krb5_boolean channel_bound = FALSE;
|
||||
const Checksum *cksum = authenticator->cksum;
|
||||
krb5_boolean client_asserted_cb;
|
||||
krb5_error_code ret;
|
||||
|
||||
/* XXX should handle checksums > 24 bytes */
|
||||
if(cksum->cksumtype != CKSUMTYPE_GSSAPI || cksum->checksum.length < 24) {
|
||||
@@ -198,8 +246,14 @@ _gsskrb5_verify_8003_checksum(
|
||||
|
||||
p += 4;
|
||||
|
||||
ret = find_ap_options(context, authenticator, &client_asserted_cb);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS
|
||||
&& memcmp(p, zeros, sizeof(zeros)) != 0) {
|
||||
&& (memcmp(p, zeros, sizeof(zeros)) != 0 || client_asserted_cb)) {
|
||||
if(hash_input_chan_bindings(input_chan_bindings, hash) != 0) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_BAD_BINDINGS;
|
||||
|
@@ -566,9 +566,10 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
|
||||
|
||||
if (authenticator->cksum != NULL
|
||||
&& authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) {
|
||||
ret = _gsskrb5_verify_8003_checksum(minor_status,
|
||||
ret = _gsskrb5_verify_8003_checksum(context,
|
||||
minor_status,
|
||||
input_chan_bindings,
|
||||
authenticator->cksum,
|
||||
authenticator,
|
||||
&ctx->flags,
|
||||
&ctx->fwd_data);
|
||||
|
||||
|
Reference in New Issue
Block a user