aboutsummaryrefslogtreecommitdiff
path: root/src/lib
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/lib
parent101446c6f40a13917fd0ba020bc276e82590058d (diff)
downloadkrb5-0ef0646069c1d1376aa632a4791ea7e429f5ae9b.zip
krb5-0ef0646069c1d1376aa632a4791ea7e429f5ae9b.tar.gz
krb5-0ef0646069c1d1376aa632a4791ea7e429f5ae9b.tar.bz2
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/lib')
-rw-r--r--src/lib/krb5/asn.1/asn1_k_decode.c453
-rw-r--r--src/lib/krb5/asn.1/asn1_k_decode.h45
-rw-r--r--src/lib/krb5/asn.1/asn1_k_encode.c434
-rw-r--r--src/lib/krb5/asn.1/asn1_k_encode.h67
-rw-r--r--src/lib/krb5/asn.1/krb5_decode.c147
-rw-r--r--src/lib/krb5/asn.1/krb5_encode.c125
-rw-r--r--src/lib/krb5/krb/preauth2.c57
-rw-r--r--src/lib/krb5/os/accessor.c29
8 files changed, 1335 insertions, 22 deletions
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c
index 6c20147..33b0f17 100644
--- a/src/lib/krb5/asn.1/asn1_k_decode.c
+++ b/src/lib/krb5/asn.1/asn1_k_decode.c
@@ -160,6 +160,28 @@
} else { len = 0; var = 0; }
/*
+ * Deal with implicitly tagged fields
+ */
+#define get_implicit_octet_string(len, var, tagexpect) \
+ if (tagnum != (tagexpect)) return ASN1_MISSING_FIELD; \
+ if (asn1class != CONTEXT_SPECIFIC || construction != PRIMITIVE) \
+ return ASN1_BAD_ID; \
+ retval = asn1buf_remove_octetstring(&subbuf, taglen, &(var)); \
+ if (retval) return retval; \
+ (len) = taglen; \
+ next_tag()
+
+#define opt_implicit_octet_string(len, var, tagexpect) \
+ if (tagnum == (tagexpect)) { \
+ if (asn1class != CONTEXT_SPECIFIC || construction != PRIMITIVE) \
+ return ASN1_BAD_ID; \
+ retval = asn1buf_remove_octetstring(&subbuf, taglen, &(var)); \
+ if (retval) return retval; \
+ (len) = taglen; \
+ next_tag(); \
+ } else { (len) = 0; (var) = NULL; }
+
+/*
* begin_structure
*
* Declares some variables for decoding SEQUENCE types. This is meant
@@ -176,6 +198,22 @@
if (retval) return retval; \
next_tag()
+/*
+ * This is used for structures which have no tagging.
+ * It is the same as begin_structure() except next_tag()
+ * is not called.
+ */
+#define begin_structure_no_tag() \
+ asn1buf subbuf; \
+ int seqindef; \
+ int indef; \
+ unused_var(taglen); \
+ unused_var(construction); \
+ retval = asn1_get_sequence(buf, &length, &seqindef); \
+ if (retval) return retval; \
+ retval = asn1buf_imbed(&subbuf, buf, length, seqindef); \
+ if (retval) return retval
+
/* skip trailing garbage */
#define end_structure() \
retval = asn1buf_sync(buf, &subbuf, asn1class, tagnum, \
@@ -183,6 +221,37 @@
if (retval) return retval
/*
+ * begin_choice
+ *
+ * Declares some variables for decoding CHOICE types. This is meant
+ * to be called in an inner block that ends with a call to
+ * end_choice().
+ */
+#define begin_choice() \
+ asn1buf subbuf; \
+ int seqindef; \
+ int indef; \
+ taginfo t; \
+ retval = asn1_get_tag_2(buf, &t); \
+ if (retval) return retval; \
+ tagnum = t.tagnum; \
+ taglen = t.length; \
+ indef = t.indef; \
+ length = t.length; \
+ seqindef = t.indef; \
+ asn1class = t.asn1class; \
+ construction = t.construction; \
+ retval = asn1buf_imbed(&subbuf, buf, length, seqindef); \
+ if (retval) return retval
+
+/* skip trailing garbage */
+#define end_choice() \
+ length -= t.length; \
+ retval = asn1buf_sync(buf, &subbuf, t.asn1class, t.tagnum, \
+ length, t.indef, seqindef); \
+ if (retval) return retval
+
+/*
* sequence_of
*
* Declares some variables for decoding SEQUENCE OF types. This is
@@ -1094,3 +1163,387 @@ asn1_error_code asn1_decode_predicted_sam_response(asn1buf *buf, krb5_predicted_
}
cleanup();
}
+
+/* PKINIT */
+
+asn1_error_code asn1_decode_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier *val)
+{
+ setup();
+ {
+ begin_structure();
+ opt_implicit_octet_string(val->subjectName.length, val->subjectName.data, 0);
+ opt_implicit_octet_string(val->issuerAndSerialNumber.length, val->issuerAndSerialNumber.data, 1);
+ opt_implicit_octet_string(val->subjectKeyIdentifier.length, val->subjectKeyIdentifier.data, 2);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_sequence_of_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier ***val)
+{
+ decode_array_body(krb5_external_principal_identifier,asn1_decode_external_principal_identifier);
+}
+
+asn1_error_code asn1_decode_pa_pk_as_req(asn1buf *buf, krb5_pa_pk_as_req *val)
+{
+ setup();
+ {
+ begin_structure();
+ get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0);
+ opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_external_principal_identifier, NULL);
+ opt_implicit_octet_string(val->kdcPkId.length, val->kdcPkId.data, 2);
+ end_structure();
+ }
+ cleanup();
+}
+
+#if 0 /* XXX This needs to be tested!!! XXX */
+asn1_error_code asn1_decode_trusted_ca(asn1buf *buf, krb5_trusted_ca *val)
+{
+ setup();
+ {
+ char *start, *end;
+ size_t alloclen;
+
+ begin_explicit_choice();
+ if (t.tagnum == choice_trusted_cas_principalName) {
+ val->choice = choice_trusted_cas_principalName;
+ } else if (t.tagnum == choice_trusted_cas_caName) {
+ val->choice = choice_trusted_cas_caName;
+ start = subbuf.next;
+ {
+ sequence_of_no_tagvars(&subbuf);
+ unused_var(size);
+ end_sequence_of_no_tagvars(&subbuf);
+ }
+ end = subbuf.next;
+ alloclen = end - start;
+ val->u.caName.data = malloc(alloclen);
+ if (val->u.caName.data == NULL)
+ return ENOMEM;
+ memcpy(val->u.caName.data, start, alloclen);
+ val->u.caName.length = alloclen;
+ next_tag();
+ } else if (t.tagnum == choice_trusted_cas_issuerAndSerial) {
+ val->choice = choice_trusted_cas_issuerAndSerial;
+ start = subbuf.next;
+ {
+ sequence_of_no_tagvars(&subbuf);
+ unused_var(size);
+ end_sequence_of_no_tagvars(&subbuf);
+ }
+ end = subbuf.next;
+ alloclen = end - start;
+ val->u.issuerAndSerial.data = malloc(alloclen);
+ if (val->u.issuerAndSerial.data == NULL)
+ return ENOMEM;
+ memcpy(val->u.issuerAndSerial.data, start, alloclen);
+ val->u.issuerAndSerial.length = alloclen;
+ next_tag();
+ } else return ASN1_BAD_ID;
+ end_explicit_choice();
+ }
+ cleanup();
+}
+#else
+asn1_error_code asn1_decode_trusted_ca(asn1buf *buf, krb5_trusted_ca *val)
+{
+ setup();
+ { begin_choice();
+ if (tagnum == choice_trusted_cas_principalName) {
+ val->choice = choice_trusted_cas_principalName;
+ asn1_decode_krb5_principal_name(&subbuf, &(val->u.principalName));
+ } else if (tagnum == choice_trusted_cas_caName) {
+ val->choice = choice_trusted_cas_caName;
+ get_implicit_octet_string(val->u.caName.length, val->u.caName.data, choice_trusted_cas_caName);
+ } else if (tagnum == choice_trusted_cas_issuerAndSerial) {
+ val->choice = choice_trusted_cas_issuerAndSerial;
+ get_implicit_octet_string(val->u.issuerAndSerial.length, val->u.issuerAndSerial.data,
+ choice_trusted_cas_issuerAndSerial);
+ } else return ASN1_BAD_ID;
+ end_choice();
+ }
+ cleanup();
+}
+#endif
+
+asn1_error_code asn1_decode_sequence_of_trusted_ca(asn1buf *buf, krb5_trusted_ca ***val)
+{
+ decode_array_body(krb5_trusted_ca, asn1_decode_trusted_ca);
+}
+
+asn1_error_code asn1_decode_pa_pk_as_req_draft9(asn1buf *buf, krb5_pa_pk_as_req_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0);
+ opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_trusted_ca, NULL);
+ opt_lenfield(val->kdcCert.length, val->kdcCert.data, 2, asn1_decode_octetstring);
+ opt_lenfield(val->encryptionCert.length, val->encryptionCert.data, 2, asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_dh_rep_info(asn1buf *buf, krb5_dh_rep_info *val)
+{
+ setup();
+ { begin_structure();
+ get_implicit_octet_string(val->dhSignedData.length, val->dhSignedData.data, 0);
+
+ opt_lenfield(val->serverDHNonce.length, val->serverDHNonce.data, 1, asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_pk_authenticator(asn1buf *buf, krb5_pk_authenticator *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->cusec, 0, asn1_decode_int32);
+ get_field(val->ctime, 1, asn1_decode_kerberos_time);
+ get_field(val->nonce, 2, asn1_decode_int32);
+ opt_lenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_pk_authenticator_draft9(asn1buf *buf, krb5_pk_authenticator_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ alloc_field(val->kdcName,krb5_principal_data);
+ get_field(val->kdcName, 0, asn1_decode_principal_name);
+ get_field(val->kdcName, 1, asn1_decode_realm);
+ get_field(val->cusec, 2, asn1_decode_int32);
+ get_field(val->ctime, 3, asn1_decode_kerberos_time);
+ get_field(val->nonce, 4, asn1_decode_int32);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_algorithm_identifier(asn1buf *buf, krb5_algorithm_identifier *val) {
+
+ setup();
+ { begin_structure_no_tag();
+ retval = asn1_decode_oid(&subbuf, &val->algorithm.length,
+ &val->algorithm.data);
+ if(retval) return retval;
+ val->parameters.length = 0;
+ val->parameters.data = NULL;
+
+ if(length > subbuf.next - subbuf.base) {
+ unsigned int size = length - (subbuf.next - subbuf.base);
+ retval = asn1buf_remove_octetstring(&subbuf, size,
+ &val->parameters.data);
+ if(retval) return retval;
+ val->parameters.length = size;
+ }
+
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_subject_pk_info(asn1buf *buf, krb5_subject_pk_info *val)
+{
+ asn1_octet unused;
+ setup();
+ { begin_structure_no_tag();
+
+ retval = asn1_decode_algorithm_identifier(&subbuf, &val->algorithm);
+ if (retval) return retval;
+
+ /* SubjectPublicKey encoded as a BIT STRING */
+ next_tag();
+ if (asn1class != UNIVERSAL || construction != PRIMITIVE ||
+ tagnum != ASN1_BITSTRING)
+ return ASN1_BAD_ID;
+
+ retval = asn1buf_remove_octet(&subbuf, &unused);
+ if(retval) return retval;
+
+ /* Number of unused bits must be between 0 and 7. */
+ /* What to do if unused is not zero? */
+ if (unused > 7) return ASN1_BAD_FORMAT;
+ taglen--;
+
+ val->subjectPublicKey.length = 0;
+ val->subjectPublicKey.data = NULL;
+ retval = asn1buf_remove_octetstring(&subbuf, taglen,
+ &val->subjectPublicKey.data);
+ if(retval) return retval;
+ val->subjectPublicKey.length = taglen;
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_sequence_of_algorithm_identifier(asn1buf *buf, krb5_algorithm_identifier ***val)
+{
+ decode_array_body(krb5_algorithm_identifier, asn1_decode_algorithm_identifier);
+}
+
+asn1_error_code asn1_decode_kdc_dh_key_info (asn1buf *buf, krb5_kdc_dh_key_info *val)
+{
+ setup();
+ { begin_structure();
+ retval = asn1buf_remove_octetstring(&subbuf, taglen, &val->subjectPublicKey.data);
+ if(retval) return retval;
+ val->subjectPublicKey.length = taglen;
+ next_tag();
+ get_field(val->nonce, 1, asn1_decode_int32);
+ opt_field(val->dhKeyExpiration, 2, asn1_decode_kerberos_time, 0);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_reply_key_pack (asn1buf *buf, krb5_reply_key_pack *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->replyKey, 0, asn1_decode_encryption_key);
+ get_field(val->asChecksum, 1, asn1_decode_checksum);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_reply_key_pack_draft9 (asn1buf *buf, krb5_reply_key_pack_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->replyKey, 0, asn1_decode_encryption_key);
+ get_field(val->nonce, 1, asn1_decode_int32);
+ end_structure();
+ }
+ cleanup();
+}
+
+
+asn1_error_code asn1_decode_krb5_principal_name (asn1buf *buf, krb5_principal *val)
+{
+ setup();
+ { begin_structure();
+ get_field(*val, 0, asn1_decode_realm);
+ get_field(*val, 1, asn1_decode_principal_name);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_auth_pack(asn1buf *buf, krb5_auth_pack *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator);
+ if (tagnum == 1) { alloc_field(val->clientPublicValue, krb5_subject_pk_info); }
+ /* can't call opt_field because it does decoder(&subbuf, &(val)); */
+ if (asn1buf_remains(&subbuf, seqindef)) {
+ if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)
+ && (tagnum || taglen || asn1class != UNIVERSAL))
+ return ASN1_BAD_ID;
+ if (tagnum == 1) {
+ retval = asn1_decode_subject_pk_info(&subbuf,
+ val->clientPublicValue);
+ if (!taglen && indef) { get_eoc(); }
+ next_tag();
+ } else val->clientPublicValue = NULL;
+ }
+ /* can't call opt_field because it does decoder(&subbuf, &(val)); */
+ if (asn1buf_remains(&subbuf, seqindef)) {
+ if (tagnum == 2) {
+ asn1_decode_sequence_of_algorithm_identifier(&subbuf, &val->supportedCMSTypes);
+ if (!taglen && indef) { get_eoc(); }
+ next_tag();
+ } else val->supportedCMSTypes = NULL;
+ }
+ opt_lenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_auth_pack_draft9(asn1buf *buf, krb5_auth_pack_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator_draft9);
+ if (tagnum == 1) {
+ alloc_field(val->clientPublicValue, krb5_subject_pk_info);
+ /* can't call opt_field because it does decoder(&subbuf, &(val)); */
+ if (asn1buf_remains(&subbuf, seqindef)) {
+ if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)
+ && (tagnum || taglen || asn1class != UNIVERSAL))
+ return ASN1_BAD_ID;
+ if (tagnum == 1) {
+ retval = asn1_decode_subject_pk_info(&subbuf,
+ val->clientPublicValue);
+ if (!taglen && indef) { get_eoc(); }
+ next_tag();
+ } else val->clientPublicValue = NULL;
+ }
+ }
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_pa_pk_as_rep(asn1buf *buf, krb5_pa_pk_as_rep *val)
+{
+ setup();
+ { begin_choice();
+ if (tagnum == choice_pa_pk_as_rep_dhInfo) {
+ val->choice = choice_pa_pk_as_rep_dhInfo;
+ get_field_body(val->u.dh_Info, asn1_decode_dh_rep_info);
+ } else if (tagnum == choice_pa_pk_as_rep_encKeyPack) {
+ val->choice = choice_pa_pk_as_rep_encKeyPack;
+ get_implicit_octet_string(val->u.encKeyPack.length, val->u.encKeyPack.data,
+ choice_pa_pk_as_rep_encKeyPack);
+ } else {
+ val->choice = choice_pa_pk_as_rep_UNKNOWN;
+ }
+ end_choice();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_pa_pk_as_rep_draft9(asn1buf *buf, krb5_pa_pk_as_rep_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ if (tagnum == choice_pa_pk_as_rep_draft9_dhSignedData) {
+ val->choice = choice_pa_pk_as_rep_draft9_dhSignedData;
+ get_lenfield(val->u.dhSignedData.length, val->u.dhSignedData.data,
+ choice_pa_pk_as_rep_draft9_dhSignedData, asn1_decode_octetstring);
+ } else if (tagnum == choice_pa_pk_as_rep_draft9_encKeyPack) {
+ val->choice = choice_pa_pk_as_rep_draft9_encKeyPack;
+ get_lenfield(val->u.encKeyPack.length, val->u.encKeyPack.data,
+ choice_pa_pk_as_rep_draft9_encKeyPack, asn1_decode_octetstring);
+ } else {
+ val->choice = choice_pa_pk_as_rep_UNKNOWN;
+ }
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_sequence_of_typed_data(asn1buf *buf, krb5_typed_data ***val)
+{
+ decode_array_body(krb5_typed_data,asn1_decode_typed_data);
+}
+
+asn1_error_code asn1_decode_typed_data(asn1buf *buf, krb5_typed_data *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->type,0,asn1_decode_int32);
+ get_lenfield(val->length,val->data,1,asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.h b/src/lib/krb5/asn.1/asn1_k_decode.h
index 22e43fd..72c4e29 100644
--- a/src/lib/krb5/asn.1/asn1_k_decode.h
+++ b/src/lib/krb5/asn.1/asn1_k_decode.h
@@ -159,6 +159,44 @@ asn1_error_code asn1_decode_sam_response_2
(asn1buf *buf, krb5_sam_response_2 *val);
asn1_error_code asn1_decode_predicted_sam_response
(asn1buf *buf, krb5_predicted_sam_response *val);
+asn1_error_code asn1_decode_external_principal_identifier
+ (asn1buf *buf, krb5_external_principal_identifier *val);
+asn1_error_code asn1_decode_pa_pk_as_req
+ (asn1buf *buf, krb5_pa_pk_as_req *val);
+asn1_error_code asn1_decode_trusted_ca
+ (asn1buf *buf, krb5_trusted_ca *val);
+asn1_error_code asn1_decode_pa_pk_as_req_draft9
+ (asn1buf *buf, krb5_pa_pk_as_req_draft9 *val);
+asn1_error_code asn1_decode_dh_rep_info
+ (asn1buf *buf, krb5_dh_rep_info *val);
+asn1_error_code asn1_decode_pk_authenticator
+ (asn1buf *buf, krb5_pk_authenticator *val);
+asn1_error_code asn1_decode_pk_authenticator_draft9
+ (asn1buf *buf, krb5_pk_authenticator_draft9 *val);
+asn1_error_code asn1_decode_subject_pk_info
+ (asn1buf *buf, krb5_subject_pk_info *val);
+asn1_error_code asn1_decode_algorithm_identifier
+ (asn1buf *buf, krb5_algorithm_identifier *val);
+asn1_error_code asn1_decode_auth_pack
+ (asn1buf *buf, krb5_auth_pack *val);
+asn1_error_code asn1_decode_auth_pack_draft9
+ (asn1buf *buf, krb5_auth_pack_draft9 *val);
+asn1_error_code asn1_decode_pa_pk_as_rep
+ (asn1buf *buf, krb5_pa_pk_as_rep *val);
+asn1_error_code asn1_decode_pa_pk_as_rep_draft9
+ (asn1buf *buf, krb5_pa_pk_as_rep_draft9 *val);
+asn1_error_code asn1_decode_kdc_dh_key_info
+ (asn1buf *buf, krb5_kdc_dh_key_info *val);
+asn1_error_code asn1_decode_krb5_principal_name
+ (asn1buf *buf, krb5_principal *val);
+asn1_error_code asn1_decode_reply_key_pack
+ (asn1buf *buf, krb5_reply_key_pack *val);
+asn1_error_code asn1_decode_reply_key_pack_draft9
+ (asn1buf *buf, krb5_reply_key_pack_draft9 *val);
+asn1_error_code asn1_decode_sequence_of_typed_data
+ (asn1buf *buf, krb5_typed_data ***val);
+asn1_error_code asn1_decode_typed_data
+ (asn1buf *buf, krb5_typed_data *val);
/* arrays */
asn1_error_code asn1_decode_authorization_data
@@ -187,6 +225,11 @@ asn1_error_code asn1_decode_etype_info
(asn1buf *buf, krb5_etype_info_entry ***val);
asn1_error_code asn1_decode_etype_info2
(asn1buf *buf, krb5_etype_info_entry ***val, krb5_boolean v1_3_behavior);
-
+asn1_error_code asn1_decode_sequence_of_external_principal_identifier
+ (asn1buf *buf, krb5_external_principal_identifier ***val);
+asn1_error_code asn1_decode_sequence_of_trusted_ca
+ (asn1buf *buf, krb5_trusted_ca ***val);
+asn1_error_code asn1_decode_sequence_of_algorithm_identifier
+ (asn1buf *buf, krb5_algorithm_identifier ***val);
#endif
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 00cfab0..4869ea7 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -103,6 +103,50 @@
return retval; }\
sum += length; }
+/* asn1_addfield_implicit -- add an implicitly tagged field, or component, to the encoding */
+#define asn1_addfield_implicit(value,tag,encoder)\
+{ retval = encoder(buf,value,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length;\
+ retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,length,&length); \
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
+/* asn1_insert_implicit_octetstring -- add an octet string with implicit tagging */
+#define asn1_insert_implicit_octetstring(len,value,tag)\
+{ retval = asn1buf_insert_octetstring(buf,len,value);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += len;\
+ retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,len,&length); \
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
+/* asn1_insert_implicit_bitstring -- add a bitstring with implicit tagging */
+#define asn1_insert_implicit_bitstring(len,value,tag)\
+{ retval = asn1buf_insert_octetstring(buf,len,value);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += len;\
+ retval = asn1buf_insert_octet(buf, 0);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum++;\
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,tag,len+1,&length); \
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
/* form a sequence (by adding a sequence header to the current encoding) */
#define asn1_makeseq()\
retval = asn1_make_sequence(buf,sum,&length);\
@@ -959,3 +1003,393 @@ asn1_error_code asn1_encode_krb_saved_safe_body(asn1buf *buf, const krb5_data *b
*retlen = body->length;
return 0;
}
+
+/*
+ * PKINIT
+ */
+
+asn1_error_code asn1_encode_pk_authenticator(asn1buf *buf, const krb5_pk_authenticator *val, unsigned int *retlen)
+{
+ asn1_setup();
+ asn1_addlenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_encode_octetstring);
+ asn1_addfield(val->nonce, 2, asn1_encode_integer);
+ asn1_addfield(val->ctime, 1, asn1_encode_kerberos_time);
+ asn1_addfield(val->cusec, 0, asn1_encode_integer);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pk_authenticator_draft9(asn1buf *buf, const krb5_pk_authenticator_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ asn1_addfield(val->nonce, 4, asn1_encode_integer);
+ asn1_addfield(val->ctime, 3, asn1_encode_kerberos_time);
+ asn1_addfield(val->cusec, 2, asn1_encode_integer);
+ asn1_addfield(val->kdcName, 1, asn1_encode_realm);
+ asn1_addfield(val->kdcName, 0, asn1_encode_principal_name);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+
+asn1_error_code asn1_encode_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->parameters.length != 0) {
+ retval = asn1buf_insert_octetstring(buf, val->parameters.length,
+ val->parameters.data);
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += val->parameters.length;
+ }
+
+ retval = asn1_encode_oid(buf, val->algorithm.length,
+ val->algorithm.data,
+ &length);
+
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += length;
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_subject_pk_info(asn1buf *buf, const krb5_subject_pk_info *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,ASN1_BITSTRING);
+
+ if (val->algorithm.parameters.length != 0) {
+ retval = asn1buf_insert_octetstring(buf, val->algorithm.parameters.length,
+ val->algorithm.parameters.data);
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += val->algorithm.parameters.length;
+ }
+
+ retval = asn1_encode_oid(buf, val->algorithm.algorithm.length,
+ val->algorithm.algorithm.data,
+ &length);
+
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += length;
+
+ retval = asn1_make_etag(buf, UNIVERSAL, ASN1_SEQUENCE,
+ val->algorithm.parameters.length + length,
+ &length);
+
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += length;
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier **val, unsigned int *retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_algorithm_identifier(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_auth_pack(asn1buf *buf, const krb5_auth_pack *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->clientDHNonce.length != 0)
+ asn1_addlenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_encode_octetstring);
+ if (val->supportedCMSTypes != NULL)
+ asn1_addfield((const krb5_algorithm_identifier **)val->supportedCMSTypes,2,asn1_encode_sequence_of_algorithm_identifier);
+ if (val->clientPublicValue != NULL)
+ asn1_addfield(val->clientPublicValue,1,asn1_encode_subject_pk_info);
+ asn1_addfield(&(val->pkAuthenticator),0,asn1_encode_pk_authenticator);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_auth_pack_draft9(asn1buf *buf, const krb5_auth_pack_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->clientPublicValue != NULL)
+ asn1_addfield(val->clientPublicValue, 1, asn1_encode_subject_pk_info);
+ asn1_addfield(&(val->pkAuthenticator), 0, asn1_encode_pk_authenticator_draft9);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ /* Verify there is something to encode */
+ if (val->subjectKeyIdentifier.length == 0 && val->issuerAndSerialNumber.length == 0 && val->subjectName.length == 0)
+ return ASN1_MISSING_FIELD;
+
+ if (val->subjectKeyIdentifier.length != 0)
+ asn1_insert_implicit_octetstring(val->subjectKeyIdentifier.length,val->subjectKeyIdentifier.data,2);
+
+ if (val->issuerAndSerialNumber.length != 0)
+ asn1_insert_implicit_octetstring(val->issuerAndSerialNumber.length,val->issuerAndSerialNumber.data,1);
+
+ if (val->subjectName.length != 0)
+ asn1_insert_implicit_octetstring(val->subjectName.length,val->subjectName.data,0);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_external_principal_identifier(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pa_pk_as_req(asn1buf *buf, const krb5_pa_pk_as_req *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->kdcPkId.length != 0)
+ asn1_insert_implicit_octetstring(val->kdcPkId.length,val->kdcPkId.data,2);
+
+ if (val->trustedCertifiers != NULL)
+ asn1_addfield((const krb5_external_principal_identifier **)val->trustedCertifiers,1,asn1_encode_sequence_of_external_principal_identifier);
+
+ asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_trusted_ca(asn1buf *buf, const krb5_trusted_ca *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ switch (val->choice) {
+ case choice_trusted_cas_issuerAndSerial:
+ asn1_insert_implicit_octetstring(val->u.issuerAndSerial.length,val->u.issuerAndSerial.data,2);
+ break;
+ case choice_trusted_cas_caName:
+ asn1_insert_implicit_octetstring(val->u.caName.length,val->u.caName.data,1);
+ break;
+ case choice_trusted_cas_principalName:
+ asn1_addfield_implicit(val->u.principalName,0,asn1_encode_principal_name);
+ break;
+ default:
+ return ASN1_MISSING_FIELD;
+ }
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_trusted_ca(asn1buf *buf, const krb5_trusted_ca **val, unsigned int *retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_trusted_ca(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pa_pk_as_req_draft9(asn1buf *buf, const krb5_pa_pk_as_req_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->encryptionCert.length != 0)
+ asn1_insert_implicit_octetstring(val->encryptionCert.length,val->encryptionCert.data,3);
+
+ if (val->kdcCert.length != 0)
+ asn1_insert_implicit_octetstring(val->kdcCert.length,val->kdcCert.data,2);
+
+ if (val->trustedCertifiers != NULL)
+ asn1_addfield((const krb5_trusted_ca **)val->trustedCertifiers,1,asn1_encode_sequence_of_trusted_ca);
+
+ asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_dh_rep_info(asn1buf *buf, const krb5_dh_rep_info *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->serverDHNonce.length != 0)
+ asn1_insert_implicit_octetstring(val->serverDHNonce.length,val->serverDHNonce.data,1);
+
+ asn1_insert_implicit_octetstring(val->dhSignedData.length,val->dhSignedData.data,0);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_kdc_dh_key_info(asn1buf *buf, const krb5_kdc_dh_key_info *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->dhKeyExpiration != 0)
+ asn1_addfield(val->dhKeyExpiration, 2, asn1_encode_kerberos_time);
+ asn1_addfield(val->nonce, 1, asn1_encode_integer);
+
+ asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,3);
+ retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0,
+ val->subjectPublicKey.length + 1 + length,
+ &length);
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += length;
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_reply_key_pack(asn1buf *buf, const krb5_reply_key_pack *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ asn1_addfield(&(val->asChecksum), 1, asn1_encode_checksum);
+ asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_reply_key_pack_draft9(asn1buf *buf, const krb5_reply_key_pack_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ asn1_addfield(val->nonce, 1, asn1_encode_integer);
+ asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pa_pk_as_rep(asn1buf *buf, const krb5_pa_pk_as_rep *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ switch (val->choice)
+ {
+ case choice_pa_pk_as_rep_dhInfo:
+ asn1_addfield(&(val->u.dh_Info), choice_pa_pk_as_rep_dhInfo, asn1_encode_dh_rep_info);
+ break;
+ case choice_pa_pk_as_rep_encKeyPack:
+ asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1);
+ break;
+ default:
+ return ASN1_MISSING_FIELD;
+ }
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pa_pk_as_rep_draft9(asn1buf *buf, const krb5_pa_pk_as_rep_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ switch (val->choice)
+ {
+ case choice_pa_pk_as_rep_draft9_dhSignedData:
+ asn1_insert_implicit_octetstring(val->u.dhSignedData.length,val->u.dhSignedData.data,0);
+ break;
+ case choice_pa_pk_as_rep_encKeyPack:
+ asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1);
+ break;
+ default:
+ return ASN1_MISSING_FIELD;
+ }
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_td_trusted_certifiers(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen)
+{
+ asn1_setup();
+ retval = asn1_encode_sequence_of_external_principal_identifier(buf, val, &length);
+ if (retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_typed_data(asn1buf *buf, const krb5_typed_data **val, unsigned int *retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_typed_data(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_typed_data(asn1buf *buf, const krb5_typed_data *val, unsigned int *retlen)
+{
+ asn1_setup();
+ asn1_addlenfield(val->length, val->data, 1, asn1_encode_octetstring);
+ asn1_addfield(val->type, 0, asn1_encode_integer);
+ asn1_makeseq();
+ asn1_cleanup();
+}
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.h b/src/lib/krb5/asn.1/asn1_k_encode.h
index caa46c5..b5f24c4 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.h
+++ b/src/lib/krb5/asn.1/asn1_k_encode.h
@@ -269,4 +269,71 @@ asn1_error_code asn1_encode_predicted_sam_response
asn1_error_code asn1_encode_krb_saved_safe_body
(asn1buf *buf, const krb5_data *body, unsigned int *retlen);
+/* PKINIT */
+
+asn1_error_code asn1_encode_pk_authenticator
+ (asn1buf *buf, const krb5_pk_authenticator *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pk_authenticator_draft9
+ (asn1buf *buf, const krb5_pk_authenticator_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_algorithm_identifier
+ (asn1buf *buf, const krb5_algorithm_identifier *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_subject_pk_info
+ (asn1buf *buf, const krb5_subject_pk_info *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_sequence_of_algorithm_identifier
+ (asn1buf *buf, const krb5_algorithm_identifier **val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_auth_pack
+ (asn1buf *buf, const krb5_auth_pack *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_auth_pack_draft9
+ (asn1buf *buf, const krb5_auth_pack_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_external_principal_identifier
+ (asn1buf *buf, const krb5_external_principal_identifier *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_sequence_of_external_principal_identifier
+ (asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pa_pk_as_req
+ (asn1buf *buf, const krb5_pa_pk_as_req *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_trusted_ca
+ (asn1buf *buf, const krb5_trusted_ca *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_sequence_of_trusted_ca
+ (asn1buf *buf, const krb5_trusted_ca **val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pa_pk_as_req_draft9
+ (asn1buf *buf, const krb5_pa_pk_as_req_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_dh_rep_info
+ (asn1buf *buf, const krb5_dh_rep_info *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_kdc_dh_key_info
+ (asn1buf *buf, const krb5_kdc_dh_key_info *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_reply_key_pack
+ (asn1buf *buf, const krb5_reply_key_pack *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_reply_key_pack_draft9
+ (asn1buf *buf, const krb5_reply_key_pack_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pa_pk_as_rep
+ (asn1buf *buf, const krb5_pa_pk_as_rep *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pa_pk_as_rep_draft9
+ (asn1buf *buf, const krb5_pa_pk_as_rep_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_td_trusted_certifiers
+ (asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_typed_data
+ (asn1buf *buf, const krb5_typed_data *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_sequence_of_typed_data
+ (asn1buf *buf, const krb5_typed_data **val, unsigned int *retlen);
#endif
diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c
index e5cd4f8..cbd6a12 100644
--- a/src/lib/krb5/asn.1/krb5_decode.c
+++ b/src/lib/krb5/asn.1/krb5_decode.c
@@ -934,3 +934,150 @@ krb5_error_code decode_krb5_predicted_sam_response(const krb5_data *code, krb5_p
cleanup(free);
}
+krb5_error_code decode_krb5_pa_pk_as_req(const krb5_data *code, krb5_pa_pk_as_req **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_pa_pk_as_req);
+
+ retval = asn1_decode_pa_pk_as_req(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_pa_pk_as_req_draft9(const krb5_data *code, krb5_pa_pk_as_req_draft9 **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_pa_pk_as_req_draft9);
+
+ retval = asn1_decode_pa_pk_as_req_draft9(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_pa_pk_as_rep(const krb5_data *code, krb5_pa_pk_as_rep **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_pa_pk_as_rep);
+
+ retval = asn1_decode_pa_pk_as_rep(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_pa_pk_as_rep_draft9(const krb5_data *code, krb5_pa_pk_as_rep_draft9 **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_pa_pk_as_rep_draft9);
+
+ retval = asn1_decode_pa_pk_as_rep_draft9(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_auth_pack(const krb5_data *code, krb5_auth_pack **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_auth_pack);
+
+ retval = asn1_decode_auth_pack(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_auth_pack_draft9(const krb5_data *code, krb5_auth_pack_draft9 **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_auth_pack_draft9);
+
+ retval = asn1_decode_auth_pack_draft9(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_kdc_dh_key_info(const krb5_data *code, krb5_kdc_dh_key_info **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_kdc_dh_key_info);
+
+ retval = asn1_decode_kdc_dh_key_info(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_principal_name(const krb5_data *code, krb5_principal_data **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_principal_data);
+
+ retval = asn1_decode_krb5_principal_name(&buf, rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_reply_key_pack(const krb5_data *code, krb5_reply_key_pack **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_reply_key_pack);
+
+ retval = asn1_decode_reply_key_pack(&buf, *rep);
+ if (retval)
+ goto error_out;
+
+ cleanup_manual();
+error_out:
+ if (rep && *rep) {
+ if ((*rep)->replyKey.contents)
+ free((*rep)->replyKey.contents);
+ if ((*rep)->asChecksum.contents)
+ free((*rep)->asChecksum.contents);
+ free(*rep);
+ *rep = NULL;
+ }
+ return retval;
+}
+
+krb5_error_code decode_krb5_reply_key_pack_draft9(const krb5_data *code, krb5_reply_key_pack_draft9 **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_reply_key_pack_draft9);
+
+ retval = asn1_decode_reply_key_pack_draft9(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_typed_data(const krb5_data *code, krb5_typed_data ***rep)
+{
+ setup_buf_only();
+ retval = asn1_decode_sequence_of_typed_data(&buf, rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_td_trusted_certifiers(const krb5_data *code, krb5_external_principal_identifier ***rep)
+{
+ setup_buf_only();
+ retval = asn1_decode_sequence_of_external_principal_identifier(&buf, rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_td_dh_parameters(const krb5_data *code, krb5_algorithm_identifier ***rep)
+{
+ setup_buf_only();
+ retval = asn1_decode_sequence_of_algorithm_identifier(&buf, rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
diff --git a/src/lib/krb5/asn.1/krb5_encode.c b/src/lib/krb5/asn.1/krb5_encode.c
index 639db43..682e9a2 100644
--- a/src/lib/krb5/asn.1/krb5_encode.c
+++ b/src/lib/krb5/asn.1/krb5_encode.c
@@ -697,6 +697,23 @@ krb5_error_code encode_krb5_authdata(const krb5_authdata **rep, krb5_data **code
krb5_cleanup();
}
+krb5_error_code encode_krb5_authdata_elt(const krb5_authdata *rep, krb5_data **code)
+{
+ asn1_error_code retval;
+ asn1buf *buf=NULL;
+ unsigned int length;
+
+ if(rep == NULL) return ASN1_MISSING_FIELD;
+
+ retval = asn1buf_create(&buf);
+ if(retval) return retval;
+
+ retval = asn1_encode_krb5_authdata_elt(buf,rep, &length);
+ if(retval) return retval;
+
+ krb5_cleanup();
+}
+
krb5_error_code encode_krb5_alt_method(const krb5_alt_method *rep, krb5_data **code)
{
krb5_setup();
@@ -887,3 +904,111 @@ krb5_error_code encode_krb5_setpw_req(const krb5_principal target,
krb5_cleanup();
}
+
+krb5_error_code encode_krb5_pa_pk_as_req(const krb5_pa_pk_as_req *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_pa_pk_as_req(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_pa_pk_as_req_draft9(const krb5_pa_pk_as_req_draft9 *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_pa_pk_as_req_draft9(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_pa_pk_as_rep(const krb5_pa_pk_as_rep *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_pa_pk_as_rep(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_pa_pk_as_rep_draft9(const krb5_pa_pk_as_rep_draft9 *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_pa_pk_as_rep_draft9(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_auth_pack(const krb5_auth_pack *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_auth_pack(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_auth_pack_draft9(const krb5_auth_pack_draft9 *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_auth_pack_draft9(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_kdc_dh_key_info(const krb5_kdc_dh_key_info *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_kdc_dh_key_info(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_reply_key_pack(const krb5_reply_key_pack *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_reply_key_pack(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_reply_key_pack_draft9(const krb5_reply_key_pack_draft9 *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_reply_key_pack_draft9(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_td_trusted_certifiers(const krb5_external_principal_identifier **rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_td_trusted_certifiers(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_typed_data(const krb5_typed_data **rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_sequence_of_typed_data(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_td_dh_parameters(const krb5_algorithm_identifier **rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_sequence_of_algorithm_identifier(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index 7be2bec..03bc2d3 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -71,7 +71,7 @@ krb5_init_preauth_context(krb5_context kcontext)
{
int n_modules, n_tables, i, j, k;
void **tables;
- struct krb5plugin_preauth_client_ftable_v0 *table;
+ struct krb5plugin_preauth_client_ftable_v1 *table;
krb5_preauth_context *context = NULL;
void *plugin_context;
krb5_preauthtype pa_type;
@@ -93,7 +93,7 @@ krb5_init_preauth_context(krb5_context kcontext)
/* pull out the module function tables for all of the modules */
tables = NULL;
if (krb5int_get_plugin_dir_data(&kcontext->preauth_plugins,
- "preauthentication_client_0",
+ "preauthentication_client_1",
&tables,
&kcontext->err) != 0) {
return;
@@ -352,37 +352,45 @@ grow_ktypes(krb5_enctype **out_ktypes, int *out_nktypes, krb5_enctype ktype)
}
}
-/* Add the given pa_data item to the list of items. Factored out here to make
- * reading the do_preauth logic easier to read. */
+/*
+ * Add the given list of pa_data items to the existing list of items.
+ * Factored out here to make reading the do_preauth logic easier to read.
+ */
static int
grow_pa_list(krb5_pa_data ***out_pa_list, int *out_pa_list_size,
- krb5_pa_data *addition)
+ krb5_pa_data **addition, int num_addition)
{
krb5_pa_data **pa_list;
- int i;
+ int i, j;
- if (out_pa_list == NULL) {
+ if (out_pa_list == NULL || addition == NULL) {
return EINVAL;
}
if (*out_pa_list == NULL) {
- /* Allocate room for one entry and a NULL terminator. */
- pa_list = malloc(2 * sizeof(krb5_pa_data *));
+ /* Allocate room for the new additions and a NULL terminator. */
+ pa_list = malloc((num_addition + 1) * sizeof(krb5_pa_data *));
if (pa_list == NULL)
return ENOMEM;
- pa_list[0] = addition;
- pa_list[1] = NULL;
+ for (i = 0; i < num_addition; i++)
+ pa_list[i] = addition[i];
+ pa_list[i] = NULL;
*out_pa_list = pa_list;
- *out_pa_list_size = 1;
+ *out_pa_list_size = num_addition;
} else {
- /* Allocate room for one more entry and a NULL terminator. */
- pa_list = malloc((*out_pa_list_size + 2) * sizeof(krb5_pa_data *));
+ /*
+ * Allocate room for the existing entries plus
+ * the new additions and a NULL terminator.
+ */
+ pa_list = malloc((*out_pa_list_size + num_addition + 1)
+ * sizeof(krb5_pa_data *));
if (pa_list == NULL)
return ENOMEM;
for (i = 0; i < *out_pa_list_size; i++)
pa_list[i] = (*out_pa_list)[i];
- pa_list[i++] = addition;
- pa_list[i++] = NULL;
+ for (j = 0; j < num_addition;)
+ pa_list[i++] = addition[j++];
+ pa_list[i] = NULL;
free(*out_pa_list);
*out_pa_list = pa_list;
*out_pa_list_size = i;
@@ -502,7 +510,7 @@ krb5_run_preauth_plugins(krb5_context kcontext,
krb5_gic_opt_ext *opte)
{
int i;
- krb5_pa_data *out_pa_data;
+ krb5_pa_data **out_pa_data;
krb5_error_code ret;
struct _krb5_preauth_context_module *module;
@@ -554,7 +562,10 @@ krb5_run_preauth_plugins(krb5_context kcontext,
*module_ret = ret;
/* Save the new preauth data item. */
if (out_pa_data != NULL) {
- ret = grow_pa_list(out_pa_list, out_pa_list_size, out_pa_data);
+ int i;
+ for (i = 0; out_pa_data[i] != NULL; i++);
+ ret = grow_pa_list(out_pa_list, out_pa_list_size, out_pa_data, i);
+ free(out_pa_data);
if (ret != 0)
return ret;
}
@@ -1363,7 +1374,7 @@ krb5_do_preauth_tryagain(krb5_context kcontext,
krb5_gic_opt_ext *opte)
{
krb5_error_code ret;
- krb5_pa_data *out_padata;
+ krb5_pa_data **out_padata;
krb5_preauth_context *context;
struct _krb5_preauth_context_module *module;
int i, j;
@@ -1404,7 +1415,11 @@ krb5_do_preauth_tryagain(krb5_context kcontext,
as_key,
&out_padata) == 0) {
if (out_padata != NULL) {
- grow_pa_list(return_padata, &out_pa_list_size, out_padata);
+ int i;
+ for (i = 0; out_padata[i] != NULL; i++);
+ grow_pa_list(return_padata, &out_pa_list_size,
+ out_padata, i);
+ free(out_padata);
return 0;
}
}
@@ -1584,7 +1599,7 @@ krb5_do_preauth(krb5_context context,
}
ret = grow_pa_list(&out_pa_list, &out_pa_list_size,
- out_pa);
+ &out_pa, 1);
if (ret != 0) {
goto cleanup;
}
diff --git a/src/lib/krb5/os/accessor.c b/src/lib/krb5/os/accessor.c
index 95f0f0f..66541e4 100644
--- a/src/lib/krb5/os/accessor.c
+++ b/src/lib/krb5/os/accessor.c
@@ -80,6 +80,35 @@ krb5int_accessor(krb5int_access *internals, krb5_int32 version)
S (krb5_ser_unpack_int64, krb5_ser_unpack_int64),
S (asn1_ldap_encode_sequence_of_keys, krb5int_ldap_encode_sequence_of_keys),
S (asn1_ldap_decode_sequence_of_keys, krb5int_ldap_decode_sequence_of_keys),
+ S (encode_krb5_pa_pk_as_req, encode_krb5_pa_pk_as_req),
+ S (encode_krb5_pa_pk_as_req_draft9, encode_krb5_pa_pk_as_req_draft9), S (encode_krb5_pa_pk_as_rep, encode_krb5_pa_pk_as_rep),
+ S (encode_krb5_pa_pk_as_rep_draft9, encode_krb5_pa_pk_as_rep_draft9),
+ S (encode_krb5_auth_pack, encode_krb5_auth_pack),
+ S (encode_krb5_auth_pack_draft9, encode_krb5_auth_pack_draft9),
+ S (encode_krb5_kdc_dh_key_info, encode_krb5_kdc_dh_key_info),
+ S (encode_krb5_reply_key_pack, encode_krb5_reply_key_pack),
+ S (encode_krb5_reply_key_pack_draft9, encode_krb5_reply_key_pack_draft9),
+ S (encode_krb5_typed_data, encode_krb5_typed_data),
+ S (encode_krb5_td_trusted_certifiers, encode_krb5_td_trusted_certifiers),
+ S (encode_krb5_td_dh_parameters, encode_krb5_td_dh_parameters),
+ S (decode_krb5_pa_pk_as_req, decode_krb5_pa_pk_as_req),
+ S (decode_krb5_pa_pk_as_req_draft9, decode_krb5_pa_pk_as_req_draft9),
+ S (decode_krb5_pa_pk_as_rep, decode_krb5_pa_pk_as_rep),
+ S (decode_krb5_pa_pk_as_rep_draft9, decode_krb5_pa_pk_as_rep_draft9),
+ S (decode_krb5_auth_pack, decode_krb5_auth_pack),
+ S (decode_krb5_auth_pack_draft9, decode_krb5_auth_pack_draft9),
+ S (decode_krb5_kdc_dh_key_info, decode_krb5_kdc_dh_key_info),
+ S (decode_krb5_principal_name, decode_krb5_principal_name),
+ S (decode_krb5_reply_key_pack, decode_krb5_reply_key_pack),
+ S (decode_krb5_reply_key_pack_draft9, decode_krb5_reply_key_pack_draft9),
+ S (decode_krb5_typed_data, decode_krb5_typed_data),
+ S (decode_krb5_td_trusted_certifiers, decode_krb5_td_trusted_certifiers),
+ S (decode_krb5_td_dh_parameters, decode_krb5_td_dh_parameters),
+ S (decode_krb5_as_req, decode_krb5_as_req),
+ S (encode_krb5_kdc_req_body, encode_krb5_kdc_req_body),
+ S (krb5_free_kdc_req, krb5_free_kdc_req),
+ S (krb5int_set_prompt_types, krb5int_set_prompt_types),
+ S (encode_krb5_authdata_elt, encode_krb5_authdata_elt)
#if DESIGNATED_INITIALIZERS
};
#else