krb5_error_code ret = 0;
const char *e_text = NULL;
krb5_crypto crypto;
- Key *ckey, *skey;
+ Key *skey;
EncryptionKey *reply_key = NULL, session_key;
int flags = HDB_F_FOR_AS_REQ;
#ifdef PKINIT
was some problem with it, other than too large skew */
if(found_pa && et.flags.pre_authent == 0){
kdc_log(context, config, 0, "%s -- %s", e_text, client_name);
+ if (!prepare_enc_data(context, config, &e_data, b, client)) {
+ goto out;
+ }
e_text = NULL;
goto out;
}
|| b->kdc_options.request_anonymous /* hack to force anon */
|| client->entry.flags.require_preauth
|| server->entry.flags.require_preauth) {
- METHOD_DATA method_data;
- PA_DATA *pa;
- unsigned char *buf;
- size_t len;
-
use_pa:
- method_data.len = 0;
- method_data.val = NULL;
-
- ret = realloc_method_data(&method_data);
- if (ret) {
- free_METHOD_DATA(&method_data);
- goto out;
- }
- pa = &method_data.val[method_data.len-1];
- pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP;
- pa->padata_value.length = 0;
- pa->padata_value.data = NULL;
-
-#ifdef PKINIT
- ret = realloc_method_data(&method_data);
- if (ret) {
- free_METHOD_DATA(&method_data);
- goto out;
- }
- pa = &method_data.val[method_data.len-1];
- pa->padata_type = KRB5_PADATA_PK_AS_REQ;
- pa->padata_value.length = 0;
- pa->padata_value.data = NULL;
-
- ret = realloc_method_data(&method_data);
- if (ret) {
- free_METHOD_DATA(&method_data);
- goto out;
- }
- pa = &method_data.val[method_data.len-1];
- pa->padata_type = KRB5_PADATA_PK_AS_REQ_WIN;
- pa->padata_value.length = 0;
- pa->padata_value.data = NULL;
-#endif
-
- /*
- * If there is a client key, send ETYPE_INFO{,2}
- */
- ret = _kdc_find_etype(context,
- config->preauth_use_strongest_session_key, TRUE,
- client, b->etype.val, b->etype.len, NULL, &ckey);
- if (ret == 0) {
-
- /*
- * RFC4120 requires:
- * - If the client only knows about old enctypes, then send
- * both info replies (we send 'info' first in the list).
- * - If the client is 'modern', because it knows about 'new'
- * enctype types, then only send the 'info2' reply.
- *
- * Before we send the full list of etype-info data, we pick
- * the client key we would have used anyway below, just pick
- * that instead.
- */
-
- if (older_enctype(ckey->key.keytype)) {
- ret = get_pa_etype_info(context, config,
- &method_data, ckey);
- if (ret) {
- free_METHOD_DATA(&method_data);
- goto out;
- }
- }
- ret = get_pa_etype_info2(context, config,
- &method_data, ckey);
- if (ret) {
- free_METHOD_DATA(&method_data);
+ if (!prepare_enc_data(context, config, &e_data, b, client)) {
goto out;
- }
}
- ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
- free_METHOD_DATA(&method_data);
-
- e_data.data = buf;
- e_data.length = len;
e_text ="Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ",
ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
return ret;
}
+krb5_boolean
+prepare_enc_data(krb5_context context,
+ krb5_kdc_configuration *config,
+ krb5_data *e_data,
+ KDC_REQ_BODY *b,
+ hdb_entry_ex *client)
+{
+ METHOD_DATA method_data;
+ PA_DATA *pa;
+ unsigned char *buf;
+ size_t len;
+ Key *ckey;
+ krb5_error_code ret;
+
+ method_data.len = 0;
+ method_data.val = NULL;
+
+ ret = realloc_method_data(&method_data);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ return FALSE;
+ }
+ pa = &method_data.val[method_data.len-1];
+ pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP;
+ pa->padata_value.length = 0;
+ pa->padata_value.data = NULL;
+
+#ifdef PKINIT
+ ret = realloc_method_data(&method_data);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ return FALSE;
+ }
+ pa = &method_data.val[method_data.len-1];
+ pa->padata_type = KRB5_PADATA_PK_AS_REQ;
+ pa->padata_value.length = 0;
+ pa->padata_value.data = NULL;
+
+ ret = realloc_method_data(&method_data);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ return FALSE;
+ }
+ pa = &method_data.val[method_data.len-1];
+ pa->padata_type = KRB5_PADATA_PK_AS_REQ_WIN;
+ pa->padata_value.length = 0;
+ pa->padata_value.data = NULL;
+#endif
+
+ /*
+ * If there is a client key, send ETYPE_INFO{,2}
+ */
+ ret = _kdc_find_etype(context,
+ config->preauth_use_strongest_session_key, TRUE,
+ client, b->etype.val, b->etype.len, NULL, &ckey);
+ if (ret == 0) {
+
+ /*
+ * RFC4120 requires:
+ * - If the client only knows about old enctypes, then send
+ * both info replies (we send 'info' first in the list).
+ * - If the client is 'modern', because it knows about 'new'
+ * enctype types, then only send the 'info2' reply.
+ *
+ * Before we send the full list of etype-info data, we pick
+ * the client key we would have used anyway below, just pick
+ * that instead.
+ */
+
+ if (older_enctype(ckey->key.keytype)) {
+ ret = get_pa_etype_info(context, config,
+ &method_data, ckey);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ return FALSE;
+ }
+ }
+ ret = get_pa_etype_info2(context, config,
+ &method_data, ckey);
+ if (ret) {
+ free_METHOD_DATA(&method_data);
+ return FALSE;
+ }
+ }
+
+ ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
+ free_METHOD_DATA(&method_data);
+
+ e_data->data = buf;
+ e_data->length = len;
+
+ return TRUE;
+}
+
/*
* Add the AuthorizationData `data´ of `type´ to the last element in
* the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT
"Got wrong error.error_code");
free_KRB_ERROR(&error);
} else if (test_context->packet_count == 1) {
+ METHOD_DATA m;
+ size_t len;
+ int i, ret = 0;
+ bool found = false;
torture_assert_int_equal(test_context->tctx,
decode_KRB_ERROR(recv_buf->data, recv_buf->length, &error, &used), 0,
"decode_AS_REP failed");
torture_assert_int_equal(test_context->tctx, error.pvno, 5, "Got wrong error.pvno");
torture_assert_int_equal(test_context->tctx, error.error_code, KRB5KDC_ERR_PREAUTH_FAILED - KRB5KDC_ERR_NONE,
"Got wrong error.error_code");
+ torture_assert(test_context->tctx, error.e_data != NULL, "No e-data returned");
+ ret = decode_METHOD_DATA(error.e_data->data, error.e_data->length, &m, &len);
+ torture_assert_int_equal(test_context->tctx, ret, 0,
+ "Got invalid method data");
+
+ torture_assert(test_context->tctx, m.len > 0, "No PA_DATA given");
+ for (i = 0; i < m.len; i++) {
+ if (m.val[i].padata_type == KRB5_PADATA_ENC_TIMESTAMP) {
+ found = true;
+ break;
+ }
+ }
+ torture_assert(test_context->tctx, found, "Encrypted timestamp not found");
+
free_KRB_ERROR(&error);
}
torture_assert(test_context->tctx, test_context->packet_count < 2, "too many packets");