summaryrefslogtreecommitdiffstats
path: root/src/lib/krb5
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb5')
-rw-r--r--src/lib/krb5/krb/fast.c10
-rw-r--r--src/lib/krb5/krb/mk_req_ext.c39
-rw-r--r--src/lib/krb5/krb/mk_safe.c55
-rw-r--r--src/lib/krb5/krb/pac.c4
-rw-r--r--src/lib/krb5/krb/preauth2.c5
5 files changed, 67 insertions, 46 deletions
diff --git a/src/lib/krb5/krb/fast.c b/src/lib/krb5/krb/fast.c
index cc9f899a7..3137195ae 100644
--- a/src/lib/krb5/krb/fast.c
+++ b/src/lib/krb5/krb/fast.c
@@ -211,7 +211,6 @@ krb5int_fast_prep_req(krb5_context context,
krb5_data *encoded_fast_req = NULL;
krb5_data *encoded_armored_req = NULL;
krb5_data *local_encoded_result = NULL;
- krb5_cksumtype cksumtype;
krb5_data random_data;
char random_buf[4];
@@ -247,15 +246,8 @@ krb5int_fast_prep_req(krb5_context context,
}
if (retval == 0)
armored_req->armor = state->armor;
- if (retval == 0)
- retval = krb5int_c_mandatory_cksumtype(context,
- state->armor_key->enctype,
- &cksumtype);
- /* DES enctypes have unkeyed mandatory checksums; need a keyed one. */
- if (retval == 0 && !krb5_c_is_keyed_cksum(cksumtype))
- cksumtype = CKSUMTYPE_RSA_MD5_DES;
if (retval ==0)
- retval = krb5_c_make_checksum(context, cksumtype, state->armor_key,
+ retval = krb5_c_make_checksum(context, 0, state->armor_key,
KRB5_KEYUSAGE_FAST_REQ_CHKSUM,
to_be_checksummed,
&armored_req->req_checksum);
diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c
index 3a4004dc0..1979b8d63 100644
--- a/src/lib/krb5/krb/mk_req_ext.c
+++ b/src/lib/krb5/krb/mk_req_ext.c
@@ -81,6 +81,36 @@ generate_authenticator(krb5_context,
krb5_enctype *desired_etypes,
krb5_enctype tkt_enctype);
+/* Return the checksum type for the AP request, or 0 to use the enctype's
+ * mandatory checksum. */
+static krb5_cksumtype
+ap_req_cksum(krb5_context context, krb5_auth_context auth_context,
+ krb5_enctype enctype)
+{
+ /* Use the configured checksum type if one was set. */
+ if (auth_context->req_cksumtype)
+ return auth_context->req_cksumtype;
+
+ /*
+ * Otherwise choose based on the enctype. For interoperability with very
+ * old implementations, use unkeyed MD4 or MD5 checkums for DES enctypes.
+ * (The authenticator checksum does not have to be keyed since it is
+ * contained within an encrypted blob.)
+ */
+ switch (enctype) {
+ case ENCTYPE_DES_CBC_CRC:
+ case ENCTYPE_DES_CBC_MD5:
+ return CKSUMTYPE_RSA_MD5;
+ break;
+ case ENCTYPE_DES_CBC_MD4:
+ return CKSUMTYPE_RSA_MD4;
+ break;
+ default:
+ /* Use the mandatory checksum type for the enctype. */
+ return 0;
+ }
+}
+
krb5_error_code KRB5_CALLCONV
krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
krb5_flags ap_req_options, krb5_data *in_data,
@@ -169,13 +199,8 @@ krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
} else {
krb5_enctype enctype = krb5_k_key_enctype(context,
(*auth_context)->key);
- krb5_cksumtype cksumtype;
- retval = krb5int_c_mandatory_cksumtype(context, enctype,
- &cksumtype);
- if (retval)
- goto cleanup_cksum;
- if ((*auth_context)->req_cksumtype)
- cksumtype = (*auth_context)->req_cksumtype;
+ krb5_cksumtype cksumtype = ap_req_cksum(context, *auth_context,
+ enctype);
if ((retval = krb5_k_make_checksum(context,
cksumtype,
(*auth_context)->key,
diff --git a/src/lib/krb5/krb/mk_safe.c b/src/lib/krb5/krb/mk_safe.c
index eaa3add82..334701dd5 100644
--- a/src/lib/krb5/krb/mk_safe.c
+++ b/src/lib/krb5/krb/mk_safe.c
@@ -59,10 +59,9 @@ krb5_mk_safe_basic(krb5_context context, const krb5_data *userdata,
krb5_checksum safe_checksum;
krb5_data *scratch1, *scratch2;
- if (!krb5_c_valid_cksumtype(sumtype))
+ if (sumtype && !krb5_c_valid_cksumtype(sumtype))
return KRB5_PROG_SUMTYPE_NOSUPP;
- if (!krb5_c_is_coll_proof_cksum(sumtype)
- || !krb5_c_is_keyed_cksum(sumtype))
+ if (sumtype && !krb5_c_is_keyed_cksum(sumtype))
return KRB5KRB_AP_ERR_INAPP_CKSUM;
safemsg.user_data = *userdata;
@@ -110,6 +109,30 @@ cleanup_checksum:
return retval;
}
+/* Return the checksum type for the KRB-SAFE message, or 0 to use the enctype's
+ * mandatory checksum. */
+static krb5_cksumtype
+safe_cksumtype(krb5_context context, krb5_auth_context auth_context,
+ krb5_enctype enctype)
+{
+ krb5_error_code retval;
+ unsigned int nsumtypes, i;
+ krb5_cksumtype *sumtypes;
+
+ /* Use the auth context's safe_cksumtype if it is valid for the enctype.
+ * Otherwise return 0 for the mandatory checksum. */
+ retval = krb5_c_keyed_checksum_types(context, enctype, &nsumtypes,
+ &sumtypes);
+ if (retval != 0 || nsumtypes == 0)
+ return 0;
+ for (i = 0; i < nsumtypes; i++) {
+ if (auth_context->safe_cksumtype == sumtypes[i])
+ break;
+ }
+ krb5_free_cksumtypes(context, sumtypes);
+ return (i == nsumtypes) ? 0 : auth_context->safe_cksumtype;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_mk_safe(krb5_context context, krb5_auth_context auth_context,
const krb5_data *userdata, krb5_data *outbuf,
@@ -195,31 +218,7 @@ krb5_mk_safe(krb5_context context, krb5_auth_context auth_context,
}
}
- {
- krb5_enctype enctype = krb5_k_key_enctype(context, key);
- unsigned int nsumtypes;
- unsigned int i;
- krb5_cksumtype *sumtypes;
- retval = krb5_c_keyed_checksum_types (context, enctype,
- &nsumtypes, &sumtypes);
- if (retval) {
- CLEANUP_DONE ();
- goto error;
- }
- if (nsumtypes == 0) {
- retval = KRB5_BAD_ENCTYPE;
- krb5_free_cksumtypes (context, sumtypes);
- CLEANUP_DONE ();
- goto error;
- }
- for (i = 0; i < nsumtypes; i++)
- if (auth_context->safe_cksumtype == sumtypes[i])
- break;
- if (i == nsumtypes)
- i = 0;
- sumtype = sumtypes[i];
- krb5_free_cksumtypes (context, sumtypes);
- }
+ sumtype = safe_cksumtype(context, auth_context, key->keyblock.enctype);
if ((retval = krb5_mk_safe_basic(context, userdata, key, &replaydata,
plocal_fulladdr, premote_fulladdr,
sumtype, outbuf))) {
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
index 5b6e18288..983b4e8a5 100644
--- a/src/lib/krb5/krb/pac.c
+++ b/src/lib/krb5/krb/pac.c
@@ -533,6 +533,8 @@ k5_pac_verify_server_checksum(krb5_context context,
checksum.checksum_type = load_32_le(p);
checksum.length = checksum_data.length - PAC_SIGNATURE_DATA_LENGTH;
checksum.contents = p + PAC_SIGNATURE_DATA_LENGTH;
+ if (!krb5_c_is_keyed_cksum(checksum.checksum_type))
+ return KRB5KRB_AP_ERR_INAPP_CKSUM;
pac_data.length = pac->data.length;
pac_data.data = malloc(pac->data.length);
@@ -603,6 +605,8 @@ k5_pac_verify_kdc_checksum(krb5_context context,
checksum.checksum_type = load_32_le(p);
checksum.length = privsvr_checksum.length - PAC_SIGNATURE_DATA_LENGTH;
checksum.contents = p + PAC_SIGNATURE_DATA_LENGTH;
+ if (!krb5_c_is_keyed_cksum(checksum.checksum_type))
+ return KRB5KRB_AP_ERR_INAPP_CKSUM;
server_checksum.data += PAC_SIGNATURE_DATA_LENGTH;
server_checksum.length -= PAC_SIGNATURE_DATA_LENGTH;
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index 5d7d2448c..f4896eb96 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -1283,7 +1283,9 @@ pa_sam_2(krb5_context context, krb5_kdc_req *request, krb5_pa_data *in_padata,
cksum = sc2->sam_cksum;
- while (*cksum) {
+ for (; *cksum; cksum++) {
+ if (!krb5_c_is_keyed_cksum((*cksum)->checksum_type))
+ continue;
/* Check this cksum */
retval = krb5_c_verify_checksum(context, as_key,
KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM,
@@ -1297,7 +1299,6 @@ pa_sam_2(krb5_context context, krb5_kdc_req *request, krb5_pa_data *in_padata,
}
if (valid_cksum)
break;
- cksum++;
}
if (!valid_cksum) {