First version of KDF in draft-ietf-krb-wg-pkinit-alg-agility-03.txt.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@22926 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2008-04-09 13:06:25 +00:00
parent bc0c286502
commit 05422a8a8a

View File

@@ -33,6 +33,7 @@
#include "krb5_locl.h"
RCSID("$Id$");
#include <pkinit_asn1.h>
#undef CRYPTO_DEBUG
#ifdef CRYPTO_DEBUG
@@ -4050,6 +4051,134 @@ _krb5_pk_octetstring2key(krb5_context context,
return ret;
}
static krb5_error_code
encode_otherinfo(krb5_context context,
const AlgorithmIdentifier *algorithmID,
krb5_const_principal client,
krb5_const_principal server,
krb5_enctype enctype,
const krb5_data *as_req,
const krb5_data *pk_as_rep,
const Ticket *ticket,
krb5_data *other)
{
PkinitSP80056AOtherInfo otherinfo;
PkinitSuppPubInfo pubinfo;
krb5_error_code ret;
krb5_data pub;
size_t size;
krb5_data_zero(other);
memset(&otherinfo, 0, sizeof(otherinfo));
memset(&pubinfo, 0, sizeof(pubinfo));
pubinfo.enctype = enctype;
pubinfo.as_REQ = *as_req;
pubinfo.pk_as_rep = *pk_as_rep;
pubinfo.ticket = *ticket;
ASN1_MALLOC_ENCODE(PkinitSuppPubInfo, pub.data, pub.length,
&pubinfo, &size, ret);
if (ret) {
krb5_set_error_string(context, "out of memory");
return ret;
}
if (pub.length != size)
krb5_abortx(context, "asn1 compiler internal error");
otherinfo.algorithmID = *algorithmID;
/* XXX set from client/KRB5PrincipalName */
krb5_data_zero(&otherinfo.partyUInfo);
/* XXX set from server/KRB5PrincipalName */
krb5_data_zero(&otherinfo.partyVInfo);
otherinfo.suppPubInfo = &pub;
ASN1_MALLOC_ENCODE(PkinitSP80056AOtherInfo, other->data, other->length,
&otherinfo, &size, ret);
free(pub.data);
if (ret) {
krb5_set_error_string(context, "out of memory");
return ret;
}
if (other->length != size)
krb5_abortx(context, "asn1 compiler internal error");
return 0;
}
krb5_error_code
_krb5_pk_kdf(krb5_context context,
const AlgorithmIdentifier *algorithmID,
const void *dhdata,
size_t dhsize,
krb5_const_principal client,
krb5_const_principal server,
krb5_enctype enctype,
const krb5_data *as_req,
const krb5_data *pk_as_rep,
const Ticket *ticket,
krb5_keyblock *key)
{
struct encryption_type *et = _find_enctype(enctype);
krb5_error_code ret;
krb5_data other;
size_t keylen, offset;
uint32_t counter = 1;
unsigned char *keydata;
unsigned char shaoutput[20];
if(et == NULL) {
krb5_set_error_string(context, "encryption type %d not supported",
enctype);
return KRB5_PROG_ETYPE_NOSUPP;
}
keylen = (et->keytype->bits + 7) / 8;
keydata = malloc(keylen);
if (keydata == NULL) {
krb5_set_error_string(context, "malloc: out of memory");
return ENOMEM;
}
ret = encode_otherinfo(context, algorithmID, client, server,
enctype, as_req, pk_as_rep, ticket, &other);
if (ret) {
free(keydata);
return ret;
}
offset = 0;
do {
unsigned char cdata[4];
SHA_CTX m;
SHA1_Init(&m);
_krb5_put_int(cdata, counter, 4);
SHA1_Update(&m, cdata, 4);
SHA1_Update(&m, dhdata, dhsize);
SHA1_Update(&m, other.data, other.length);
SHA1_Final(shaoutput, &m);
memcpy((unsigned char *)keydata + offset,
shaoutput,
min(keylen - offset, sizeof(shaoutput)));
offset += sizeof(shaoutput);
counter++;
} while (keylen < offset);
memset(shaoutput, 0, sizeof(shaoutput));
free(other.data);
ret = krb5_random_to_key(context, enctype, keydata, keylen, key);
memset(keydata, 0, sizeof(keylen));
free(keydata);
return ret;
}
krb5_error_code KRB5_LIB_FUNCTION
krb5_crypto_prf_length(krb5_context context,
krb5_enctype type,