#include "pkinit.h"
-/* Remove when FAST PKINIT is settled. */
-#include "fast_factor.h"
-
/*
* It is anticipated that all the special checks currently
* required when talking to a Longhorn server will go away
pkinit_context plgctx,
pkinit_req_context reqctx,
krb5_kdc_req * request,
- krb5_pa_data * in_padata,
+ krb5_preauthtype pa_type,
krb5_pa_data *** out_padata,
krb5_prompter_fct prompter,
void *prompter_data,
krb5_pa_data **return_pa_data = NULL;
cksum.contents = NULL;
- reqctx->pa_type = in_padata->pa_type;
+ reqctx->pa_type = pa_type;
pkiDebug("kdc_options = 0x%x till = %d\n",
request->kdc_options, request->till);
der_req, &cksum);
if (retval)
goto cleanup;
+ TRACE_PKINIT_CLIENT_REQ_CHECKSUM(context, &cksum);
#ifdef DEBUG_CKSUM
pkiDebug("calculating checksum on buf size (%d)\n", der_req->length);
print_buffer(der_req->data, der_req->length);
return_pa_data[0]->magic = KV5M_PA_DATA;
- if (in_padata->pa_type == KRB5_PADATA_PK_AS_REQ_OLD)
+ if (pa_type == KRB5_PADATA_PK_AS_REQ_OLD)
return_pa_data[0]->pa_type = KRB5_PADATA_PK_AS_REP_OLD;
else
- return_pa_data[0]->pa_type = in_padata->pa_type;
+ return_pa_data[0]->pa_type = pa_type;
return_pa_data[0]->length = out_data->length;
return_pa_data[0]->contents = (krb5_octet *) out_data->data;
auth_pack9->pkAuthenticator.cusec = cusec;
auth_pack9->pkAuthenticator.nonce = nonce;
auth_pack9->pkAuthenticator.kdcName = server;
- auth_pack9->pkAuthenticator.kdcRealm.magic = 0;
- auth_pack9->pkAuthenticator.kdcRealm.data =
- (unsigned char *)server->realm.data;
- auth_pack9->pkAuthenticator.kdcRealm.length = server->realm.length;
free(cksum->contents);
break;
case KRB5_PADATA_PK_AS_REQ:
auth_pack->pkAuthenticator.paChecksum = *cksum;
auth_pack->clientDHNonce.length = 0;
auth_pack->clientPublicValue = info;
- auth_pack->supportedKDFs = (krb5_octet_data **) supported_kdf_alg_ids;
+ auth_pack->supportedKDFs = (krb5_data **) supported_kdf_alg_ids;
/* add List of CMS algorithms */
retval = create_krb5_supportedCMSTypes(context, plgctx->cryptoctx,
switch(protocol) {
case DH_PROTOCOL:
+ TRACE_PKINIT_CLIENT_REQ_DH(context);
pkiDebug("as_req: DH key transport algorithm\n");
- retval = pkinit_copy_krb5_octet_data(&info->algorithm.algorithm, &dh_oid);
+ retval = pkinit_copy_krb5_data(&info->algorithm.algorithm, &dh_oid);
if (retval) {
pkiDebug("failed to copy dh_oid\n");
goto cleanup;
/* create client-side DH keys */
if ((retval = client_create_dh(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx, reqctx->opts->dh_size,
+ (unsigned char **)
&info->algorithm.parameters.data,
&info->algorithm.parameters.length,
+ (unsigned char **)
&info->subjectPublicKey.data,
&info->subjectPublicKey.length)) != 0) {
pkiDebug("failed to create dh parameters\n");
}
break;
case RSA_PROTOCOL:
+ TRACE_PKINIT_CLIENT_REQ_RSA(context);
pkiDebug("as_req: RSA key transport algorithm\n");
switch((int)reqctx->pa_type) {
case KRB5_PADATA_PK_AS_REQ_OLD:
if (use_content_info(context, reqctx, client)) {
retval = cms_contentinfo_create(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx,
- CMS_SIGN_CLIENT, (unsigned char *)
+ CMS_SIGN_CLIENT,
+ (unsigned char *)
coded_auth_pack->data,
coded_auth_pack->length,
+ (unsigned char **)
&req->signedAuthPack.data,
&req->signedAuthPack.length);
} else {
(unsigned char *)
coded_auth_pack->data,
coded_auth_pack->length,
+ (unsigned char **)
&req->signedAuthPack.data,
&req->signedAuthPack.length);
}
}
retval = cms_signeddata_create(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_DRAFT9, 1,
- (unsigned char *)coded_auth_pack->data, coded_auth_pack->length,
- &req9->signedAuthPack.data, &req9->signedAuthPack.length);
+ (unsigned char *)coded_auth_pack->data,
+ coded_auth_pack->length,
+ (unsigned char **)
+ &req9->signedAuthPack.data,
+ &req9->signedAuthPack.length);
break;
#ifdef DEBUG_ASN1
print_buffer_bin((unsigned char *)req9->signedAuthPack.data,
if (retval)
goto cleanup;
retval = create_issuerAndSerial(context, plgctx->cryptoctx,
- reqctx->cryptoctx, reqctx->idctx, &req->kdcPkId.data,
+ reqctx->cryptoctx, reqctx->idctx,
+ (unsigned char **)&req->kdcPkId.data,
&req->kdcPkId.length);
if (retval)
goto cleanup;
retval = k5int_encode_krb5_pa_pk_as_req(req, as_req);
break;
case KRB5_PADATA_PK_AS_REQ_OLD:
-#if 0
- /* W2K3 KDC doesn't like this */
- retval = create_krb5_trustedCas(context, plgctx->cryptoctx,
- reqctx->cryptoctx, reqctx->idctx, 1, &req9->trustedCertifiers);
- if (retval)
- goto cleanup;
-
-#endif
retval = create_issuerAndSerial(context, plgctx->cryptoctx,
- reqctx->cryptoctx, reqctx->idctx, &req9->kdcCert.data,
+ reqctx->cryptoctx, reqctx->idctx,
+ (unsigned char **)&req9->kdcCert.data,
&req9->kdcCert.length);
if (retval)
goto cleanup;
int *need_eku_checking)
{
krb5_error_code retval;
- char **certhosts = NULL, **cfghosts = NULL;
- krb5_principal *princs = NULL;
+ char **certhosts = NULL, **cfghosts = NULL, **hostptr;
+ krb5_principal *princs = NULL, *princptr;
unsigned char ***get_dns;
int i, j;
} else {
pkiDebug("%s: pkinit_kdc_hostname values found in config file\n",
__FUNCTION__);
+ for (hostptr = cfghosts; *hostptr != NULL; hostptr++)
+ TRACE_PKINIT_CLIENT_SAN_CONFIG_DNSNAME(context, *hostptr);
get_dns = (unsigned char ***)&certhosts;
}
&princs, NULL, get_dns);
if (retval) {
pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__);
+ TRACE_PKINIT_CLIENT_SAN_ERR(context);
retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
goto out;
}
+ for (princptr = princs; *princptr != NULL; princptr++)
+ TRACE_PKINIT_CLIENT_SAN_KDCCERT_PRINC(context, *princptr);
+ if (certhosts != NULL) {
+ for (hostptr = certhosts; *hostptr != NULL; hostptr++)
+ TRACE_PKINIT_CLIENT_SAN_KDCCERT_DNSNAME(context, *hostptr);
+ }
#if 0
retval = call_san_checking_plugins(context, plgctx, reqctx, idctx,
princs, hosts, &plugin_decision,
pkiDebug("%s: Checking pkinit sans\n", __FUNCTION__);
for (i = 0; princs != NULL && princs[i] != NULL; i++) {
if (krb5_principal_compare(context, princs[i], kdcprinc)) {
+ TRACE_PKINIT_CLIENT_SAN_MATCH_PRINC(context, kdcprinc);
pkiDebug("%s: pkinit san match found\n", __FUNCTION__);
*valid_san = 1;
*need_eku_checking = 0;
pkiDebug("%s: comparing cert name '%s' with config name '%s'\n",
__FUNCTION__, certhosts[i], cfghosts[j]);
if (strcmp(certhosts[i], cfghosts[j]) == 0) {
+ TRACE_PKINIT_CLIENT_SAN_MATCH_DNSNAME(context, certhosts[i]);
pkiDebug("%s: we have a dnsName match\n", __FUNCTION__);
*valid_san = 1;
retval = 0;
}
}
}
+ TRACE_PKINIT_CLIENT_SAN_MATCH_NONE(context);
pkiDebug("%s: no dnsName san match found\n", __FUNCTION__);
/* We found no match */
*eku_accepted = 0;
if (reqctx->opts->require_eku == 0) {
+ TRACE_PKINIT_CLIENT_EKU_SKIP(context);
pkiDebug("%s: configuration requests no EKU checking\n", __FUNCTION__);
*eku_accepted = 1;
retval = 0;
}
out:
+ if (eku_accepted)
+ TRACE_PKINIT_CLIENT_EKU_ACCEPT(context);
+ else
+ TRACE_PKINIT_CLIENT_EKU_REJECT(context);
pkiDebug("%s: returning retval %d, eku_accepted %d\n",
__FUNCTION__, retval, *eku_accepted);
return retval;
krb5_kdc_dh_key_info *kdc_dh = NULL;
krb5_reply_key_pack *key_pack = NULL;
krb5_reply_key_pack_draft9 *key_pack9 = NULL;
- krb5_octet_data dh_data = { 0, 0, NULL };
+ krb5_data dh_data = { 0, 0, NULL };
unsigned char *client_key = NULL, *kdc_hostname = NULL;
unsigned int client_key_len = 0;
krb5_checksum cksum = {0, 0, 0, NULL};
krb5_data k5data;
- krb5_octet_data secret;
+ krb5_data secret;
int valid_san = 0;
int valid_eku = 0;
int need_eku_checking = 1;
if ((retval = cms_signeddata_verify(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_SERVER,
reqctx->opts->require_crl_checking,
+ (unsigned char *)
kdc_reply->u.dh_Info.dhSignedData.data,
kdc_reply->u.dh_Info.dhSignedData.length,
- &dh_data.data, &dh_data.length,
+ (unsigned char **)&dh_data.data,
+ &dh_data.length,
NULL, NULL, NULL)) != 0) {
pkiDebug("failed to verify pkcs7 signed data\n");
+ TRACE_PKINIT_CLIENT_REP_DH_FAIL(context);
goto cleanup;
}
-
+ TRACE_PKINIT_CLIENT_REP_DH(context);
break;
case choice_pa_pk_as_rep_encKeyPack:
pkiDebug("as_rep: RSA key transport algorithm\n");
if ((retval = cms_envelopeddata_verify(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx, pa_type,
reqctx->opts->require_crl_checking,
+ (unsigned char *)
kdc_reply->u.encKeyPack.data,
kdc_reply->u.encKeyPack.length,
- &dh_data.data, &dh_data.length)) != 0) {
+ (unsigned char **)&dh_data.data,
+ &dh_data.length)) != 0) {
pkiDebug("failed to verify pkcs7 enveloped data\n");
+ TRACE_PKINIT_CLIENT_REP_RSA_FAIL(context);
goto cleanup;
}
+ TRACE_PKINIT_CLIENT_REP_RSA(context);
break;
default:
pkiDebug("unknown as_rep type %d\n", kdc_reply->choice);
/* client after KDC reply */
if ((retval = client_process_dh(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx,
+ (unsigned char *)
kdc_dh->subjectPublicKey.data,
kdc_dh->subjectPublicKey.length,
&client_key, &client_key_len)) != 0) {
/* If we have a KDF algorithm ID, call the algorithm agility KDF... */
if (kdc_reply->u.dh_Info.kdfID) {
secret.length = client_key_len;
- secret.data = client_key;
+ secret.data = (char *)client_key;
retval = pkinit_alg_agility_kdf(context, &secret,
kdc_reply->u.dh_Info.kdfID,
- request->client,
- request->server, etype,
- (krb5_octet_data *)encoded_request,
- (krb5_octet_data *)as_rep,
- key_block);
+ request->client, request->server,
+ etype, encoded_request,
+ (krb5_data *)as_rep, key_block);
if (retval) {
pkiDebug("failed to create key pkinit_alg_agility_kdf %s\n",
error_message(retval));
goto cleanup;
}
+ TRACE_PKINIT_CLIENT_KDF_ALG(context, kdc_reply->u.dh_Info.kdfID,
+ key_block);
- /* ...otherwise, use the older octetstring2key function. */
+ /* ...otherwise, use the older octetstring2key function. */
} else {
retval = pkinit_octetstring2key(context, etype, client_key,
- client_key_len, key_block);
+ client_key_len, key_block);
if (retval) {
pkiDebug("failed to create key pkinit_octetstring2key %s\n",
error_message(retval));
goto cleanup;
}
+ TRACE_PKINIT_CLIENT_KDF_OS2K(context, key_block);
}
break;
if ((cksum.length != key_pack->asChecksum.length) ||
memcmp(cksum.contents, key_pack->asChecksum.contents,
cksum.length)) {
+ TRACE_PKINIT_CLIENT_REP_CHECKSUM_FAIL(context, &cksum,
+ &key_pack->asChecksum);
pkiDebug("failed to match the checksums\n");
#ifdef DEBUG_CKSUM
pkiDebug("calculating checksum on buf size (%d)\n",
krb5_copy_keyblock_contents(context, &key_pack->replyKey,
key_block);
+ TRACE_PKINIT_CLIENT_REP_RSA_KEY(context, key_block, &cksum);
break;
default:
pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata,
krb5_clpreauth_modreq modreq,
krb5_get_init_creds_opt *gic_opt,
- krb5_clpreauth_get_data_fn get_data_proc,
- krb5_clpreauth_rock rock, krb5_kdc_req *request,
- krb5_data *encoded_request_body,
+ krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock,
+ krb5_kdc_req *request, krb5_data *encoded_request_body,
krb5_data *encoded_previous_request,
krb5_pa_data *in_padata,
krb5_prompter_fct prompter, void *prompter_data,
- krb5_clpreauth_get_as_key_fn gak_fct, void *gak_data,
- krb5_data *salt, krb5_data *s2kparams,
- krb5_keyblock *as_key, krb5_pa_data ***out_padata)
+ krb5_pa_data ***out_padata)
{
krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
krb5_enctype enctype = -1;
- krb5_data *cdata = NULL;
int processing_request = 0;
pkinit_context plgctx = (pkinit_context)moddata;
pkinit_req_context reqctx = (pkinit_req_context)modreq;
- krb5_keyblock *armor_key = NULL;
+ krb5_keyblock as_key;
pkiDebug("pkinit_client_process %p %p %p %p\n",
context, plgctx, reqctx, request);
- /* Remove (along with armor_key) when FAST PKINIT is settled. */
- retval = fast_get_armor_key(context, get_data_proc, rock, &armor_key);
- if (retval == 0 && armor_key != NULL) {
- /* Don't use PKINIT if also using FAST. */
- krb5_free_keyblock(context, armor_key);
- return EINVAL;
- }
if (plgctx == NULL || reqctx == NULL)
return EINVAL;
reqctx->cryptoctx, reqctx->idopts,
reqctx->idctx, 1, request->client);
if (retval) {
+ TRACE_PKINIT_CLIENT_NO_IDENTITY(context);
pkiDebug("pkinit_identity_initialize returned %d (%s)\n",
retval, error_message(retval));
return retval;
}
retval = pa_pkinit_gen_req(context, plgctx, reqctx, request,
- in_padata, out_padata, prompter,
+ in_padata->pa_type, out_padata, prompter,
prompter_data, gic_opt);
} else {
/*
* Get the enctype of the reply.
*/
- retval = (*get_data_proc)(context, rock, krb5_clpreauth_get_etype,
- &cdata);
- if (retval) {
- pkiDebug("get_data_proc returned %d (%s)\n",
- retval, error_message(retval));
- return retval;
- }
- enctype = *((krb5_enctype *)cdata->data);
- (*get_data_proc)(context, rock, krb5_clpreauth_free_etype, &cdata);
+ enctype = cb->get_etype(context, rock);
retval = pa_pkinit_parse_rep(context, plgctx, reqctx, request,
- in_padata, enctype, as_key,
+ in_padata, enctype, &as_key,
encoded_previous_request);
+ if (retval == 0)
+ retval = cb->set_as_key(context, rock, &as_key);
}
pkiDebug("pkinit_client_process: returning %d (%s)\n",
pkinit_client_tryagain(krb5_context context, krb5_clpreauth_moddata moddata,
krb5_clpreauth_modreq modreq,
krb5_get_init_creds_opt *gic_opt,
- krb5_clpreauth_get_data_fn get_data_proc,
- krb5_clpreauth_rock rock, krb5_kdc_req *request,
- krb5_data *encoded_request_body,
+ krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock,
+ krb5_kdc_req *request, krb5_data *encoded_request_body,
krb5_data *encoded_previous_request,
- krb5_pa_data *in_padata, krb5_error *err_reply,
- krb5_prompter_fct prompter, void *prompter_data,
- krb5_clpreauth_get_as_key_fn gak_fct, void *gak_data,
- krb5_data *salt, krb5_data *s2kparams,
- krb5_keyblock *as_key, krb5_pa_data ***out_padata)
+ krb5_preauthtype pa_type, krb5_error *err_reply,
+ krb5_pa_data **err_padata, krb5_prompter_fct prompter,
+ void *prompter_data, krb5_pa_data ***out_padata)
{
krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
pkinit_context plgctx = (pkinit_context)moddata;
pkinit_req_context reqctx = (pkinit_req_context)modreq;
- krb5_typed_data **typed_data = NULL;
+ krb5_pa_data *pa;
krb5_data scratch;
- krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
+ krb5_external_principal_identifier **certifiers = NULL;
krb5_algorithm_identifier **algId = NULL;
int do_again = 0;
pkiDebug("pkinit_client_tryagain %p %p %p %p\n",
context, plgctx, reqctx, request);
- if (reqctx->pa_type != in_padata->pa_type)
+ if (reqctx->pa_type != pa_type || err_padata == NULL)
return retval;
-#ifdef DEBUG_ASN1
- print_buffer_bin((unsigned char *)err_reply->e_data.data,
- err_reply->e_data.length, "/tmp/client_edata");
-#endif
- retval = k5int_decode_krb5_typed_data(&err_reply->e_data, &typed_data);
- if (retval) {
- pkiDebug("decode_krb5_typed_data failed\n");
- goto cleanup;
- }
-#ifdef DEBUG_ASN1
- print_buffer_bin(typed_data[0]->data, typed_data[0]->length,
- "/tmp/client_typed_data");
-#endif
- OCTETDATA_TO_KRB5DATA(typed_data[0], &scratch);
-
- switch(typed_data[0]->type) {
- case TD_TRUSTED_CERTIFIERS:
- case TD_INVALID_CERTIFICATES:
- retval = k5int_decode_krb5_td_trusted_certifiers(&scratch,
- &krb5_trusted_certifiers);
- if (retval) {
- pkiDebug("failed to decode sequence of trusted certifiers\n");
- goto cleanup;
- }
- retval = pkinit_process_td_trusted_certifiers(context,
- plgctx->cryptoctx, reqctx->cryptoctx, reqctx->idctx,
- krb5_trusted_certifiers, typed_data[0]->type);
- if (!retval)
- do_again = 1;
- break;
- case TD_DH_PARAMETERS:
- retval = k5int_decode_krb5_td_dh_parameters(&scratch, &algId);
- if (retval) {
- pkiDebug("failed to decode td_dh_parameters\n");
- goto cleanup;
+ for (; *err_padata != NULL && !do_again; err_padata++) {
+ pa = *err_padata;
+ PADATA_TO_KRB5DATA(pa, &scratch);
+ switch (pa->pa_type) {
+ case TD_TRUSTED_CERTIFIERS:
+ case TD_INVALID_CERTIFICATES:
+ retval = k5int_decode_krb5_td_trusted_certifiers(&scratch,
+ &certifiers);
+ if (retval) {
+ pkiDebug("failed to decode sequence of trusted certifiers\n");
+ goto cleanup;
+ }
+ retval = pkinit_process_td_trusted_certifiers(context,
+ plgctx->cryptoctx,
+ reqctx->cryptoctx,
+ reqctx->idctx,
+ certifiers,
+ pa->pa_type);
+ if (!retval)
+ do_again = 1;
+ break;
+ case TD_DH_PARAMETERS:
+ retval = k5int_decode_krb5_td_dh_parameters(&scratch, &algId);
+ if (retval) {
+ pkiDebug("failed to decode td_dh_parameters\n");
+ goto cleanup;
+ }
+ retval = pkinit_process_td_dh_params(context, plgctx->cryptoctx,
+ reqctx->cryptoctx,
+ reqctx->idctx, algId,
+ &reqctx->opts->dh_size);
+ if (!retval)
+ do_again = 1;
+ break;
+ default:
+ break;
}
- retval = pkinit_process_td_dh_params(context, plgctx->cryptoctx,
- reqctx->cryptoctx, reqctx->idctx, algId,
- &reqctx->opts->dh_size);
- if (!retval)
- do_again = 1;
- break;
- default:
- break;
}
if (do_again) {
- retval = pa_pkinit_gen_req(context, plgctx, reqctx, request, in_padata,
- out_padata, prompter, prompter_data, gic_opt);
+ TRACE_PKINIT_CLIENT_TRYAGAIN(context);
+ retval = pa_pkinit_gen_req(context, plgctx, reqctx, request, pa_type,
+ out_padata, prompter, prompter_data,
+ gic_opt);
if (retval)
goto cleanup;
}
retval = 0;
cleanup:
- if (krb5_trusted_certifiers != NULL)
- free_krb5_external_principal_identifier(&krb5_trusted_certifiers);
-
- if (typed_data != NULL)
- free_krb5_typed_data(&typed_data);
+ if (certifiers != NULL)
+ free_krb5_external_principal_identifier(&certifiers);
if (algId != NULL)
free_krb5_algorithm_identifiers(&algId);