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