Check certificate for Kerberos Principal in OtherName of subjectAltName
Based on patch from Mayur Patel <patelm4@rpi.edu> git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@13990 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
76
kdc/pkinit.c
76
kdc/pkinit.c
@@ -44,11 +44,13 @@ RCSID("$Id$");
|
|||||||
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/asn1.h>
|
#include <openssl/asn1.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
int enable_pkinit = 0;
|
int enable_pkinit = 0;
|
||||||
|
int enable_pkinit_princ_in_cert = 0;
|
||||||
|
|
||||||
/* XXX copied from lib/krb5/pkinit.c */
|
/* XXX copied from lib/krb5/pkinit.c */
|
||||||
struct krb5_pk_identity {
|
struct krb5_pk_identity {
|
||||||
@@ -106,7 +108,6 @@ struct pk_principal_mapping {
|
|||||||
extern heim_oid heim_dhpublicnumber_oid;
|
extern heim_oid heim_dhpublicnumber_oid;
|
||||||
extern heim_oid pkcs7_signed_oid;
|
extern heim_oid pkcs7_signed_oid;
|
||||||
extern heim_oid heim_pkauthdata_oid;
|
extern heim_oid heim_pkauthdata_oid;
|
||||||
extern heim_oid heim_des_ede3_cbc_oid;
|
|
||||||
extern heim_oid heim_pkdhkeydata_oid;
|
extern heim_oid heim_pkdhkeydata_oid;
|
||||||
extern heim_oid pkcs7_signed_oid;
|
extern heim_oid pkcs7_signed_oid;
|
||||||
extern heim_oid heim_pkrkeydata_oid;
|
extern heim_oid heim_pkrkeydata_oid;
|
||||||
@@ -962,6 +963,60 @@ pk_mk_pa_reply(krb5_context context,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pk_principal_from_X509(krb5_context context,
|
||||||
|
struct krb5_pk_cert *client_cert,
|
||||||
|
krb5_principal *principal)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
GENERAL_NAMES *gens;
|
||||||
|
GENERAL_NAME *gen;
|
||||||
|
ASN1_OBJECT *obj;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*principal = NULL;
|
||||||
|
|
||||||
|
obj = OBJ_txt2obj("1.3.6.1.5.2.2",1);
|
||||||
|
|
||||||
|
gens = X509_get_ext_d2i(client_cert->cert, NID_subject_alt_name,
|
||||||
|
NULL, NULL);
|
||||||
|
if (gens)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
|
||||||
|
KerberosName kn;
|
||||||
|
size_t len, size;
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
gen = sk_GENERAL_NAME_value(gens, i);
|
||||||
|
if (gen->type != GEN_OTHERNAME)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(OBJ_cmp(obj, gen->d.otherName->type_id) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
p = ASN1_STRING_data(gen->d.otherName->value->value.sequence);
|
||||||
|
len = ASN1_STRING_length(gen->d.otherName->value->value.sequence);
|
||||||
|
|
||||||
|
ret = decode_KerberosName(p, len, &kn, &size);
|
||||||
|
if (ret) {
|
||||||
|
kdc_log(0, "Decoding kerberos name in certificate failed: %s",
|
||||||
|
krb5_get_err_text(context, ret));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*principal = malloc(sizeof(**principal));
|
||||||
|
if (*principal == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
(*principal)->name = kn.principalName;
|
||||||
|
(*principal)->realm = kn.realm;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* XXX match with issuer too ? */
|
/* XXX match with issuer too ? */
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
@@ -972,8 +1027,11 @@ pk_check_client(krb5_context context,
|
|||||||
char **subject_name)
|
char **subject_name)
|
||||||
{
|
{
|
||||||
struct krb5_pk_cert *client_cert = client_params->certificate;
|
struct krb5_pk_cert *client_cert = client_params->certificate;
|
||||||
|
krb5_principal cert_princ;
|
||||||
X509_NAME *name;
|
X509_NAME *name;
|
||||||
char *subject = NULL;
|
char *subject = NULL;
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_boolean b;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
*subject_name = NULL;
|
*subject_name = NULL;
|
||||||
@@ -995,13 +1053,21 @@ pk_check_client(krb5_context context,
|
|||||||
}
|
}
|
||||||
OPENSSL_free(subject);
|
OPENSSL_free(subject);
|
||||||
|
|
||||||
for (i = 0; i < principal_mappings.len; i++) {
|
if (enable_pkinit_princ_in_cert) {
|
||||||
krb5_boolean ret;
|
ret = pk_principal_from_X509(context, client_cert, &cert_princ);
|
||||||
|
if (ret == 0) {
|
||||||
|
b = krb5_principal_compare(context, client_princ, cert_princ);
|
||||||
|
krb5_free_principal(context, cert_princ);
|
||||||
|
if (b == TRUE)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = krb5_principal_compare(context,
|
for (i = 0; i < principal_mappings.len; i++) {
|
||||||
|
b = krb5_principal_compare(context,
|
||||||
client_princ,
|
client_princ,
|
||||||
principal_mappings.val[i].principal);
|
principal_mappings.val[i].principal);
|
||||||
if (ret == FALSE)
|
if (b == FALSE)
|
||||||
continue;
|
continue;
|
||||||
if (strcmp(principal_mappings.val[i].subject, *subject_name) != 0)
|
if (strcmp(principal_mappings.val[i].subject, *subject_name) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
Reference in New Issue
Block a user