/* This version will be incremented when incompatible changes are made to the
* KDB API, and will be kept in sync with the libkdb major version. */
-#define KRB5_KDB_API_VERSION 5
+#define KRB5_KDB_API_VERSION 6
/* Salt types */
#define KRB5_KDB_SALTTYPE_NORMAL 0
krb5_db_entry *server,
krb5_timestamp kdc_time,
const char **status,
- krb5_data *e_data);
+ krb5_pa_data ***e_data);
krb5_error_code krb5_db_check_policy_tgs(krb5_context kcontext,
krb5_kdc_req *request,
krb5_db_entry *server,
krb5_ticket *ticket,
const char **status,
- krb5_data *e_data);
+ krb5_pa_data ***e_data);
void krb5_db_audit_as_req(krb5_context kcontext, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
* This number indicates the date of the last incompatible change to the DAL.
* The maj_ver field of the module's vtable structure must match this version.
*/
-#define KRB5_KDB_DAL_MAJOR_VERSION 2
+#define KRB5_KDB_DAL_MAJOR_VERSION 3
/*
* A krb5_context can hold one database object. Modules should use
krb5_db_entry *server,
krb5_timestamp kdc_time,
const char **status,
- krb5_data *e_data);
+ krb5_pa_data ***e_data);
/*
* Optional: Perform a policy check on a TGS request, in addition to the
krb5_db_entry *server,
krb5_ticket *ticket,
const char **status,
- krb5_data *e_data);
+ krb5_pa_data ***e_data);
/*
* Optional: This method informs the module of a successful or unsuccessful
*/
#define PA_PSEUDO 0x00000080
+/*
+ * For kdcpreauth mechanisms, indicates that e_data in non-FAST errors should
+ * be encoded as typed data instead of padata.
+ */
+#define PA_TYPED_E_DATA 0x00000100
/*
* clpreauth plugin interface definition.
krb5_pa_data *pa_out);
/*
- * Optional: 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
- * per-request module data for consumption by the return_fn or free_modreq_fn
- * below.
+ * Responder for krb5_kdcpreauth_verify_fn. Invoke with the arg parameter
+ * supplied to verify, the error code (0 for success), an optional module
+ * request state object to be consumed by return_fn or free_modreq_fn, optional
+ * e_data to be passed to the caller if code is nonzero, and optional
+ * authorization data to be included in the ticket. In non-FAST replies,
+ * e_data will be encoded as typed-data if the module sets the PA_TYPED_E_DATA
+ * flag, and as pa-data otherwise. e_data and authz_data will be freed by the
+ * KDC.
*/
typedef void
(*krb5_kdcpreauth_verify_respond_fn)(void *arg, krb5_error_code code,
krb5_kdcpreauth_modreq modreq,
- krb5_data *e_data,
+ krb5_pa_data **e_data,
krb5_authdata **authz_data);
+/*
+ * Optional: 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. The implementation must invoke the respond function
+ * when complete, whether successful or not.
+ */
typedef void
(*krb5_kdcpreauth_verify_fn)(krb5_context context,
struct _krb5_db_entry_new *client,
static krb5_error_code
prepare_error_as(struct kdc_request_state *, krb5_kdc_req *,
- int, krb5_data *, krb5_principal, krb5_data **,
- const char *);
+ int, krb5_pa_data **, krb5_boolean, krb5_principal,
+ krb5_data **, const char *);
/* Determine the key-expiration value according to RFC 4120 section 5.4.2. */
static krb5_timestamp
krb5_db_entry *server;
krb5_kdc_req *request;
const char *status;
- krb5_data e_data;
+ krb5_pa_data **e_data;
+ krb5_boolean typed_e_data;
krb5_kdc_rep reply;
krb5_timestamp kdc_time;
krb5_timestamp authtime;
errcode = KRB_ERR_GENERIC;
errcode = prepare_error_as(state->rstate, state->request,
- errcode, &state->e_data,
+ errcode, state->e_data,
+ state->typed_e_data,
(state->client != NULL) ?
state->client->princ :
NULL,
free(state->ticket_reply.enc_part.ciphertext.data);
}
- krb5_free_data_contents(kdc_context, &state->e_data);
+ krb5_free_pa_data(kdc_context, state->e_data);
kdc_free_rstate(state->rstate);
state->request->kdc_state = NULL;
krb5_free_kdc_req(kdc_context, state->request);
state->client = NULL;
state->server = NULL;
state->request = request;
- state->e_data = empty_data();
+ state->e_data = NULL;
state->authtime = 0;
state->req_pkt = req_pkt;
state->rstate = NULL;
if (state->request->padata) {
check_padata(kdc_context, state->client, state->req_pkt,
state->request, &state->enc_tkt_reply, &state->pa_context,
- &state->e_data, finish_preauth, state);
+ &state->e_data, &state->typed_e_data, finish_preauth,
+ state);
return;
}
finish_process_as_req(state, errcode);
}
-/*
- * If e_data contains a padata or typed data sequence, produce a padata
- * sequence for FAST in *pa_out. If e_data contains neither, set *pa_out to
- * NULL and return successfully.
- */
-static krb5_error_code
-get_error_padata(const krb5_data *e_data, krb5_pa_data ***pa_out)
-{
- krb5_error_code retval;
- krb5_pa_data **pa = NULL, *pad;
- krb5_typed_data **td = NULL;
- size_t size, i;
-
- *pa_out = NULL;
-
- /* Try decoding e_data as padata. */
- retval = decode_krb5_padata_sequence(e_data, &pa);
- if (retval == 0) {
- *pa_out = pa;
- return 0;
- }
-
- /* Try decoding e_data as typed data. If it doesn't decode, assume there
- * is no error padata. */
- retval = decode_krb5_typed_data(e_data, &td);
- if (retval == ENOMEM)
- return retval;
- else if (retval != 0)
- return 0;
-
- /* Convert the typed data to padata. */
- for (size = 0; td[size]; size++);
- pa = k5alloc((size + 1) * sizeof(*pa), &retval);
- if (pa == NULL)
- goto cleanup;
- for (i = 0; i < size; i++) {
- pad = k5alloc(sizeof(*pad), &retval);
- if (pad == NULL)
- goto cleanup;
- pad->pa_type = td[i]->type;
- pad->contents = td[i]->data;
- pad->length = td[i]->length;
- pa[i] = pad;
- td[i]->data = NULL;
- }
-
- *pa_out = pa;
- pa = NULL;
-
-cleanup:
- krb5_free_typed_data(kdc_context, td);
- krb5_free_pa_data(kdc_context, pa);
- return retval;
-}
-
static krb5_error_code
prepare_error_as (struct kdc_request_state *rstate, krb5_kdc_req *request,
- int error, krb5_data *e_data,
+ int error, krb5_pa_data **e_data, krb5_boolean typed_e_data,
krb5_principal canon_client, krb5_data **response,
const char *status)
{
krb5_error errpkt;
krb5_error_code retval;
- krb5_data *scratch = NULL, *fast_edata = NULL;
- krb5_pa_data **pa = NULL;
+ krb5_data *scratch = NULL, *e_data_asn1 = NULL, *fast_edata = NULL;
errpkt.ctime = request->nonce;
errpkt.cusec = 0;
errpkt.server = request->server;
errpkt.client = (error == KRB5KDC_ERR_WRONG_REALM) ? canon_client :
request->client;
- errpkt.e_data = *e_data;
errpkt.text = string2data((char *)status);
- retval = get_error_padata(e_data, &pa);
- if (retval)
- goto cleanup;
- retval = kdc_fast_handle_error(kdc_context, rstate, request, pa, &errpkt,
- &fast_edata);
+ if (e_data != NULL) {
+ if (typed_e_data) {
+ retval = encode_krb5_typed_data((const krb5_typed_data **)e_data,
+ &e_data_asn1);
+ } else
+ retval = encode_krb5_padata_sequence(e_data, &e_data_asn1);
+ if (retval)
+ goto cleanup;
+ errpkt.e_data = *e_data_asn1;
+ } else
+ errpkt.e_data = empty_data();
+
+ retval = kdc_fast_handle_error(kdc_context, rstate, request, e_data,
+ &errpkt, &fast_edata);
if (retval)
goto cleanup;
if (fast_edata != NULL)
errpkt.e_data = *fast_edata;
+
scratch = k5alloc(sizeof(*scratch), &retval);
if (scratch == NULL)
goto cleanup;
scratch = NULL;
cleanup:
- krb5_free_pa_data(kdc_context, pa);
krb5_free_data(kdc_context, fast_edata);
+ krb5_free_data(kdc_context, e_data_asn1);
free(scratch);
return retval;
}
static krb5_error_code
prepare_error_tgs(struct kdc_request_state *, krb5_kdc_req *,krb5_ticket *,int,
- krb5_principal,krb5_data **,const char *, krb5_data *);
+ krb5_principal,krb5_data **,const char *, krb5_pa_data **);
static krb5_int32
prep_reprocess_req(krb5_kdc_req *,krb5_principal *);
struct kdc_request_state *state = NULL;
krb5_pa_data *pa_tgs_req; /*points into request*/
krb5_data scratch;
- krb5_data e_data = empty_data(); /* backend-provided error data */
+ krb5_pa_data **e_data = NULL;
reply.padata = 0; /* For cleanup handler */
reply_encpart.enc_padata = 0;
enc_tkt_reply.authorization_data = NULL;
- e_data.data = NULL;
session_key.contents = NULL;
retval = prepare_error_tgs(state, request, header_ticket, errcode,
(server != NULL) ? server->princ : NULL,
- response, status, &e_data);
+ response, status, e_data);
if (got_err) {
krb5_free_error_message (kdc_context, status);
status = 0;
krb5_free_pa_data(kdc_context, reply_encpart.enc_padata);
if (enc_tkt_reply.authorization_data != NULL)
krb5_free_authdata(kdc_context, enc_tkt_reply.authorization_data);
- krb5_free_data_contents(kdc_context, &e_data);
+ krb5_free_pa_data(kdc_context, e_data);
return retval;
}
krb5_kdc_req *request, krb5_ticket *ticket, int error,
krb5_principal canon_server,
krb5_data **response, const char *status,
- krb5_data *e_data)
+ krb5_pa_data **e_data)
{
krb5_error errpkt;
krb5_error_code retval = 0;
- krb5_data *scratch, *fast_edata = NULL;
+ krb5_data *scratch, *e_data_asn1 = NULL, *fast_edata = NULL;
errpkt.ctime = request->nonce;
errpkt.cusec = 0;
free(errpkt.text.data);
return ENOMEM;
}
- errpkt.e_data = *e_data;
+
+ if (e_data != NULL) {
+ retval = encode_krb5_padata_sequence(e_data, &e_data_asn1);
+ if (retval) {
+ free(scratch);
+ free(errpkt.text.data);
+ return retval;
+ }
+ errpkt.e_data = *e_data_asn1;
+ } else
+ errpkt.e_data = empty_data();
+
if (state) {
- retval = kdc_fast_handle_error(kdc_context, state, request, NULL,
+ retval = kdc_fast_handle_error(kdc_context, state, request, e_data,
&errpkt, &fast_edata);
}
if (retval) {
free(scratch);
free(errpkt.text.data);
+ krb5_free_data(kdc_context, e_data_asn1);
return retval;
}
if (fast_edata)
errpkt.e_data = *fast_edata;
retval = krb5_mk_error(kdc_context, &errpkt, scratch);
free(errpkt.text.data);
+ krb5_free_data(kdc_context, e_data_asn1);
krb5_free_data(kdc_context, fast_edata);
if (retval)
free(scratch);
void
get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
- krb5_db_entry *server, krb5_data *e_data)
+ krb5_db_entry *server, krb5_pa_data ***e_data_out)
{
int hw_only;
preauth_system *ap;
krb5_pa_data **pa_data, **pa;
- krb5_data *edat;
krb5_error_code retval;
- /* Zero these out in case we need to abort */
- e_data->length = 0;
- e_data->data = 0;
+ *e_data_out = NULL;
hw_only = isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH);
/* Allocate two extra entries for the cookie and the terminator. */
* still reasonable to continue with the response
*/
kdc_preauth_get_cookie(request->kdc_state, pa);
- retval = encode_krb5_padata_sequence(pa_data, &edat);
- if (retval)
- goto errout;
- *e_data = *edat;
- free(edat);
+
+ *e_data_out = pa_data;
+ pa_data = NULL;
errout:
krb5_free_pa_data(kdc_context, pa_data);
krb5_kdc_req *request;
krb5_enc_tkt_part *enc_tkt_reply;
void **padata_context;
- krb5_data *e_data;
preauth_system *pa_sys;
- krb5_data *pa_e_data;
+ krb5_pa_data **pa_e_data;
+ krb5_boolean typed_e_data_flag;
int pa_ok;
krb5_error_code saved_code;
+
+ krb5_pa_data ***e_data_out;
+ krb5_boolean *typed_e_data_out;
};
static void
oldrespond = state->respond;
oldarg = state->arg;
- /* Don't bother copying and returning e-data on success */
- if (state->pa_ok && state->pa_e_data != NULL) {
- krb5_free_data(state->context, state->pa_e_data);
- state->pa_e_data = NULL;
- }
-
- /* Return any e-data from the preauth that caused us to exit the loop */
- if (state->pa_e_data != NULL) {
- state->e_data->data = malloc(state->pa_e_data->length);
- if (state->e_data->data == NULL) {
- krb5_free_data(state->context, state->pa_e_data);
- free(state);
- (*oldrespond)(oldarg, KRB5KRB_ERR_GENERIC);
- return;
- }
- memcpy(state->e_data->data, state->pa_e_data->data,
- state->pa_e_data->length);
- state->e_data->length = state->pa_e_data->length;
- krb5_free_data(state->context, state->pa_e_data);
- state->pa_e_data = NULL;
- }
+ if (!state->pa_ok) {
+ /* Return any saved preauth e-data. */
+ *state->e_data_out = state->pa_e_data;
+ *state->typed_e_data_out = state->typed_e_data_flag;
+ } else
+ krb5_free_pa_data(state->context, state->pa_e_data);
if (state->pa_ok) {
free(state);
static void
finish_verify_padata(void *arg, krb5_error_code code,
- krb5_kdcpreauth_modreq modreq, krb5_data *e_data,
+ krb5_kdcpreauth_modreq modreq, krb5_pa_data **e_data,
krb5_authdata **authz_data)
{
struct padata_state *state = arg;
const char *emsg;
+ krb5_boolean typed_e_data_flag;
assert(state);
kdc_active_realm = state->realm; /* Restore the realm. */
authz_data = NULL;
}
+ typed_e_data_flag = ((state->pa_sys->flags & PA_TYPED_E_DATA) != 0);
+
/*
* We'll return edata from either the first PA_REQUIRED module
* that fails, or the first non-PA_REQUIRED module that fails.
if (state->pa_sys->flags & PA_REQUIRED) {
/* free up any previous edata we might have been saving */
if (state->pa_e_data != NULL)
- krb5_free_data(state->context, state->pa_e_data);
+ krb5_free_pa_data(state->context, state->pa_e_data);
state->pa_e_data = e_data;
+ state->typed_e_data_flag = typed_e_data_flag;
/* Make sure we use the current retval */
state->pa_ok = 0;
} else if (state->pa_e_data == NULL) {
/* save the first error code and e-data */
state->pa_e_data = e_data;
+ state->typed_e_data_flag = typed_e_data_flag;
state->saved_code = code;
} else if (e_data != NULL) {
/* discard this extra e-data from non-PA_REQUIRED module */
- krb5_free_data(state->context, e_data);
+ krb5_free_pa_data(state->context, e_data);
}
} else {
#ifdef DEBUG
/* Ignore any edata returned on success */
if (e_data != NULL)
- krb5_free_data(state->context, e_data);
+ krb5_free_pa_data(state->context, e_data);
/* Add any authorization data to the ticket */
if (authz_data != NULL) {
void
check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
- void **padata_context, krb5_data *e_data,
- kdc_preauth_respond_fn respond, void *arg)
+ void **padata_context, krb5_pa_data ***e_data,
+ krb5_boolean *typed_e_data, kdc_preauth_respond_fn respond,
+ void *arg)
{
struct padata_state *state;
state->request = request;
state->enc_tkt_reply = enc_tkt_reply;
state->padata_context = padata_context;
- state->e_data = e_data;
+ state->e_data_out = e_data;
+ state->typed_e_data_out = typed_e_data;
state->realm = kdc_active_realm;
#ifdef DEBUG
int
validate_as_request(register krb5_kdc_req *request, krb5_db_entry client,
krb5_db_entry server, krb5_timestamp kdc_time,
- const char **status, krb5_data *e_data)
+ const char **status, krb5_pa_data ***e_data)
{
int errcode;
krb5_error_code ret;
int
validate_tgs_request(register krb5_kdc_req *request, krb5_db_entry server,
krb5_ticket *ticket, krb5_timestamp kdc_time,
- const char **status, krb5_data *e_data)
+ const char **status, krb5_pa_data ***e_data)
{
int errcode;
int st_idx = 0;
*/
if (is_local_principal((*s4u_x509_user)->user_id.user)) {
krb5_db_entry no_server;
- krb5_data e_data;
+ krb5_pa_data **e_data = NULL;
- e_data.data = NULL;
code = krb5_db_get_principal(context, (*s4u_x509_user)->user_id.user,
KRB5_KDB_FLAG_INCLUDE_PAC, &princ);
if (code == KRB5_KDB_NOENTRY) {
no_server, kdc_time, status, &e_data);
if (code) {
krb5_db_free_principal(context, princ);
- krb5_free_data_contents(context, &e_data);
+ krb5_free_pa_data(context, e_data);
return code;
}
int
validate_as_request (krb5_kdc_req *, krb5_db_entry,
krb5_db_entry, krb5_timestamp,
- const char **, krb5_data *);
+ const char **, krb5_pa_data ***);
int
validate_forwardable(krb5_kdc_req *, krb5_db_entry,
int
validate_tgs_request (krb5_kdc_req *, krb5_db_entry,
krb5_ticket *, krb5_timestamp,
- const char **, krb5_data *);
+ const char **, krb5_pa_data ***);
int
fetch_asn1_field (unsigned char *, unsigned int, unsigned int, krb5_data *);
int
against_local_policy_as (krb5_kdc_req *, krb5_db_entry,
krb5_db_entry, krb5_timestamp,
- const char **, krb5_data *);
+ const char **, krb5_pa_data ***);
int
against_local_policy_tgs (krb5_kdc_req *, krb5_db_entry,
krb5_ticket *, const char **,
- krb5_data *);
+ krb5_pa_data ***);
/* kdc_preauth.c */
krb5_boolean
get_preauth_hint_list (krb5_kdc_req * request,
krb5_db_entry *client,
krb5_db_entry *server,
- krb5_data *e_data);
+ krb5_pa_data ***e_data_out);
void
load_preauth_plugins(krb5_context context);
void
typedef void (*kdc_preauth_respond_fn)(void *arg, krb5_error_code code);
void
-check_padata (krb5_context context,
- krb5_db_entry *client, krb5_data *req_pkt,
- krb5_kdc_req *request,
- krb5_enc_tkt_part *enc_tkt_reply,
- void **padata_context, krb5_data *e_data,
- kdc_preauth_respond_fn respond, void *state);
+check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
+ krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
+ void **padata_context, krb5_pa_data ***e_data,
+ krb5_boolean *typed_e_data, kdc_preauth_respond_fn respond,
+ void *state);
krb5_error_code
return_padata (krb5_context context, krb5_db_entry *client,
int
against_local_policy_as(register krb5_kdc_req *request, krb5_db_entry client,
krb5_db_entry server, krb5_timestamp kdc_time,
- const char **status, krb5_data *e_data)
+ const char **status, krb5_pa_data ***e_data)
{
#if 0
/* An AS request must include the addresses field */
krb5_error_code
against_local_policy_tgs(register krb5_kdc_req *request, krb5_db_entry server,
krb5_ticket *ticket, const char **status,
- krb5_data *e_data)
+ krb5_pa_data ***e_data)
{
#if 0
/*
# Keep LIBMAJOR in sync with KRB5_KDB_API_VERSION in include/kdb.h.
LIBBASE=kdb5
-LIBMAJOR=5
+LIBMAJOR=6
LIBMINOR=0
LIBINITFUNC=kdb_init_lock_list
LIBFINIFUNC=kdb_fini_lock_list
krb5_db_check_policy_as(krb5_context kcontext, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp kdc_time, const char **status,
- krb5_data *e_data)
+ krb5_pa_data ***e_data)
{
krb5_error_code ret;
kdb_vftabl *v;
*status = NULL;
- *e_data = empty_data();
+ *e_data = NULL;
ret = get_vftabl(kcontext, &v);
if (ret)
return ret;
krb5_error_code
krb5_db_check_policy_tgs(krb5_context kcontext, krb5_kdc_req *request,
krb5_db_entry *server, krb5_ticket *ticket,
- const char **status, krb5_data *e_data)
+ const char **status, krb5_pa_data ***e_data)
{
krb5_error_code ret;
kdb_vftabl *v;
*status = NULL;
- *e_data = empty_data();
+ *e_data = NULL;
ret = get_vftabl(kcontext, &v);
if (ret)
return ret;
encode_krb5_tgs_rep
encode_krb5_tgs_req
encode_krb5_ticket
+encode_krb5_typed_data
et_asn1_error_table
et_k524_error_table
et_kdb5_error_table
krb5_db2_check_policy_as(krb5_context kcontext, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp kdc_time, const char **status,
- krb5_data *e_data)
+ krb5_pa_data ***e_data)
{
krb5_error_code retval;
krb5_db2_check_policy_as(krb5_context kcontext, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp kdc_time, const char **status,
- krb5_data *e_data);
+ krb5_pa_data ***e_data);
void
krb5_db2_audit_as_req(krb5_context kcontext, krb5_kdc_req *request,
krb5_db_entry *server,
krb5_timestamp kdc_time,
const char **status,
- krb5_data *e_data);
+ krb5_pa_data ***e_data);
krb5_error_code
kh_hdb_windc_init(krb5_context context,
krb5_db_entry *server,
krb5_timestamp kdc_time,
const char **status,
- krb5_data *e_data)
+ krb5_pa_data ***e_data_out)
{
kh_db_context *kh = KH_DB_CONTEXT(context);
krb5_error_code code;
+ krb5_data d;
+ krb5_pa_data **e_data;
heim_octet_string he_data;
KDC_REQ hkdcreq;
Principal *hclient = NULL;
KH_DB_ENTRY(client),
&hkdcreq, &he_data);
- e_data->data = he_data.data;
- e_data->length = he_data.length;
+ if (he_data.data != NULL) {
+ d = make_data(he_data.data, he_data.length);
+ code = decode_krb5_padata_sequence(&d, &e_data);
+ if (code == 0)
+ *e_data_out = e_data;
+ free(he_data.data);
+ code = 0;
+ }
cleanup:
kh_free_HostAddresses(context, hkdcreq.req_body.addresses);
krb5_ldap_check_policy_as(krb5_context kcontext, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp kdc_time, const char **status,
- krb5_data *e_data)
+ krb5_pa_data ***e_data)
{
krb5_error_code retval;
krb5_ldap_check_policy_as(krb5_context kcontext, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp kdc_time, const char **status,
- krb5_data *e_data);
+ krb5_pa_data ***e_data);
void
krb5_ldap_audit_as_req(krb5_context kcontext, krb5_kdc_req *request,
void init_krb5_auth_pack_draft9(krb5_auth_pack_draft9 **in);
void init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in);
void init_krb5_pa_pk_as_rep_draft9(krb5_pa_pk_as_rep_draft9 **in);
-void init_krb5_typed_data(krb5_typed_data **in);
void init_krb5_subject_pk_info(krb5_subject_pk_info **in);
void free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
pkinit_req_crypto_context req_cryptoctx, /* IN */
pkinit_identity_crypto_context id_cryptoctx, /* IN */
pkinit_plg_opts *opts, /* IN */
- krb5_data **edata); /* OUT */
+ krb5_pa_data ***e_data_out); /* OUT */
/*
* this function processes edata that contains TD-DH-PARAMETERS.
pkinit_plg_crypto_context plg_cryptoctx, /* IN */
pkinit_req_crypto_context req_cryptoctx, /* IN */
pkinit_identity_crypto_context id_cryptoctx, /* IN */
- krb5_data **edata); /* OUT */
+ krb5_pa_data ***e_data_out); /* OUT */
/*
* this function creates edata that contains TD-TRUSTED-CERTIFIERS
pkinit_plg_crypto_context plg_cryptoctx, /* IN */
pkinit_req_crypto_context req_cryptoctx, /* IN */
pkinit_identity_crypto_context id_cryptoctx, /* IN */
- krb5_data **edata); /* OUT */
+ krb5_pa_data ***e_data_out); /* OUT */
/*
* this function processes edata that contains either
(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx,
pkinit_req_crypto_context req_cryptoctx,
pkinit_identity_crypto_context id_cryptoctx,
- int type, krb5_data **out_data);
+ int type, krb5_pa_data ***e_data_out);
#ifndef WITHOUT_PKCS11
static krb5_error_code pkinit_find_private_key
pkinit_req_crypto_context req_cryptoctx,
pkinit_identity_crypto_context id_cryptoctx,
int type,
- krb5_data **out_data)
+ krb5_pa_data ***e_data_out)
{
krb5_error_code retval = KRB5KRB_ERR_GENERIC;
krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
- krb5_data *td_certifiers = NULL, *data = NULL;
- krb5_typed_data **typed_data = NULL;
+ krb5_data *td_certifiers = NULL;
+ krb5_pa_data **pa_data = NULL;
switch(type) {
case TD_TRUSTED_CERTIFIERS:
print_buffer_bin((unsigned char *)td_certifiers->data,
td_certifiers->length, "/tmp/kdc_td_certifiers");
#endif
- typed_data = malloc(2 * sizeof(krb5_typed_data *));
- if (typed_data == NULL) {
+ pa_data = malloc(2 * sizeof(krb5_pa_data *));
+ if (pa_data == NULL) {
retval = ENOMEM;
goto cleanup;
}
- typed_data[1] = NULL;
- init_krb5_typed_data(&typed_data[0]);
- if (typed_data[0] == NULL) {
+ pa_data[1] = NULL;
+ pa_data[0] = malloc(sizeof(krb5_pa_data));
+ if (pa_data[0] == NULL) {
retval = ENOMEM;
goto cleanup;
}
- typed_data[0]->type = type;
- typed_data[0]->length = td_certifiers->length;
- typed_data[0]->data = (unsigned char *)td_certifiers->data;
- retval = k5int_encode_krb5_typed_data((const krb5_typed_data **)typed_data,
- &data);
- if (retval) {
- pkiDebug("encode_krb5_typed_data failed\n");
- goto cleanup;
- }
-#ifdef DEBUG_ASN1
- print_buffer_bin((unsigned char *)data->data, data->length,
- "/tmp/kdc_edata");
-#endif
- *out_data = malloc(sizeof(krb5_data));
- (*out_data)->length = data->length;
- (*out_data)->data = malloc(data->length);
- memcpy((*out_data)->data, data->data, data->length);
-
+ pa_data[0]->pa_type = type;
+ pa_data[0]->length = td_certifiers->length;
+ pa_data[0]->contents = (krb5_octet *)td_certifiers->data;
+ *e_data_out = pa_data;
retval = 0;
cleanup:
if (krb5_trusted_certifiers != NULL)
free_krb5_external_principal_identifier(&krb5_trusted_certifiers);
-
- if (data != NULL) {
- free(data->data);
- free(data);
- }
-
free(td_certifiers);
- free_krb5_typed_data(&typed_data);
-
return retval;
}
pkinit_plg_crypto_context plg_cryptoctx,
pkinit_req_crypto_context req_cryptoctx,
pkinit_identity_crypto_context id_cryptoctx,
- krb5_data **out_data)
+ krb5_pa_data ***e_data_out)
{
krb5_error_code retval = KRB5KRB_ERR_GENERIC;
retval = pkinit_create_sequence_of_principal_identifiers(context,
plg_cryptoctx, req_cryptoctx, id_cryptoctx,
- TD_TRUSTED_CERTIFIERS, out_data);
+ TD_TRUSTED_CERTIFIERS, e_data_out);
return retval;
}
pkinit_plg_crypto_context plg_cryptoctx,
pkinit_req_crypto_context req_cryptoctx,
pkinit_identity_crypto_context id_cryptoctx,
- krb5_data **out_data)
+ krb5_pa_data ***e_data_out)
{
krb5_error_code retval = KRB5KRB_ERR_GENERIC;
retval = pkinit_create_sequence_of_principal_identifiers(context,
plg_cryptoctx, req_cryptoctx, id_cryptoctx,
- TD_INVALID_CERTIFICATES, out_data);
+ TD_INVALID_CERTIFICATES, e_data_out);
return retval;
}
pkinit_req_crypto_context req_cryptoctx,
pkinit_identity_crypto_context id_cryptoctx,
pkinit_plg_opts *opts,
- krb5_data **out_data)
+ krb5_pa_data ***e_data_out)
{
krb5_error_code retval = ENOMEM;
unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0;
unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
- krb5_typed_data **typed_data = NULL;
- krb5_data *data = NULL, *encoded_algId = NULL;
+ krb5_pa_data **pa_data = NULL;
+ krb5_data *encoded_algId = NULL;
krb5_algorithm_identifier **algId = NULL;
if (opts->dh_min_bits > 4096)
print_buffer_bin((unsigned char *)encoded_algId->data,
encoded_algId->length, "/tmp/kdc_td_dh_params");
#endif
- typed_data = malloc(2 * sizeof(krb5_typed_data *));
- if (typed_data == NULL) {
+ pa_data = malloc(2 * sizeof(krb5_pa_data *));
+ if (pa_data == NULL) {
retval = ENOMEM;
goto cleanup;
}
- typed_data[1] = NULL;
- init_krb5_typed_data(&typed_data[0]);
- if (typed_data == NULL) {
+ pa_data[1] = NULL;
+ pa_data[0] = malloc(sizeof(krb5_pa_data));
+ if (pa_data[0] == NULL) {
retval = ENOMEM;
goto cleanup;
}
- typed_data[0]->type = TD_DH_PARAMETERS;
- typed_data[0]->length = encoded_algId->length;
- typed_data[0]->data = (unsigned char *)encoded_algId->data;
- retval = k5int_encode_krb5_typed_data((const krb5_typed_data**)typed_data,
- &data);
- if (retval) {
- pkiDebug("encode_krb5_typed_data failed\n");
- goto cleanup;
- }
-#ifdef DEBUG_ASN1
- print_buffer_bin((unsigned char *)data->data, data->length,
- "/tmp/kdc_edata");
-#endif
- *out_data = malloc(sizeof(krb5_data));
- if (*out_data == NULL)
- goto cleanup;
- (*out_data)->length = data->length;
- (*out_data)->data = malloc(data->length);
- if ((*out_data)->data == NULL) {
- free(*out_data);
- *out_data = NULL;
- goto cleanup;
- }
- memcpy((*out_data)->data, data->data, data->length);
-
+ pa_data[0]->pa_type = TD_DH_PARAMETERS;
+ pa_data[0]->length = encoded_algId->length;
+ pa_data[0]->contents = (krb5_octet *)encoded_algId->data;
+ *e_data_out = pa_data;
retval = 0;
cleanup:
free(buf1);
free(buf2);
free(buf3);
- if (data != NULL) {
- free(data->data);
- free(data);
- }
- free_krb5_typed_data(&typed_data);
free(encoded_algId);
if (algId != NULL) {
(*in)->u.encKeyPack.data = NULL;
}
-void
-init_krb5_typed_data(krb5_typed_data **in)
-{
- (*in) = malloc(sizeof(krb5_typed_data));
- if ((*in) == NULL) return;
- (*in)->type = 0;
- (*in)->length = 0;
- (*in)->data = NULL;
-}
-
void
init_krb5_subject_pk_info(krb5_subject_pk_info **in)
{
pkinit_identity_crypto_context id_cryptoctx,
pkinit_plg_opts *opts,
krb5_error_code err_code,
- krb5_data **e_data)
+ krb5_pa_data ***e_data_out)
{
krb5_error_code retval = KRB5KRB_ERR_GENERIC;
switch(err_code) {
case KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE:
retval = pkinit_create_td_trusted_certifiers(context,
- plg_cryptoctx, req_cryptoctx, id_cryptoctx, e_data);
+ plg_cryptoctx, req_cryptoctx, id_cryptoctx, e_data_out);
break;
case KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED:
retval = pkinit_create_td_dh_parameters(context, plg_cryptoctx,
- req_cryptoctx, id_cryptoctx, opts, e_data);
+ req_cryptoctx, id_cryptoctx, opts, e_data_out);
break;
case KRB5KDC_ERR_INVALID_CERTIFICATE:
case KRB5KDC_ERR_REVOKED_CERTIFICATE:
retval = pkinit_create_td_invalid_certificate(context,
- plg_cryptoctx, req_cryptoctx, id_cryptoctx, e_data);
+ plg_cryptoctx, req_cryptoctx, id_cryptoctx, e_data_out);
break;
default:
pkiDebug("no edata needed for error %d (%s)\n",
krb5_data k5data;
int is_signed = 1;
krb5_keyblock *armor_key;
- krb5_data *e_data = NULL;
+ krb5_pa_data **e_data = NULL;
krb5_kdcpreauth_modreq modreq = NULL;
pkiDebug("pkinit_verify_padata: entered!\n");
{
if (patype == KRB5_PADATA_PKINIT_KX)
return PA_INFO;
- return PA_SUFFICIENT | PA_REPLACES_KEY;
+ return PA_SUFFICIENT | PA_REPLACES_KEY | PA_TYPED_E_DATA;
}
static krb5_preauthtype supported_server_pa_types[] = {