mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
crypto: add decrypt_drsuapi_blob from samba4.
Guenther
This commit is contained in:
parent
05d6f2e00c
commit
3b6352a60e
@ -5134,6 +5134,11 @@ WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,
|
||||
struct wkssvc_PasswordBuffer *pwd_buf,
|
||||
DATA_BLOB *session_key,
|
||||
char **pwd);
|
||||
DATA_BLOB decrypt_drsuapi_blob(TALLOC_CTX *mem_ctx,
|
||||
const DATA_BLOB *session_key,
|
||||
bool rcrypt,
|
||||
uint32_t rid,
|
||||
const DATA_BLOB *buffer);
|
||||
|
||||
/* The following definitions come from libsmb/smberr.c */
|
||||
|
||||
|
@ -782,3 +782,117 @@ WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
DATA_BLOB decrypt_drsuapi_blob(TALLOC_CTX *mem_ctx,
|
||||
const DATA_BLOB *session_key,
|
||||
bool rcrypt,
|
||||
uint32_t rid,
|
||||
const DATA_BLOB *buffer)
|
||||
{
|
||||
DATA_BLOB confounder;
|
||||
DATA_BLOB enc_buffer;
|
||||
|
||||
struct MD5Context md5;
|
||||
uint8_t _enc_key[16];
|
||||
DATA_BLOB enc_key;
|
||||
|
||||
DATA_BLOB dec_buffer;
|
||||
|
||||
uint32_t crc32_given;
|
||||
uint32_t crc32_calc;
|
||||
DATA_BLOB checked_buffer;
|
||||
|
||||
DATA_BLOB plain_buffer;
|
||||
|
||||
/*
|
||||
* the combination "c[3] s[1] e[1] d[0]..."
|
||||
* was successful!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*/
|
||||
|
||||
/*
|
||||
* the first 16 bytes at the beginning are the confounder
|
||||
* followed by the 4 byte crc32 checksum
|
||||
*/
|
||||
if (buffer->length < 20) {
|
||||
return data_blob_const(NULL, 0);
|
||||
}
|
||||
confounder = data_blob_const(buffer->data, 16);
|
||||
enc_buffer = data_blob_const(buffer->data + 16, buffer->length - 16);
|
||||
|
||||
/*
|
||||
* build the encryption key md5 over the session key followed
|
||||
* by the confounder
|
||||
*
|
||||
* here the gensec session key is used and
|
||||
* not the dcerpc ncacn_ip_tcp "SystemLibraryDTC" key!
|
||||
*/
|
||||
enc_key = data_blob_const(_enc_key, sizeof(_enc_key));
|
||||
MD5Init(&md5);
|
||||
MD5Update(&md5, session_key->data, session_key->length);
|
||||
MD5Update(&md5, confounder.data, confounder.length);
|
||||
MD5Final(enc_key.data, &md5);
|
||||
|
||||
/*
|
||||
* copy the encrypted buffer part and
|
||||
* decrypt it using the created encryption key using arcfour
|
||||
*/
|
||||
dec_buffer = data_blob_talloc(mem_ctx, enc_buffer.data, enc_buffer.length);
|
||||
if (!dec_buffer.data) {
|
||||
return data_blob_const(NULL, 0);
|
||||
}
|
||||
SamOEMhashBlob(dec_buffer.data, dec_buffer.length, &enc_key);
|
||||
|
||||
/*
|
||||
* the first 4 byte are the crc32 checksum
|
||||
* of the remaining bytes
|
||||
*/
|
||||
crc32_given = IVAL(dec_buffer.data, 0);
|
||||
crc32_calc = crc32_calc_buffer((const char *)dec_buffer.data + 4 , dec_buffer.length - 4);
|
||||
if (crc32_given != crc32_calc) {
|
||||
DEBUG(1,("CRC32: given[0x%08X] calc[0x%08X]\n",
|
||||
crc32_given, crc32_calc));
|
||||
return data_blob_const(NULL, 0);
|
||||
}
|
||||
checked_buffer = data_blob_talloc(mem_ctx, dec_buffer.data + 4, dec_buffer.length - 4);
|
||||
if (!checked_buffer.data) {
|
||||
return data_blob_const(NULL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* some attributes seem to be in a usable form after this decryption
|
||||
* (supplementalCredentials, priorValue, currentValue, trustAuthOutgoing,
|
||||
* trustAuthIncoming, initialAuthOutgoing, initialAuthIncoming)
|
||||
* At least supplementalCredentials contains plaintext
|
||||
* like "Primary:Kerberos" (in unicode form)
|
||||
*
|
||||
* some attributes seem to have some additional encryption
|
||||
* dBCSPwd, unicodePwd, ntPwdHistory, lmPwdHistory
|
||||
*
|
||||
* it's the sam_rid_crypt() function, as the value is constant,
|
||||
* so it doesn't depend on sessionkeys.
|
||||
*/
|
||||
if (rcrypt) {
|
||||
uint32_t i, num_hashes;
|
||||
|
||||
if ((checked_buffer.length % 16) != 0) {
|
||||
return data_blob_const(NULL, 0);
|
||||
}
|
||||
|
||||
plain_buffer = data_blob_talloc(mem_ctx, checked_buffer.data, checked_buffer.length);
|
||||
if (!plain_buffer.data) {
|
||||
return data_blob_const(NULL, 0);
|
||||
}
|
||||
|
||||
num_hashes = plain_buffer.length / 16;
|
||||
for (i = 0; i < num_hashes; i++) {
|
||||
uint32_t offset = i * 16;
|
||||
sam_pwd_hash(rid, checked_buffer.data + offset, plain_buffer.data + offset, 0);
|
||||
}
|
||||
} else {
|
||||
plain_buffer = checked_buffer;
|
||||
}
|
||||
|
||||
return plain_buffer;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user