From c0e8144c5d1e402b36ebe04b843eba62e7ab9958 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 9 Aug 2005 03:04:47 +0000 Subject: r9221: Try to merge Heimdal across from lorikeet-heimdal to samba4. This is my first attempt at this, so there may be a few rough edges. Andrew Bartlett (This used to be commit 9a1d2f2fec67930975da856a2d365345cec46216) --- source4/heimdal/lib/krb5/crypto.c | 88 +++++++++-- source4/heimdal/lib/krb5/get_cred.c | 6 +- source4/heimdal/lib/krb5/keytab.c | 14 +- source4/heimdal/lib/krb5/keytab_file.c | 10 +- source4/heimdal/lib/krb5/krb5-private.h | 15 +- source4/heimdal/lib/krb5/krb5-protos.h | 6 +- source4/heimdal/lib/krb5/krb5.h | 52 +++---- source4/heimdal/lib/krb5/pkinit.c | 188 +++++++++++++----------- source4/heimdal/lib/krb5/principal.c | 18 +-- source4/heimdal/lib/krb5/rd_cred.c | 9 +- source4/heimdal/lib/krb5/test_crypto_wrapping.c | 163 ++++++++++++++++++++ source4/heimdal/lib/krb5/test_pkinit_dh2key.c | 110 ++++++++++++++ 12 files changed, 518 insertions(+), 161 deletions(-) create mode 100644 source4/heimdal/lib/krb5/test_crypto_wrapping.c create mode 100644 source4/heimdal/lib/krb5/test_pkinit_dh2key.c (limited to 'source4/heimdal/lib/krb5') diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 2b1ac3a5c4..c8fa556696 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: crypto.c,v 1.123 2005/06/29 22:20:33 lha Exp $"); +RCSID("$Id: crypto.c,v 1.128 2005/07/20 07:22:43 lha Exp $"); #undef CRYPTO_DEBUG #ifdef CRYPTO_DEBUG @@ -2124,7 +2124,8 @@ verify_checksum(krb5_context context, return KRB5_PROG_SUMTYPE_NOSUPP; } if(ct->checksumsize != cksum->checksum.length) { - krb5_clear_error_string (context); + krb5_set_error_string (context, "checksum length was %d, but should be %d for checksum type %s", + cksum->checksum.length, ct->checksumsize, ct->name); return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */ } keyed_checksum = (ct->flags & F_KEYED) != 0; @@ -2145,8 +2146,11 @@ verify_checksum(krb5_context context, (*ct->checksum)(context, dkey, data, len, usage, &c); - if(c.checksum.length != cksum->checksum.length || - memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) { + if(c.checksum.length != cksum->checksum.length) { + krb5_set_error_string (context, "(INTERNAL ERROR) our checksum length was %d, but should be %d for checksum type %s", + c.checksum.length, ct->checksumsize, ct->name); + ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; + } else if (memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) { krb5_clear_error_string (context); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; } else { @@ -3246,7 +3250,7 @@ static krb5_error_code encrypt_internal_derived(krb5_context context, krb5_crypto crypto, unsigned usage, - void *data, + const void *data, size_t len, krb5_data *result, void *ivec) @@ -3315,7 +3319,7 @@ encrypt_internal_derived(krb5_context context, static krb5_error_code encrypt_internal(krb5_context context, krb5_crypto crypto, - void *data, + const void *data, size_t len, krb5_data *result, void *ivec) @@ -3395,7 +3399,7 @@ static krb5_error_code encrypt_internal_special(krb5_context context, krb5_crypto crypto, int usage, - void *data, + const void *data, size_t len, krb5_data *result, void *ivec) @@ -3624,7 +3628,7 @@ krb5_error_code KRB5_LIB_FUNCTION krb5_encrypt_ivec(krb5_context context, krb5_crypto crypto, unsigned usage, - void *data, + const void *data, size_t len, krb5_data *result, void *ivec) @@ -3643,7 +3647,7 @@ krb5_error_code KRB5_LIB_FUNCTION krb5_encrypt(krb5_context context, krb5_crypto crypto, unsigned usage, - void *data, + const void *data, size_t len, krb5_data *result) { @@ -4228,14 +4232,9 @@ wrapped_length (krb5_context context, { struct encryption_type *et = crypto->et; size_t padsize = et->padsize; - size_t checksumsize; + size_t checksumsize = CHECKSUMSIZE(et->checksum); size_t res; - if (et->keyed_checksum) - checksumsize = et->keyed_checksum->checksumsize; - else - checksumsize = et->checksum->checksumsize; - res = et->confoundersize + checksumsize + data_len; res = (res + padsize - 1) / padsize * padsize; return res; @@ -4306,6 +4305,65 @@ krb5_random_to_key(krb5_context context, return 0; } +krb5_error_code +_krb5_pk_octetstring2key(krb5_context context, + krb5_enctype type, + const void *dhdata, + size_t dhsize, + const heim_octet_string *c_n, + const heim_octet_string *k_n, + krb5_keyblock *key) +{ + struct encryption_type *et = _find_enctype(type); + krb5_error_code ret; + size_t keylen, offset; + void *keydata; + unsigned char counter; + unsigned char shaoutput[20]; + + if(et == NULL) { + krb5_set_error_string(context, "encryption type %d not supported", + type); + 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; + } + + counter = 0; + offset = 0; + do { + SHA_CTX m; + + SHA1_Init(&m); + SHA1_Update(&m, &counter, 1); + SHA1_Update(&m, dhdata, dhsize); + if (c_n) + SHA1_Update(&m, c_n->data, c_n->length); + if (k_n) + SHA1_Update(&m, k_n->data, k_n->length); + SHA1_Final(shaoutput, &m); + + memcpy((unsigned char *)keydata + offset, + shaoutput, + min(keylen - offset, sizeof(shaoutput))); + + offset += sizeof(shaoutput); + counter++; + } while(offset < keylen); + memset(shaoutput, 0, sizeof(shaoutput)); + + ret = krb5_random_to_key(context, type, keydata, keylen, key); + memset(keydata, 0, sizeof(keylen)); + free(keydata); + return ret; +} + + #ifdef CRYPTO_DEBUG static krb5_error_code diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index 63fb55608c..7043b8ae51 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -33,7 +33,7 @@ #include -RCSID("$Id: get_cred.c,v 1.107 2005/06/16 22:57:14 lha Exp $"); +RCSID("$Id: get_cred.c,v 1.108 2005/07/13 07:38:02 lha Exp $"); /* * Take the `body' and encode it into `padata' using the credentials @@ -837,10 +837,6 @@ krb5_get_credentials_with_flags(krb5_context context, if (in_creds->session.keytype) options |= KRB5_TC_MATCH_KEYTYPE; - ret = krb5_cc_retrieve_cred(context, - ccache, - options, - in_creds, res_creds); /* * If we got a credential, check if credential is expired before * returning it. diff --git a/source4/heimdal/lib/krb5/keytab.c b/source4/heimdal/lib/krb5/keytab.c index a405664122..23f6685049 100644 --- a/source4/heimdal/lib/krb5/keytab.c +++ b/source4/heimdal/lib/krb5/keytab.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab.c,v 1.60 2005/05/19 14:04:45 lha Exp $"); +RCSID("$Id: keytab.c,v 1.62 2005/07/06 01:14:42 lha Exp $"); /* * Register a new keytab in `ops' @@ -240,8 +240,8 @@ krb5_kt_get_name(krb5_context context, } /* - * Finish using the keytab in `id'. All resources will be released. - * Return 0 or an error. + * Finish using the keytab in `id'. All resources will be released, + * even on errors. Return 0 or an error. */ krb5_error_code KRB5_LIB_FUNCTION @@ -251,8 +251,8 @@ krb5_kt_close(krb5_context context, krb5_error_code ret; ret = (*id->close)(context, id); - if(ret == 0) - free(id); + memset(id, 0, sizeof(*id)); + free(id); return ret; } @@ -302,8 +302,10 @@ krb5_kt_get_entry(krb5_context context, return (*id->get)(context, id, principal, kvno, enctype, entry); ret = krb5_kt_start_seq_get (context, id, &cursor); - if (ret) + if (ret) { + krb5_clear_error_string(context); return KRB5_KT_NOTFOUND; /* XXX i.e. file not found */ + } entry->vno = 0; while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) { diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c index dca09ff6f3..6ff2680ed1 100644 --- a/source4/heimdal/lib/krb5/keytab_file.c +++ b/source4/heimdal/lib/krb5/keytab_file.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_file.c,v 1.18 2005/05/31 21:50:43 lha Exp $"); +RCSID("$Id: keytab_file.c,v 1.20 2005/07/13 06:08:07 lha Exp $"); #define KRB5_KT_VNO_1 1 #define KRB5_KT_VNO_2 2 @@ -332,6 +332,12 @@ fkt_start_seq_get_int(krb5_context context, return ret; } c->sp = krb5_storage_from_fd(c->fd); + if (c->sp == NULL) { + _krb5_xunlock(context, c->fd); + close(c->fd); + krb5_set_error_string (context, "malloc: out of memory"); + return ENOMEM; + } krb5_storage_set_eof_code(c->sp, KRB5_KT_END); ret = krb5_ret_int8(c->sp, &pvno); if(ret) { diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h index e59cab8ca7..b877de8cf2 100644 --- a/source4/heimdal/lib/krb5/krb5-private.h +++ b/source4/heimdal/lib/krb5/krb5-private.h @@ -329,6 +329,14 @@ _krb5_put_int ( unsigned long /*value*/, size_t /*size*/); +krb5_error_code KRB5_LIB_FUNCTION +_krb5_rd_rep_type ( + krb5_context /*context*/, + krb5_auth_context /*auth_context*/, + const krb5_data */*inbuf*/, + krb5_ap_rep_enc_part **/*repl*/, + krb5_boolean /*dce_style_response*/); + int _krb5_send_and_recv_tcp ( int /*fd*/, @@ -348,11 +356,4 @@ _krb5_xunlock ( krb5_context /*context*/, int /*fd*/); -krb5_error_code KRB5_LIB_FUNCTION -_krb5_rd_rep_type(krb5_context context, - krb5_auth_context auth_context, - const krb5_data *inbuf, - krb5_ap_rep_enc_part **repl, - krb5_boolean dce_style_response); - #endif /* __krb5_private_h__ */ diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h index cee8a02419..f306bf949f 100644 --- a/source4/heimdal/lib/krb5/krb5-protos.h +++ b/source4/heimdal/lib/krb5/krb5-protos.h @@ -1305,7 +1305,7 @@ krb5_encrypt ( krb5_context /*context*/, krb5_crypto /*crypto*/, unsigned /*usage*/, - void */*data*/, + const void */*data*/, size_t /*len*/, krb5_data */*result*/); @@ -1324,7 +1324,7 @@ krb5_encrypt_ivec ( krb5_context /*context*/, krb5_crypto /*crypto*/, unsigned /*usage*/, - void */*data*/, + const void */*data*/, size_t /*len*/, krb5_data */*result*/, void */*ivec*/); @@ -2424,7 +2424,7 @@ krb5_principal_get_comp_string ( const char* KRB5_LIB_FUNCTION krb5_principal_get_realm ( krb5_context /*context*/, - krb5_const_principal /*principal*/); + krb5_principal /*principal*/); int KRB5_LIB_FUNCTION krb5_principal_get_type ( diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 890a500caa..5789bff205 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5.h,v 1.236 2005/06/11 00:05:24 lha Exp $ */ +/* $Id: krb5.h,v 1.237 2005/07/09 14:47:21 lha Exp $ */ #ifndef __KRB5_H__ #define __KRB5_H__ @@ -567,8 +567,8 @@ typedef struct krb5_auth_context_data { krb5_rcache rcache; - krb5_keytype keytype; /* ¿requested key type ? */ - krb5_cksumtype cksumtype; /* ¡requested checksum type! */ + krb5_keytype keytype; /* ¿requested key type ? */ + krb5_cksumtype cksumtype; /* ¡requested checksum type! */ }krb5_auth_context_data, *krb5_auth_context; @@ -617,28 +617,28 @@ typedef struct _krb5_prompt { krb5_prompt_type type; } krb5_prompt; -typedef int (*krb5_prompter_fct)(krb5_context context, - void *data, - const char *name, - const char *banner, - int num_prompts, - krb5_prompt prompts[]); -typedef krb5_error_code (*krb5_key_proc)(krb5_context context, - krb5_enctype type, - krb5_salt salt, - krb5_const_pointer keyseed, - krb5_keyblock **key); -typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context, - krb5_keyblock *key, - krb5_key_usage usage, - krb5_const_pointer decrypt_arg, - krb5_kdc_rep *dec_rep); -typedef krb5_error_code (*krb5_s2k_proc)(krb5_context context, - krb5_enctype type, - krb5_const_pointer keyseed, - krb5_salt salt, - krb5_data *s2kparms, - krb5_keyblock **key); +typedef int (*krb5_prompter_fct)(krb5_context /*context*/, + void * /*data*/, + const char * /*name*/, + const char * /*banner*/, + int /*num_prompts*/, + krb5_prompt /*prompts*/[]); +typedef krb5_error_code (*krb5_key_proc)(krb5_context /*context*/, + krb5_enctype /*type*/, + krb5_salt /*salt*/, + krb5_const_pointer /*keyseed*/, + krb5_keyblock ** /*key*/); +typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context /*context*/, + krb5_keyblock * /*key*/, + krb5_key_usage /*usage*/, + krb5_const_pointer /*decrypt_arg*/, + krb5_kdc_rep * /*dec_rep*/); +typedef krb5_error_code (*krb5_s2k_proc)(krb5_context /*context*/, + krb5_enctype /*type*/, + krb5_const_pointer /*keyseed*/, + krb5_salt /*salt*/, + krb5_data * /*s2kparms*/, + krb5_keyblock ** /*key*/); struct _krb5_get_init_creds_opt_private; diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index 84db4fe544..35a751c291 100755 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: pkinit.c,v 1.55 2005/05/19 18:49:05 lha Exp $"); +RCSID("$Id: pkinit.c,v 1.58 2005/07/23 10:42:01 lha Exp $"); #ifdef PKINIT @@ -407,34 +407,25 @@ _krb5_pk_create_sign(krb5_context context, goto out; } - sd.certificates->data = NULL; - sd.certificates->length = 0; + i = sk_X509_num(id->cert); + sd.certificates->val = malloc(sizeof(sd.certificates->val[0]) * i); + if (sd.certificates->val == NULL) { + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + sd.certificates->len = i; for (i = 0; i < sk_X509_num(id->cert); i++) { - void *data; - OPENSSL_ASN1_MALLOC_ENCODE(X509, - buf.data, - buf.length, + sd.certificates->val[i].data, + sd.certificates->val[i].length, sk_X509_value(id->cert, i), ret); if (ret) { krb5_clear_error_string(context); goto out; } - data = realloc(sd.certificates->data, - sd.certificates->length + buf.length); - if (data == NULL) { - free(buf.data); - krb5_clear_error_string(context); - ret = ENOMEM; - goto out; - } - memcpy(((char *)data) + sd.certificates->length, - buf.data, buf.length); - sd.certificates->length += buf.length; - sd.certificates->data = data; - free(buf.data); } ASN1_MALLOC_ENCODE(SignedData, sd_data->data, sd_data->length, @@ -563,7 +554,7 @@ build_auth_pack(krb5_context context, if (ret == 0 && dh) { DomainParameters dp; heim_integer dh_pub_key; - krb5_data buf; + krb5_data dhbuf; size_t size; ALLOC(a->clientPublicValue, 1); @@ -615,25 +606,25 @@ build_auth_pack(krb5_context context, if (ret) return ret; - buf.length = length_heim_integer(&dh_pub_key); - buf.data = malloc(buf.length); - if (buf.data == NULL) { + dhbuf.length = length_heim_integer(&dh_pub_key); + dhbuf.data = malloc(dhbuf.length); + if (dhbuf.data == NULL) { free_heim_integer(&dh_pub_key); krb5_set_error_string(context, "malloc: out of memory"); return ret; } - ret = der_put_heim_integer((char *)buf.data + buf.length - 1, - buf.length, &dh_pub_key, &size); + ret = der_put_heim_integer((char *)dhbuf.data + dhbuf.length - 1, + dhbuf.length, &dh_pub_key, &size); free_heim_integer(&dh_pub_key); if (ret) { - free(buf.data); + free(dhbuf.data); return ret; } - if (size != buf.length) + if (size != dhbuf.length) krb5_abortx(context, "asn1 internal error"); - a->clientPublicValue->subjectPublicKey.length = buf.length * 8; - a->clientPublicValue->subjectPublicKey.data = buf.data; + a->clientPublicValue->subjectPublicKey.length = dhbuf.length * 8; + a->clientPublicValue->subjectPublicKey.data = dhbuf.data; } return ret; @@ -894,7 +885,7 @@ _krb5_pk_mk_padata(krb5_context context, if (provisioning_server) { /* PacketCable requires the PROV-SRV-LOCATION authenticator */ - const PROV_SRV_LOCATION prov_server = (char *)provisioning_server; + const PROV_SRV_LOCATION prov_server = rk_UNCONST(provisioning_server); ASN1_MALLOC_ENCODE(PROV_SRV_LOCATION, buf.data, buf.length, &prov_server, &size, ret); @@ -1104,7 +1095,7 @@ pk_verify_chain_standard(krb5_context context, } static int -cert_to_X509(krb5_context context, CertificateSetReal *set, +cert_to_X509(krb5_context context, CertificateSet *set, STACK_OF(X509_CRL) **certs) { krb5_error_code ret; @@ -1112,6 +1103,9 @@ cert_to_X509(krb5_context context, CertificateSetReal *set, *certs = sk_X509_new_null(); + if (set == NULL) + return 0; + ret = 0; for (i = 0; i < set->len; i++) { unsigned char *p; @@ -1134,45 +1128,6 @@ cert_to_X509(krb5_context context, CertificateSetReal *set, return ret; } -static krb5_error_code -any_to_CertificateSet(krb5_context context, heim_any *cert, - CertificateSetReal *set) -{ - size_t size, len, length; - heim_any *val; - int ret; - char *p; - - set->len = 0; - set->val = NULL; - - len = 0; - p = cert->data; - length = cert->length; - while (len < cert->length) { - val = realloc(set->val, (set->len + 1) * sizeof(set->val[0])); - if (val == NULL) { - ret = ENOMEM; - goto out; - } - set->val = val; - ret = decode_heim_any(p, length, &set->val[set->len], &size); - if (ret) - goto out; - set->len++; - - p += size; - len += size; - length -= size; - } - return 0; - out: - krb5_clear_error_string(context); - free_CertificateSetReal(set); - set->val = NULL; - return ret; -} - krb5_error_code KRB5_LIB_FUNCTION _krb5_pk_verify_sign(krb5_context context, const char *data, @@ -1187,7 +1142,6 @@ _krb5_pk_verify_sign(krb5_context context, const EVP_MD *evp_type; EVP_PKEY *public_key; krb5_error_code ret; - CertificateSetReal set; EVP_MD_CTX md; X509 *cert; SignedData sd; @@ -1227,15 +1181,14 @@ _krb5_pk_verify_sign(krb5_context context, signer_info = &sd.signerInfos.val[0]; - ret = any_to_CertificateSet(context, sd.certificates, &set); - if (ret) { - krb5_set_error_string(context, - "PKINIT: failed to decode CertificateSet"); - goto out; - } + { + CertificateSet set; + set.val = sd.certificates->val; + set.len = sd.certificates->len; - ret = cert_to_X509(context, &set, &certificates); - free_CertificateSetReal(&set); + ret = cert_to_X509(context, &set, &certificates); + free_CertificateSet(&set); + } if (ret) { krb5_set_error_string(context, "PKINIT: failed to decode Certificates"); @@ -1530,7 +1483,6 @@ pk_rd_pa_reply_enckey(krb5_context context, /* win2k uses ContentInfo */ if (win2k_compat) { ContentInfo ci; - size_t size; ret = decode_ContentInfo(p, length, &ci, &size); if (ret) { @@ -1604,6 +1556,8 @@ pk_rd_pa_reply_dh(krb5_context context, ContentInfo *rep, krb5_pk_init_ctx ctx, krb5_enctype etype, + const DHNonce *c_n, + const DHNonce *k_n, unsigned nonce, PA_DATA *pa, krb5_keyblock **key) @@ -1666,6 +1620,30 @@ pk_rd_pa_reply_dh(krb5_context context, goto out; } + if (kdc_dh_info.dhKeyExpiration) { + if (k_n == NULL) { + krb5_set_error_string(context, "pkinit; got key expiration " + "without server nonce"); + ret = KRB5KRB_ERR_GENERIC; + goto out; + } + if (c_n == NULL) { + krb5_set_error_string(context, "pkinit; got DH reuse but no " + "client nonce"); + ret = KRB5KRB_ERR_GENERIC; + goto out; + } + } else { + if (k_n) { + krb5_set_error_string(context, "pkinit; got server nonce " + "without key expiration"); + ret = KRB5KRB_ERR_GENERIC; + goto out; + } + c_n = NULL; + } + + p = kdc_dh_info.subjectPublicKey.data; size = (kdc_dh_info.subjectPublicKey.length + 7) / 8; dh_pub_key = d2i_ASN1_INTEGER(NULL, &p, size); @@ -1684,14 +1662,21 @@ pk_rd_pa_reply_dh(krb5_context context, goto out; } - dh_gen_key = malloc(DH_size(ctx->dh)); + dh_gen_keylen = DH_size(ctx->dh); + size = BN_num_bytes(ctx->dh->p); + if (size < dh_gen_keylen) + size = dh_gen_keylen; + + dh_gen_key = malloc(size); if (dh_gen_key == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } + memset(dh_gen_key, 0, size - dh_gen_keylen); - dh_gen_keylen = DH_compute_key(dh_gen_key, kdc_dh_pubkey, ctx->dh); + dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen), + kdc_dh_pubkey, ctx->dh); if (dh_gen_keylen == -1) { krb5_set_error_string(context, "PKINIT: Can't compute Diffie-Hellman key (%s)", @@ -1707,7 +1692,11 @@ pk_rd_pa_reply_dh(krb5_context context, goto out; } - ret = krb5_random_to_key(context, etype, dh_gen_key, dh_gen_keylen, *key); + ret = _krb5_pk_octetstring2key(context, + etype, + dh_gen_key, dh_gen_keylen, + c_n, k_n, + *key); if (ret) { krb5_set_error_string(context, "PKINIT: can't create key from DH key"); @@ -1761,6 +1750,25 @@ _krb5_pk_rd_pa_reply(krb5_context context, return ret; switch (rep.element) { + case choice_PA_PK_AS_REP_dhInfo: + ret = decode_ContentInfo(rep.u.dhInfo.dhSignedData.data, + rep.u.dhInfo.dhSignedData.length, + &ci, + &size); + if (ret) { + krb5_set_error_string(context, + "PKINIT: -25 decoding failed DH " + "ContentInfo: %d", ret); + + free_PA_PK_AS_REP(&rep); + break; + } + ret = pk_rd_pa_reply_dh(context, &ci, ctx, + etype, NULL, NULL, nonce, pa, key); + free_ContentInfo(&ci); + free_PA_PK_AS_REP(&rep); + + break; case choice_PA_PK_AS_REP_encKeyPack: ret = decode_ContentInfo(rep.u.encKeyPack.data, rep.u.encKeyPack.length, @@ -1799,7 +1807,8 @@ _krb5_pk_rd_pa_reply(krb5_context context, switch(rep19.element) { case choice_PA_PK_AS_REP_19_dhSignedData: ret = pk_rd_pa_reply_dh(context, &rep19.u.dhSignedData, ctx, - etype, nonce, pa, key); + etype, NULL, NULL, + nonce, pa, key); break; case choice_PA_PK_AS_REP_19_encKeyPack: ret = pk_rd_pa_reply_enckey(context, 0, @@ -2314,8 +2323,8 @@ _krb5_pk_load_openssl_id(krb5_context context, FILE *f; krb5_error_code (*load_pair)(krb5_context, char *, - krb5_prompter_fct prompter, - void * prompter_data, + krb5_prompter_fct, + void *, const char *, struct krb5_pk_identity *) = NULL; @@ -2553,24 +2562,29 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, dh = DH_new(); if (dh == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); _krb5_get_init_creds_opt_free_pkinit(opt); return ENOMEM; } opt->private->pk_init_ctx->dh = dh; if (!BN_hex2bn(&dh->p, P)) { + krb5_set_error_string(context, "malloc: out of memory"); _krb5_get_init_creds_opt_free_pkinit(opt); return ENOMEM; } if (!BN_hex2bn(&dh->g, G)) { + krb5_set_error_string(context, "malloc: out of memory"); _krb5_get_init_creds_opt_free_pkinit(opt); return ENOMEM; } if (!BN_hex2bn(&dh->q, Q)) { + krb5_set_error_string(context, "malloc: out of memory"); _krb5_get_init_creds_opt_free_pkinit(opt); return ENOMEM; } /* XXX generate a new key for each request ? */ if (DH_generate_key(dh) != 1) { + krb5_set_error_string(context, "malloc: out of memory"); _krb5_get_init_creds_opt_free_pkinit(opt); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index b7194b4c41..b510478f65 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -76,7 +76,7 @@ krb5_principal_get_type(krb5_context context, const char* KRB5_LIB_FUNCTION krb5_principal_get_realm(krb5_context context, - krb5_const_principal principal) + krb5_principal principal) { return princ_realm(principal); } @@ -235,19 +235,19 @@ static const char replace_chars[] = " ntb\\/@"; #define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0); static size_t -quote_string(const char *s, char *out, size_t string_index, size_t len) +quote_string(const char *s, char *out, size_t idx, size_t len) { const char *p, *q; - for(p = s; *p && string_index < len; p++){ + for(p = s; *p && idx < len; p++){ if((q = strchr(quotable_chars, *p))){ - add_char(out, string_index, len, '\\'); - add_char(out, string_index, len, replace_chars[q - quotable_chars]); + add_char(out, idx, len, '\\'); + add_char(out, idx, len, replace_chars[q - quotable_chars]); }else - add_char(out, string_index, len, *p); + add_char(out, idx, len, *p); } - if(string_index < len) - out[string_index] = '\0'; - return string_index; + if(idx < len) + out[idx] = '\0'; + return idx; } diff --git a/source4/heimdal/lib/krb5/rd_cred.c b/source4/heimdal/lib/krb5/rd_cred.c index 9129eceeff..2571591e9d 100644 --- a/source4/heimdal/lib/krb5/rd_cred.c +++ b/source4/heimdal/lib/krb5/rd_cred.c @@ -33,7 +33,7 @@ #include -RCSID("$Id: rd_cred.c,v 1.23 2005/06/17 04:31:48 lha Exp $"); +RCSID("$Id: rd_cred.c,v 1.24 2005/07/13 08:22:50 lha Exp $"); static krb5_error_code compare_addrs(krb5_context context, @@ -68,6 +68,8 @@ krb5_rd_cred(krb5_context context, krb5_crypto crypto; int i; + memset(&enc_krb_cred_part, 0, sizeof(enc_krb_cred_part)); + if ((auth_context->flags & (KRB5_AUTH_CONTEXT_RET_TIME | KRB5_AUTH_CONTEXT_RET_SEQUENCE)) && outdata == NULL) @@ -262,9 +264,14 @@ krb5_rd_cred(krb5_context context, } (*ret_creds)[i] = NULL; + + free_KRB_CRED (&cred); + free_EncKrbCredPart(&enc_krb_cred_part); + return 0; out: + free_EncKrbCredPart(&enc_krb_cred_part); free_KRB_CRED (&cred); if(*ret_creds) { for(i = 0; (*ret_creds)[i]; i++) diff --git a/source4/heimdal/lib/krb5/test_crypto_wrapping.c b/source4/heimdal/lib/krb5/test_crypto_wrapping.c new file mode 100644 index 0000000000..37d9bbacb7 --- /dev/null +++ b/source4/heimdal/lib/krb5/test_crypto_wrapping.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of KTH nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "krb5_locl.h" +#include +#include + +RCSID("$Id: test_crypto_wrapping.c,v 1.2 2005/07/09 01:31:43 lha Exp $"); + +static void +test_wrapping(krb5_context context, + size_t min_size, + size_t max_size, + size_t step, + krb5_enctype etype) +{ + krb5_error_code ret; + krb5_keyblock key; + krb5_crypto crypto; + krb5_data data; + char *etype_name; + void *buf; + size_t size; + + ret = krb5_generate_random_keyblock(context, etype, &key); + if (ret) + krb5_err(context, 1, ret, "krb5_generate_random_keyblock"); + + ret = krb5_enctype_to_string(context, etype, &etype_name); + if (ret) + krb5_err(context, 1, ret, "krb5_enctype_to_string"); + + buf = malloc(max_size); + if (buf == NULL) + krb5_errx(context, 1, "out of memory"); + memset(buf, 0, max_size); + + ret = krb5_crypto_init(context, &key, 0, &crypto); + if (ret) + krb5_err(context, 1, ret, "krb5_crypto_init"); + + for (size = min_size; size < max_size; size += step) { + size_t wrapped_size; + + ret = krb5_encrypt(context, crypto, 0, buf, size, &data); + if (ret) + krb5_err(context, 1, ret, "encrypt size %d using %s", + size, etype_name); + + wrapped_size = krb5_get_wrapped_length(context, crypto, size); + + if (wrapped_size != data.length) + krb5_errx(context, 1, "calculated wrapped length %lu != " + "real wrapped length %lu for data length %lu using " + "enctype %s", + (unsigned long)wrapped_size, + (unsigned long)data.length, + (unsigned long)size, + etype_name); + krb5_data_free(&data); + } + + free(buf); + krb5_crypto_destroy(context, crypto); + krb5_free_keyblock_contents(context, &key); +} + + + +static int version_flag = 0; +static int help_flag = 0; + +static struct getargs args[] = { + {"version", 0, arg_flag, &version_flag, + "print version", NULL }, + {"help", 0, arg_flag, &help_flag, + NULL, NULL } +}; + +static void +usage (int ret) +{ + arg_printusage (args, + sizeof(args)/sizeof(*args), + NULL, + ""); + exit (ret); +} + +int +main(int argc, char **argv) +{ + krb5_context context; + krb5_error_code ret; + int i, optidx = 0; + + krb5_enctype enctypes[] = { + ETYPE_DES_CBC_CRC, + ETYPE_DES_CBC_MD4, + ETYPE_DES_CBC_MD5, + ETYPE_DES3_CBC_SHA1, + ETYPE_ARCFOUR_HMAC_MD5, + ETYPE_AES128_CTS_HMAC_SHA1_96, + ETYPE_AES256_CTS_HMAC_SHA1_96 + }; + + setprogname(argv[0]); + + if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) + usage(1); + + if (help_flag) + usage (0); + + if(version_flag){ + print_version(NULL); + exit(0); + } + + argc -= optidx; + argv += optidx; + + ret = krb5_init_context(&context); + if (ret) + errx (1, "krb5_init_context failed: %d", ret); + + for (i = 0; i < sizeof(enctypes)/sizeof(enctypes[0]); i++) { + test_wrapping(context, 0, 1024, 1, enctypes[i]); + test_wrapping(context, 1024, 1024 * 100, 1024, enctypes[i]); + } + krb5_free_context(context); + + return 0; +} diff --git a/source4/heimdal/lib/krb5/test_pkinit_dh2key.c b/source4/heimdal/lib/krb5/test_pkinit_dh2key.c new file mode 100644 index 0000000000..a40c218e12 --- /dev/null +++ b/source4/heimdal/lib/krb5/test_pkinit_dh2key.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of KTH nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "krb5_locl.h" +#include +#include + +RCSID("$Id: test_pkinit_dh2key.c,v 1.1 2005/07/20 16:27:58 lha Exp $"); + +static void +test_dh2key(krb5_context context, + const heim_octet_string *K, + const heim_octet_string *c_n, + const heim_octet_string *k_n, + krb5_enctype etype) +{ + return; +} + + + +static int version_flag = 0; +static int help_flag = 0; + +static struct getargs args[] = { + {"version", 0, arg_flag, &version_flag, + "print version", NULL }, + {"help", 0, arg_flag, &help_flag, + NULL, NULL } +}; + +static void +usage (int ret) +{ + arg_printusage (args, + sizeof(args)/sizeof(*args), + NULL, + ""); + exit (ret); +} + +int +main(int argc, char **argv) +{ + krb5_context context; + krb5_error_code ret; + int i, optidx = 0; + + krb5_enctype enctypes[] = { + ETYPE_AES128_CTS_HMAC_SHA1_96, + ETYPE_AES256_CTS_HMAC_SHA1_96 + }; + + setprogname(argv[0]); + + if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) + usage(1); + + if (help_flag) + usage (0); + + if(version_flag){ + print_version(NULL); + exit(0); + } + + argc -= optidx; + argv += optidx; + + ret = krb5_init_context(&context); + if (ret) + errx (1, "krb5_init_context failed: %d", ret); + + for (i = 0; i < sizeof(enctypes)/sizeof(enctypes[0]); i++) { + test_dh2key(context, NULL, NULL, NULL, enctypes[i]); + } + + krb5_free_context(context); + + return 0; +} -- cgit