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 /*
32 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
33 */
34
35 #ifndef _PKINIT_H
36 #define _PKINIT_H
37
38 /* Solaris Kerberos */
39 #include <preauth_plugin.h>
40 #include <k5-int-pkinit.h>
41 #include <profile.h>
42 #include "pkinit_accessor.h"
43
44 /*
45 * It is anticipated that all the special checks currently
46 * required when talking to a Longhorn server will go away
47 * by the time it is officially released and all references
48 * to the longhorn global can be removed and any code
49 * #ifdef'd with LONGHORN_BETA_COMPAT can be removed.
50 * And this #define!
51 */
52 #define LONGHORN_BETA_COMPAT 1
53 #ifdef LONGHORN_BETA_COMPAT
54 extern int longhorn; /* XXX Talking to a Longhorn server? */
55 #endif
56
57
58 #ifndef WITHOUT_PKCS11
59 /* Solaris Kerberos */
60 #include <security/cryptoki.h>
61 #include <security/pkcs11.h>
62
63 /* Solaris Kerberos */
64 #define PKCS11_MODNAME "/usr/lib/libpkcs11.so"
65
66 #define PK_SIGLEN_GUESS 1000
67 #define PK_NOSLOT 999999
68 #endif
69
70 #define DH_PROTOCOL 1
71 #define RSA_PROTOCOL 2
72
73 #define TD_TRUSTED_CERTIFIERS 104
74 #define TD_INVALID_CERTIFICATES 105
75 #define TD_DH_PARAMETERS 109
76
77 #define PKINIT_CTX_MAGIC 0x05551212
78 #define PKINIT_REQ_CTX_MAGIC 0xdeadbeef
79
80 #define PKINIT_DEFAULT_DH_MIN_BITS 2048
81
82 /* Make pkiDebug(fmt,...) print, or not. */
83 #ifdef DEBUG
84 #define pkiDebug printf
85 #else
86 /* Still evaluates for side effects. */
87 /* ARGSUSED */
pkiDebug(const char * fmt,...)88 static void pkiDebug (const char *fmt, ...) { }
89 /* This is better if the compiler doesn't inline variadic functions
90 well, but gcc will warn about "left-hand operand of comma
91 expression has no effect". Still evaluates for side effects. */
92 /* #define pkiDebug (void) */
93 #endif
94
95 /* Solaris Kerberos */
96 #if (__STDC_VERSION__ >= 199901L) || \
97 (defined(__SUNPRO_C) && defined(__C99FEATURES__))
98 #define __FUNCTION__ __func__
99 #else
100 #define __FUNCTION__ ""
101 #endif
102
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 extern const krb5_octet_data dh_oid;
111
112 /*
113 * notes about crypto contexts:
114 *
115 * the basic idea is that there are crypto contexts that live at
116 * both the plugin level and request level. the identity context (that
117 * keeps info about your own certs and such) is separate because
118 * it is needed at different levels for the kdc and and the client.
119 * (the kdc's identity is at the plugin level, the client's identity
120 * information could change per-request.)
121 * the identity context is meant to have the entity's cert,
122 * a list of trusted and intermediate cas, a list of crls, and any
123 * pkcs11 information. the req context is meant to have the
124 * received certificate and the DH related information. the plugin
125 * context is meant to have global crypto information, i.e., OIDs
126 * and constant DH parameter information.
127 */
128
129 /*
130 * plugin crypto context should keep plugin common information,
131 * eg., OIDs, known DHparams
132 */
133 typedef struct _pkinit_plg_crypto_context *pkinit_plg_crypto_context;
134
135 /*
136 * request crypto context should keep reqyest common information,
137 * eg., received credentials, DH parameters of this request
138 */
139 typedef struct _pkinit_req_crypto_context *pkinit_req_crypto_context;
140
141 /*
142 * identity context should keep information about credentials
143 * for the request, eg., my credentials, trusted ca certs,
144 * intermediate ca certs, crls, pkcs11 info
145 */
146 typedef struct _pkinit_identity_crypto_context *pkinit_identity_crypto_context;
147
148 /*
149 * this structure keeps information about the config options
150 */
151 typedef struct _pkinit_plg_opts {
152 int require_eku; /* require EKU checking (default is true) */
153 int accept_secondary_eku;/* accept secondary EKU (default is false) */
154 int allow_upn; /* allow UPN-SAN instead of pkinit-SAN */
155 int dh_or_rsa; /* selects DH or RSA based pkinit */
156 int require_crl_checking; /* require CRL for a CA (default is false) */
157 int dh_min_bits; /* minimum DH modulus size allowed */
158 } pkinit_plg_opts;
159
160 /*
161 * this structure keeps options used for a given request
162 */
163 typedef struct _pkinit_req_opts {
164 int require_eku;
165 int accept_secondary_eku;
166 int allow_upn;
167 int dh_or_rsa;
168 int require_crl_checking;
169 int dh_size; /* initial request DH modulus size (default=1024) */
170 int require_hostname_match;
171 int win2k_target;
172 int win2k_require_cksum;
173 } pkinit_req_opts;
174
175 /*
176 * information about identity from config file or command line
177 */
178
179 #define PKINIT_ID_OPT_USER_IDENTITY 1
180 #define PKINIT_ID_OPT_ANCHOR_CAS 2
181 #define PKINIT_ID_OPT_INTERMEDIATE_CAS 3
182 #define PKINIT_ID_OPT_CRLS 4
183 #define PKINIT_ID_OPT_OCSP 5
184 #define PKINIT_ID_OPT_DN_MAPPING 6 /* XXX ? */
185
186 typedef struct _pkinit_identity_opts {
187 char *identity;
188 char **identity_alt;
189 char **anchors;
190 char **intermediates;
191 char **crls;
192 char *ocsp;
193 char *dn_mapping_file;
194 int idtype;
195 char *cert_filename;
196 char *key_filename;
197 #ifndef WITHOUT_PKCS11
198 char *p11_module_name;
199 CK_SLOT_ID slotid;
200 char *token_label;
201 char *cert_id_string;
202 char *cert_label;
203 char *PIN; /* Solaris Kerberos */
204 #endif
205 } pkinit_identity_opts;
206
207
208 /*
209 * Client's plugin context
210 */
211 struct _pkinit_context {
212 int magic;
213 pkinit_plg_crypto_context cryptoctx;
214 pkinit_plg_opts *opts;
215 pkinit_identity_opts *idopts;
216 };
217 typedef struct _pkinit_context *pkinit_context;
218
219 /*
220 * Client's per-request context
221 */
222 struct _pkinit_req_context {
223 int magic;
224 pkinit_req_crypto_context cryptoctx;
225 pkinit_req_opts *opts;
226 pkinit_identity_crypto_context idctx;
227 pkinit_identity_opts *idopts;
228 krb5_preauthtype pa_type;
229 };
230 typedef struct _pkinit_kdc_context *pkinit_kdc_context;
231
232 /*
233 * KDC's (per-realm) plugin context
234 */
235 struct _pkinit_kdc_context {
236 int magic;
237 pkinit_plg_crypto_context cryptoctx;
238 pkinit_plg_opts *opts;
239 pkinit_identity_crypto_context idctx;
240 pkinit_identity_opts *idopts;
241 char *realmname;
242 unsigned int realmname_len;
243 };
244 typedef struct _pkinit_req_context *pkinit_req_context;
245
246 /*
247 * KDC's per-request context
248 */
249 struct _pkinit_kdc_req_context {
250 int magic;
251 pkinit_req_crypto_context cryptoctx;
252 krb5_auth_pack *rcv_auth_pack;
253 krb5_auth_pack_draft9 *rcv_auth_pack9;
254 krb5_preauthtype pa_type;
255 };
256 typedef struct _pkinit_kdc_req_context *pkinit_kdc_req_context;
257
258 /*
259 * Functions in pkinit_lib.c
260 */
261
262 krb5_error_code pkinit_init_req_opts(pkinit_req_opts **);
263 void pkinit_fini_req_opts(pkinit_req_opts *);
264
265 krb5_error_code pkinit_init_plg_opts(pkinit_plg_opts **);
266 void pkinit_fini_plg_opts(pkinit_plg_opts *);
267
268 krb5_error_code pkinit_init_identity_opts(pkinit_identity_opts **idopts);
269 void pkinit_fini_identity_opts(pkinit_identity_opts *idopts);
270 krb5_error_code pkinit_dup_identity_opts(pkinit_identity_opts *src_opts,
271 pkinit_identity_opts **dest_opts);
272
273 /*
274 * Functions in pkinit_identity.c
275 */
276 char * idtype2string(int idtype);
277 char * catype2string(int catype);
278
279 krb5_error_code pkinit_identity_initialize
280 (krb5_context context, /* IN */
281 pkinit_plg_crypto_context plg_cryptoctx, /* IN */
282 pkinit_req_crypto_context req_cryptoctx, /* IN */
283 pkinit_identity_opts *idopts, /* IN */
284 pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */
285 int do_matching, /* IN */
286 krb5_principal princ); /* IN (optional) */
287
288 krb5_error_code pkinit_cert_matching
289 (krb5_context context,
290 pkinit_plg_crypto_context plg_cryptoctx,
291 pkinit_req_crypto_context req_cryptoctx,
292 pkinit_identity_crypto_context id_cryptoctx,
293 krb5_principal princ,
294 krb5_boolean do_select);
295
296 /*
297 * initialization and free functions
298 */
299 void init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
300 void init_krb5_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 **in);
301 void init_krb5_reply_key_pack(krb5_reply_key_pack **in);
302 void init_krb5_reply_key_pack_draft9(krb5_reply_key_pack_draft9 **in);
303
304 void init_krb5_auth_pack(krb5_auth_pack **in);
305 void init_krb5_auth_pack_draft9(krb5_auth_pack_draft9 **in);
306 void init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in);
307 void init_krb5_pa_pk_as_rep_draft9(krb5_pa_pk_as_rep_draft9 **in);
308 void init_krb5_typed_data(krb5_typed_data **in);
309 void init_krb5_subject_pk_info(krb5_subject_pk_info **in);
310
311 void free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
312 void free_krb5_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 **in);
313 void free_krb5_reply_key_pack(krb5_reply_key_pack **in);
314 void free_krb5_reply_key_pack_draft9(krb5_reply_key_pack_draft9 **in);
315 void free_krb5_auth_pack(krb5_auth_pack **in);
316 void free_krb5_auth_pack_draft9(krb5_context, krb5_auth_pack_draft9 **in);
317 void free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in);
318 void free_krb5_pa_pk_as_rep_draft9(krb5_pa_pk_as_rep_draft9 **in);
319 void free_krb5_external_principal_identifier(krb5_external_principal_identifier ***in);
320 void free_krb5_trusted_ca(krb5_trusted_ca ***in);
321 void free_krb5_typed_data(krb5_typed_data ***in);
322 void free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in);
323 void free_krb5_algorithm_identifier(krb5_algorithm_identifier *in);
324 void free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in);
325 void free_krb5_subject_pk_info(krb5_subject_pk_info **in);
326 krb5_error_code pkinit_copy_krb5_octet_data(krb5_octet_data *dst, const krb5_octet_data *src);
327
328
329 /*
330 * Functions in pkinit_profile.c
331 */
332 krb5_error_code pkinit_kdcdefault_strings
333 (krb5_context context, const char *realmname, const char *option,
334 char ***ret_value);
335 krb5_error_code pkinit_kdcdefault_string
336 (krb5_context context, const char *realmname, const char *option,
337 char **ret_value);
338 krb5_error_code pkinit_kdcdefault_boolean
339 (krb5_context context, const char *realmname, const char *option,
340 int default_value, int *ret_value);
341 krb5_error_code pkinit_kdcdefault_integer
342 (krb5_context context, const char *realmname, const char *option,
343 int default_value, int *ret_value);
344
345
346 krb5_error_code pkinit_libdefault_strings
347 (krb5_context context, const krb5_data *realm,
348 const char *option, char ***ret_value);
349 krb5_error_code pkinit_libdefault_string
350 (krb5_context context, const krb5_data *realm,
351 const char *option, char **ret_value);
352 krb5_error_code pkinit_libdefault_boolean
353 (krb5_context context, const krb5_data *realm, const char *option,
354 int default_value, int *ret_value);
355 krb5_error_code pkinit_libdefault_integer
356 (krb5_context context, const krb5_data *realm, const char *option,
357 int default_value, int *ret_value);
358
359 /*
360 * debugging functions
361 */
362 void print_buffer(unsigned char *, unsigned int);
363 void print_buffer_bin(unsigned char *, unsigned int, char *);
364
365 /*
366 * Now get crypto function declarations
367 */
368 #include "pkinit_crypto.h"
369
370 #endif /* _PKINIT_H */
371