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/krb5/preauth_plugin.h | |
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/krb5/preauth_plugin.h')
-rw-r--r-- | src/include/krb5/preauth_plugin.h | 391 |
1 files changed, 263 insertions, 128 deletions
diff --git a/src/include/krb5/preauth_plugin.h b/src/include/krb5/preauth_plugin.h index 7243a00b17..2429560762 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; /* |