summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/krb5
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-08-09 03:04:47 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:31:33 -0500
commitc0e8144c5d1e402b36ebe04b843eba62e7ab9958 (patch)
tree1b885ceee1a88e8cb2822051690b023c8f8acb78 /source4/heimdal/lib/krb5
parent4b93e377cd9809199487e20fa53d8a2c98ad32ea (diff)
downloadsamba-c0e8144c5d1e402b36ebe04b843eba62e7ab9958.tar.gz
samba-c0e8144c5d1e402b36ebe04b843eba62e7ab9958.tar.bz2
samba-c0e8144c5d1e402b36ebe04b843eba62e7ab9958.zip
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)
Diffstat (limited to 'source4/heimdal/lib/krb5')
-rw-r--r--source4/heimdal/lib/krb5/crypto.c88
-rw-r--r--source4/heimdal/lib/krb5/get_cred.c6
-rw-r--r--source4/heimdal/lib/krb5/keytab.c14
-rw-r--r--source4/heimdal/lib/krb5/keytab_file.c10
-rw-r--r--source4/heimdal/lib/krb5/krb5-private.h15
-rw-r--r--source4/heimdal/lib/krb5/krb5-protos.h6
-rw-r--r--source4/heimdal/lib/krb5/krb5.h52
-rwxr-xr-xsource4/heimdal/lib/krb5/pkinit.c188
-rw-r--r--source4/heimdal/lib/krb5/principal.c18
-rw-r--r--source4/heimdal/lib/krb5/rd_cred.c9
-rw-r--r--source4/heimdal/lib/krb5/test_crypto_wrapping.c163
-rw-r--r--source4/heimdal/lib/krb5/test_pkinit_dh2key.c110
12 files changed, 518 insertions, 161 deletions
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 <krb5_locl.h>
-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 <krb5_locl.h>
-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 <err.h>
+#include <getarg.h>
+
+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 <err.h>
+#include <getarg.h>
+
+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;
+}