summaryrefslogtreecommitdiff
path: root/source4/heimdal/kdc/pkinit.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2007-01-10 01:57:32 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:37:20 -0500
commitf7242f643763ccb6e10801af4ce53d0873e2d3e1 (patch)
treecd06665f49d12795e23699e6666d85da1f64d7bd /source4/heimdal/kdc/pkinit.c
parent08976cb3d2adfe5ea90ed53e6aa6fa8161649f7a (diff)
downloadsamba-f7242f643763ccb6e10801af4ce53d0873e2d3e1.tar.gz
samba-f7242f643763ccb6e10801af4ce53d0873e2d3e1.tar.bz2
samba-f7242f643763ccb6e10801af4ce53d0873e2d3e1.zip
r20640: Commit part 2/2
Update Heimdal to match current lorikeet-heimdal. This includes integrated PAC hooks, so Samba doesn't have to handle this any more. This also brings in the PKINIT code, hence so many new files. Andrew Bartlett (This used to be commit 351f7040f7bb73b9a60b22b564686f7c2f98a729)
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) {