xref: /freebsd/crypto/krb5/src/plugins/preauth/pkinit/pkinit.h (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /*
2  * COPYRIGHT (C) 2006,2007
3  * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
4  * ALL RIGHTS RESERVED
5  *
6  * Permission is granted to use, copy, create derivative works
7  * and redistribute this software and such derivative works
8  * for any purpose, so long as the name of The University of
9  * Michigan is not used in any advertising or publicity
10  * pertaining to the use of distribution of this software
11  * without specific, written prior authorization.  If the
12  * above copyright notice or any other identification of the
13  * University of Michigan is included in any copy of any
14  * portion of this software, then the disclaimer below must
15  * also be included.
16  *
17  * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
18  * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
19  * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
20  * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
21  * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
22  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
23  * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
24  * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
25  * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
26  * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
27  * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGES.
29  */
30 
31 #ifndef _PKINIT_H
32 #define _PKINIT_H
33 
34 #include <k5-platform.h>
35 #include <krb5/krb5.h>
36 #include <krb5/preauth_plugin.h>
37 #include <k5-int-pkinit.h>
38 #include <profile.h>
39 #include "pkinit_accessor.h"
40 #include "pkinit_trace.h"
41 
42 #ifndef WITHOUT_PKCS11
43 #include "pkcs11.h"
44 
45 #define PK_SIGLEN_GUESS 1000
46 #define PK_NOSLOT 999999
47 #endif
48 
49 #define DH_PROTOCOL     1
50 #define RSA_PROTOCOL    2
51 
52 #define TD_TRUSTED_CERTIFIERS 104
53 #define TD_INVALID_CERTIFICATES 105
54 #define TD_DH_PARAMETERS 109
55 
56 #define PKINIT_CTX_MAGIC	0x05551212
57 #define PKINIT_REQ_CTX_MAGIC	0xdeadbeef
58 #define PKINIT_DEFERRED_ID_MAGIC    0x3ca20d21
59 
60 #define PKINIT_DEFAULT_DH_MIN_BITS  2048
61 #define PKINIT_DH_MIN_CONFIG_BITS   1024
62 
63 #define KRB5_CONF_KDCDEFAULTS                   "kdcdefaults"
64 #define KRB5_CONF_LIBDEFAULTS                   "libdefaults"
65 #define KRB5_CONF_REALMS                        "realms"
66 #define KRB5_CONF_PKINIT_ALLOW_UPN              "pkinit_allow_upn"
67 #define KRB5_CONF_PKINIT_ANCHORS                "pkinit_anchors"
68 #define KRB5_CONF_PKINIT_INDICATOR              "pkinit_indicator"
69 #define KRB5_CONF_PKINIT_CERT_MATCH             "pkinit_cert_match"
70 #define KRB5_CONF_PKINIT_DH_MIN_BITS            "pkinit_dh_min_bits"
71 #define KRB5_CONF_PKINIT_EKU_CHECKING           "pkinit_eku_checking"
72 #define KRB5_CONF_PKINIT_IDENTITIES             "pkinit_identities"
73 #define KRB5_CONF_PKINIT_IDENTITY               "pkinit_identity"
74 #define KRB5_CONF_PKINIT_KDC_HOSTNAME           "pkinit_kdc_hostname"
75 /* pkinit_kdc_ocsp has been removed */
76 #define KRB5_CONF_PKINIT_KDC_OCSP               "pkinit_kdc_ocsp"
77 #define KRB5_CONF_PKINIT_POOL                   "pkinit_pool"
78 #define KRB5_CONF_PKINIT_REQUIRE_CRL_CHECKING   "pkinit_require_crl_checking"
79 #define KRB5_CONF_PKINIT_REQUIRE_FRESHNESS      "pkinit_require_freshness"
80 #define KRB5_CONF_PKINIT_REVOKE                 "pkinit_revoke"
81 
82 /* Make pkiDebug(fmt,...) print, or not.  */
83 #ifdef DEBUG
84 #define pkiDebug	printf
85 #else
86 /* Still evaluates for side effects.  */
pkiDebug(const char * fmt,...)87 static inline void pkiDebug (const char *fmt, ...) { }
88 /* This is better if the compiler doesn't inline variadic functions
89    well, but gcc will warn about "left-hand operand of comma
90    expression has no effect".  Still evaluates for side effects.  */
91 /* #define pkiDebug	(void) */
92 #endif
93 
94 /* Solaris compiler doesn't grok __FUNCTION__
95  * hack for now.  Fix all the uses eventually. */
96 #define __FUNCTION__ __func__
97 
98 /* Macros to deal with converting between various data types... */
99 #define PADATA_TO_KRB5DATA(pad, k5d) \
100     (k5d)->length = (pad)->length; (k5d)->data = (char *)(pad)->contents;
101 #define OCTETDATA_TO_KRB5DATA(octd, k5d) \
102     (k5d)->length = (octd)->length; (k5d)->data = (char *)(octd)->data;
103 
104 extern const krb5_data dh_oid;
105 
106 /*
107  * notes about crypto contexts:
108  *
109  * the basic idea is that there are crypto contexts that live at
110  * both the plugin level and request level. the identity context (that
111  * keeps info about your own certs and such) is separate because
112  * it is needed at different levels for the kdc and and the client.
113  * (the kdc's identity is at the plugin level, the client's identity
114  * information could change per-request.)
115  * the identity context is meant to have the entity's cert,
116  * a list of trusted and intermediate cas, a list of crls, and any
117  * pkcs11 information.  the req context is meant to have the
118  * received certificate and the DH related information. the plugin
119  * context is meant to have global crypto information, i.e., OIDs
120  * and constant DH parameter information.
121  */
122 
123 /*
124  * plugin crypto context should keep plugin common information,
125  * eg., OIDs, known DHparams
126  */
127 typedef struct _pkinit_plg_crypto_context *pkinit_plg_crypto_context;
128 
129 /*
130  * request crypto context should keep reqyest common information,
131  * eg., received credentials, DH parameters of this request
132  */
133 typedef struct _pkinit_req_crypto_context *pkinit_req_crypto_context;
134 
135 /*
136  * identity context should keep information about credentials
137  * for the request, eg., my credentials, trusted ca certs,
138  * intermediate ca certs, crls, pkcs11 info
139  */
140 typedef struct _pkinit_identity_crypto_context *pkinit_identity_crypto_context;
141 
142 /*
143  * this structure keeps information about the config options
144  */
145 typedef struct _pkinit_plg_opts {
146     int require_eku;	    /* require EKU checking (default is true) */
147     int accept_secondary_eku;/* accept secondary EKU (default is false) */
148     int allow_upn;	    /* allow UPN-SAN instead of pkinit-SAN */
149     int dh_or_rsa;	    /* selects DH or RSA based pkinit */
150     int require_crl_checking; /* require CRL for a CA (default is false) */
151     int require_freshness;  /* require freshness token (default is false) */
152     int disable_freshness;  /* disable freshness token on client for testing */
153     int dh_min_bits;	    /* minimum DH modulus size allowed */
154 } pkinit_plg_opts;
155 
156 /*
157  * this structure keeps options used for a given request
158  */
159 typedef struct _pkinit_req_opts {
160     int require_eku;
161     int accept_secondary_eku;
162     int allow_upn;
163     int dh_or_rsa;
164     int require_crl_checking;
165     int dh_size;	    /* initial request DH modulus size (default=1024) */
166     int require_hostname_match;
167     int disable_freshness;
168 } pkinit_req_opts;
169 
170 /*
171  * information about identity from config file or command line
172  */
173 
174 typedef struct _pkinit_identity_opts {
175     char *identity;
176     char **identity_alt;
177     char **anchors;
178     char **intermediates;
179     char **crls;
180     int  idtype;
181     char *cert_filename;
182     char *key_filename;
183 #ifndef WITHOUT_PKCS11
184     char *p11_module_name;
185     CK_SLOT_ID slotid;
186     char *token_label;
187     char *cert_id_string;
188     char *cert_label;
189 #endif
190 } pkinit_identity_opts;
191 
192 
193 /*
194  * Client's plugin context
195  */
196 struct _pkinit_context {
197     int magic;
198     pkinit_plg_crypto_context cryptoctx;
199     pkinit_plg_opts *opts;
200     pkinit_identity_opts *idopts;
201 };
202 typedef struct _pkinit_context *pkinit_context;
203 
204 /*
205  * Client's per-request context
206  */
207 struct _pkinit_req_context {
208     unsigned int magic;
209     pkinit_req_crypto_context cryptoctx;
210     pkinit_req_opts *opts;
211     pkinit_identity_crypto_context idctx;
212     pkinit_identity_opts *idopts;
213     int do_identity_matching;
214     krb5_preauthtype pa_type;
215     int rfc6112_kdc;
216     int identity_initialized;
217     int identity_prompted;
218     krb5_error_code identity_prompt_retval;
219     krb5_data *freshness_token;
220 };
221 typedef struct _pkinit_req_context *pkinit_req_context;
222 
223 /*
224  * KDC's (per-realm) plugin context
225  */
226 struct _pkinit_kdc_context {
227     int magic;
228     pkinit_plg_crypto_context cryptoctx;
229     pkinit_plg_opts *opts;
230     pkinit_identity_crypto_context idctx;
231     pkinit_identity_opts *idopts;
232     char *realmname;
233     unsigned int realmname_len;
234     char **auth_indicators;
235 };
236 typedef struct _pkinit_kdc_context *pkinit_kdc_context;
237 
238 /*
239  * KDC's per-request context
240  */
241 struct _pkinit_kdc_req_context {
242     int magic;
243     pkinit_req_crypto_context cryptoctx;
244     krb5_auth_pack *rcv_auth_pack;
245     krb5_preauthtype pa_type;
246 };
247 typedef struct _pkinit_kdc_req_context *pkinit_kdc_req_context;
248 
249 /*
250  * Functions in pkinit_lib.c
251  */
252 
253 krb5_error_code pkinit_init_req_opts(pkinit_req_opts **);
254 void pkinit_fini_req_opts(pkinit_req_opts *);
255 
256 krb5_error_code pkinit_init_plg_opts(pkinit_plg_opts **);
257 void pkinit_fini_plg_opts(pkinit_plg_opts *);
258 
259 krb5_error_code pkinit_init_identity_opts(pkinit_identity_opts **idopts);
260 void pkinit_fini_identity_opts(pkinit_identity_opts *idopts);
261 krb5_error_code pkinit_dup_identity_opts(pkinit_identity_opts *src_opts,
262 					 pkinit_identity_opts **dest_opts);
263 
264 /*
265  * Functions in pkinit_identity.c
266  */
267 char * idtype2string(int idtype);
268 char * catype2string(int catype);
269 
270 krb5_error_code pkinit_identity_initialize
271 	(krb5_context context,				/* IN */
272 	 pkinit_plg_crypto_context plg_cryptoctx,	/* IN */
273 	 pkinit_req_crypto_context req_cryptoctx,	/* IN */
274 	 pkinit_identity_opts *idopts,			/* IN */
275 	 pkinit_identity_crypto_context id_cryptoctx,	/* IN/OUT */
276 	 krb5_clpreauth_callbacks cb,			/* IN/OUT */
277 	 krb5_clpreauth_rock rock,			/* IN/OUT */
278 	 krb5_principal princ);				/* IN (optional) */
279 
280 krb5_error_code pkinit_identity_prompt
281 	(krb5_context context,				/* IN */
282 	 pkinit_plg_crypto_context plg_cryptoctx,	/* IN */
283 	 pkinit_req_crypto_context req_cryptoctx,	/* IN */
284 	 pkinit_identity_opts *idopts,			/* IN */
285 	 pkinit_identity_crypto_context id_cryptoctx,	/* IN/OUT */
286 	 krb5_clpreauth_callbacks cb,			/* IN/OUT */
287 	 krb5_clpreauth_rock rock,			/* IN/OUT */
288 	 int do_matching,				/* IN */
289 	 krb5_principal princ);				/* IN (optional) */
290 
291 krb5_error_code pkinit_cert_matching
292 	(krb5_context context,
293 	pkinit_plg_crypto_context plg_cryptoctx,
294 	pkinit_req_crypto_context req_cryptoctx,
295 	pkinit_identity_crypto_context id_cryptoctx,
296 	krb5_principal princ);
297 
298 krb5_error_code pkinit_client_cert_match
299 	(krb5_context context,
300 	pkinit_plg_crypto_context plgctx,
301 	pkinit_req_crypto_context reqctx,
302 	const char *match_rule,
303 	krb5_boolean *matched);
304 
305 /*
306  * Client's list of identities for which it needs PINs or passwords
307  */
308 struct _pkinit_deferred_id {
309     int magic;
310     char *identity;
311     unsigned long ck_flags;
312     char *password;
313 };
314 typedef struct _pkinit_deferred_id *pkinit_deferred_id;
315 
316 krb5_error_code pkinit_set_deferred_id
317 	(pkinit_deferred_id **identities, const char *identity,
318 	 unsigned long ck_flags, const char *password);
319 const char * pkinit_find_deferred_id
320 	(pkinit_deferred_id *identities, const char *identity);
321 unsigned long pkinit_get_deferred_id_flags
322 	(pkinit_deferred_id *identities, const char *identity);
323 void pkinit_free_deferred_ids(pkinit_deferred_id *identities);
324 
325 /*
326  * initialization and free functions
327  */
328 void init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
329 void init_krb5_reply_key_pack(krb5_reply_key_pack **in);
330 
331 void init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in);
332 
333 void free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
334 void free_krb5_reply_key_pack(krb5_reply_key_pack **in);
335 void free_krb5_auth_pack(krb5_auth_pack **in);
336 void free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in);
337 void free_krb5_external_principal_identifier(krb5_external_principal_identifier ***in);
338 void free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in);
339 void free_krb5_algorithm_identifier(krb5_algorithm_identifier *in);
340 void free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in);
341 krb5_error_code pkinit_copy_krb5_data(krb5_data *dst, const krb5_data *src);
342 
343 
344 /*
345  * Functions in pkinit_profile.c
346  */
347 krb5_error_code pkinit_kdcdefault_strings
348 	(krb5_context context, const char *realmname, const char *option,
349 	 char ***ret_value);
350 krb5_error_code pkinit_kdcdefault_string
351 	(krb5_context context, const char *realmname, const char *option,
352 	 char **ret_value);
353 krb5_error_code pkinit_kdcdefault_boolean
354 	(krb5_context context, const char *realmname, const char *option,
355 	 int default_value, int *ret_value);
356 krb5_error_code pkinit_kdcdefault_integer
357 	(krb5_context context, const char *realmname, const char *option,
358 	 int default_value, int *ret_value);
359 
360 
361 krb5_error_code pkinit_libdefault_strings
362 	(krb5_context context, const krb5_data *realm,
363 	 const char *option, char ***ret_value);
364 krb5_error_code pkinit_libdefault_string
365 	(krb5_context context, const krb5_data *realm,
366 	 const char *option, char **ret_value);
367 krb5_error_code pkinit_libdefault_boolean
368 	(krb5_context context, const krb5_data *realm, const char *option,
369 	 int default_value, int *ret_value);
370 krb5_error_code pkinit_libdefault_integer
371 	(krb5_context context, const krb5_data *realm, const char *option,
372 	 int default_value, int *ret_value);
373 
374 /*
375  * debugging functions
376  */
377 void print_buffer(const unsigned char *, unsigned int);
378 void print_buffer_bin(unsigned char *, unsigned int, char *);
379 
380 /*
381  * Now get crypto function declarations
382  */
383 #include "pkinit_crypto.h"
384 
385 #endif	/* _PKINIT_H */
386