diff options
| author | Kevin Coffman <kwc@citi.umich.edu> | 2007-08-01 22:09:13 +0000 |
|---|---|---|
| committer | Kevin Coffman <kwc@citi.umich.edu> | 2007-08-01 22:09:13 +0000 |
| commit | 0ef0646069c1d1376aa632a4791ea7e429f5ae9b (patch) | |
| tree | 5b9f842dc45a9a14d5698a6f3ff321cea612d7c5 /src/include | |
| parent | 101446c6f40a13917fd0ba020bc276e82590058d (diff) | |
| download | krb5-0ef0646069c1d1376aa632a4791ea7e429f5ae9b.tar.gz krb5-0ef0646069c1d1376aa632a4791ea7e429f5ae9b.tar.xz krb5-0ef0646069c1d1376aa632a4791ea7e429f5ae9b.zip | |
Add PKINIT support
Pull up PKINIT support onto the trunk.
Changes from the version in branch users/coffman/pkinit are:
- Update the preauth plugin interface version to avoid
conflict with any existing plugins.
- Add a pkcs11.h locally to the pkinit code rather than
depending on opensc being installed.
ticket: new
Target_Version: 1.6.3
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19745 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/k5-int-pkinit.h | 270 | ||||
| -rw-r--r-- | src/include/k5-int.h | 145 | ||||
| -rw-r--r-- | src/include/krb5/krb5.hin | 11 | ||||
| -rw-r--r-- | src/include/krb5/preauth_plugin.h | 391 |
4 files changed, 645 insertions, 172 deletions
diff --git a/src/include/k5-int-pkinit.h b/src/include/k5-int-pkinit.h new file mode 100644 index 000000000..e75c8031f --- /dev/null +++ b/src/include/k5-int-pkinit.h @@ -0,0 +1,270 @@ +/* + * COPYRIGHT (C) 2006 + * 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 _KRB5_INT_PKINIT_H +#define _KRB5_INT_PKINIT_H + +/* + * pkinit structures + */ + +/* PKAuthenticator */ +typedef struct _krb5_pk_authenticator { + krb5_int32 cusec; /* (0..999999) */ + krb5_timestamp ctime; + krb5_int32 nonce; /* (0..4294967295) */ + krb5_checksum paChecksum; +} krb5_pk_authenticator; + +/* PKAuthenticator draft9 */ +typedef struct _krb5_pk_authenticator_draft9 { + krb5_principal kdcName; + krb5_octet_data kdcRealm; + krb5_int32 cusec; /* (0..999999) */ + krb5_timestamp ctime; + krb5_int32 nonce; /* (0..4294967295) */ +} krb5_pk_authenticator_draft9; + +/* AlgorithmIdentifier */ +typedef struct _krb5_algorithm_identifier { + krb5_octet_data algorithm; /* OID */ + krb5_octet_data parameters; /* Optional */ +} krb5_algorithm_identifier; + +/* SubjectPublicKeyInfo */ +typedef struct _krb5_subject_pk_info { + krb5_algorithm_identifier algorithm; + krb5_octet_data subjectPublicKey; /* BIT STRING */ +} krb5_subject_pk_info; + +/* AuthPack */ +typedef struct _krb5_auth_pack { + krb5_pk_authenticator pkAuthenticator; + krb5_subject_pk_info *clientPublicValue; /* Optional */ + krb5_algorithm_identifier **supportedCMSTypes; /* Optional */ + krb5_octet_data clientDHNonce; /* Optional */ +} krb5_auth_pack; + +/* AuthPack draft9 */ +typedef struct _krb5_auth_pack_draft9 { + krb5_pk_authenticator_draft9 pkAuthenticator; + krb5_subject_pk_info *clientPublicValue; /* Optional */ +} krb5_auth_pack_draft9; + +/* ExternalPrincipalIdentifier */ +typedef struct _krb5_external_principal_identifier { + krb5_octet_data subjectName; /* Optional */ + krb5_octet_data issuerAndSerialNumber; /* Optional */ + krb5_octet_data subjectKeyIdentifier; /* Optional */ +} krb5_external_principal_identifier; + +/* TrustedCas */ +typedef struct _krb5_trusted_ca { + enum { + choice_trusted_cas_UNKNOWN = -1, + choice_trusted_cas_principalName = 0, + choice_trusted_cas_caName = 1, + choice_trusted_cas_issuerAndSerial = 2 + } choice; + union { + krb5_principal principalName; + krb5_octet_data caName; /* fully-qualified X.500 "Name" as defined by X.509 (der-encoded) */ + krb5_octet_data issuerAndSerial; /* Optional -- IssuerAndSerialNumber (der-encoded) */ + } u; +} krb5_trusted_ca; + +/* typed data */ +typedef struct _krb5_typed_data { + krb5_magic magic; + krb5_int32 type; + unsigned int length; + krb5_octet *data; +} krb5_typed_data; + +/* PA-PK-AS-REQ (Draft 9 -- PA TYPE 14) */ +typedef struct _krb5_pa_pk_as_req_draft9 { + krb5_octet_data signedAuthPack; + krb5_trusted_ca **trustedCertifiers; /* Optional array */ + krb5_octet_data kdcCert; /* Optional */ + krb5_octet_data encryptionCert; +} krb5_pa_pk_as_req_draft9; + +/* PA-PK-AS-REQ (rfc4556 -- PA TYPE 16) */ +typedef struct _krb5_pa_pk_as_req { + krb5_octet_data signedAuthPack; + krb5_external_principal_identifier **trustedCertifiers; /* Optional array */ + krb5_octet_data kdcPkId; /* Optional */ +} krb5_pa_pk_as_req; + +/* DHRepInfo */ +typedef struct _krb5_dh_rep_info { + krb5_octet_data dhSignedData; + krb5_octet_data serverDHNonce; /* Optional */ +} krb5_dh_rep_info; + +/* KDCDHKeyInfo */ +typedef struct _krb5_kdc_dh_key_info { + krb5_octet_data subjectPublicKey; /* BIT STRING */ + krb5_int32 nonce; /* (0..4294967295) */ + krb5_timestamp dhKeyExpiration; /* Optional */ +} krb5_kdc_dh_key_info; + +/* KDCDHKeyInfo draft9*/ +typedef struct _krb5_kdc_dh_key_info_draft9 { + krb5_octet_data subjectPublicKey; /* BIT STRING */ + krb5_int32 nonce; /* (0..4294967295) */ +} krb5_kdc_dh_key_info_draft9; + +/* ReplyKeyPack */ +typedef struct _krb5_reply_key_pack { + krb5_keyblock replyKey; + krb5_checksum asChecksum; +} krb5_reply_key_pack; + +/* ReplyKeyPack */ +typedef struct _krb5_reply_key_pack_draft9 { + krb5_keyblock replyKey; + krb5_int32 nonce; +} krb5_reply_key_pack_draft9; + +/* PA-PK-AS-REP (Draft 9 -- PA TYPE 15) */ +typedef struct _krb5_pa_pk_as_rep_draft9 { + enum { + choice_pa_pk_as_rep_draft9_UNKNOWN = -1, + choice_pa_pk_as_rep_draft9_dhSignedData = 0, + choice_pa_pk_as_rep_draft9_encKeyPack = 1 + } choice; + union { + krb5_octet_data dhSignedData; + krb5_octet_data encKeyPack; + } u; +} krb5_pa_pk_as_rep_draft9; + +/* PA-PK-AS-REP (rfc4556 -- PA TYPE 17) */ +typedef struct _krb5_pa_pk_as_rep { + enum { + choice_pa_pk_as_rep_UNKNOWN = -1, + choice_pa_pk_as_rep_dhInfo = 0, + choice_pa_pk_as_rep_encKeyPack = 1 + } choice; + union { + krb5_dh_rep_info dh_Info; + krb5_octet_data encKeyPack; + } u; +} krb5_pa_pk_as_rep; + +/* + * Begin "asn1.h" + */ + +/************************************************************************* + * Prototypes for pkinit asn.1 encode routines + *************************************************************************/ + +krb5_error_code encode_krb5_pa_pk_as_req + (const krb5_pa_pk_as_req *rep, krb5_data **code); + +krb5_error_code encode_krb5_pa_pk_as_req_draft9 + (const krb5_pa_pk_as_req_draft9 *rep, krb5_data **code); + +krb5_error_code encode_krb5_pa_pk_as_rep + (const krb5_pa_pk_as_rep *rep, krb5_data **code); + +krb5_error_code encode_krb5_pa_pk_as_rep_draft9 + (const krb5_pa_pk_as_rep_draft9 *rep, krb5_data **code); + +krb5_error_code encode_krb5_auth_pack + (const krb5_auth_pack *rep, krb5_data **code); + +krb5_error_code encode_krb5_auth_pack_draft9 + (const krb5_auth_pack_draft9 *rep, krb5_data **code); + +krb5_error_code encode_krb5_kdc_dh_key_info + (const krb5_kdc_dh_key_info *rep, krb5_data **code); + +krb5_error_code encode_krb5_reply_key_pack + (const krb5_reply_key_pack *, krb5_data **code); + +krb5_error_code encode_krb5_reply_key_pack_draft9 + (const krb5_reply_key_pack_draft9 *, krb5_data **code); + +krb5_error_code encode_krb5_typed_data + (const krb5_typed_data **, krb5_data **code); + +krb5_error_code encode_krb5_td_trusted_certifiers + (const krb5_external_principal_identifier **, krb5_data **code); + +krb5_error_code encode_krb5_td_dh_parameters + (const krb5_algorithm_identifier **, krb5_data **code); + +/************************************************************************* + * Prototypes for pkinit asn.1 decode routines + *************************************************************************/ + +krb5_error_code decode_krb5_pa_pk_as_req + (const krb5_data *, krb5_pa_pk_as_req **); + +krb5_error_code decode_krb5_pa_pk_as_req_draft9 + (const krb5_data *, krb5_pa_pk_as_req_draft9 **); + +krb5_error_code decode_krb5_pa_pk_as_rep + (const krb5_data *, krb5_pa_pk_as_rep **); + +krb5_error_code decode_krb5_pa_pk_as_rep_draft9 + (const krb5_data *, krb5_pa_pk_as_rep_draft9 **); + +krb5_error_code decode_krb5_auth_pack + (const krb5_data *, krb5_auth_pack **); + +krb5_error_code decode_krb5_auth_pack_draft9 + (const krb5_data *, krb5_auth_pack_draft9 **); + +krb5_error_code decode_krb5_kdc_dh_key_info + (const krb5_data *, krb5_kdc_dh_key_info **); + +krb5_error_code decode_krb5_principal_name + (const krb5_data *, krb5_principal_data **); + +krb5_error_code decode_krb5_reply_key_pack + (const krb5_data *, krb5_reply_key_pack **); + +krb5_error_code decode_krb5_reply_key_pack_draft9 + (const krb5_data *, krb5_reply_key_pack_draft9 **); + +krb5_error_code decode_krb5_typed_data + (const krb5_data *, krb5_typed_data ***); + +krb5_error_code decode_krb5_td_trusted_certifiers + (const krb5_data *, krb5_external_principal_identifier ***); + +krb5_error_code decode_krb5_td_dh_parameters + (const krb5_data *, krb5_algorithm_identifier ***); + +#endif /* _KRB5_INT_PKINIT_H */ diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 2b9796078..d5a8d4789 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -252,6 +252,23 @@ typedef INT64_TYPE krb5_int64; /* in e-text) */ #define KRB_ERR_FIELD_TOOLONG 61 /* Field is too long for impl. */ +/* PKINIT server-reported errors */ +#define KDC_ERR_CLIENT_NOT_TRUSTED 62 /* client cert not trusted */ +#define KDC_ERR_INVALID_SIG 64 /* client signature verify failed */ +#define KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED 65 /* invalid Diffie-Hellman parameters */ +#define KDC_ERR_CANT_VERIFY_CERTIFICATE 70 /* client cert not verifiable to */ + /* trusted root cert */ +#define KDC_ERR_INVALID_CERTIFICATE 71 /* client cert had invalid signature */ +#define KDC_ERR_REVOKED_CERTIFICATE 72 /* client cert was revoked */ +#define KDC_ERR_REVOCATION_STATUS_UNKNOWN 73 /* client cert revoked, reason unknown */ +#define KDC_ERR_CLIENT_NAME_MISMATCH 75 /* mismatch between client cert and */ + /* principal name */ +#define KDC_ERR_INCONSISTENT_KEY_PURPOSE 77 /* bad extended key use */ +#define KDC_ERR_DIGEST_IN_CERT_NOT_ACCEPTED 78 /* bad digest algorithm in client cert */ +#define KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED 79 /* missing paChecksum in PA-PK-AS-REQ */ +#define KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED 80 /* bad digest algorithm in SignedData */ +#define KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED 81 + #endif /* KRB5_ERRORS__ */ /* * End "k5-errors.h" @@ -417,6 +434,13 @@ typedef struct _krb5_enc_sam_response_enc_2 { } krb5_enc_sam_response_enc_2; /* + * Keep the pkinit definitions in a separate file so that the plugin + * only has to include k5-int-pkinit.h rather than k5-int.h + */ + +#include "k5-int-pkinit.h" + +/* * Begin "ext-proto.h" */ #ifndef KRB5_EXT_PROTO__ @@ -869,54 +893,17 @@ typedef struct _krb5_preauth_context { krb5_enctype *enctypes; /* The plugin's per-plugin context and a function to clear it. */ void *plugin_context; - void (*client_fini)(krb5_context context, void *plugin_context); + preauth_client_plugin_fini_proc client_fini; /* The module's table, and some of its members, copied here for * convenience when we populated the list. */ struct krb5plugin_preauth_client_ftable_v0 *ftable; const char *name; int flags, use_count; - krb5_error_code (*client_process)(krb5_context context, - void *plugin_context, - void *request_context, - krb5_get_init_creds_opt *opt, - preauth_get_client_data_proc get_data_proc, - krb5_preauth_client_rock *rock, - krb5_kdc_req *request, - krb5_data *encoded_request_body, - krb5_data *encoded_previous_request, - krb5_pa_data *pa_data, - krb5_prompter_fct prompter, - void *prompter_data, - preauth_get_as_key_proc gak_fct, - void *gak_data, - krb5_data *salt, - krb5_data *s2kparams, - krb5_keyblock *as_key, - krb5_pa_data **out_pa_data); - krb5_error_code (*client_tryagain)(krb5_context context, - void *plugin_context, - void *request_context, - krb5_get_init_creds_opt *opt, - preauth_get_client_data_proc get_data_proc, - krb5_preauth_client_rock *rock, - krb5_kdc_req *request, - krb5_data *encoded_request_body, - krb5_data *encoded_previous_request, - krb5_pa_data *old_pa_data, - krb5_error *err_reply, - krb5_prompter_fct prompter, - void *prompter_data, - preauth_get_as_key_proc gak_fct, - void *gak_data, - krb5_data *salt, - krb5_data *s2kparams, - krb5_keyblock *as_key, - krb5_pa_data **new_pa_data); - supply_gic_opts_proc client_supply_gic_opts; - void (*client_req_init)(krb5_context context, void *plugin_context, - void **request_context); - void (*client_req_fini)(krb5_context context, void *plugin_context, - void *request_context); + preauth_client_process_proc client_process; + preauth_client_tryagain_proc client_tryagain; + preauth_client_supply_gic_opts_proc client_supply_gic_opts; + preauth_client_request_init_proc client_req_init; + preauth_client_request_fini_proc client_req_fini; /* The per-request context which the client_req_init() function * might allocate, which we'll need to clean up later by * calling the client_req_fini() function. */ @@ -1450,6 +1437,9 @@ krb5_error_code encode_krb5_error krb5_error_code encode_krb5_authdata (const krb5_authdata **rep, krb5_data **code); +krb5_error_code encode_krb5_authdata_elt + (const krb5_authdata *rep, krb5_data **code); + krb5_error_code encode_krb5_pwd_sequence (const passwd_phrase_element *rep, krb5_data **code); @@ -1863,7 +1853,7 @@ void krb5int_free_srv_dns_data(struct srv_dns_entry *); /* To keep happy libraries which are (for now) accessing internal stuff */ /* Make sure to increment by one when changing the struct */ -#define KRB5INT_ACCESS_STRUCT_VERSION 10 +#define KRB5INT_ACCESS_STRUCT_VERSION 11 #ifndef ANAME_SZ struct ktext; /* from krb.h, for krb524 support */ @@ -1919,6 +1909,73 @@ typedef struct _krb5int_access { struct _krb5_key_data **out, krb5_int16 *n_key_data, int *mkvno); + + /* + * pkinit asn.1 encode/decode functions + */ + krb5_error_code (*encode_krb5_auth_pack) + (const krb5_auth_pack *rep, krb5_data **code); + krb5_error_code (*encode_krb5_auth_pack_draft9) + (const krb5_auth_pack_draft9 *rep, krb5_data **code); + krb5_error_code (*encode_krb5_kdc_dh_key_info) + (const krb5_kdc_dh_key_info *rep, krb5_data **code); + krb5_error_code (*encode_krb5_pa_pk_as_rep) + (const krb5_pa_pk_as_rep *rep, krb5_data **code); + krb5_error_code (*encode_krb5_pa_pk_as_rep_draft9) + (const krb5_pa_pk_as_rep_draft9 *rep, krb5_data **code); + krb5_error_code (*encode_krb5_pa_pk_as_req) + (const krb5_pa_pk_as_req *rep, krb5_data **code); + krb5_error_code (*encode_krb5_pa_pk_as_req_draft9) + (const krb5_pa_pk_as_req_draft9 *rep, krb5_data **code); + krb5_error_code (*encode_krb5_reply_key_pack) + (const krb5_reply_key_pack *, krb5_data **code); + krb5_error_code (*encode_krb5_reply_key_pack_draft9) + (const krb5_reply_key_pack_draft9 *, krb5_data **code); + krb5_error_code (*encode_krb5_td_dh_parameters) + (const krb5_algorithm_identifier **, krb5_data **code); + krb5_error_code (*encode_krb5_td_trusted_certifiers) + (const krb5_external_principal_identifier **, krb5_data **code); + krb5_error_code (*encode_krb5_typed_data) + (const krb5_typed_data **, krb5_data **code); + + krb5_error_code (*decode_krb5_auth_pack) + (const krb5_data *, krb5_auth_pack **); + krb5_error_code (*decode_krb5_auth_pack_draft9) + (const krb5_data *, krb5_auth_pack_draft9 **); + krb5_error_code (*decode_krb5_pa_pk_as_req) + (const krb5_data *, krb5_pa_pk_as_req **); + krb5_error_code (*decode_krb5_pa_pk_as_req_draft9) + (const krb5_data *, krb5_pa_pk_as_req_draft9 **); + krb5_error_code (*decode_krb5_pa_pk_as_rep) + (const krb5_data *, krb5_pa_pk_as_rep **); + krb5_error_code (*decode_krb5_pa_pk_as_rep_draft9) + (const krb5_data *, krb5_pa_pk_as_rep_draft9 **); + krb5_error_code (*decode_krb5_kdc_dh_key_info) + (const krb5_data *, krb5_kdc_dh_key_info **); + krb5_error_code (*decode_krb5_principal_name) + (const krb5_data *, krb5_principal_data **); + krb5_error_code (*decode_krb5_reply_key_pack) + (const krb5_data *, krb5_reply_key_pack **); + krb5_error_code (*decode_krb5_reply_key_pack_draft9) + (const krb5_data *, krb5_reply_key_pack_draft9 **); + krb5_error_code (*decode_krb5_td_dh_parameters) + (const krb5_data *, krb5_algorithm_identifier ***); + krb5_error_code (*decode_krb5_td_trusted_certifiers) + (const krb5_data *, krb5_external_principal_identifier ***); + krb5_error_code (*decode_krb5_typed_data) + (const krb5_data *, krb5_typed_data ***); + + krb5_error_code (*decode_krb5_as_req) + (const krb5_data *output, krb5_kdc_req **rep); + krb5_error_code (*encode_krb5_kdc_req_body) + (const krb5_kdc_req *rep, krb5_data **code); + void KRB5_CALLCONV (*krb5_free_kdc_req) + (krb5_context, krb5_kdc_req * ); + void (*krb5int_set_prompt_types) + (krb5_context, krb5_prompt_type *); + krb5_error_code (*encode_krb5_authdata_elt) + (const krb5_authdata *rep, krb5_data **code); + } krb5int_access; #define KRB5INT_ACCESS_VERSION \ diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin index 88154f885..ea5d0fcbb 100644 --- a/src/include/krb5/krb5.hin +++ b/src/include/krb5/krb5.hin @@ -202,6 +202,12 @@ typedef struct _krb5_data { char *data; } krb5_data; +typedef struct _krb5_octet_data { + krb5_magic magic; + unsigned int length; + krb5_octet *data; +} krb5_octet_data; + /* * Hack length for crypto library to use the afs_string_to_key It is * equivalent to -1 without possible sign extension @@ -890,6 +896,11 @@ krb5_error_code KRB5_CALLCONV krb5_verify_checksum #define KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE 64 /* authorization data types */ +#define KRB5_AUTHDATA_IF_RELEVANT 1 +#define KRB5_AUTHDATA_KDC_ISSUED 4 +#define KRB5_AUTHDATA_AND_OR 5 +#define KRB5_AUTHDATA_MANDATORY_FOR_KDC 8 +#define KRB5_AUTHDATA_INITIAL_VERIFIED_CAS 9 #define KRB5_AUTHDATA_OSF_DCE 64 #define KRB5_AUTHDATA_SESAME 65 diff --git a/src/include/krb5/preauth_plugin.h b/src/include/krb5/preauth_plugin.h index 7243a00b1..242956076 100644 --- a/src/include/krb5/preauth_plugin.h +++ b/src/include/krb5/preauth_plugin.h @@ -93,34 +93,30 @@ struct _krb5_preauth_client_rock; * which gets sent over the wire. */ #define PA_PSEUDO 0x00000080 + +/*************************************************************************** + * + * Client-side preauthentication plugin interface definition. + * + ***************************************************************************/ + /* - * A server module's callback functions are allowed to request specific types - * of information about the given client or server record or request, even - * though the database records themselves are opaque to the module. + * A callback which will obtain the user's long-term AS key by prompting the + * user for the password, then salting it properly, and so on. For the moment, + * it's identical to the get_as_key callback used inside of libkrb5, but we + * define a new typedef here instead of making the existing one public to + * isolate ourselves from potential future changes. */ -enum krb5plugin_preauth_entry_request_type { - /* The returned krb5_data item holds a DER-encoded X.509 certificate. */ - krb5plugin_preauth_entry_request_certificate = 1, - /* The returned krb5_data_item holds a krb5_deltat. */ - krb5plugin_preauth_entry_max_time_skew = 2, - /* The returned krb5_data_item holds an array of krb5_keyblock structures, - * terminated by an entry with key type = 0. - * Each keyblock should have its contents freed in turn, and then the data - * item itself should be freed. */ - krb5plugin_preauth_keys = 3, - /* The returned krb5_data_item holds the request structure, re-encoded - * using DER. Unless the client implementation is the same as the server - * implementation, there's a good chance that the result will not match - * what the client sent, so don't go creating any fatal errors if it - * doesn't match up. */ - krb5plugin_preauth_request_body = 4 -}; typedef krb5_error_code -(*preauth_get_entry_data_proc)(krb5_context, - krb5_kdc_req *, - struct _krb5_db_entry_new *, - krb5_int32 request_type, - krb5_data **); +(*preauth_get_as_key_proc)(krb5_context, + krb5_principal, + krb5_enctype, + krb5_prompter_fct, + void *prompter_data, + krb5_data *salt, + krb5_data *s2kparams, + krb5_keyblock *as_key, + void *gak_data); /* * A client module's callback functions are allowed to request various @@ -139,23 +135,92 @@ typedef krb5_error_code krb5_int32 request_type, krb5_data **); -/* - * A callback which will obtain the user's long-term AS key by prompting the - * user for the password, then salting it properly, and so on. For the moment, - * it's identical to the get_as_key callback used inside of libkrb5, but we - * define a new typedef here instead of making the existing one public to - * isolate ourselves from potential future changes. - */ +/* Per-plugin initialization/cleanup. The init function is called + * by libkrb5 when the plugin is loaded, and the fini function is + * called before the plugin is unloaded. Both are optional and + * may be called multiple times in case the plugin is used in + * multiple contexts. The returned context lives the lifetime of + * the krb5_context */ typedef krb5_error_code -(*preauth_get_as_key_proc)(krb5_context, - krb5_principal, - krb5_enctype, - krb5_prompter_fct, - void *prompter_data, - krb5_data *salt, - krb5_data *s2kparams, - krb5_keyblock *as_key, - void *gak_data); +(*preauth_client_plugin_init_proc)(krb5_context context, + void **plugin_context); +typedef void +(*preauth_client_plugin_fini_proc)(krb5_context context, + void *plugin_context); + +/* A callback which returns flags indicating if the module is a "real" or + * an "info" mechanism, and so on. This function is called for each entry + * in the client_pa_type_list. */ +typedef int +(*preauth_client_get_flags_proc)(krb5_context context, + krb5_preauthtype pa_type); + +/* Per-request initialization/cleanup. The request_init function is + * called when beginning to process a get_init_creds request and the + * request_fini function is called when processing of the request is + * complete. This is optional. It may be called multiple times in + * the lifetime of a krb5_context. */ +typedef void +(*preauth_client_request_init_proc)(krb5_context context, + void *plugin_context, + void **request_context); +typedef void +(*preauth_client_request_fini_proc)(krb5_context context, + void *plugin_context, + void *request_context); + +/* Client function which processes server-supplied data in pa_data, + * returns created data in out_pa_data, storing any of its own state in + * client_context if data for the associated preauthentication type is + * needed. It is also called after the AS-REP is received if the AS-REP + * includes preauthentication data of the associated type. + * NOTE! the encoded_previous_request will be NULL the first time this + * function is called, because it is expected to only ever contain the data + * obtained from a previous call to this function. */ +typedef krb5_error_code +(*preauth_client_process_proc)(krb5_context context, + void *plugin_context, + void *request_context, + krb5_get_init_creds_opt *opt, + preauth_get_client_data_proc get_data_proc, + struct _krb5_preauth_client_rock *rock, + krb5_kdc_req *request, + krb5_data *encoded_request_body, + krb5_data *encoded_previous_request, + krb5_pa_data *pa_data, + krb5_prompter_fct prompter, + void *prompter_data, + preauth_get_as_key_proc gak_fct, + void *gak_data, + krb5_data *salt, + krb5_data *s2kparams, + krb5_keyblock *as_key, + krb5_pa_data ***out_pa_data); + +/* Client function which can attempt to use e-data in the error response to + * try to recover from the given error. If this function is not NULL, and + * it stores data in out_pa_data which is different data from the contents + * of in_pa_data, then the client library will retransmit the request. */ +typedef krb5_error_code +(*preauth_client_tryagain_proc)(krb5_context context, + void *plugin_context, + void *request_context, + krb5_get_init_creds_opt *opt, + preauth_get_client_data_proc get_data_proc, + struct _krb5_preauth_client_rock *rock, + krb5_kdc_req *request, + krb5_data *encoded_request_body, + krb5_data *encoded_previous_request, + krb5_pa_data *in_pa_data, + krb5_error *error, + krb5_prompter_fct prompter, + void *prompter_data, + preauth_get_as_key_proc gak_fct, + void *gak_data, + krb5_data *salt, + krb5_data *s2kparams, + krb5_keyblock *as_key, + krb5_pa_data ***out_pa_data); /* * Client function which receives krb5_get_init_creds_opt information. @@ -163,18 +228,19 @@ typedef krb5_error_code * the module if it wishes to reference it after returning from this call. */ typedef krb5_error_code -(*supply_gic_opts_proc)(krb5_context context, - void *plugin_context, - krb5_get_init_creds_opt *opt, - const char *attr, - const char *value); +(*preauth_client_supply_gic_opts_proc)(krb5_context context, + void *plugin_context, + krb5_get_init_creds_opt *opt, + const char *attr, + const char *value); + /* * The function table / structure which a preauth client module must export as * "preauthentication_client_0". If the interfaces work correctly, future * versions of the table will add either more callbacks or more arguments to * callbacks, and in both cases we'll be able to wrap the v0 functions. */ -typedef struct krb5plugin_preauth_client_ftable_v0 { +typedef struct krb5plugin_preauth_client_ftable_v1 { /* Not-usually-visible name. */ char *name; @@ -192,21 +258,22 @@ typedef struct krb5plugin_preauth_client_ftable_v0 { * may be called multiple times in case the plugin is used in * multiple contexts. The returned context lives the lifetime of * the krb5_context */ - krb5_error_code (*init)(krb5_context context, void **plugin_context); - void (*fini)(krb5_context context, void *plugin_context); + preauth_client_plugin_init_proc init; + preauth_client_plugin_fini_proc fini; + /* A callback which returns flags indicating if the module is a "real" or * an "info" mechanism, and so on. This function is called for each entry * in the client_pa_type_list. */ - int (*flags)(krb5_context context, krb5_preauthtype pa_type); + preauth_client_get_flags_proc flags; + /* Per-request initialization/cleanup. The request_init function is * called when beginning to process a get_init_creds request and the * request_fini function is called when processing of the request is * complete. This is optional. It may be called multiple times in * the lifetime of a krb5_context. */ - void (*request_init)(krb5_context context, void *plugin_context, - void **request_context); - void (*request_fini)(krb5_context context, void *plugin_context, - void *request_context); + preauth_client_request_init_proc request_init; + preauth_client_request_fini_proc request_fini; + /* Client function which processes server-supplied data in pa_data, * returns created data in out_pa_data, storing any of its own state in * client_context if data for the associated preauthentication type is @@ -215,52 +282,140 @@ typedef struct krb5plugin_preauth_client_ftable_v0 { * NOTE! the encoded_previous_request will be NULL the first time this * function is called, because it is expected to only ever contain the data * obtained from a previous call to this function. */ - krb5_error_code (*process)(krb5_context context, - void *plugin_context, - void *request_context, - krb5_get_init_creds_opt *opt, - preauth_get_client_data_proc get_data_proc, - struct _krb5_preauth_client_rock *rock, - krb5_kdc_req *request, - krb5_data *encoded_request_body, - krb5_data *encoded_previous_request, - krb5_pa_data *pa_data, - krb5_prompter_fct prompter, - void *prompter_data, - preauth_get_as_key_proc gak_fct, - void *gak_data, - krb5_data *salt, krb5_data *s2kparams, - krb5_keyblock *as_key, - krb5_pa_data **out_pa_data); + preauth_client_process_proc process; + /* Client function which can attempt to use e-data in the error response to * try to recover from the given error. If this function is not NULL, and * it stores data in out_pa_data which is different data from the contents * of in_pa_data, then the client library will retransmit the request. */ - krb5_error_code (*tryagain)(krb5_context context, - void *plugin_context, - void *request_context, - krb5_get_init_creds_opt *opt, - preauth_get_client_data_proc get_data_proc, - struct _krb5_preauth_client_rock *rock, - krb5_kdc_req *request, - krb5_data *encoded_request_body, - krb5_data *encoded_previous_request, - krb5_pa_data *in_pa_data, - krb5_error *error, - krb5_prompter_fct prompter, - void *prompter_data, - preauth_get_as_key_proc gak_fct, - void *gak_data, - krb5_data *salt, krb5_data *s2kparams, - krb5_keyblock *as_key, - krb5_pa_data **out_pa_data); + preauth_client_tryagain_proc tryagain; + /* * Client function which receives krb5_get_init_creds_opt information. * The attr and value information supplied should be copied locally by * the module if it wishes to reference it after returning from this call. */ - supply_gic_opts_proc gic_opts; -} krb5plugin_preauth_client_ftable_v0; + preauth_client_supply_gic_opts_proc gic_opts; + +} krb5plugin_preauth_client_ftable_v1; + + +/*************************************************************************** + * + * Server-side preauthentication plugin interface definition. + * + ***************************************************************************/ + +/* + * A server module's callback functions are allowed to request specific types + * of information about the given client or server record or request, even + * though the database records themselves are opaque to the module. + */ +enum krb5plugin_preauth_entry_request_type { + /* The returned krb5_data item holds a DER-encoded X.509 certificate. */ + krb5plugin_preauth_entry_request_certificate = 1, + /* The returned krb5_data_item holds a krb5_deltat. */ + krb5plugin_preauth_entry_max_time_skew = 2, + /* The returned krb5_data_item holds an array of krb5_keyblock structures, + * terminated by an entry with key type = 0. + * Each keyblock should have its contents freed in turn, and then the data + * item itself should be freed. */ + krb5plugin_preauth_keys = 3, + /* The returned krb5_data_item holds the request structure, re-encoded + * using DER. Unless the client implementation is the same as the server + * implementation, there's a good chance that the result will not match + * what the client sent, so don't go creating any fatal errors if it + * doesn't match up. */ + krb5plugin_preauth_request_body = 4 +}; + +typedef krb5_error_code +(*preauth_get_entry_data_proc)(krb5_context, + krb5_kdc_req *, + struct _krb5_db_entry_new *, + krb5_int32 request_type, + krb5_data **); + +/* Preauth plugin initialization function */ +typedef krb5_error_code +(*preauth_server_init_proc)(krb5_context context, + void **plugin_context, + const char** realmnames); + +/* Preauth plugin cleanup function */ +typedef void +(*preauth_server_fini_proc)(krb5_context context, void *plugin_context); + +/* Return the flags which the KDC should use for this module. This is a + * callback instead of a static value because the module may or may not + * wish to count itself as a hardware preauthentication module (in other + * words, the flags may be affected by the configuration, for example if a + * site administrator can force a particular preauthentication type to be + * supported using only hardware). This function is called for each entry + * entry in the server_pa_type_list. */ +typedef int +(*preauth_server_flags_proc)(krb5_context context, krb5_preauthtype patype); + +/* Get preauthentication data to send to the client as part of the "you + * need to use preauthentication" error. The module doesn't need to + * actually provide data if the protocol doesn't require it, but it should + * return either zero or non-zero to control whether its padata type is + * included in the list which is sent back to the client. Is not allowed + * to create a context because we have no guarantee that the client will + * ever call again (or that it will hit this server if it does), in which + * case a context might otherwise hang around forever. */ +typedef krb5_error_code +(*preauth_server_edata_proc)(krb5_context, + krb5_kdc_req *request, + struct _krb5_db_entry_new *client, + struct _krb5_db_entry_new *server, + preauth_get_entry_data_proc, + void *pa_module_context, + krb5_pa_data *data); + +/* Verify preauthentication data sent by the client, setting the + * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags" + * field as appropriate, and returning nonzero on failure. Can create + * context data for consumption by the return_proc or freepa_proc below. */ +typedef krb5_error_code +(*preauth_server_verify_proc)(krb5_context context, + struct _krb5_db_entry_new *client, + krb5_data *req_pkt, + krb5_kdc_req *request, + krb5_enc_tkt_part *enc_tkt_reply, + krb5_pa_data *data, + preauth_get_entry_data_proc, + void *pa_module_context, + void **pa_request_context, + krb5_data **e_data, + krb5_authdata ***authz_data); + +/* Generate preauthentication response data to send to the client as part + * of the AS-REP. If it needs to override the key which is used to encrypt + * the response, it can do so. The module is expected (but not required, + * if a preauth_server_free_reqcontext_proc is also provided) to free any + * context data it saved in "pa_request_context". */ +typedef krb5_error_code +(*preauth_server_return_proc)(krb5_context context, + krb5_pa_data * padata, + struct _krb5_db_entry_new *client, + krb5_data *req_pkt, + krb5_kdc_req *request, + krb5_kdc_rep *reply, + struct _krb5_key_data *client_keys, + krb5_keyblock *encrypting_key, + krb5_pa_data **send_pa, + preauth_get_entry_data_proc, + void *pa_module_context, + void **pa_request_context); + +/* Free up the server-side per-request context, in cases where + * server_return_proc() didn't or for whatever reason was not called. + * Can be NULL. */ +typedef krb5_error_code +(*preauth_server_free_reqcontext_proc)(krb5_context, + void *pa_module_context, + void **request_pa_context); /* * The function table / structure which a preauth server module must export as @@ -270,7 +425,7 @@ typedef struct krb5plugin_preauth_client_ftable_v0 { * more arguments to callbacks, and in both cases we'll be able to wrap the v0 * functions. */ -typedef struct krb5plugin_preauth_server_ftable_v0 { +typedef struct krb5plugin_preauth_server_ftable_v1 { /* Not-usually-visible name. */ char *name; @@ -281,8 +436,9 @@ typedef struct krb5plugin_preauth_server_ftable_v0 { /* Per-plugin initialization/cleanup. The init function is called by the * KDC when the plugin is loaded, and the fini function is called before * the plugin is unloaded. Both are optional. */ - krb5_error_code (*init_proc)(krb5_context, void **); - void (*fini_proc)(krb5_context, void *); + preauth_server_init_proc init_proc; + preauth_server_fini_proc fini_proc; + /* Return the flags which the KDC should use for this module. This is a * callback instead of a static value because the module may or may not * wish to count itself as a hardware preauthentication module (in other @@ -290,7 +446,8 @@ typedef struct krb5plugin_preauth_server_ftable_v0 { * site administrator can force a particular preauthentication type to be * supported using only hardware). This function is called for each entry * entry in the server_pa_type_list. */ - int (*flags_proc)(krb5_context, krb5_preauthtype); + preauth_server_flags_proc flags_proc; + /* Get preauthentication data to send to the client as part of the "you * need to use preauthentication" error. The module doesn't need to * actually provide data if the protocol doesn't require it, but it should @@ -299,49 +456,27 @@ typedef struct krb5plugin_preauth_server_ftable_v0 { * to create a context because we have no guarantee that the client will * ever call again (or that it will hit this server if it does), in which * case a context might otherwise hang around forever. */ - krb5_error_code (*edata_proc)(krb5_context, krb5_kdc_req *request, - struct _krb5_db_entry_new *client, - struct _krb5_db_entry_new *server, - preauth_get_entry_data_proc, - void *pa_module_context, - krb5_pa_data *data); + preauth_server_edata_proc edata_proc; + /* Verify preauthentication data sent by the client, setting the * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags" * field as appropriate, and returning nonzero on failure. Can create * context data for consumption by the return_proc or freepa_proc below. */ - krb5_error_code (*verify_proc)(krb5_context, - struct _krb5_db_entry_new *client, - krb5_data *req_pkt, - krb5_kdc_req *request, - krb5_enc_tkt_part *enc_tkt_reply, - krb5_pa_data *data, - preauth_get_entry_data_proc, - void *pa_module_context, - void **pa_request_context, - krb5_data **e_data); + preauth_server_verify_proc verify_proc; + /* Generate preauthentication response data to send to the client as part * of the AS-REP. If it needs to override the key which is used to encrypt * the response, it can do so. The module is expected (but not required, * if a freepa_proc is also provided) to free any context data it saved in * "request_pa_context". */ - krb5_error_code (*return_proc)(krb5_context, krb5_pa_data * padata, - struct _krb5_db_entry_new *client, - krb5_data *req_pkt, - krb5_kdc_req *request, - krb5_kdc_rep *reply, - struct _krb5_key_data *client_keys, - krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, - preauth_get_entry_data_proc, - void *pa_module_context, - void **pa_request_context); + preauth_server_return_proc return_proc; + /* Free up the server-side per-request context, in cases where - * server_return_proc() didn't or for whatever reason was not called. Can - * be NULL. */ - krb5_error_code (*freepa_reqcontext_proc)(krb5_context, - void *pa_module_context, - void **request_pa_context); -} krb5plugin_preauth_server_ftable_v0; + * server_return_proc() didn't or for whatever reason was not called. + * Can be NULL. */ + preauth_server_free_reqcontext_proc freepa_reqcontext_proc; + +} krb5plugin_preauth_server_ftable_v1; /* |
