summaryrefslogtreecommitdiff
path: root/source4/heimdal/kdc/pkinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/kdc/pkinit.c')
-rwxr-xr-xsource4/heimdal/kdc/pkinit.c202
1 files changed, 131 insertions, 71 deletions
diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c
index 6657ab7c44..418a38d030 100755
--- a/source4/heimdal/kdc/pkinit.c
+++ b/source4/heimdal/kdc/pkinit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: pkinit.c,v 1.74 2006/11/10 03:37:43 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.86 2007/01/04 12:54:09 lha Exp $");
#ifdef PKINIT
@@ -68,6 +68,8 @@ struct pk_client_params {
DH *dh;
EncryptionKey reply_key;
char *dh_group_name;
+ hx509_peer_info peer;
+ hx509_certs client_anchors;
};
struct pk_principal_mapping {
@@ -180,6 +182,10 @@ _kdc_pk_free_client_param(krb5_context context,
krb5_free_keyblock_contents(context, &client_params->reply_key);
if (client_params->dh_group_name)
free(client_params->dh_group_name);
+ if (client_params->peer)
+ hx509_peer_info_free(client_params->peer);
+ if (client_params->client_anchors)
+ hx509_certs_free(&client_params->client_anchors);
memset(client_params, 0, sizeof(*client_params));
free(client_params);
}
@@ -302,8 +308,10 @@ get_dh_param(krb5_context context,
ret = _krb5_dh_group_ok(context, config->pkinit_dh_min_bits,
&dhparam.p, &dhparam.g, &dhparam.q, moduli,
&client_params->dh_group_name);
- if (ret)
+ if (ret) {
+ /* XXX send back proposal of better group */
goto out;
+ }
dh = DH_new();
if (dh == NULL) {
@@ -354,64 +362,6 @@ get_dh_param(krb5_context context,
return ret;
}
-#if 0
-/*
- * XXX We only need this function if there are several certs for the
- * KDC to choose from, and right now, we can't handle that so punt for
- * now.
- *
- * If client has sent a list of CA's trusted by him, make sure our
- * CA is in the list.
- *
- */
-
-static void
-verify_trusted_ca(PA_PK_AS_REQ_19 *r)
-{
-
- if (r.trustedCertifiers != NULL) {
- X509_NAME *kdc_issuer;
- X509 *kdc_cert;
-
- kdc_cert = sk_X509_value(kdc_identity->cert, 0);
- kdc_issuer = X509_get_issuer_name(kdc_cert);
-
- /* XXX will work for heirarchical CA's ? */
- /* XXX also serial_number should be compared */
-
- ret = KRB5_KDC_ERR_KDC_NOT_TRUSTED;
- for (i = 0; i < r.trustedCertifiers->len; i++) {
- TrustedCA_19 *ca = &r.trustedCertifiers->val[i];
-
- switch (ca->element) {
- case choice_TrustedCA_19_caName: {
- X509_NAME *name;
- unsigned char *p;
-
- p = ca->u.caName.data;
- name = d2i_X509_NAME(NULL, &p, ca->u.caName.length);
- if (name == NULL) /* XXX should this be a failure instead ? */
- break;
- if (X509_NAME_cmp(name, kdc_issuer) == 0)
- ret = 0;
- X509_NAME_free(name);
- break;
- }
- case choice_TrustedCA_19_issuerAndSerial:
- /* IssuerAndSerialNumber issuerAndSerial */
- break;
- default:
- break;
- }
- if (ret == 0)
- break;
- }
- if (ret)
- goto out;
- }
-}
-#endif /* 0 */
-
krb5_error_code
_kdc_pk_rd_padata(krb5_context context,
krb5_kdc_configuration *config,
@@ -483,7 +433,61 @@ _kdc_pk_rd_padata(krb5_context context,
goto out;
}
- /* XXX look at r.trustedCertifiers and r.kdcPkId */
+ /* XXX look at r.kdcPkId */
+ if (r.trustedCertifiers) {
+ ExternalPrincipalIdentifiers *edi = r.trustedCertifiers;
+ unsigned int i;
+
+ ret = hx509_certs_init(kdc_identity->hx509ctx,
+ "MEMORY:client-anchors",
+ 0, NULL,
+ &client_params->client_anchors);
+ if (ret) {
+ krb5_set_error_string(context, "Can't allocate client anchors: %d", ret);
+ goto out;
+
+ }
+ for (i = 0; i < edi->len; i++) {
+ IssuerAndSerialNumber iasn;
+ hx509_query *q;
+ hx509_cert cert;
+ size_t size;
+
+ if (edi->val[i].issuerAndSerialNumber == NULL)
+ continue;
+
+ ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+ if (ret) {
+ krb5_set_error_string(context,
+ "Failed to allocate hx509_query");
+ goto out;
+ }
+
+ ret = decode_IssuerAndSerialNumber(edi->val[i].issuerAndSerialNumber->data,
+ edi->val[i].issuerAndSerialNumber->length,
+ &iasn,
+ &size);
+ if (ret || size != 0) {
+ hx509_query_free(kdc_identity->hx509ctx, q);
+ continue;
+ }
+ ret = hx509_query_match_issuer_serial(q, &iasn.issuer, &iasn.serialNumber);
+ free_IssuerAndSerialNumber(&iasn);
+ if (ret)
+ continue;
+
+ ret = hx509_certs_find(kdc_identity->hx509ctx,
+ kdc_identity->certs,
+ q,
+ &cert);
+ hx509_query_free(kdc_identity->hx509ctx, q);
+ if (ret)
+ continue;
+ hx509_certs_add(kdc_identity->hx509ctx,
+ client_params->client_anchors, cert);
+ hx509_cert_free(cert);
+ }
+ }
ret = hx509_cms_unwrap_ContentInfo(&r.signedAuthPack,
&contentInfoOid,
@@ -611,6 +615,23 @@ _kdc_pk_rd_padata(krb5_context context,
goto out;
}
}
+
+ if (ap.supportedCMSTypes) {
+ ret = hx509_peer_info_alloc(kdc_identity->hx509ctx,
+ &client_params->peer);
+ if (ret) {
+ free_AuthPack(&ap);
+ goto out;
+ }
+ ret = hx509_peer_info_set_cms_algs(kdc_identity->hx509ctx,
+ client_params->peer,
+ ap.supportedCMSTypes->val,
+ ap.supportedCMSTypes->len);
+ if (ret) {
+ free_AuthPack(&ap);
+ goto out;
+ }
+ }
free_AuthPack(&ap);
} else
krb5_abortx(context, "internal pkinit error");
@@ -752,7 +773,8 @@ pk_mk_pa_reply_enckey(krb5_context context,
buf.length,
NULL,
cert,
- kdc_identity->anchors,
+ client_params->peer,
+ client_params->client_anchors,
kdc_identity->certpool,
&signed_data);
hx509_cert_free(cert);
@@ -864,7 +886,8 @@ pk_mk_pa_reply_dh(krb5_context context,
buf.length,
NULL,
cert,
- kdc_identity->anchors,
+ client_params->peer,
+ client_params->client_anchors,
kdc_identity->certpool,
&signed_data);
*kdc_cert = cert;
@@ -948,8 +971,12 @@ _kdc_pk_mk_pa_reply(krb5_context context,
rep.element = choice_PA_PK_AS_REP_encKeyPack;
- krb5_generate_random_keyblock(context, enctype,
- &client_params->reply_key);
+ ret = krb5_generate_random_keyblock(context, enctype,
+ &client_params->reply_key);
+ if (ret) {
+ free_PA_PK_AS_REP(&rep);
+ goto out;
+ }
ret = pk_mk_pa_reply_enckey(context,
client_params,
req,
@@ -1039,8 +1066,12 @@ _kdc_pk_mk_pa_reply(krb5_context context,
pa_type = KRB5_PADATA_PK_AS_REP_19;
rep.element = choice_PA_PK_AS_REP_encKeyPack;
- krb5_generate_random_keyblock(context, enctype,
- &client_params->reply_key);
+ ret = krb5_generate_random_keyblock(context, enctype,
+ &client_params->reply_key);
+ if (ret) {
+ free_PA_PK_AS_REP_Win2k(&rep);
+ goto out;
+ }
ret = pk_mk_pa_reply_enckey(context,
client_params,
req,
@@ -1337,6 +1368,35 @@ add_principal_mapping(krb5_context context,
return 0;
}
+krb5_error_code
+_kdc_add_inital_verified_cas(krb5_context context,
+ krb5_kdc_configuration *config,
+ pk_client_params *params,
+ EncTicketPart *tkt)
+{
+ AD_INITIAL_VERIFIED_CAS cas;
+ krb5_error_code ret;
+ krb5_data data;
+ size_t size;
+
+ memset(&cas, 0, sizeof(cas));
+
+ /* XXX add CAs to cas here */
+
+ ASN1_MALLOC_ENCODE(AD_INITIAL_VERIFIED_CAS, data.data, data.length,
+ &cas, &size, ret);
+ if (ret)
+ return ret;
+ if (data.length != size)
+ krb5_abortx(context, "internal asn.1 encoder error");
+
+ ret = _kdc_tkt_add_if_relevant_ad(context, tkt,
+ ad_initial_verified_cas, &data);
+ krb5_data_free(&data);
+ return ret;
+}
+
+
krb5_error_code
_kdc_pk_initialize(krb5_context context,
@@ -1372,7 +1432,7 @@ _kdc_pk_initialize(krb5_context context,
NULL,
NULL);
if (ret) {
- krb5_warn(context, ret, "PKINIT: failed to load");
+ krb5_warn(context, ret, "PKINIT: ");
config->enable_pkinit = 0;
return ret;
}
@@ -1411,7 +1471,7 @@ _kdc_pk_initialize(krb5_context context,
NULL,
FALSE,
"kdc",
- "pki-allow-proxy-certificate",
+ "pkinit_allow_proxy_certificate",
NULL);
_krb5_pk_allow_proxy_certificate(kdc_identity, ret);
@@ -1419,7 +1479,7 @@ _kdc_pk_initialize(krb5_context context,
NULL,
HDB_DB_DIR "/pki-mapping",
"kdc",
- "pki-mappings-file",
+ "pkinit_mappings_file",
NULL);
f = fopen(file, "r");
if (f == NULL) {