Skip to content

Commit

Permalink
Use OpenSSL SubjectPublicKeyInfo parsing in PKINIT
Browse files Browse the repository at this point in the history
Shift responsibility for encoding and decoding SubjectPublicKeyInfo
from libkrb5 to the PKINIT ASN.1 module.  OpenSSL 1.0 does not support
DHX (RFC 3279 section 3), so for that version use custom ASN.1
marshalling of the parameters and compose that into
SubjectPublicKeyInfo marshalling using X509_PUBKEY.
  • Loading branch information
greghudson committed Nov 4, 2021
1 parent 9a0575f commit 4936bdc
Show file tree
Hide file tree
Showing 14 changed files with 288 additions and 398 deletions.
8 changes: 1 addition & 7 deletions src/include/k5-int-pkinit.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,10 @@ typedef struct _krb5_algorithm_identifier {
krb5_data parameters; /* Optional */
} krb5_algorithm_identifier;

/* SubjectPublicKeyInfo */
typedef struct _krb5_subject_pk_info {
krb5_algorithm_identifier algorithm;
krb5_data subjectPublicKey; /* BIT STRING */
} krb5_subject_pk_info;

/** AuthPack from RFC 4556*/
typedef struct _krb5_auth_pack {
krb5_pk_authenticator pkAuthenticator;
krb5_subject_pk_info *clientPublicValue; /* Optional */
krb5_data clientPublicValue; /* Optional */
krb5_algorithm_identifier **supportedCMSTypes; /* Optional */
krb5_data clientDHNonce; /* Optional */
krb5_data **supportedKDFs; /* OIDs of KDFs; OPTIONAL */
Expand Down
13 changes: 1 addition & 12 deletions src/lib/krb5/asn.1/asn1_k_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1446,19 +1446,8 @@ DEFCOUNTEDSTRINGTYPE(s_bitstring, char *, unsigned int,
ASN1_BITSTRING);
DEFCOUNTEDTYPE(bitstring_data, krb5_data, data, length, s_bitstring);

/* RFC 3280. No context tags. */
DEFOFFSETTYPE(spki_0, krb5_subject_pk_info, algorithm, algorithm_identifier);
DEFOFFSETTYPE(spki_1, krb5_subject_pk_info, subjectPublicKey, bitstring_data);
static const struct atype_info *subject_pk_info_fields[] = {
&k5_atype_spki_0, &k5_atype_spki_1
};
DEFSEQTYPE(subject_pk_info, krb5_subject_pk_info, subject_pk_info_fields);
DEFPTRTYPE(subject_pk_info_ptr, subject_pk_info);
DEFOPTIONALZEROTYPE(opt_subject_pk_info_ptr, subject_pk_info_ptr);

DEFFIELD(auth_pack_0, krb5_auth_pack, pkAuthenticator, 0, pk_authenticator);
DEFFIELD(auth_pack_1, krb5_auth_pack, clientPublicValue, 1,
opt_subject_pk_info_ptr);
DEFFIELD(auth_pack_1, krb5_auth_pack, clientPublicValue, 1, opt_der_data);
DEFFIELD(auth_pack_2, krb5_auth_pack, supportedCMSTypes, 2,
opt_ptr_seqof_algorithm_identifier);
DEFFIELD(auth_pack_3, krb5_auth_pack, clientDHNonce, 3, opt_ostring_data);
Expand Down
2 changes: 0 additions & 2 deletions src/plugins/preauth/pkinit/pkinit.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,6 @@ void init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
void init_krb5_reply_key_pack(krb5_reply_key_pack **in);

void init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **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);
void free_krb5_reply_key_pack(krb5_reply_key_pack **in);
Expand All @@ -340,7 +339,6 @@ void free_krb5_external_principal_identifier(krb5_external_principal_identifier
void free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in);
void free_krb5_algorithm_identifier(krb5_algorithm_identifier *in);
void free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in);
void free_krb5_subject_pk_info(krb5_subject_pk_info **in);
krb5_error_code pkinit_copy_krb5_data(krb5_data *dst, const krb5_data *src);


Expand Down
18 changes: 4 additions & 14 deletions src/plugins/preauth/pkinit/pkinit_clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,19 +187,15 @@ pkinit_as_req_create(krb5_context context,
krb5_data ** as_req)
{
krb5_error_code retval = ENOMEM;
krb5_subject_pk_info info;
krb5_data *coded_auth_pack = NULL;
krb5_data spki = empty_data(), *coded_auth_pack = NULL;
krb5_auth_pack auth_pack;
krb5_pa_pk_as_req *req = NULL;
krb5_algorithm_identifier **cmstypes = NULL;
int protocol = reqctx->opts->dh_or_rsa;
unsigned char *dh_params = NULL, *dh_pubkey = NULL;
unsigned int dh_params_len, dh_pubkey_len;

pkiDebug("pkinit_as_req_create pa_type = %d\n", reqctx->pa_type);

/* Create the authpack */
memset(&info, 0, sizeof(info));
memset(&auth_pack, 0, sizeof(auth_pack));
auth_pack.pkAuthenticator.ctime = ctsec;
auth_pack.pkAuthenticator.cusec = cusec;
Expand All @@ -208,7 +204,6 @@ pkinit_as_req_create(krb5_context context,
if (!reqctx->opts->disable_freshness)
auth_pack.pkAuthenticator.freshnessToken = reqctx->freshness_token;
auth_pack.clientDHNonce.length = 0;
auth_pack.clientPublicValue = &info;
auth_pack.supportedKDFs = (krb5_data **)supported_kdf_alg_ids;

/* add List of CMS algorithms */
Expand All @@ -223,24 +218,20 @@ pkinit_as_req_create(krb5_context context,
case DH_PROTOCOL:
TRACE_PKINIT_CLIENT_REQ_DH(context);
pkiDebug("as_req: DH key transport algorithm\n");
info.algorithm.algorithm = dh_oid;

/* create client-side DH keys */
retval = client_create_dh(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx,
reqctx->opts->dh_size, &dh_params,
&dh_params_len, &dh_pubkey, &dh_pubkey_len);
reqctx->opts->dh_size, &spki);
auth_pack.clientPublicValue = spki;
if (retval != 0) {
pkiDebug("failed to create dh parameters\n");
goto cleanup;
}
info.algorithm.parameters = make_data(dh_params, dh_params_len);
info.subjectPublicKey = make_data(dh_pubkey, dh_pubkey_len);
break;
case RSA_PROTOCOL:
TRACE_PKINIT_CLIENT_REQ_RSA(context);
pkiDebug("as_req: RSA key transport algorithm\n");
auth_pack.clientPublicValue = NULL;
break;
default:
pkiDebug("as_req: unknown key transport protocol %d\n",
Expand Down Expand Up @@ -324,9 +315,8 @@ pkinit_as_req_create(krb5_context context,

cleanup:
free_krb5_algorithm_identifiers(&cmstypes);
free(dh_params);
free(dh_pubkey);
free_krb5_pa_pk_as_req(&req);
krb5_free_data_contents(context, &spki);

pkiDebug("pkinit_as_req_create retval=%d\n", (int) retval);

Expand Down
18 changes: 4 additions & 14 deletions src/plugins/preauth/pkinit/pkinit_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,8 @@ krb5_error_code client_create_dh
pkinit_identity_crypto_context id_cryptoctx, /* IN */
int dh_size, /* IN
specifies the DH modulous, eg 1024, 2048, or 4096 */
unsigned char **dh_params_out, /* OUT
contains DER encoded DH params */
unsigned int *dh_params_len_out, /* OUT
contains length of encoded DH params */
unsigned char **dh_pubkey_out, /* OUT
receives DER encoded DH pub key */
unsigned int *dh_pubkey_len_out); /* OUT
receives length of DH pub key */
krb5_data *spki_out); /* OUT
receives SubjectPublicKeyInfo encoding */

/*
* this function completes client's the DH protocol. client
Expand Down Expand Up @@ -353,8 +347,8 @@ krb5_error_code server_check_dh
pkinit_plg_crypto_context plg_cryptoctx, /* IN */
pkinit_req_crypto_context req_cryptoctx, /* IN */
pkinit_identity_crypto_context id_cryptoctx, /* IN */
krb5_data *dh_params, /* IN
???? */
const krb5_data *client_spki, /* IN
SubjectPublicKeyInfo encoding from client */
int minbits); /* IN
the minimum number of key bits acceptable */

Expand All @@ -367,10 +361,6 @@ krb5_error_code server_process_dh
pkinit_plg_crypto_context plg_cryptoctx, /* IN */
pkinit_req_crypto_context req_cryptoctx, /* IN */
pkinit_identity_crypto_context id_cryptoctx, /* IN */
unsigned char *received_pubkey, /* IN
contains client's DER encoded DH pub key */
unsigned int received_pub_len, /* IN
contains length of received_pubkey */
unsigned char **dh_pubkey_out, /* OUT
receives KDC's DER encoded DH pub key */
unsigned int *dh_pubkey_len_out, /* OUT
Expand Down

0 comments on commit 4936bdc

Please sign in to comment.