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. */ 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