xref: /freebsd/crypto/krb5/src/plugins/preauth/pkinit/pkinit.h (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
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 /* Rough finite-field bit strength equivalents for the elliptic curve groups */
63 #define PKINIT_DH_P256_BITS         3072
64 #define PKINIT_DH_P384_BITS         7680
65 #define PKINIT_DH_P521_BITS         15360
66 
67 #define KRB5_CONF_KDCDEFAULTS                   "kdcdefaults"
68 #define KRB5_CONF_LIBDEFAULTS                   "libdefaults"
69 #define KRB5_CONF_REALMS                        "realms"
70 #define KRB5_CONF_PKINIT_ALLOW_UPN              "pkinit_allow_upn"
71 #define KRB5_CONF_PKINIT_ANCHORS                "pkinit_anchors"
72 #define KRB5_CONF_PKINIT_INDICATOR              "pkinit_indicator"
73 #define KRB5_CONF_PKINIT_CERT_MATCH             "pkinit_cert_match"
74 #define KRB5_CONF_PKINIT_DH_MIN_BITS            "pkinit_dh_min_bits"
75 #define KRB5_CONF_PKINIT_EKU_CHECKING           "pkinit_eku_checking"
76 #define KRB5_CONF_PKINIT_IDENTITIES             "pkinit_identities"
77 #define KRB5_CONF_PKINIT_IDENTITY               "pkinit_identity"
78 #define KRB5_CONF_PKINIT_KDC_HOSTNAME           "pkinit_kdc_hostname"
79 /* pkinit_kdc_ocsp has been removed */
80 #define KRB5_CONF_PKINIT_KDC_OCSP               "pkinit_kdc_ocsp"
81 #define KRB5_CONF_PKINIT_POOL                   "pkinit_pool"
82 #define KRB5_CONF_PKINIT_REQUIRE_CRL_CHECKING   "pkinit_require_crl_checking"
83 #define KRB5_CONF_PKINIT_REQUIRE_FRESHNESS      "pkinit_require_freshness"
84 #define KRB5_CONF_PKINIT_REVOKE                 "pkinit_revoke"
85 
86 /* Make pkiDebug(fmt,...) print, or not.  */
87 #ifdef DEBUG
88 #define pkiDebug	printf
89 #else
90 /* Still evaluates for side effects.  */
pkiDebug(const char * fmt,...)91 static inline void pkiDebug (const char *fmt, ...) { }
92 /* This is better if the compiler doesn't inline variadic functions
93    well, but gcc will warn about "left-hand operand of comma
94    expression has no effect".  Still evaluates for side effects.  */
95 /* #define pkiDebug	(void) */
96 #endif
97 
98 /* Solaris compiler doesn't grok __FUNCTION__
99  * hack for now.  Fix all the uses eventually. */
100 #ifndef _WIN32
101 #define __FUNCTION__ __func__
102 #endif
103 
104 /* Macros to deal with converting between various data types... */
105 #define PADATA_TO_KRB5DATA(pad, k5d) \
106     (k5d)->length = (pad)->length; (k5d)->data = (char *)(pad)->contents;
107 #define OCTETDATA_TO_KRB5DATA(octd, k5d) \
108     (k5d)->length = (octd)->length; (k5d)->data = (char *)(octd)->data;
109 
110 /*
111  * notes about crypto contexts:
112  *
113  * the basic idea is that there are crypto contexts that live at
114  * both the plugin level and request level. the identity context (that
115  * keeps info about your own certs and such) is separate because
116  * it is needed at different levels for the kdc and and the client.
117  * (the kdc's identity is at the plugin level, the client's identity
118  * information could change per-request.)
119  * the identity context is meant to have the entity's cert,
120  * a list of trusted and intermediate cas, a list of crls, and any
121  * pkcs11 information.  the req context is meant to have the
122  * received certificate and the DH related information. the plugin
123  * context is meant to have global crypto information, i.e., OIDs
124  * and constant DH parameter information.
125  */
126 
127 /*
128  * plugin crypto context should keep plugin common information,
129  * eg., OIDs, known DHparams
130  */
131 typedef struct _pkinit_plg_crypto_context *pkinit_plg_crypto_context;
132 
133 /*
134  * request crypto context should keep reqyest common information,
135  * eg., received credentials, DH parameters of this request
136  */
137 typedef struct _pkinit_req_crypto_context *pkinit_req_crypto_context;
138 
139 /*
140  * identity context should keep information about credentials
141  * for the request, eg., my credentials, trusted ca certs,
142  * intermediate ca certs, crls, pkcs11 info
143  */
144 typedef struct _pkinit_identity_crypto_context *pkinit_identity_crypto_context;
145 
146 /*
147  * this structure keeps information about the config options
148  */
149 typedef struct _pkinit_plg_opts {
150     int require_eku;	    /* require EKU checking (default is true) */
151     int accept_secondary_eku;/* accept secondary EKU (default is false) */
152     int allow_upn;	    /* allow UPN-SAN instead of pkinit-SAN */
153     int require_crl_checking; /* require CRL for a CA (default is false) */
154     int require_freshness;  /* require freshness token (default is false) */
155     int disable_freshness;  /* disable freshness token on client for testing */
156     int dh_min_bits;	    /* minimum DH modulus size allowed */
157 } pkinit_plg_opts;
158 
159 /*
160  * this structure keeps options used for a given request
161  */
162 typedef struct _pkinit_req_opts {
163     int require_eku;
164     int accept_secondary_eku;
165     int allow_upn;
166     int require_crl_checking;
167     int dh_size;	    /* initial request DH modulus size (default=1024) */
168     int require_hostname_match;
169     int disable_freshness;
170 } pkinit_req_opts;
171 
172 /*
173  * information about identity from config file or command line
174  */
175 
176 typedef struct _pkinit_identity_opts {
177     char *identity;
178     char **identity_alt;
179     char **anchors;
180     char **intermediates;
181     char **crls;
182     int  idtype;
183     char *cert_filename;
184     char *key_filename;
185 #ifndef WITHOUT_PKCS11
186     char *p11_module_name;
187     CK_SLOT_ID slotid;
188     char *token_label;
189     char *cert_id_string;
190     char *cert_label;
191 #endif
192 } pkinit_identity_opts;
193 
194 
195 /*
196  * Client's plugin context
197  */
198 struct _pkinit_context {
199     int magic;
200     pkinit_plg_crypto_context cryptoctx;
201     pkinit_plg_opts *opts;
202     pkinit_identity_opts *idopts;
203 };
204 typedef struct _pkinit_context *pkinit_context;
205 
206 /*
207  * Client's per-request context
208  */
209 struct _pkinit_req_context {
210     unsigned int magic;
211     pkinit_req_crypto_context cryptoctx;
212     pkinit_req_opts *opts;
213     pkinit_identity_crypto_context idctx;
214     pkinit_identity_opts *idopts;
215     int do_identity_matching;
216     krb5_preauthtype pa_type;
217     int rfc6112_kdc;
218     int identity_initialized;
219     int identity_prompted;
220     krb5_error_code identity_prompt_retval;
221     krb5_data *freshness_token;
222 };
223 typedef struct _pkinit_req_context *pkinit_req_context;
224 
225 /*
226  * KDC's (per-realm) plugin context
227  */
228 struct _pkinit_kdc_context {
229     int magic;
230     pkinit_plg_crypto_context cryptoctx;
231     pkinit_plg_opts *opts;
232     pkinit_identity_crypto_context idctx;
233     pkinit_identity_opts *idopts;
234     char *realmname;
235     unsigned int realmname_len;
236     char **auth_indicators;
237 };
238 typedef struct _pkinit_kdc_context *pkinit_kdc_context;
239 
240 /*
241  * KDC's per-request context
242  */
243 struct _pkinit_kdc_req_context {
244     int magic;
245     pkinit_req_crypto_context cryptoctx;
246     krb5_auth_pack *rcv_auth_pack;
247     krb5_preauthtype pa_type;
248 };
249 typedef struct _pkinit_kdc_req_context *pkinit_kdc_req_context;
250 
251 /*
252  * Functions in pkinit_lib.c
253  */
254 
255 krb5_error_code pkinit_init_req_opts(pkinit_req_opts **);
256 void pkinit_fini_req_opts(pkinit_req_opts *);
257 
258 krb5_error_code pkinit_init_plg_opts(pkinit_plg_opts **);
259 void pkinit_fini_plg_opts(pkinit_plg_opts *);
260 
261 krb5_error_code pkinit_init_identity_opts(pkinit_identity_opts **idopts);
262 void pkinit_fini_identity_opts(pkinit_identity_opts *idopts);
263 krb5_error_code pkinit_dup_identity_opts(pkinit_identity_opts *src_opts,
264 					 pkinit_identity_opts **dest_opts);
265 
266 /*
267  * Functions in pkinit_identity.c
268  */
269 char * idtype2string(int idtype);
270 char * catype2string(int catype);
271 
272 krb5_error_code pkinit_identity_initialize
273 	(krb5_context context,				/* IN */
274 	 pkinit_plg_crypto_context plg_cryptoctx,	/* IN */
275 	 pkinit_req_crypto_context req_cryptoctx,	/* IN */
276 	 pkinit_identity_opts *idopts,			/* IN */
277 	 pkinit_identity_crypto_context id_cryptoctx,	/* IN/OUT */
278 	 krb5_clpreauth_callbacks cb,			/* IN/OUT */
279 	 krb5_clpreauth_rock rock,			/* IN/OUT */
280 	 krb5_principal princ);				/* IN (optional) */
281 
282 krb5_error_code pkinit_identity_prompt
283 	(krb5_context context,				/* IN */
284 	 pkinit_plg_crypto_context plg_cryptoctx,	/* IN */
285 	 pkinit_req_crypto_context req_cryptoctx,	/* IN */
286 	 pkinit_identity_opts *idopts,			/* IN */
287 	 pkinit_identity_crypto_context id_cryptoctx,	/* IN/OUT */
288 	 krb5_clpreauth_callbacks cb,			/* IN/OUT */
289 	 krb5_clpreauth_rock rock,			/* IN/OUT */
290 	 int do_matching,				/* IN */
291 	 krb5_principal princ);				/* IN (optional) */
292 
293 krb5_error_code pkinit_cert_matching
294 	(krb5_context context,
295 	pkinit_plg_crypto_context plg_cryptoctx,
296 	pkinit_req_crypto_context req_cryptoctx,
297 	pkinit_identity_crypto_context id_cryptoctx,
298 	krb5_principal princ);
299 
300 krb5_error_code pkinit_client_cert_match
301 	(krb5_context context,
302 	pkinit_plg_crypto_context plgctx,
303 	pkinit_req_crypto_context reqctx,
304 	const char *match_rule,
305 	krb5_boolean *matched);
306 
307 /*
308  * Client's list of identities for which it needs PINs or passwords
309  */
310 struct _pkinit_deferred_id {
311     int magic;
312     char *identity;
313     unsigned long ck_flags;
314     char *password;
315 };
316 typedef struct _pkinit_deferred_id *pkinit_deferred_id;
317 
318 krb5_error_code pkinit_set_deferred_id
319 	(pkinit_deferred_id **identities, const char *identity,
320 	 unsigned long ck_flags, const char *password);
321 const char * pkinit_find_deferred_id
322 	(pkinit_deferred_id *identities, const char *identity);
323 unsigned long pkinit_get_deferred_id_flags
324 	(pkinit_deferred_id *identities, const char *identity);
325 void pkinit_free_deferred_ids(pkinit_deferred_id *identities);
326 
327 /*
328  * initialization and free functions
329  */
330 void init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
331 void init_krb5_reply_key_pack(krb5_reply_key_pack **in);
332 
333 void init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in);
334 
335 void free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
336 void free_krb5_reply_key_pack(krb5_reply_key_pack **in);
337 void free_krb5_auth_pack(krb5_auth_pack **in);
338 void free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in);
339 void free_krb5_external_principal_identifier(krb5_external_principal_identifier ***in);
340 void free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in);
341 void free_krb5_algorithm_identifier(krb5_algorithm_identifier *in);
342 void free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in);
343 void free_pachecksum2(krb5_context context, krb5_pachecksum2 **in);
344 krb5_error_code pkinit_copy_krb5_data(krb5_data *dst, const krb5_data *src);
345 
346 
347 /*
348  * Functions in pkinit_profile.c
349  */
350 krb5_error_code pkinit_kdcdefault_strings
351 	(krb5_context context, const char *realmname, const char *option,
352 	 char ***ret_value);
353 krb5_error_code pkinit_kdcdefault_string
354 	(krb5_context context, const char *realmname, const char *option,
355 	 char **ret_value);
356 krb5_error_code pkinit_kdcdefault_boolean
357 	(krb5_context context, const char *realmname, const char *option,
358 	 int default_value, int *ret_value);
359 krb5_error_code pkinit_kdcdefault_integer
360 	(krb5_context context, const char *realmname, const char *option,
361 	 int default_value, int *ret_value);
362 
363 
364 krb5_error_code pkinit_libdefault_strings
365 	(krb5_context context, const krb5_data *realm,
366 	 const char *option, char ***ret_value);
367 krb5_error_code pkinit_libdefault_string
368 	(krb5_context context, const krb5_data *realm,
369 	 const char *option, char **ret_value);
370 krb5_error_code pkinit_libdefault_boolean
371 	(krb5_context context, const krb5_data *realm, const char *option,
372 	 int default_value, int *ret_value);
373 krb5_error_code pkinit_libdefault_integer
374 	(krb5_context context, const krb5_data *realm, const char *option,
375 	 int default_value, int *ret_value);
376 
377 /*
378  * debugging functions
379  */
380 void print_buffer(const unsigned char *, unsigned int);
381 void print_buffer_bin(unsigned char *, unsigned int, char *);
382 
383 /*
384  * Now get crypto function declarations
385  */
386 #include "pkinit_crypto.h"
387 
388 #endif	/* _PKINIT_H */
389