/* * COPYRIGHT (C) 2006,2007 * THE REGENTS OF THE UNIVERSITY OF MICHIGAN * ALL RIGHTS RESERVED * * Permission is granted to use, copy, create derivative works * and redistribute this software and such derivative works * for any purpose, so long as the name of The University of * Michigan is not used in any advertising or publicity * pertaining to the use of distribution of this software * without specific, written prior authorization. If the * above copyright notice or any other identification of the * University of Michigan is included in any copy of any * portion of this software, then the disclaimer below must * also be included. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF * SUCH DAMAGES. */ #ifndef _PKINIT_H #define _PKINIT_H #include #include #include #include #include #include "pkinit_accessor.h" #include "pkinit_trace.h" #ifndef WITHOUT_PKCS11 #include "pkcs11.h" #define PKCS11_MODNAME "opensc-pkcs11.so" #define PK_SIGLEN_GUESS 1000 #define PK_NOSLOT 999999 #endif #define DH_PROTOCOL 1 #define RSA_PROTOCOL 2 #define TD_TRUSTED_CERTIFIERS 104 #define TD_INVALID_CERTIFICATES 105 #define TD_DH_PARAMETERS 109 #define PKINIT_CTX_MAGIC 0x05551212 #define PKINIT_REQ_CTX_MAGIC 0xdeadbeef #define PKINIT_DEFERRED_ID_MAGIC 0x3ca20d21 #define PKINIT_DEFAULT_DH_MIN_BITS 2048 #define PKINIT_DH_MIN_CONFIG_BITS 1024 #define KRB5_CONF_KDCDEFAULTS "kdcdefaults" #define KRB5_CONF_LIBDEFAULTS "libdefaults" #define KRB5_CONF_REALMS "realms" #define KRB5_CONF_PKINIT_ALLOW_UPN "pkinit_allow_upn" #define KRB5_CONF_PKINIT_ANCHORS "pkinit_anchors" #define KRB5_CONF_PKINIT_INDICATOR "pkinit_indicator" #define KRB5_CONF_PKINIT_CERT_MATCH "pkinit_cert_match" #define KRB5_CONF_PKINIT_DH_MIN_BITS "pkinit_dh_min_bits" #define KRB5_CONF_PKINIT_EKU_CHECKING "pkinit_eku_checking" #define KRB5_CONF_PKINIT_IDENTITIES "pkinit_identities" #define KRB5_CONF_PKINIT_IDENTITY "pkinit_identity" #define KRB5_CONF_PKINIT_KDC_HOSTNAME "pkinit_kdc_hostname" /* pkinit_kdc_ocsp has been removed */ #define KRB5_CONF_PKINIT_KDC_OCSP "pkinit_kdc_ocsp" #define KRB5_CONF_PKINIT_POOL "pkinit_pool" #define KRB5_CONF_PKINIT_REQUIRE_CRL_CHECKING "pkinit_require_crl_checking" #define KRB5_CONF_PKINIT_REQUIRE_FRESHNESS "pkinit_require_freshness" #define KRB5_CONF_PKINIT_REVOKE "pkinit_revoke" /* Make pkiDebug(fmt,...) print, or not. */ #ifdef DEBUG #define pkiDebug printf #else /* Still evaluates for side effects. */ static inline void pkiDebug (const char *fmt, ...) { } /* This is better if the compiler doesn't inline variadic functions well, but gcc will warn about "left-hand operand of comma expression has no effect". Still evaluates for side effects. */ /* #define pkiDebug (void) */ #endif /* Solaris compiler doesn't grok __FUNCTION__ * hack for now. Fix all the uses eventually. */ #define __FUNCTION__ __func__ /* Macros to deal with converting between various data types... */ #define PADATA_TO_KRB5DATA(pad, k5d) \ (k5d)->length = (pad)->length; (k5d)->data = (char *)(pad)->contents; #define OCTETDATA_TO_KRB5DATA(octd, k5d) \ (k5d)->length = (octd)->length; (k5d)->data = (char *)(octd)->data; extern const krb5_data dh_oid; /* * notes about crypto contexts: * * the basic idea is that there are crypto contexts that live at * both the plugin level and request level. the identity context (that * keeps info about your own certs and such) is separate because * it is needed at different levels for the kdc and and the client. * (the kdc's identity is at the plugin level, the client's identity * information could change per-request.) * the identity context is meant to have the entity's cert, * a list of trusted and intermediate cas, a list of crls, and any * pkcs11 information. the req context is meant to have the * received certificate and the DH related information. the plugin * context is meant to have global crypto information, i.e., OIDs * and constant DH parameter information. */ /* * plugin crypto context should keep plugin common information, * eg., OIDs, known DHparams */ typedef struct _pkinit_plg_crypto_context *pkinit_plg_crypto_context; /* * request crypto context should keep reqyest common information, * eg., received credentials, DH parameters of this request */ typedef struct _pkinit_req_crypto_context *pkinit_req_crypto_context; /* * identity context should keep information about credentials * for the request, eg., my credentials, trusted ca certs, * intermediate ca certs, crls, pkcs11 info */ typedef struct _pkinit_identity_crypto_context *pkinit_identity_crypto_context; /* * this structure keeps information about the config options */ typedef struct _pkinit_plg_opts { int require_eku; /* require EKU checking (default is true) */ int accept_secondary_eku;/* accept secondary EKU (default is false) */ int allow_upn; /* allow UPN-SAN instead of pkinit-SAN */ int dh_or_rsa; /* selects DH or RSA based pkinit */ int require_crl_checking; /* require CRL for a CA (default is false) */ int require_freshness; /* require freshness token (default is false) */ int disable_freshness; /* disable freshness token on client for testing */ int dh_min_bits; /* minimum DH modulus size allowed */ } pkinit_plg_opts; /* * this structure keeps options used for a given request */ typedef struct _pkinit_req_opts { int require_eku; int accept_secondary_eku; int allow_upn; int dh_or_rsa; int require_crl_checking; int dh_size; /* initial request DH modulus size (default=1024) */ int require_hostname_match; int disable_freshness; } pkinit_req_opts; /* * information about identity from config file or command line */ typedef struct _pkinit_identity_opts { char *identity; char **identity_alt; char **anchors; char **intermediates; char **crls; int idtype; char *cert_filename; char *key_filename; #ifndef WITHOUT_PKCS11 char *p11_module_name; CK_SLOT_ID slotid; char *token_label; char *cert_id_string; char *cert_label; #endif } pkinit_identity_opts; /* * Client's plugin context */ struct _pkinit_context { int magic; pkinit_plg_crypto_context cryptoctx; pkinit_plg_opts *opts; pkinit_identity_opts *idopts; }; typedef struct _pkinit_context *pkinit_context; /* * Client's per-request context */ struct _pkinit_req_context { unsigned int magic; pkinit_req_crypto_context cryptoctx; pkinit_req_opts *opts; pkinit_identity_crypto_context idctx; pkinit_identity_opts *idopts; int do_identity_matching; krb5_preauthtype pa_type; int rfc6112_kdc; int identity_initialized; int identity_prompted; krb5_error_code identity_prompt_retval; krb5_data *freshness_token; }; typedef struct _pkinit_req_context *pkinit_req_context; /* * KDC's (per-realm) plugin context */ struct _pkinit_kdc_context { int magic; pkinit_plg_crypto_context cryptoctx; pkinit_plg_opts *opts; pkinit_identity_crypto_context idctx; pkinit_identity_opts *idopts; char *realmname; unsigned int realmname_len; char **auth_indicators; }; typedef struct _pkinit_kdc_context *pkinit_kdc_context; /* * KDC's per-request context */ struct _pkinit_kdc_req_context { int magic; pkinit_req_crypto_context cryptoctx; krb5_auth_pack *rcv_auth_pack; krb5_preauthtype pa_type; }; typedef struct _pkinit_kdc_req_context *pkinit_kdc_req_context; /* * Functions in pkinit_lib.c */ krb5_error_code pkinit_init_req_opts(pkinit_req_opts **); void pkinit_fini_req_opts(pkinit_req_opts *); krb5_error_code pkinit_init_plg_opts(pkinit_plg_opts **); void pkinit_fini_plg_opts(pkinit_plg_opts *); krb5_error_code pkinit_init_identity_opts(pkinit_identity_opts **idopts); void pkinit_fini_identity_opts(pkinit_identity_opts *idopts); krb5_error_code pkinit_dup_identity_opts(pkinit_identity_opts *src_opts, pkinit_identity_opts **dest_opts); /* * Functions in pkinit_identity.c */ char * idtype2string(int idtype); char * catype2string(int catype); krb5_error_code pkinit_identity_initialize (krb5_context context, /* IN */ pkinit_plg_crypto_context plg_cryptoctx, /* IN */ pkinit_req_crypto_context req_cryptoctx, /* IN */ pkinit_identity_opts *idopts, /* IN */ pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */ krb5_clpreauth_callbacks cb, /* IN/OUT */ krb5_clpreauth_rock rock, /* IN/OUT */ krb5_principal princ); /* IN (optional) */ krb5_error_code pkinit_identity_prompt (krb5_context context, /* IN */ pkinit_plg_crypto_context plg_cryptoctx, /* IN */ pkinit_req_crypto_context req_cryptoctx, /* IN */ pkinit_identity_opts *idopts, /* IN */ pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */ krb5_clpreauth_callbacks cb, /* IN/OUT */ krb5_clpreauth_rock rock, /* IN/OUT */ int do_matching, /* IN */ krb5_principal princ); /* IN (optional) */ krb5_error_code pkinit_cert_matching (krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, pkinit_req_crypto_context req_cryptoctx, pkinit_identity_crypto_context id_cryptoctx, krb5_principal princ); krb5_error_code pkinit_client_cert_match (krb5_context context, pkinit_plg_crypto_context plgctx, pkinit_req_crypto_context reqctx, const char *match_rule, krb5_boolean *matched); /* * Client's list of identities for which it needs PINs or passwords */ struct _pkinit_deferred_id { int magic; char *identity; unsigned long ck_flags; char *password; }; typedef struct _pkinit_deferred_id *pkinit_deferred_id; krb5_error_code pkinit_set_deferred_id (pkinit_deferred_id **identities, const char *identity, unsigned long ck_flags, const char *password); const char * pkinit_find_deferred_id (pkinit_deferred_id *identities, const char *identity); unsigned long pkinit_get_deferred_id_flags (pkinit_deferred_id *identities, const char *identity); void pkinit_free_deferred_ids(pkinit_deferred_id *identities); /* * initialization and free functions */ void init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in); void init_krb5_reply_key_pack(krb5_reply_key_pack **in); void init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in); void init_krb5_subject_pk_info(krb5_subject_pk_info **in); void free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in); void free_krb5_reply_key_pack(krb5_reply_key_pack **in); void free_krb5_auth_pack(krb5_auth_pack **in); void free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in); void free_krb5_external_principal_identifier(krb5_external_principal_identifier ***in); void free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in); void free_krb5_algorithm_identifier(krb5_algorithm_identifier *in); void free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in); void free_krb5_subject_pk_info(krb5_subject_pk_info **in); krb5_error_code pkinit_copy_krb5_data(krb5_data *dst, const krb5_data *src); /* * Functions in pkinit_profile.c */ krb5_error_code pkinit_kdcdefault_strings (krb5_context context, const char *realmname, const char *option, char ***ret_value); krb5_error_code pkinit_kdcdefault_string (krb5_context context, const char *realmname, const char *option, char **ret_value); krb5_error_code pkinit_kdcdefault_boolean (krb5_context context, const char *realmname, const char *option, int default_value, int *ret_value); krb5_error_code pkinit_kdcdefault_integer (krb5_context context, const char *realmname, const char *option, int default_value, int *ret_value); krb5_error_code pkinit_libdefault_strings (krb5_context context, const krb5_data *realm, const char *option, char ***ret_value); krb5_error_code pkinit_libdefault_string (krb5_context context, const krb5_data *realm, const char *option, char **ret_value); krb5_error_code pkinit_libdefault_boolean (krb5_context context, const krb5_data *realm, const char *option, int default_value, int *ret_value); krb5_error_code pkinit_libdefault_integer (krb5_context context, const krb5_data *realm, const char *option, int default_value, int *ret_value); /* * debugging functions */ void print_buffer(const unsigned char *, unsigned int); void print_buffer_bin(unsigned char *, unsigned int, char *); /* * Now get crypto function declarations */ #include "pkinit_crypto.h" #endif /* _PKINIT_H */