Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
d865c043
Commit
d865c043
authored
Apr 30, 2021
by
Hans Leidekker
Committed by
Alexandre Julliard
Apr 30, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msv1_0: Implement SpMakeSignature.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ce7da2e1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
198 additions
and
1 deletion
+198
-1
main.c
dlls/msv1_0/main.c
+198
-1
No files found.
dlls/msv1_0/main.c
View file @
d865c043
...
...
@@ -523,6 +523,26 @@ static void arc4_init( struct arc4_info *info, const char *key, unsigned int len
}
}
static
void
arc4_process
(
struct
arc4_info
*
info
,
char
*
buf
,
unsigned
int
len
)
{
char
*
state
=
info
->
state
;
unsigned
int
x
=
info
->
x
,
y
=
info
->
y
,
a
,
b
;
while
(
len
--
)
{
x
=
(
x
+
1
)
&
0xff
;
a
=
state
[
x
];
y
=
(
y
+
a
)
&
0xff
;
b
=
state
[
y
];
state
[
x
]
=
b
;
state
[
y
]
=
a
;
*
buf
++
^=
state
[(
a
+
b
)
&
0xff
];
}
info
->
x
=
x
;
info
->
y
=
y
;
}
static
int
get_buffer_index
(
SecBufferDesc
*
desc
,
ULONG
type
)
{
int
idx
;
...
...
@@ -1178,11 +1198,188 @@ static NTSTATUS NTAPI ntlm_SpInstanceInit( ULONG version, SECPKG_DLL_FUNCTIONS *
return
STATUS_SUCCESS
;
}
struct
hmac_md5_ctx
{
struct
md5_ctx
ctx
;
char
outer_padding
[
64
];
};
static
void
hmac_md5_init
(
struct
hmac_md5_ctx
*
ctx
,
const
char
*
key
,
unsigned
int
key_len
)
{
char
inner_padding
[
64
],
tmp_key
[
16
];
unsigned
int
i
;
if
(
key_len
>
64
)
{
struct
md5_ctx
tmp_ctx
;
MD5Init
(
&
tmp_ctx
);
MD5Update
(
&
tmp_ctx
,
key
,
key_len
);
MD5Final
(
&
tmp_ctx
);
memcpy
(
tmp_key
,
tmp_ctx
.
digest
,
16
);
key
=
tmp_key
;
key_len
=
16
;
}
memset
(
inner_padding
,
0
,
64
);
memset
(
ctx
->
outer_padding
,
0
,
64
);
memcpy
(
inner_padding
,
key
,
key_len
);
memcpy
(
ctx
->
outer_padding
,
key
,
key_len
);
for
(
i
=
0
;
i
<
64
;
i
++
)
{
inner_padding
[
i
]
^=
0x36
;
ctx
->
outer_padding
[
i
]
^=
0x5c
;
}
MD5Init
(
&
ctx
->
ctx
);
MD5Update
(
&
ctx
->
ctx
,
inner_padding
,
64
);
}
static
void
hmac_md5_update
(
struct
hmac_md5_ctx
*
ctx
,
const
char
*
buf
,
unsigned
int
len
)
{
MD5Update
(
&
ctx
->
ctx
,
buf
,
len
);
}
static
void
hmac_md5_final
(
struct
hmac_md5_ctx
*
ctx
,
char
*
digest
)
{
struct
md5_ctx
outer_ctx
;
char
inner_digest
[
16
];
MD5Final
(
&
ctx
->
ctx
);
memcpy
(
inner_digest
,
ctx
->
ctx
.
digest
,
16
);
MD5Init
(
&
outer_ctx
);
MD5Update
(
&
outer_ctx
,
ctx
->
outer_padding
,
64
);
MD5Update
(
&
outer_ctx
,
inner_digest
,
16
);
MD5Final
(
&
outer_ctx
);
memcpy
(
digest
,
outer_ctx
.
digest
,
16
);
}
static
SECURITY_STATUS
create_signature
(
struct
ntlm_ctx
*
ctx
,
unsigned
int
flags
,
SecBufferDesc
*
msg
,
int
idx
,
enum
sign_direction
dir
,
BOOL
encrypt
)
{
unsigned
int
i
,
sign_version
=
1
;
char
*
sig
=
msg
->
pBuffers
[
idx
].
pvBuffer
;
if
(
flags
&
FLAG_NEGOTIATE_NTLM2
&&
flags
&
FLAG_NEGOTIATE_SIGN
)
{
char
digest
[
16
],
seq_no
[
4
];
struct
hmac_md5_ctx
hmac_md5
;
if
(
dir
==
SIGN_SEND
)
{
seq_no
[
0
]
=
(
ctx
->
crypt
.
ntlm2
.
send_seq_no
>>
0
)
&
0xff
;
seq_no
[
1
]
=
(
ctx
->
crypt
.
ntlm2
.
send_seq_no
>>
8
)
&
0xff
;
seq_no
[
2
]
=
(
ctx
->
crypt
.
ntlm2
.
send_seq_no
>>
16
)
&
0xff
;
seq_no
[
3
]
=
(
ctx
->
crypt
.
ntlm2
.
send_seq_no
>>
24
)
&
0xff
;
ctx
->
crypt
.
ntlm2
.
send_seq_no
++
;
hmac_md5_init
(
&
hmac_md5
,
ctx
->
crypt
.
ntlm2
.
send_sign_key
,
16
);
}
else
{
seq_no
[
0
]
=
(
ctx
->
crypt
.
ntlm2
.
recv_seq_no
>>
0
)
&
0xff
;
seq_no
[
1
]
=
(
ctx
->
crypt
.
ntlm2
.
recv_seq_no
>>
8
)
&
0xff
;
seq_no
[
2
]
=
(
ctx
->
crypt
.
ntlm2
.
recv_seq_no
>>
16
)
&
0xff
;
seq_no
[
3
]
=
(
ctx
->
crypt
.
ntlm2
.
recv_seq_no
>>
24
)
&
0xff
;
ctx
->
crypt
.
ntlm2
.
recv_seq_no
++
;
hmac_md5_init
(
&
hmac_md5
,
ctx
->
crypt
.
ntlm2
.
recv_sign_key
,
16
);
}
hmac_md5_update
(
&
hmac_md5
,
seq_no
,
4
);
for
(
i
=
0
;
i
<
msg
->
cBuffers
;
++
i
)
{
if
(
msg
->
pBuffers
[
i
].
BufferType
&
SECBUFFER_DATA
)
hmac_md5_update
(
&
hmac_md5
,
msg
->
pBuffers
[
i
].
pvBuffer
,
msg
->
pBuffers
[
i
].
cbBuffer
);
}
hmac_md5_final
(
&
hmac_md5
,
digest
);
if
(
encrypt
&&
flags
&
FLAG_NEGOTIATE_KEY_EXCHANGE
)
{
if
(
dir
==
SIGN_SEND
)
arc4_process
(
&
ctx
->
crypt
.
ntlm2
.
send_arc4info
,
digest
,
8
);
else
arc4_process
(
&
ctx
->
crypt
.
ntlm2
.
recv_arc4info
,
digest
,
8
);
}
sig
[
0
]
=
(
sign_version
>>
0
)
&
0xff
;
sig
[
1
]
=
(
sign_version
>>
8
)
&
0xff
;
sig
[
2
]
=
(
sign_version
>>
16
)
&
0xff
;
sig
[
3
]
=
(
sign_version
>>
24
)
&
0xff
;
memcpy
(
sig
+
4
,
digest
,
8
);
memcpy
(
sig
+
12
,
seq_no
,
4
);
msg
->
pBuffers
[
idx
].
cbBuffer
=
16
;
return
SEC_E_OK
;
}
if
(
flags
&
FLAG_NEGOTIATE_SIGN
)
{
unsigned
int
crc
=
0
;
for
(
i
=
0
;
i
<
msg
->
cBuffers
;
++
i
)
{
if
(
msg
->
pBuffers
[
i
].
BufferType
&
SECBUFFER_DATA
)
crc
=
RtlComputeCrc32
(
crc
,
msg
->
pBuffers
[
i
].
pvBuffer
,
msg
->
pBuffers
[
i
].
cbBuffer
);
}
sig
[
0
]
=
(
sign_version
>>
0
)
&
0xff
;
sig
[
1
]
=
(
sign_version
>>
8
)
&
0xff
;
sig
[
2
]
=
(
sign_version
>>
16
)
&
0xff
;
sig
[
3
]
=
(
sign_version
>>
24
)
&
0xff
;
memset
(
sig
+
4
,
0
,
4
);
sig
[
8
]
=
(
crc
>>
0
)
&
0xff
;
sig
[
9
]
=
(
crc
>>
8
)
&
0xff
;
sig
[
10
]
=
(
crc
>>
16
)
&
0xff
;
sig
[
11
]
=
(
crc
>>
24
)
&
0xff
;
sig
[
12
]
=
(
ctx
->
crypt
.
ntlm
.
seq_no
>>
0
)
&
0xff
;
sig
[
13
]
=
(
ctx
->
crypt
.
ntlm
.
seq_no
>>
8
)
&
0xff
;
sig
[
14
]
=
(
ctx
->
crypt
.
ntlm
.
seq_no
>>
16
)
&
0xff
;
sig
[
15
]
=
(
ctx
->
crypt
.
ntlm
.
seq_no
>>
24
)
&
0xff
;
ctx
->
crypt
.
ntlm
.
seq_no
++
;
if
(
encrypt
)
arc4_process
(
&
ctx
->
crypt
.
ntlm
.
arc4info
,
sig
+
4
,
12
);
return
SEC_E_OK
;
}
if
(
flags
&
FLAG_NEGOTIATE_ALWAYS_SIGN
||
!
flags
)
{
/* create dummy signature */
memset
(
msg
->
pBuffers
[
idx
].
pvBuffer
,
0
,
16
);
memset
(
msg
->
pBuffers
[
idx
].
pvBuffer
,
1
,
1
);
msg
->
pBuffers
[
idx
].
cbBuffer
=
16
;
return
SEC_E_OK
;
}
return
SEC_E_UNSUPPORTED_FUNCTION
;
}
static
NTSTATUS
NTAPI
ntlm_SpMakeSignature
(
LSA_SEC_HANDLE
handle
,
ULONG
qop
,
SecBufferDesc
*
msg
,
ULONG
msg_seq_no
)
{
struct
ntlm_ctx
*
ctx
=
(
struct
ntlm_ctx
*
)
handle
;
int
idx
;
TRACE
(
"%lx, 0x%08x, %p, %u
\n
"
,
handle
,
qop
,
msg
,
msg_seq_no
);
if
(
qop
)
FIXME
(
"ignoring quality of protection %08x
\n
"
,
qop
);
if
(
msg_seq_no
)
FIXME
(
"ignoring message sequence number %u
\n
"
,
msg_seq_no
);
if
(
!
handle
)
return
SEC_E_INVALID_HANDLE
;
if
(
!
msg
||
!
msg
->
pBuffers
||
msg
->
cBuffers
<
2
||
(
idx
=
get_buffer_index
(
msg
,
SECBUFFER_TOKEN
))
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
if
(
msg
->
pBuffers
[
idx
].
cbBuffer
<
16
)
return
SEC_E_BUFFER_TOO_SMALL
;
return
create_signature
(
ctx
,
ctx
->
flags
,
msg
,
idx
,
SIGN_SEND
,
TRUE
);
}
static
SECPKG_USER_FUNCTION_TABLE
ntlm_user_table
=
{
ntlm_SpInstanceInit
,
NULL
,
/* SpInitUserModeContext */
NULL
,
/* SpMakeSignature */
ntlm_SpMakeSignature
,
NULL
,
/* SpVerifySignature */
NULL
,
/* SpSealMessage */
NULL
,
/* SpUnsealMessage */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment