summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorKevin Coffman <kwc@citi.umich.edu>2007-08-01 22:09:13 +0000
committerKevin Coffman <kwc@citi.umich.edu>2007-08-01 22:09:13 +0000
commit0ef0646069c1d1376aa632a4791ea7e429f5ae9b (patch)
tree5b9f842dc45a9a14d5698a6f3ff321cea612d7c5 /src/include
parent101446c6f40a13917fd0ba020bc276e82590058d (diff)
downloadkrb5-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.h270
-rw-r--r--src/include/k5-int.h145
-rw-r--r--src/include/krb5/krb5.hin11
-rw-r--r--src/include/krb5/preauth_plugin.h391
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;
/*