summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/krb5/pkinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/krb5/pkinit.c')
-rwxr-xr-xsource4/heimdal/lib/krb5/pkinit.c90
1 files changed, 64 insertions, 26 deletions
diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c
index c8587770f4..4a585bff07 100755
--- a/source4/heimdal/lib/krb5/pkinit.c
+++ b/source4/heimdal/lib/krb5/pkinit.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: pkinit.c 21684 2007-07-23 23:09:10Z lha $");
+RCSID("$Id: pkinit.c 22673 2008-03-10 15:00:05Z lha $");
struct krb5_dh_moduli {
char *name;
@@ -139,17 +139,59 @@ integer_to_BN(krb5_context context, const char *field, const heim_integer *f)
return bn;
}
+struct certfind {
+ const char *type;
+ const heim_oid *oid;
+};
+
+/*
+ * Try searchin the key by to use by first looking for for PK-INIT
+ * EKU, then the Microsoft smart card EKU and last, no special EKU at all.
+ */
static krb5_error_code
-_krb5_pk_create_sign(krb5_context context,
- const heim_oid *eContentType,
- krb5_data *eContent,
- struct krb5_pk_identity *id,
- hx509_peer_info peer,
- krb5_data *sd_data)
+find_cert(krb5_context context, struct krb5_pk_identity *id,
+ hx509_query *q, hx509_cert *cert)
{
- hx509_cert cert;
- hx509_query *q;
+ struct certfind cf[3] = {
+ { "PKINIT EKU" },
+ { "MS EKU" },
+ { "no" }
+ };
+ int i, ret;
+
+ cf[0].oid = oid_id_pkekuoid();
+ cf[1].oid = oid_id_pkinit_ms_eku();
+ cf[2].oid = NULL;
+
+ for (i = 0; i < sizeof(cf)/sizeof(cf[0]); i++) {
+ ret = hx509_query_match_eku(q, cf[i].oid);
+ if (ret) {
+ _krb5_pk_copy_error(context, id->hx509ctx, ret,
+ "Failed setting %s OID", cf[i].type);
+ return ret;
+ }
+
+ ret = hx509_certs_find(id->hx509ctx, id->certs, q, cert);
+ if (ret == 0)
+ break;
+ _krb5_pk_copy_error(context, id->hx509ctx, ret,
+ "Failed cert for finding %s OID", cf[i].type);
+ }
+ return ret;
+}
+
+
+static krb5_error_code
+create_signature(krb5_context context,
+ const heim_oid *eContentType,
+ krb5_data *eContent,
+ struct krb5_pk_identity *id,
+ hx509_peer_info peer,
+ krb5_data *sd_data)
+{
+ hx509_cert cert = NULL;
+ hx509_query *q = NULL;
int ret;
ret = hx509_query_alloc(id->hx509ctx, &q);
@@ -162,13 +204,10 @@ _krb5_pk_create_sign(krb5_context context,
hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
- ret = hx509_certs_find(id->hx509ctx, id->certs, q, &cert);
+ ret = find_cert(context, id, q, &cert);
hx509_query_free(id->hx509ctx, q);
- if (ret) {
- _krb5_pk_copy_error(context, id->hx509ctx, ret,
- "Find certificate to signed CMS data");
+ if (ret)
return ret;
- }
ret = hx509_cms_create_signed_1(id->hx509ctx,
0,
@@ -181,11 +220,14 @@ _krb5_pk_create_sign(krb5_context context,
NULL,
id->certs,
sd_data);
- if (ret)
- _krb5_pk_copy_error(context, id->hx509ctx, ret, "create CMS signedData");
hx509_cert_free(cert);
+ if (ret) {
+ _krb5_pk_copy_error(context, id->hx509ctx, ret,
+ "Create CMS signedData");
+ return ret;
+ }
- return ret;
+ return 0;
}
static int
@@ -212,8 +254,7 @@ cert2epi(hx509_context context, void *ctx, hx509_cert c)
return ENOMEM;
}
- ret = hx509_name_to_der_name(subject, &id.subjectName->data,
- &id.subjectName->length);
+ ret = hx509_name_binary(subject, id.subjectName);
if (ret) {
hx509_name_free(&subject);
free_ExternalPrincipalIdentifier(&id);
@@ -544,12 +585,8 @@ pk_mk_padata(krb5_context context,
} else
krb5_abortx(context, "internal pkinit error");
- ret = _krb5_pk_create_sign(context,
- oid,
- &buf,
- ctx->id,
- ctx->peer,
- &sd_buf);
+ ret = create_signature(context, oid, &buf, ctx->id,
+ ctx->peer, &sd_buf);
krb5_data_free(&buf);
if (ret)
goto out;
@@ -878,7 +915,8 @@ pk_verify_host(krb5_context context,
hx509_octet_string_list list;
int i;
- ret = hx509_cert_find_subjectAltName_otherName(host->cert,
+ ret = hx509_cert_find_subjectAltName_otherName(ctx->id->hx509ctx,
+ host->cert,
oid_id_pkinit_san(),
&list);
if (ret) {