~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/libcli/smb2/signing.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
 
 
4
   SMB2 Signing Code
 
5
 
 
6
   Copyright (C) Andrew Tridgell <tridge@samba.org> 2008
 
7
 
 
8
   This program is free software; you can redistribute it and/or modify
 
9
   it under the terms of the GNU General Public License as published by
 
10
   the Free Software Foundation; either version 3 of the License, or
 
11
   (at your option) any later version.
 
12
   
 
13
   This program is distributed in the hope that it will be useful,
 
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
   
 
18
   You should have received a copy of the GNU General Public License
 
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
*/
 
21
 
 
22
#include "includes.h"
 
23
#include "libcli/raw/libcliraw.h"
 
24
#include "libcli/smb2/smb2.h"
 
25
#include "libcli/smb2/smb2_calls.h"
 
26
#include "../lib/crypto/crypto.h"
 
27
 
 
28
/*
 
29
  sign an outgoing message
 
30
 */
 
31
NTSTATUS smb2_sign_message(struct smb2_request_buffer *buf, DATA_BLOB session_key)
 
32
{
 
33
        struct HMACSHA256Context m;
 
34
        uint8_t res[32];
 
35
        uint64_t session_id;
 
36
 
 
37
        if (buf->size < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) {
 
38
                /* can't sign non-SMB2 messages */
 
39
                return NT_STATUS_OK;
 
40
        }
 
41
 
 
42
        session_id = BVAL(buf->hdr, SMB2_HDR_SESSION_ID);
 
43
        if (session_id == 0) {
 
44
                /* we don't sign messages with a zero session_id. See
 
45
                   MS-SMB2 3.2.4.1.1 */
 
46
                return NT_STATUS_OK;            
 
47
        }
 
48
 
 
49
        if (session_key.length == 0) {
 
50
                DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
 
51
                         (unsigned)session_key.length));
 
52
                return NT_STATUS_ACCESS_DENIED;
 
53
        }
 
54
 
 
55
        memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16);
 
56
 
 
57
        SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED);
 
58
 
 
59
        ZERO_STRUCT(m);
 
60
        hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
 
61
        hmac_sha256_update(buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE, &m);
 
62
        hmac_sha256_final(res, &m);
 
63
        DEBUG(5,("signed SMB2 message of size %u\n", (unsigned)buf->size - NBT_HDR_SIZE));
 
64
 
 
65
        memcpy(buf->hdr + SMB2_HDR_SIGNATURE, res, 16);
 
66
 
 
67
        return NT_STATUS_OK;    
 
68
}
 
69
 
 
70
/*
 
71
  check an incoming signature
 
72
 */
 
73
NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session_key)
 
74
{
 
75
        uint64_t session_id;
 
76
        struct HMACSHA256Context m;
 
77
        uint8_t res[SHA256_DIGEST_LENGTH];
 
78
        uint8_t sig[16];
 
79
 
 
80
        if (buf->size < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) {
 
81
                /* can't check non-SMB2 messages */
 
82
                return NT_STATUS_OK;
 
83
        }
 
84
 
 
85
        session_id = BVAL(buf->hdr, SMB2_HDR_SESSION_ID);
 
86
        if (session_id == 0) {
 
87
                /* don't sign messages with a zero session_id. See
 
88
                   MS-SMB2 3.2.4.1.1 */
 
89
                return NT_STATUS_OK;            
 
90
        }
 
91
 
 
92
        if (session_key.length == 0) {
 
93
                /* we don't have the session key yet */
 
94
                return NT_STATUS_OK;
 
95
        }
 
96
 
 
97
        memcpy(sig, buf->hdr+SMB2_HDR_SIGNATURE, 16);
 
98
 
 
99
        memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16);
 
100
 
 
101
        ZERO_STRUCT(m);
 
102
        hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
 
103
        hmac_sha256_update(buf->hdr, buf->size-NBT_HDR_SIZE, &m);
 
104
        hmac_sha256_final(res, &m);
 
105
 
 
106
        memcpy(buf->hdr+SMB2_HDR_SIGNATURE, sig, 16);
 
107
 
 
108
        if (memcmp(res, sig, 16) != 0) {
 
109
                DEBUG(0,("Bad SMB2 signature for message of size %u\n", 
 
110
                         (unsigned)buf->size-NBT_HDR_SIZE));
 
111
                dump_data(0, sig, 16);
 
112
                dump_data(0, res, 16);
 
113
                return NT_STATUS_ACCESS_DENIED;
 
114
        }
 
115
 
 
116
        return NT_STATUS_OK;    
 
117
}