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:
		
							
								
								
									
										80
									
								
								kdc/pkinit.c
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								kdc/pkinit.c
									
									
									
									
									
								
							| @@ -44,11 +44,13 @@ RCSID("$Id$"); | ||||
|  | ||||
| #include <openssl/evp.h> | ||||
| #include <openssl/x509.h> | ||||
| #include <openssl/x509v3.h> | ||||
| #include <openssl/bn.h> | ||||
| #include <openssl/asn1.h> | ||||
| #include <openssl/err.h> | ||||
|  | ||||
| int enable_pkinit = 0; | ||||
| int enable_pkinit_princ_in_cert = 0; | ||||
|  | ||||
| /* XXX copied from lib/krb5/pkinit.c */ | ||||
| struct krb5_pk_identity { | ||||
| @@ -106,7 +108,6 @@ struct pk_principal_mapping { | ||||
| extern heim_oid heim_dhpublicnumber_oid; | ||||
| extern heim_oid pkcs7_signed_oid; | ||||
| extern heim_oid heim_pkauthdata_oid; | ||||
| extern heim_oid heim_des_ede3_cbc_oid; | ||||
| extern heim_oid heim_pkdhkeydata_oid; | ||||
| extern heim_oid pkcs7_signed_oid; | ||||
| extern heim_oid heim_pkrkeydata_oid; | ||||
| @@ -962,6 +963,60 @@ pk_mk_pa_reply(krb5_context context, | ||||
|     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 ? */ | ||||
|  | ||||
| krb5_error_code | ||||
| @@ -972,8 +1027,11 @@ pk_check_client(krb5_context context, | ||||
| 		char **subject_name) | ||||
| { | ||||
|     struct krb5_pk_cert *client_cert = client_params->certificate; | ||||
|     krb5_principal cert_princ; | ||||
|     X509_NAME *name; | ||||
|     char *subject = NULL; | ||||
|     krb5_error_code ret; | ||||
|     krb5_boolean b; | ||||
|     int i; | ||||
|  | ||||
|     *subject_name = NULL; | ||||
| @@ -995,13 +1053,21 @@ pk_check_client(krb5_context context, | ||||
|     } | ||||
|     OPENSSL_free(subject); | ||||
|  | ||||
|     for (i = 0; i < principal_mappings.len; i++) { | ||||
| 	krb5_boolean ret; | ||||
|     if (enable_pkinit_princ_in_cert) { | ||||
| 	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, | ||||
| 				     client_princ, | ||||
| 				     principal_mappings.val[i].principal); | ||||
| 	if (ret == FALSE) | ||||
|     for (i = 0; i < principal_mappings.len; i++) { | ||||
| 	b = krb5_principal_compare(context, | ||||
| 				   client_princ, | ||||
| 				   principal_mappings.val[i].principal); | ||||
| 	if (b == FALSE) | ||||
| 	    continue; | ||||
| 	if (strcmp(principal_mappings.val[i].subject, *subject_name) != 0) | ||||
| 	    continue; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Love Hörnquist Åstrand
					Love Hörnquist Åstrand