diff options
author | Andrew Bartlett <abartlet@samba.org> | 2010-11-11 11:27:33 +1100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2010-11-15 01:25:06 +0000 |
commit | 1342185e333cb8139b7a70b7fe43571bcc2716a7 (patch) | |
tree | 0e1cb8d3cfc437bd7cc3a97f2bdc472f54d95dbd /source4/heimdal/lib/krb5/pac.c | |
parent | 13fd22f61017124d2d4964db3e32c667d119b56c (diff) | |
download | samba-1342185e333cb8139b7a70b7fe43571bcc2716a7.tar.gz samba-1342185e333cb8139b7a70b7fe43571bcc2716a7.tar.bz2 samba-1342185e333cb8139b7a70b7fe43571bcc2716a7.zip |
s4:heimdal: import lorikeet-heimdal-201011102149 (commit 5734d03c20e104c8f45533d07f2a2cbbd3224f29)
Diffstat (limited to 'source4/heimdal/lib/krb5/pac.c')
-rw-r--r-- | source4/heimdal/lib/krb5/pac.c | 157 |
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; } |