add pkinit support
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@13143 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		
							
								
								
									
										114
									
								
								kdc/kerberos5.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								kdc/kerberos5.c
									
									
									
									
									
								
							| @@ -47,16 +47,26 @@ fix_time(time_t **t) | |||||||
|     if(**t == 0) **t = MAX_TIME; /* fix for old clients */ |     if(**t == 0) **t = MAX_TIME; /* fix for old clients */ | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | realloc_method_data(METHOD_DATA *md) | ||||||
|  | { | ||||||
|  |     PA_DATA *pa; | ||||||
|  |     pa = realloc(md->val, (md->len + 1) * sizeof(*md->val)); | ||||||
|  |     if(pa == NULL) | ||||||
|  | 	return ENOMEM; | ||||||
|  |     md->val = pa; | ||||||
|  |     md->len++; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| set_salt_padata (METHOD_DATA **m, Salt *salt) | set_salt_padata (METHOD_DATA *md, Salt *salt) | ||||||
| { | { | ||||||
|     if (salt) { |     if (salt) { | ||||||
| 	ALLOC(*m); | 	realloc_method_data(md); | ||||||
| 	(*m)->len = 1; | 	md->val[md->len - 1].padata_type = salt->type; | ||||||
| 	ALLOC((*m)->val); |  | ||||||
| 	(*m)->val->padata_type = salt->type; |  | ||||||
| 	copy_octet_string(&salt->salt, | 	copy_octet_string(&salt->salt, | ||||||
| 			  &(*m)->val->padata_value); | 			  &md->val[md->len - 1].padata_value); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -261,18 +271,6 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int |  | ||||||
| realloc_method_data(METHOD_DATA *md) |  | ||||||
| { |  | ||||||
|     PA_DATA *pa; |  | ||||||
|     pa = realloc(md->val, (md->len + 1) * sizeof(*md->val)); |  | ||||||
|     if(pa == NULL) |  | ||||||
| 	return ENOMEM; |  | ||||||
|     md->val = pa; |  | ||||||
|     md->len++; |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static krb5_error_code | static krb5_error_code | ||||||
| make_etype_info_entry(ETYPE_INFO_ENTRY *ent, Key *key) | make_etype_info_entry(ETYPE_INFO_ENTRY *ent, Key *key) | ||||||
| { | { | ||||||
| @@ -648,6 +646,10 @@ as_rep(KDC_REQ *req, | |||||||
|     const char *e_text = NULL; |     const char *e_text = NULL; | ||||||
|     krb5_crypto crypto; |     krb5_crypto crypto; | ||||||
|     Key *ckey, *skey; |     Key *ckey, *skey; | ||||||
|  |     EncryptionKey *reply_key; | ||||||
|  | #ifdef PKINIT | ||||||
|  |     pk_client_params *pkp = NULL; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     memset(&rep, 0, sizeof(rep)); |     memset(&rep, 0, sizeof(rep)); | ||||||
|  |  | ||||||
| @@ -705,7 +707,50 @@ as_rep(KDC_REQ *req, | |||||||
| 	int i = 0; | 	int i = 0; | ||||||
| 	PA_DATA *pa; | 	PA_DATA *pa; | ||||||
| 	int found_pa = 0; | 	int found_pa = 0; | ||||||
| 	kdc_log(5, "Looking for pa-data -- %s", client_name); |  | ||||||
|  | #ifdef PKINIT | ||||||
|  | 	kdc_log(5, "Looking for PKINIT pa-data -- %s", client_name); | ||||||
|  |  | ||||||
|  | 	i = 0; | ||||||
|  | 	e_text = "No PKINIT PA found"; | ||||||
|  | 	while((pa = find_padata(req, &i, KRB5_PADATA_PK_AS_REQ))){ | ||||||
|  | 	    char *client_cert = NULL; | ||||||
|  | 	    found_pa = 1; | ||||||
|  | 	     | ||||||
|  | 	    ret = pk_rd_padata(context, req, pa, &pkp); | ||||||
|  | 	    if (ret) { | ||||||
|  | 		ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; | ||||||
|  | 		kdc_log(5, "Failed to decode PKINIT PA-DATA -- %s",  | ||||||
|  | 			client_name); | ||||||
|  | 		continue; | ||||||
|  | 	    } | ||||||
|  | 	    if (ret == 0 && pkp == NULL) | ||||||
|  | 		continue; | ||||||
|  |  | ||||||
|  | 	    ret = pk_check_client(context,  | ||||||
|  | 				  client_princ,  | ||||||
|  | 				  pkp, | ||||||
|  | 				  &client_cert); | ||||||
|  | 	    if (ret) { | ||||||
|  | 		e_text = "PKINIT certificate not allowed to " | ||||||
|  | 		    "impersonate principal"; | ||||||
|  | 		pk_free_client_param(context, pkp); | ||||||
|  | 		pkp = NULL; | ||||||
|  | 		goto preauth_done; | ||||||
|  | 	    } | ||||||
|  | 	    et.flags.pre_authent = 1; | ||||||
|  | 	    kdc_log(2, "PKINIT pre-authentication succeded -- %s using %s",  | ||||||
|  | 		    client_name, client_cert); | ||||||
|  | 	    free(client_cert); | ||||||
|  | 	    break; | ||||||
|  | 	} | ||||||
|  | 	if (pkp) | ||||||
|  | 	    goto preauth_done; | ||||||
|  | #endif | ||||||
|  | 	kdc_log(5, "Looking for ENC-TS pa-data -- %s", client_name); | ||||||
|  |  | ||||||
|  | 	i = 0; | ||||||
|  | 	e_text = "No ENC-TS found"; | ||||||
| 	while((pa = find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){ | 	while((pa = find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){ | ||||||
| 	    krb5_data ts_data; | 	    krb5_data ts_data; | ||||||
| 	    PA_ENC_TS_ENC p; | 	    PA_ENC_TS_ENC p; | ||||||
| @@ -792,9 +837,11 @@ as_rep(KDC_REQ *req, | |||||||
| 		goto out; | 		goto out; | ||||||
| 	    } | 	    } | ||||||
| 	    et.flags.pre_authent = 1; | 	    et.flags.pre_authent = 1; | ||||||
| 	    kdc_log(2, "Pre-authentication succeded -- %s", client_name); | 	    kdc_log(2, "ENC-TS Pre-authentication succeded -- %s",  | ||||||
|  | 		    client_name); | ||||||
| 	    break; | 	    break; | ||||||
| 	} | 	} | ||||||
|  |     preauth_done: | ||||||
| 	if(found_pa == 0 && require_preauth) | 	if(found_pa == 0 && require_preauth) | ||||||
| 	    goto use_pa; | 	    goto use_pa; | ||||||
| 	/* We come here if we found a pa-enc-timestamp, but if there | 	/* We come here if we found a pa-enc-timestamp, but if there | ||||||
| @@ -1059,9 +1106,28 @@ as_rep(KDC_REQ *req, | |||||||
| 	copy_HostAddresses(et.caddr, ek.caddr); | 	copy_HostAddresses(et.caddr, ek.caddr); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     set_salt_padata (&rep.padata, ckey->salt); |     ALLOC(rep.padata); | ||||||
|  |     rep.padata->len = 0; | ||||||
|  |     rep.padata->val = NULL; | ||||||
|  |  | ||||||
|  |     reply_key = &ckey->key; | ||||||
|  | #if PKINIT | ||||||
|  |     if (pkp) { | ||||||
|  | 	ret = pk_mk_pa_reply(context, pkp, &reply_key, rep.padata); | ||||||
|  | 	if (ret) | ||||||
|  | 	    goto out; | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     set_salt_padata (rep.padata, ckey->salt); | ||||||
|  |  | ||||||
|  |     if (rep.padata->len == 0) { | ||||||
|  | 	free(rep.padata); | ||||||
|  | 	rep.padata = NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key, |     ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key, | ||||||
| 		       client->kvno, &ckey->key, &e_text, reply); | 		       client->kvno, reply_key, &e_text, reply); | ||||||
|     free_EncTicketPart(&et); |     free_EncTicketPart(&et); | ||||||
|     free_EncKDCRepPart(&ek); |     free_EncKDCRepPart(&ek); | ||||||
|   out: |   out: | ||||||
| @@ -1079,6 +1145,10 @@ as_rep(KDC_REQ *req, | |||||||
| 	ret = 0; | 	ret = 0; | ||||||
|     } |     } | ||||||
|   out2: |   out2: | ||||||
|  | #ifdef PKINIT | ||||||
|  |     if (pkp) | ||||||
|  | 	pk_free_client_param(context, pkp); | ||||||
|  | #endif | ||||||
|     if (client_princ) |     if (client_princ) | ||||||
| 	krb5_free_principal(context, client_princ); | 	krb5_free_principal(context, client_princ); | ||||||
|     free(client_name); |     free(client_name); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Love Hörnquist Åstrand
					Love Hörnquist Åstrand