summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/krb5/pac.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/krb5/pac.c')
-rw-r--r--source4/heimdal/lib/krb5/pac.c157
1 files changed, 88 insertions, 69 deletions
diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c
index 69d9879330..d50052c8bc 100644
--- a/source4/heimdal/lib/krb5/pac.c
+++ b/source4/heimdal/lib/krb5/pac.c
@@ -76,6 +76,43 @@ struct krb5_pac_data {
static const char zeros[PAC_ALIGNMENT] = { 0 };
/*
+ * HMAC-MD5 checksum over any key (needed for the PAC routines)
+ */
+
+static krb5_error_code
+HMAC_MD5_any_checksum(krb5_context context,
+ const krb5_keyblock *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *result)
+{
+ struct key_data local_key;
+ krb5_error_code ret;
+
+ memset(&local_key, 0, sizeof(local_key));
+
+ ret = krb5_copy_keyblock(context, key, &local_key.key);
+ if (ret)
+ return ret;
+
+ ret = krb5_data_alloc (&result->checksum, 16);
+ if (ret) {
+ krb5_free_keyblock(context, local_key.key);
+ return ret;
+ }
+
+ result->cksumtype = CKSUMTYPE_HMAC_MD5;
+ ret = _krb5_HMAC_MD5_checksum(context, &local_key, data, len, usage, result);
+ if (ret)
+ krb5_data_free(&result->checksum);
+
+ krb5_free_keyblock(context, local_key.key);
+ return ret;
+}
+
+
+/*
*
*/
@@ -90,15 +127,13 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
p = calloc(1, sizeof(*p));
if (p == NULL) {
- ret = ENOMEM;
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ ret = _krb5_enomem(context);
goto out;
}
sp = krb5_storage_from_readonly_mem(ptr, len);
if (sp == NULL) {
- ret = ENOMEM;
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ ret = _krb5_enomem(context);
goto out;
}
krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
@@ -121,8 +156,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
p->pac = calloc(1,
sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (tmp - 1)));
if (p->pac == NULL) {
- ret = ENOMEM;
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ ret = _krb5_enomem(context);
goto out;
}
@@ -232,26 +266,22 @@ krb5_pac_init(krb5_context context, krb5_pac *pac)
p = calloc(1, sizeof(*p));
if (p == NULL) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
+ return _krb5_enomem(context);
}
p->pac = calloc(1, sizeof(*p->pac));
if (p->pac == NULL) {
free(p);
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
+ return _krb5_enomem(context);
}
ret = krb5_data_alloc(&p->data, PACTYPE_SIZE);
if (ret) {
free (p->pac);
free(p);
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
- return ret;
+ return _krb5_enomem(context);
}
-
*pac = p;
return 0;
}
@@ -269,10 +299,9 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p,
ptr = realloc(p->pac,
sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * len));
- if (ptr == NULL) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
- }
+ if (ptr == NULL)
+ return _krb5_enomem(context);
+
p->pac = ptr;
for (i = 0; i < len; i++)
@@ -379,8 +408,7 @@ krb5_pac_get_types(krb5_context context,
*types = calloc(p->pac->numbuffers, sizeof(*types));
if (*types == NULL) {
*len = 0;
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
+ return _krb5_enomem(context);
}
for (i = 0; i < p->pac->numbuffers; i++)
(*types)[i] = p->pac->buffers[i].type;
@@ -421,10 +449,9 @@ verify_checksum(krb5_context context,
sp = krb5_storage_from_mem((char *)data->data + sig->offset_lo,
sig->buffersize);
- if (sp == NULL) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
- }
+ if (sp == NULL)
+ return _krb5_enomem(context);
+
krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
CHECK(ret, krb5_ret_uint32(sp, &type), out);
@@ -433,8 +460,7 @@ verify_checksum(krb5_context context,
sig->buffersize - krb5_storage_seek(sp, 0, SEEK_CUR);
cksum.checksum.data = malloc(cksum.checksum.length);
if (cksum.checksum.data == NULL) {
- ret = ENOMEM;
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ ret = _krb5_enomem(context);
goto out;
}
ret = krb5_storage_read(sp, cksum.checksum.data, cksum.checksum.length);
@@ -459,20 +485,23 @@ verify_checksum(krb5_context context,
* for the same issue in MIT, and
* http://blogs.msdn.com/b/openspecification/archive/2010/01/01/verifying-the-server-signature-in-kerberos-privilege-account-certificate.aspx
* for Microsoft's explaination */
+
if (cksum.cksumtype == CKSUMTYPE_HMAC_MD5) {
Checksum local_checksum;
- ret = HMAC_MD5_any_checksum(context, key, ptr, len, KRB5_KU_OTHER_CKSUM, &local_checksum);
+ memset(&local_checksum, 0, sizeof(local_checksum));
- if(local_checksum.checksum.length != cksum.checksum.length ||
- ct_memcmp(local_checksum.checksum.data, cksum.checksum.data, local_checksum.checksum.length)) {
+ ret = HMAC_MD5_any_checksum(context, key, ptr, len,
+ KRB5_KU_OTHER_CKSUM, &local_checksum);
+
+ if (ret != 0 || krb5_data_ct_cmp(&local_checksum.checksum, &cksum.checksum) != 0) {
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
krb5_set_error_message(context, ret,
- N_("PAC integrity check failed for hmac-md5 checksum", ""));
- } else {
- ret = 0;
+ N_("PAC integrity check failed for "
+ "hmac-md5 checksum", ""));
}
krb5_data_free(&local_checksum.checksum);
+
} else {
krb5_crypto crypto = NULL;
@@ -516,8 +545,10 @@ create_checksum(krb5_context context,
* for the same issue in MIT, and
* http://blogs.msdn.com/b/openspecification/archive/2010/01/01/verifying-the-server-signature-in-kerberos-privilege-account-certificate.aspx
* for Microsoft's explaination */
+
if (cksumtype == CKSUMTYPE_HMAC_MD5) {
- ret = HMAC_MD5_any_checksum(context, key, data, datalen, KRB5_KU_OTHER_CKSUM, &cksum);
+ ret = HMAC_MD5_any_checksum(context, key, data, datalen,
+ KRB5_KU_OTHER_CKSUM, &cksum);
} else {
ret = krb5_crypto_init(context, key, 0, &crypto);
if (ret)
@@ -572,10 +603,8 @@ verify_logonname(krb5_context context,
sp = krb5_storage_from_readonly_mem((const char *)data->data + logon_name->offset_lo,
logon_name->buffersize);
- if (sp == NULL) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
- }
+ if (sp == NULL)
+ return _krb5_enomem(context);
krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
@@ -602,8 +631,7 @@ verify_logonname(krb5_context context,
s = malloc(len);
if (s == NULL) {
krb5_storage_free(sp);
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
+ return _krb5_enomem(context);
}
ret = krb5_storage_read(sp, s, len);
if (ret != len) {
@@ -619,10 +647,9 @@ verify_logonname(krb5_context context,
unsigned int flags = WIND_RW_LE;
ucs2 = malloc(sizeof(ucs2[0]) * ucs2len);
- if (ucs2 == NULL) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
- }
+ if (ucs2 == NULL)
+ return _krb5_enomem(context);
+
ret = wind_ucs2read(s, len, &flags, ucs2, &ucs2len);
free(s);
if (ret) {
@@ -640,8 +667,7 @@ verify_logonname(krb5_context context,
s = malloc(u8len);
if (s == NULL) {
free(ucs2);
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
+ return _krb5_enomem(context);
}
ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len);
free(ucs2);
@@ -687,10 +713,9 @@ build_logon_name(krb5_context context,
krb5_data_zero(logon);
sp = krb5_storage_emem();
- if (sp == NULL) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
- }
+ if (sp == NULL)
+ return _krb5_enomem(context);
+
krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
CHECK(ret, krb5_store_uint32(sp, t & 0xffffffff), out);
@@ -708,7 +733,7 @@ build_logon_name(krb5_context context,
#if 1 /* cheat for now */
s2 = malloc(len * 2);
if (s2 == NULL) {
- ret = ENOMEM;
+ ret = _krb5_enomem(context);
free(s);
goto out;
}
@@ -724,7 +749,7 @@ build_logon_name(krb5_context context,
ret = krb5_storage_write(sp, s2, len * 2);
free(s2);
if (ret != len * 2) {
- ret = ENOMEM;
+ ret = _krb5_enomem(context);
goto out;
}
ret = krb5_storage_to_data(sp, logon);
@@ -851,10 +876,9 @@ fill_zeros(krb5_context context, krb5_storage *sp, size_t len)
if (l > sizeof(zeros))
l = sizeof(zeros);
sret = krb5_storage_write(sp, zeros, l);
- if (sret <= 0) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
- }
+ if (sret <= 0)
+ return _krb5_enomem(context);
+
len -= sret;
}
return 0;
@@ -924,10 +948,9 @@ _krb5_pac_sign(krb5_context context,
void *ptr;
ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (p->pac->numbuffers + num - 1)));
- if (ptr == NULL) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
- }
+ if (ptr == NULL)
+ return _krb5_enomem(context);
+
p->pac = ptr;
if (p->logon_name == NULL) {
@@ -962,17 +985,15 @@ _krb5_pac_sign(krb5_context context,
/* Encode PAC */
sp = krb5_storage_emem();
- if (sp == NULL) {
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
- }
+ if (sp == NULL)
+ return _krb5_enomem(context);
+
krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
spdata = krb5_storage_emem();
if (spdata == NULL) {
krb5_storage_free(sp);
- krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
- return ENOMEM;
+ return _krb5_enomem(context);
}
krb5_storage_set_flags(spdata, KRB5_STORAGE_BYTEORDER_LE);
@@ -1010,8 +1031,7 @@ _krb5_pac_sign(krb5_context context,
sret = krb5_storage_write(spdata, ptr, len);
if (sret != len) {
- ret = ENOMEM;
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ ret = _krb5_enomem(context);
goto out;
}
/* XXX if not aligned, fill_zeros */
@@ -1048,15 +1068,14 @@ _krb5_pac_sign(krb5_context context,
ret = krb5_storage_write(sp, d.data, d.length);
if (ret != d.length) {
krb5_data_free(&d);
- ret = ENOMEM;
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ ret = _krb5_enomem(context);
goto out;
}
krb5_data_free(&d);
ret = krb5_storage_to_data(sp, &d);
if (ret) {
- krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ ret = _krb5_enomem(context);
goto out;
}