|
Packit |
fd8b60 |
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* COPYRIGHT (C) 2006,2007
|
|
Packit |
fd8b60 |
* THE REGENTS OF THE UNIVERSITY OF MICHIGAN
|
|
Packit |
fd8b60 |
* ALL RIGHTS RESERVED
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Permission is granted to use, copy, create derivative works
|
|
Packit |
fd8b60 |
* and redistribute this software and such derivative works
|
|
Packit |
fd8b60 |
* for any purpose, so long as the name of The University of
|
|
Packit |
fd8b60 |
* Michigan is not used in any advertising or publicity
|
|
Packit |
fd8b60 |
* pertaining to the use of distribution of this software
|
|
Packit |
fd8b60 |
* without specific, written prior authorization. If the
|
|
Packit |
fd8b60 |
* above copyright notice or any other identification of the
|
|
Packit |
fd8b60 |
* University of Michigan is included in any copy of any
|
|
Packit |
fd8b60 |
* portion of this software, then the disclaimer below must
|
|
Packit |
fd8b60 |
* also be included.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
|
|
Packit |
fd8b60 |
* FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
|
|
Packit |
fd8b60 |
* PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
|
|
Packit |
fd8b60 |
* MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
|
Packit |
fd8b60 |
* WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
|
|
Packit |
fd8b60 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
|
Packit |
fd8b60 |
* REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
|
|
Packit |
fd8b60 |
* FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
|
|
Packit |
fd8b60 |
* CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
|
|
Packit |
fd8b60 |
* OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
|
|
Packit |
fd8b60 |
* IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
|
|
Packit |
fd8b60 |
* SUCH DAMAGES.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include "pkinit.h"
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#define FAKECERT
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
const krb5_data dh_oid = { 0, 7, "\x2A\x86\x48\xce\x3e\x02\x01" };
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_init_req_opts(pkinit_req_opts **reqopts)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code retval = ENOMEM;
|
|
Packit |
fd8b60 |
pkinit_req_opts *opts = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*reqopts = NULL;
|
|
Packit |
fd8b60 |
opts = calloc(1, sizeof(*opts));
|
|
Packit |
fd8b60 |
if (opts == NULL)
|
|
Packit |
fd8b60 |
return retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
opts->require_eku = 1;
|
|
Packit |
fd8b60 |
opts->accept_secondary_eku = 0;
|
|
Packit |
fd8b60 |
opts->allow_upn = 0;
|
|
Packit |
fd8b60 |
opts->dh_or_rsa = DH_PROTOCOL;
|
|
Packit |
fd8b60 |
opts->require_crl_checking = 0;
|
|
Packit |
fd8b60 |
opts->dh_size = PKINIT_DEFAULT_DH_MIN_BITS;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*reqopts = opts;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
pkinit_fini_req_opts(pkinit_req_opts *opts)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
free(opts);
|
|
Packit |
fd8b60 |
return;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_init_plg_opts(pkinit_plg_opts **plgopts)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code retval = ENOMEM;
|
|
Packit |
fd8b60 |
pkinit_plg_opts *opts = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*plgopts = NULL;
|
|
Packit |
fd8b60 |
opts = calloc(1, sizeof(pkinit_plg_opts));
|
|
Packit |
fd8b60 |
if (opts == NULL)
|
|
Packit |
fd8b60 |
return retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
opts->require_eku = 1;
|
|
Packit |
fd8b60 |
opts->accept_secondary_eku = 0;
|
|
Packit |
fd8b60 |
opts->dh_or_rsa = DH_PROTOCOL;
|
|
Packit |
fd8b60 |
opts->allow_upn = 0;
|
|
Packit |
fd8b60 |
opts->require_crl_checking = 0;
|
|
Packit |
fd8b60 |
opts->require_freshness = 0;
|
|
Packit |
fd8b60 |
opts->disable_freshness = 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
opts->dh_min_bits = PKINIT_DEFAULT_DH_MIN_BITS;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*plgopts = opts;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
pkinit_fini_plg_opts(pkinit_plg_opts *opts)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
free(opts);
|
|
Packit |
fd8b60 |
return;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (*in == NULL) return;
|
|
Packit |
fd8b60 |
free((*in)->signedAuthPack.data);
|
|
Packit |
fd8b60 |
if ((*in)->trustedCertifiers != NULL)
|
|
Packit |
fd8b60 |
free_krb5_external_principal_identifier(&(*in)->trustedCertifiers);
|
|
Packit |
fd8b60 |
free((*in)->kdcPkId.data);
|
|
Packit |
fd8b60 |
free(*in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
free_krb5_reply_key_pack(krb5_reply_key_pack **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (*in == NULL) return;
|
|
Packit |
fd8b60 |
free((*in)->replyKey.contents);
|
|
Packit |
fd8b60 |
free((*in)->asChecksum.contents);
|
|
Packit |
fd8b60 |
free(*in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
free_krb5_auth_pack(krb5_auth_pack **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if ((*in) == NULL) return;
|
|
Packit |
fd8b60 |
if ((*in)->clientPublicValue != NULL) {
|
|
Packit |
fd8b60 |
free((*in)->clientPublicValue->algorithm.algorithm.data);
|
|
Packit |
fd8b60 |
free((*in)->clientPublicValue->algorithm.parameters.data);
|
|
Packit |
fd8b60 |
free((*in)->clientPublicValue->subjectPublicKey.data);
|
|
Packit |
fd8b60 |
free((*in)->clientPublicValue);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
free((*in)->pkAuthenticator.paChecksum.contents);
|
|
Packit |
fd8b60 |
krb5_free_data(NULL, (*in)->pkAuthenticator.freshnessToken);
|
|
Packit |
fd8b60 |
if ((*in)->supportedCMSTypes != NULL)
|
|
Packit |
fd8b60 |
free_krb5_algorithm_identifiers(&((*in)->supportedCMSTypes));
|
|
Packit |
fd8b60 |
if ((*in)->supportedKDFs) {
|
|
Packit |
fd8b60 |
krb5_data **supportedKDFs = (*in)->supportedKDFs;
|
|
Packit |
fd8b60 |
unsigned i;
|
|
Packit |
fd8b60 |
for (i = 0; supportedKDFs[i]; i++)
|
|
Packit |
fd8b60 |
krb5_free_data(NULL, supportedKDFs[i]);
|
|
Packit |
fd8b60 |
free(supportedKDFs);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
free(*in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (*in == NULL) return;
|
|
Packit |
fd8b60 |
switch ((*in)->choice) {
|
|
Packit |
fd8b60 |
case choice_pa_pk_as_rep_dhInfo:
|
|
Packit |
fd8b60 |
krb5_free_data(NULL, (*in)->u.dh_Info.kdfID);
|
|
Packit |
fd8b60 |
free((*in)->u.dh_Info.dhSignedData.data);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case choice_pa_pk_as_rep_encKeyPack:
|
|
Packit |
fd8b60 |
free((*in)->u.encKeyPack.data);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
default:
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
free(*in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
free_krb5_external_principal_identifier(krb5_external_principal_identifier ***in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int i = 0;
|
|
Packit |
fd8b60 |
if (*in == NULL) return;
|
|
Packit |
fd8b60 |
while ((*in)[i] != NULL) {
|
|
Packit |
fd8b60 |
free((*in)[i]->subjectName.data);
|
|
Packit |
fd8b60 |
free((*in)[i]->issuerAndSerialNumber.data);
|
|
Packit |
fd8b60 |
free((*in)[i]->subjectKeyIdentifier.data);
|
|
Packit |
fd8b60 |
free((*in)[i]);
|
|
Packit |
fd8b60 |
i++;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
free(*in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
free_krb5_algorithm_identifier(krb5_algorithm_identifier *in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (in == NULL)
|
|
Packit |
fd8b60 |
return;
|
|
Packit |
fd8b60 |
free(in->algorithm.data);
|
|
Packit |
fd8b60 |
free(in->parameters.data);
|
|
Packit |
fd8b60 |
free(in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int i;
|
|
Packit |
fd8b60 |
if (in == NULL || *in == NULL)
|
|
Packit |
fd8b60 |
return;
|
|
Packit |
fd8b60 |
for (i = 0; (*in)[i] != NULL; i++) {
|
|
Packit |
fd8b60 |
free_krb5_algorithm_identifier((*in)[i]);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
free(*in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
free_krb5_subject_pk_info(krb5_subject_pk_info **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if ((*in) == NULL) return;
|
|
Packit |
fd8b60 |
free((*in)->algorithm.parameters.data);
|
|
Packit |
fd8b60 |
free((*in)->subjectPublicKey.data);
|
|
Packit |
fd8b60 |
free(*in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (*in == NULL) return;
|
|
Packit |
fd8b60 |
free((*in)->subjectPublicKey.data);
|
|
Packit |
fd8b60 |
free(*in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
(*in) = malloc(sizeof(krb5_pa_pk_as_req));
|
|
Packit |
fd8b60 |
if ((*in) == NULL) return;
|
|
Packit |
fd8b60 |
(*in)->signedAuthPack.data = NULL;
|
|
Packit |
fd8b60 |
(*in)->signedAuthPack.length = 0;
|
|
Packit |
fd8b60 |
(*in)->trustedCertifiers = NULL;
|
|
Packit |
fd8b60 |
(*in)->kdcPkId.data = NULL;
|
|
Packit |
fd8b60 |
(*in)->kdcPkId.length = 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
init_krb5_reply_key_pack(krb5_reply_key_pack **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
(*in) = malloc(sizeof(krb5_reply_key_pack));
|
|
Packit |
fd8b60 |
if ((*in) == NULL) return;
|
|
Packit |
fd8b60 |
(*in)->replyKey.contents = NULL;
|
|
Packit |
fd8b60 |
(*in)->replyKey.length = 0;
|
|
Packit |
fd8b60 |
(*in)->asChecksum.contents = NULL;
|
|
Packit |
fd8b60 |
(*in)->asChecksum.length = 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
(*in) = malloc(sizeof(krb5_pa_pk_as_rep));
|
|
Packit |
fd8b60 |
if ((*in) == NULL) return;
|
|
Packit |
fd8b60 |
(*in)->u.dh_Info.serverDHNonce.length = 0;
|
|
Packit |
fd8b60 |
(*in)->u.dh_Info.serverDHNonce.data = NULL;
|
|
Packit |
fd8b60 |
(*in)->u.dh_Info.dhSignedData.length = 0;
|
|
Packit |
fd8b60 |
(*in)->u.dh_Info.dhSignedData.data = NULL;
|
|
Packit |
fd8b60 |
(*in)->u.encKeyPack.length = 0;
|
|
Packit |
fd8b60 |
(*in)->u.encKeyPack.data = NULL;
|
|
Packit |
fd8b60 |
(*in)->u.dh_Info.kdfID = NULL;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
init_krb5_subject_pk_info(krb5_subject_pk_info **in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
(*in) = malloc(sizeof(krb5_subject_pk_info));
|
|
Packit |
fd8b60 |
if ((*in) == NULL) return;
|
|
Packit |
fd8b60 |
(*in)->algorithm.parameters.data = NULL;
|
|
Packit |
fd8b60 |
(*in)->algorithm.parameters.length = 0;
|
|
Packit |
fd8b60 |
(*in)->subjectPublicKey.data = NULL;
|
|
Packit |
fd8b60 |
(*in)->subjectPublicKey.length = 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_copy_krb5_data(krb5_data *dst, const krb5_data *src)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (dst == NULL || src == NULL)
|
|
Packit |
fd8b60 |
return EINVAL;
|
|
Packit |
fd8b60 |
if (src->data == NULL) {
|
|
Packit |
fd8b60 |
dst->data = NULL;
|
|
Packit |
fd8b60 |
dst->length = 0;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
dst->data = malloc(src->length);
|
|
Packit |
fd8b60 |
if (dst->data == NULL)
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
memcpy(dst->data, src->data, src->length);
|
|
Packit |
fd8b60 |
dst->length = src->length;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* debugging functions */
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
print_buffer(const unsigned char *buf, unsigned int len)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
unsigned i = 0;
|
|
Packit |
fd8b60 |
if (len <= 0)
|
|
Packit |
fd8b60 |
return;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (i = 0; i < len; i++)
|
|
Packit |
fd8b60 |
pkiDebug("%02x ", buf[i]);
|
|
Packit |
fd8b60 |
pkiDebug("\n");
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
print_buffer_bin(unsigned char *buf, unsigned int len, char *filename)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
FILE *f = NULL;
|
|
Packit |
fd8b60 |
unsigned int i = 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (len <= 0 || filename == NULL)
|
|
Packit |
fd8b60 |
return;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if ((f = fopen(filename, "w")) == NULL)
|
|
Packit |
fd8b60 |
return;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
set_cloexec_file(f);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (i = 0; i < len; i++)
|
|
Packit |
fd8b60 |
fputc(buf[i], f);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
fclose(f);
|
|
Packit |
fd8b60 |
}
|