return true;
}
-NTSTATUS smb2_signing_sign_pdu(DATA_BLOB signing_key,
+NTSTATUS smb2_signing_sign_pdu(struct smb2_signing_key *signing_key,
enum protocol_types protocol,
struct iovec *vector,
int count)
return NT_STATUS_OK;
}
- if (signing_key.length == 0) {
- DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
- (unsigned)signing_key.length));
+ if (!smb2_signing_key_valid(signing_key)) {
+ DBG_WARNING("Wrong session key length %zu for SMB2 signing\n",
+ signing_key->blob.length);
return NT_STATUS_ACCESS_DENIED;
}
struct aes_cmac_128_context ctx;
uint8_t key[AES_BLOCK_SIZE] = {0};
- memcpy(key, signing_key.data, MIN(signing_key.length, 16));
+ memcpy(key,
+ signing_key->blob.data,
+ MIN(signing_key->blob.length, 16));
aes_cmac_128_init(&ctx, key);
for (i=0; i < count; i++) {
ZERO_ARRAY(key);
} else {
- gnutls_hmac_hd_t hmac_hnd = NULL;
uint8_t digest[gnutls_hmac_get_len(GNUTLS_MAC_SHA256)];
int rc;
- rc = gnutls_hmac_init(&hmac_hnd,
- GNUTLS_MAC_SHA256,
- signing_key.data,
- MIN(signing_key.length, 16));
- if (rc < 0) {
- return NT_STATUS_NO_MEMORY;
+ if (signing_key->hmac_hnd == NULL) {
+ rc = gnutls_hmac_init(&signing_key->hmac_hnd,
+ GNUTLS_MAC_SHA256,
+ signing_key->blob.data,
+ MIN(signing_key->blob.length, 16));
+ if (rc < 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
}
for (i = 0; i < count; i++) {
- rc = gnutls_hmac(hmac_hnd,
+ rc = gnutls_hmac(signing_key->hmac_hnd,
vector[i].iov_base,
vector[i].iov_len);
if (rc < 0) {
- gnutls_hmac_deinit(hmac_hnd, NULL);
return NT_STATUS_NO_MEMORY;
}
}
- gnutls_hmac_deinit(hmac_hnd, digest);
+ gnutls_hmac_output(signing_key->hmac_hnd, digest);
memcpy(res, digest, sizeof(res));
}
DEBUG(5,("signed SMB2 message\n"));
return status;
}
} else if (req->last_key.length > 0) {
- status = smb2_signing_sign_pdu(req->last_key,
+ struct smb2_signing_key key = {
+ .blob = req->last_key,
+ };
+
+ status = smb2_signing_sign_pdu(&key,
xconn->protocol,
outhdr_v,
SMBD_SMB2_NUM_IOV_PER_REQ - 1);
+ smb2_signing_key_destructor(&key);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
return NT_STATUS_OK;
}
-static DATA_BLOB smbd_smb2_signing_key(struct smbXsrv_session *session,
- struct smbXsrv_connection *xconn)
+static
+struct smb2_signing_key *smbd_smb2_signing_key(struct smbXsrv_session *session,
+ struct smbXsrv_connection *xconn)
{
struct smbXsrv_channel_global0 *c = NULL;
NTSTATUS status;
- DATA_BLOB key = data_blob_null;
+ struct smb2_signing_key *key = NULL;
status = smbXsrv_session_find_channel(session, xconn, &c);
if (NT_STATUS_IS_OK(status)) {
- key = c->signing_key->blob;
+ key = c->signing_key;
}
- if (key.length == 0) {
- key = session->global->signing_key->blob;
+ if (!smb2_signing_key_valid(key)) {
+ key = session->global->signing_key;
}
return key;
}
} else if (req->do_signing) {
struct smbXsrv_session *x = req->session;
- DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
+ struct smb2_signing_key *signing_key =
+ smbd_smb2_signing_key(x, xconn);
status = smb2_signing_sign_pdu(signing_key,
xconn->protocol,
if (req->was_encrypted) {
signing_required = false;
} else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
- DATA_BLOB signing_key = data_blob_null;
+ struct smb2_signing_key *signing_key = NULL;
if (x == NULL) {
/*
* If we have a signing key, we should
* sign the response
*/
- if (signing_key.length > 0) {
+ if (smb2_signing_key_valid(signing_key)) {
req->do_signing = true;
}
- status = smb2_signing_check_pdu(signing_key,
+ status = smb2_signing_check_pdu(signing_key->blob,
xconn->protocol,
SMBD_SMB2_IN_HDR_IOV(req),
SMBD_SMB2_NUM_IOV_PER_REQ - 1);
{
int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
+ struct smb2_signing_key key = {
+ .blob = req->last_key,
+ };
/*
* As we are sure the header of the last request in the
* compound chain will not change, we can to sign here
* with the last signing key we remembered.
*/
- status = smb2_signing_sign_pdu(req->last_key,
+ status = smb2_signing_sign_pdu(&key,
xconn->protocol,
lasthdr,
SMBD_SMB2_NUM_IOV_PER_REQ - 1);
+ smb2_signing_key_destructor(&key);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (req->do_signing && firsttf->iov_len == 0) {
struct smbXsrv_session *x = req->session;
- DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
+ struct smb2_signing_key *signing_key =
+ smbd_smb2_signing_key(x, xconn);
/*
* we need to remember the signing key
* we are sure that we do not change
* the header again.
*/
- req->last_key = data_blob_dup_talloc(req, signing_key);
+ req->last_key = data_blob_dup_talloc(req,
+ signing_key->blob);
if (req->last_key.data == NULL) {
return NT_STATUS_NO_MEMORY;
}
}
} else if (req->do_signing) {
struct smbXsrv_session *x = req->session;
- DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
+ struct smb2_signing_key *signing_key =
+ smbd_smb2_signing_key(x, xconn);
status = smb2_signing_sign_pdu(signing_key,
xconn->protocol,