Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
29cae46f
Commit
29cae46f
authored
Aug 10, 2007
by
Juan Lang
Committed by
Alexandre Julliard
Aug 13, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wintrust: Implement decoding SPC links.
parent
44047e02
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
348 additions
and
13 deletions
+348
-13
Makefile.in
dlls/wintrust/Makefile.in
+1
-1
asn.c
dlls/wintrust/asn.c
+343
-4
asn.c
dlls/wintrust/tests/asn.c
+4
-8
No files found.
dlls/wintrust/Makefile.in
View file @
29cae46f
...
...
@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH
=
@srcdir@
MODULE
=
wintrust.dll
IMPORTLIB
=
libwintrust.
$(IMPLIBEXT)
IMPORTS
=
crypt32 user32 advapi32 kernel32
IMPORTS
=
crypt32 user32 advapi32 kernel32
ntdll
DELAYIMPORTS
=
imagehlp
C_SRCS
=
\
...
...
dlls/wintrust/asn.c
View file @
29cae46f
...
...
@@ -18,16 +18,32 @@
*
*/
#include <stdarg.h>
#include <assert.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wincrypt.h"
#include "wintrust.h"
#include "snmp.h"
#include "winternl.h"
#include "wine/debug.h"
#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
cryptasn
);
#ifdef WORDS_BIGENDIAN
#define hton16(x) (x)
#define n16toh(x) (x)
#else
#define hton16(x) RtlUshortByteSwap(x)
#define n16toh(x) RtlUshortByteSwap(x)
#endif
BOOL
WINAPI
WVTAsn1SpcLinkEncode
(
DWORD
dwCertEncodingType
,
LPCSTR
lpszStructType
,
const
void
*
pvStructInfo
,
BYTE
*
pbEncoded
,
DWORD
*
pcbEncoded
)
...
...
@@ -48,14 +64,337 @@ BOOL WINAPI WVTAsn1SpcPeImageDataEncode(DWORD dwCertEncodingType,
return
FALSE
;
}
/* Gets the number of length bytes from the given (leading) length byte */
#define GET_LEN_BYTES(b) ((b) <= 0x7f ? 1 : 1 + ((b) & 0x7f))
/* Helper function to get the encoded length of the data starting at pbEncoded,
* where pbEncoded[0] is the tag. If the data are too short to contain a
* length or if the length is too large for cbEncoded, sets an appropriate
* error code and returns FALSE.
*/
static
BOOL
CRYPT_GetLen
(
const
BYTE
*
pbEncoded
,
DWORD
cbEncoded
,
DWORD
*
len
)
{
BOOL
ret
;
if
(
cbEncoded
<=
1
)
{
SetLastError
(
CRYPT_E_ASN1_CORRUPT
);
ret
=
FALSE
;
}
else
if
(
pbEncoded
[
1
]
<=
0x7f
)
{
if
(
pbEncoded
[
1
]
+
1
>
cbEncoded
)
{
SetLastError
(
CRYPT_E_ASN1_EOD
);
ret
=
FALSE
;
}
else
{
*
len
=
pbEncoded
[
1
];
ret
=
TRUE
;
}
}
else
if
(
pbEncoded
[
1
]
==
0x80
)
{
FIXME
(
"unimplemented for indefinite-length encoding
\n
"
);
SetLastError
(
CRYPT_E_ASN1_CORRUPT
);
ret
=
FALSE
;
}
else
{
BYTE
lenLen
=
GET_LEN_BYTES
(
pbEncoded
[
1
]);
if
(
lenLen
>
sizeof
(
DWORD
)
+
1
)
{
SetLastError
(
CRYPT_E_ASN1_LARGE
);
ret
=
FALSE
;
}
else
if
(
lenLen
+
2
>
cbEncoded
)
{
SetLastError
(
CRYPT_E_ASN1_CORRUPT
);
ret
=
FALSE
;
}
else
{
DWORD
out
=
0
;
pbEncoded
+=
2
;
while
(
--
lenLen
)
{
out
<<=
8
;
out
|=
*
pbEncoded
++
;
}
if
(
out
+
lenLen
+
1
>
cbEncoded
)
{
SetLastError
(
CRYPT_E_ASN1_EOD
);
ret
=
FALSE
;
}
else
{
*
len
=
out
;
ret
=
TRUE
;
}
}
}
return
ret
;
}
static
BOOL
WINAPI
CRYPT_AsnDecodeOctets
(
DWORD
dwCertEncodingType
,
LPCSTR
lpszStructType
,
const
BYTE
*
pbEncoded
,
DWORD
cbEncoded
,
DWORD
dwFlags
,
void
*
pvStructInfo
,
DWORD
*
pcbStructInfo
)
{
BOOL
ret
;
DWORD
bytesNeeded
,
dataLen
;
TRACE
(
"%p, %d, %08x, %p, %d
\n
"
,
pbEncoded
,
cbEncoded
,
dwFlags
,
pvStructInfo
,
*
pcbStructInfo
);
if
(
!
cbEncoded
)
{
SetLastError
(
CRYPT_E_ASN1_CORRUPT
);
ret
=
FALSE
;
}
else
if
(
pbEncoded
[
0
]
!=
ASN_OCTETSTRING
)
{
SetLastError
(
CRYPT_E_ASN1_BADTAG
);
ret
=
FALSE
;
}
else
if
((
ret
=
CRYPT_GetLen
(
pbEncoded
,
cbEncoded
,
&
dataLen
)))
{
if
(
dwFlags
&
CRYPT_DECODE_NOCOPY_FLAG
)
bytesNeeded
=
sizeof
(
CRYPT_DATA_BLOB
);
else
bytesNeeded
=
dataLen
+
sizeof
(
CRYPT_DATA_BLOB
);
if
(
!
pvStructInfo
)
*
pcbStructInfo
=
bytesNeeded
;
else
if
(
*
pcbStructInfo
<
bytesNeeded
)
{
SetLastError
(
ERROR_MORE_DATA
);
*
pcbStructInfo
=
bytesNeeded
;
ret
=
FALSE
;
}
else
{
CRYPT_DATA_BLOB
*
blob
;
BYTE
lenBytes
=
GET_LEN_BYTES
(
pbEncoded
[
1
]);
blob
=
(
CRYPT_DATA_BLOB
*
)
pvStructInfo
;
blob
->
cbData
=
dataLen
;
if
(
dwFlags
&
CRYPT_DECODE_NOCOPY_FLAG
)
blob
->
pbData
=
(
BYTE
*
)
pbEncoded
+
1
+
lenBytes
;
else
{
assert
(
blob
->
pbData
);
if
(
blob
->
cbData
)
memcpy
(
blob
->
pbData
,
pbEncoded
+
1
+
lenBytes
,
blob
->
cbData
);
}
}
}
return
ret
;
}
static
BOOL
WINAPI
CRYPT_AsnDecodeSPCLinkInternal
(
DWORD
dwCertEncodingType
,
LPCSTR
lpszStructType
,
const
BYTE
*
pbEncoded
,
DWORD
cbEncoded
,
DWORD
dwFlags
,
void
*
pvStructInfo
,
DWORD
*
pcbStructInfo
)
{
BOOL
ret
=
FALSE
;
DWORD
bytesNeeded
=
sizeof
(
SPC_LINK
),
dataLen
;
TRACE
(
"%p, %d, %08x, %p, %d
\n
"
,
pbEncoded
,
cbEncoded
,
dwFlags
,
pvStructInfo
,
*
pcbStructInfo
);
if
((
ret
=
CRYPT_GetLen
(
pbEncoded
,
cbEncoded
,
&
dataLen
)))
{
BYTE
lenBytes
=
GET_LEN_BYTES
(
pbEncoded
[
1
]);
DWORD
realDataLen
;
switch
(
pbEncoded
[
0
])
{
case
ASN_CONTEXT
:
bytesNeeded
+=
(
dataLen
+
1
)
*
sizeof
(
WCHAR
);
if
(
!
pvStructInfo
)
*
pcbStructInfo
=
bytesNeeded
;
else
if
(
*
pcbStructInfo
<
bytesNeeded
)
{
*
pcbStructInfo
=
bytesNeeded
;
SetLastError
(
ERROR_MORE_DATA
);
ret
=
FALSE
;
}
else
{
PSPC_LINK
link
=
(
PSPC_LINK
)
pvStructInfo
;
DWORD
i
;
link
->
dwLinkChoice
=
SPC_URL_LINK_CHOICE
;
for
(
i
=
0
;
i
<
dataLen
;
i
++
)
link
->
u
.
pwszUrl
[
i
]
=
*
(
pbEncoded
+
1
+
lenBytes
+
i
);
link
->
u
.
pwszUrl
[
i
]
=
'\0'
;
TRACE
(
"returning url %s
\n
"
,
debugstr_w
(
link
->
u
.
pwszUrl
));
}
break
;
case
ASN_CONSTRUCTOR
|
ASN_CONTEXT
|
1
:
{
CRYPT_DATA_BLOB
classId
;
DWORD
size
=
sizeof
(
classId
);
if
((
ret
=
CRYPT_AsnDecodeOctets
(
dwCertEncodingType
,
NULL
,
pbEncoded
+
1
+
lenBytes
,
cbEncoded
-
1
-
lenBytes
,
CRYPT_DECODE_NOCOPY_FLAG
,
&
classId
,
&
size
)))
{
if
(
classId
.
cbData
!=
sizeof
(
SPC_UUID
))
{
SetLastError
(
CRYPT_E_BAD_ENCODE
);
ret
=
FALSE
;
}
else
{
CRYPT_DATA_BLOB
data
;
/* The tag length for the classId must be 1 since the
* length is correct.
*/
size
=
sizeof
(
data
);
if
((
ret
=
CRYPT_AsnDecodeOctets
(
dwCertEncodingType
,
NULL
,
pbEncoded
+
3
+
lenBytes
+
classId
.
cbData
,
cbEncoded
-
3
-
lenBytes
-
classId
.
cbData
,
CRYPT_DECODE_NOCOPY_FLAG
,
&
data
,
&
size
)))
{
bytesNeeded
+=
data
.
cbData
;
if
(
!
pvStructInfo
)
*
pcbStructInfo
=
bytesNeeded
;
else
if
(
*
pcbStructInfo
<
bytesNeeded
)
{
*
pcbStructInfo
=
bytesNeeded
;
SetLastError
(
ERROR_MORE_DATA
);
ret
=
FALSE
;
}
else
{
PSPC_LINK
link
=
(
PSPC_LINK
)
pvStructInfo
;
link
->
dwLinkChoice
=
SPC_MONIKER_LINK_CHOICE
;
/* pwszFile pointer was set by caller, copy it
* before overwriting it
*/
link
->
u
.
Moniker
.
SerializedData
.
pbData
=
(
BYTE
*
)
link
->
u
.
pwszFile
;
memcpy
(
&
link
->
u
.
Moniker
.
ClassId
,
classId
.
pbData
,
classId
.
cbData
);
memcpy
(
link
->
u
.
Moniker
.
SerializedData
.
pbData
,
data
.
pbData
,
data
.
cbData
);
link
->
u
.
Moniker
.
SerializedData
.
cbData
=
data
.
cbData
;
}
}
}
}
break
;
}
case
ASN_CONSTRUCTOR
|
ASN_CONTEXT
|
2
:
if
(
dataLen
&&
pbEncoded
[
1
+
lenBytes
]
!=
ASN_CONTEXT
)
SetLastError
(
CRYPT_E_ASN1_BADTAG
);
else
if
((
ret
=
CRYPT_GetLen
(
pbEncoded
+
1
+
lenBytes
,
dataLen
,
&
realDataLen
)))
{
BYTE
realLenBytes
=
GET_LEN_BYTES
(
pbEncoded
[
2
+
lenBytes
]);
bytesNeeded
+=
realDataLen
+
sizeof
(
WCHAR
);
if
(
!
pvStructInfo
)
*
pcbStructInfo
=
bytesNeeded
;
else
if
(
*
pcbStructInfo
<
bytesNeeded
)
{
*
pcbStructInfo
=
bytesNeeded
;
SetLastError
(
ERROR_MORE_DATA
);
ret
=
FALSE
;
}
else
{
PSPC_LINK
link
=
(
PSPC_LINK
)
pvStructInfo
;
DWORD
i
;
const
BYTE
*
ptr
=
pbEncoded
+
2
+
lenBytes
+
realLenBytes
;
link
->
dwLinkChoice
=
SPC_FILE_LINK_CHOICE
;
for
(
i
=
0
;
i
<
dataLen
/
sizeof
(
WCHAR
);
i
++
)
link
->
u
.
pwszFile
[
i
]
=
hton16
(
*
(
WORD
*
)(
ptr
+
i
*
sizeof
(
WCHAR
)));
link
->
u
.
pwszFile
[
realDataLen
/
sizeof
(
WCHAR
)]
=
'\0'
;
TRACE
(
"returning file %s
\n
"
,
debugstr_w
(
link
->
u
.
pwszFile
));
}
}
else
{
bytesNeeded
+=
sizeof
(
WCHAR
);
if
(
!
pvStructInfo
)
*
pcbStructInfo
=
bytesNeeded
;
else
if
(
*
pcbStructInfo
<
bytesNeeded
)
{
*
pcbStructInfo
=
bytesNeeded
;
SetLastError
(
ERROR_MORE_DATA
);
ret
=
FALSE
;
}
else
{
PSPC_LINK
link
=
(
PSPC_LINK
)
pvStructInfo
;
link
->
dwLinkChoice
=
SPC_FILE_LINK_CHOICE
;
link
->
u
.
pwszFile
[
0
]
=
'\0'
;
ret
=
TRUE
;
}
}
break
;
default:
SetLastError
(
CRYPT_E_ASN1_BADTAG
);
}
}
TRACE
(
"returning %d
\n
"
,
ret
);
return
ret
;
}
BOOL
WINAPI
WVTAsn1SpcLinkDecode
(
DWORD
dwCertEncodingType
,
LPCSTR
lpszStructType
,
const
BYTE
*
pbEncoded
,
DWORD
cbEncoded
,
DWORD
dwFlags
,
void
*
pvStructInfo
,
DWORD
*
pcbStructInfo
)
{
FIXME
(
"(0x%08x, %s, %p, %d, 0x%08x, %p, %p)
\n
"
,
dwCertEncodingType
,
debugstr_a
(
lpszStructType
),
pbEncoded
,
cbEncoded
,
dwFlags
,
pvStructInfo
,
pcbStructInfo
);
return
FALSE
;
BOOL
ret
=
FALSE
;
TRACE
(
"%p, %d, %08x, %p, %d
\n
"
,
pbEncoded
,
cbEncoded
,
dwFlags
,
pvStructInfo
,
*
pcbStructInfo
);
__TRY
{
DWORD
bytesNeeded
;
ret
=
CRYPT_AsnDecodeSPCLinkInternal
(
dwCertEncodingType
,
lpszStructType
,
pbEncoded
,
cbEncoded
,
dwFlags
,
NULL
,
&
bytesNeeded
);
if
(
ret
)
{
if
(
!
pvStructInfo
)
*
pcbStructInfo
=
bytesNeeded
;
else
if
(
*
pcbStructInfo
<
bytesNeeded
)
{
*
pcbStructInfo
=
bytesNeeded
;
SetLastError
(
ERROR_MORE_DATA
);
ret
=
FALSE
;
}
else
{
SPC_LINK
*
link
=
(
SPC_LINK
*
)
pvStructInfo
;
link
->
u
.
pwszFile
=
(
LPWSTR
)((
BYTE
*
)
pvStructInfo
+
sizeof
(
SPC_LINK
));
ret
=
CRYPT_AsnDecodeSPCLinkInternal
(
dwCertEncodingType
,
lpszStructType
,
pbEncoded
,
cbEncoded
,
dwFlags
,
pvStructInfo
,
pcbStructInfo
);
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError
(
STATUS_ACCESS_VIOLATION
);
}
__ENDTRY
TRACE
(
"returning %d
\n
"
,
ret
);
return
ret
;
}
BOOL
WINAPI
WVTAsn1SpcPeImageDataDecode
(
DWORD
dwCertEncodingType
,
...
...
dlls/wintrust/tests/asn.c
View file @
29cae46f
...
...
@@ -147,7 +147,6 @@ static void test_decodeSPCLink(void)
ret
=
CryptDecodeObjectEx
(
X509_ASN_ENCODING
,
SPC_LINK_STRUCT
,
emptyURLSPCLink
,
sizeof
(
emptyURLSPCLink
),
CRYPT_DECODE_ALLOC_FLAG
,
NULL
,
(
BYTE
*
)
&
buf
,
&
size
);
todo_wine
ok
(
ret
,
"CryptDecodeObjectEx failed: %08x
\n
"
,
GetLastError
());
if
(
ret
)
{
...
...
@@ -160,7 +159,6 @@ static void test_decodeSPCLink(void)
ret
=
CryptDecodeObjectEx
(
X509_ASN_ENCODING
,
SPC_LINK_STRUCT
,
urlSPCLink
,
sizeof
(
urlSPCLink
),
CRYPT_DECODE_ALLOC_FLAG
,
NULL
,
(
BYTE
*
)
&
buf
,
&
size
);
todo_wine
ok
(
ret
,
"CryptDecodeObjectEx failed: %08x
\n
"
,
GetLastError
());
if
(
ret
)
{
...
...
@@ -173,7 +171,6 @@ static void test_decodeSPCLink(void)
ret
=
CryptDecodeObjectEx
(
X509_ASN_ENCODING
,
SPC_LINK_STRUCT
,
fileSPCLink
,
sizeof
(
fileSPCLink
),
CRYPT_DECODE_ALLOC_FLAG
,
NULL
,
(
BYTE
*
)
&
buf
,
&
size
);
todo_wine
ok
(
ret
,
"CryptDecodeObjectEx failed: %08x
\n
"
,
GetLastError
());
if
(
ret
)
{
...
...
@@ -186,7 +183,6 @@ static void test_decodeSPCLink(void)
ret
=
CryptDecodeObjectEx
(
X509_ASN_ENCODING
,
SPC_LINK_STRUCT
,
emptyMonikerSPCLink
,
sizeof
(
emptyMonikerSPCLink
),
CRYPT_DECODE_ALLOC_FLAG
,
NULL
,
(
BYTE
*
)
&
buf
,
&
size
);
todo_wine
ok
(
ret
,
"CryptDecodeObjectEx failed: %08x
\n
"
,
GetLastError
());
if
(
ret
)
{
...
...
@@ -195,14 +191,15 @@ static void test_decodeSPCLink(void)
link
=
(
SPC_LINK
*
)
buf
;
ok
(
link
->
dwLinkChoice
==
SPC_MONIKER_LINK_CHOICE
,
"Expected SPC_MONIKER_LINK_CHOICE, got %d
\n
"
,
link
->
dwLinkChoice
);
ok
(
!
memcmp
(
&
link
->
Moniker
,
&
emptyMoniker
,
sizeof
(
emptyMoniker
)),
"Unexpected value
\n
"
);
ok
(
!
memcmp
(
&
link
->
Moniker
.
ClassId
,
&
emptyMoniker
.
ClassId
,
sizeof
(
emptyMoniker
.
ClassId
)),
"Unexpected value
\n
"
);
ok
(
link
->
Moniker
.
SerializedData
.
cbData
==
0
,
"Expected no serialized data
\n
"
);
LocalFree
(
buf
);
}
ret
=
CryptDecodeObjectEx
(
X509_ASN_ENCODING
,
SPC_LINK_STRUCT
,
monikerSPCLink
,
sizeof
(
monikerSPCLink
),
CRYPT_DECODE_ALLOC_FLAG
,
NULL
,
(
BYTE
*
)
&
buf
,
&
size
);
todo_wine
ok
(
ret
,
"CryptDecodeObjectEx failed: %08x
\n
"
,
GetLastError
());
if
(
ret
)
{
...
...
@@ -224,7 +221,6 @@ static void test_decodeSPCLink(void)
ret
=
CryptDecodeObjectEx
(
X509_ASN_ENCODING
,
SPC_LINK_STRUCT
,
badMonikerSPCLink
,
sizeof
(
badMonikerSPCLink
),
CRYPT_DECODE_ALLOC_FLAG
,
NULL
,
(
BYTE
*
)
&
buf
,
&
size
);
todo_wine
ok
(
!
ret
&&
GetLastError
()
==
CRYPT_E_BAD_ENCODE
,
"Expected CRYPT_E_BAD_ENCODE, got %08x
\n
"
,
GetLastError
());
}
...
...
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