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
9e8c0bbd
Commit
9e8c0bbd
authored
Aug 30, 2005
by
Juan Lang
Committed by
Alexandre Julliard
Aug 30, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement collection stores.
parent
a18042e7
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
677 additions
and
4 deletions
+677
-4
cert.c
dlls/crypt32/cert.c
+370
-4
cert.c
dlls/crypt32/tests/cert.c
+307
-0
No files found.
dlls/crypt32/cert.c
View file @
9e8c0bbd
...
@@ -161,6 +161,35 @@ typedef struct _WINE_MEMSTORE
...
@@ -161,6 +161,35 @@ typedef struct _WINE_MEMSTORE
struct
list
certs
;
struct
list
certs
;
}
WINE_MEMSTORE
,
*
PWINE_MEMSTORE
;
}
WINE_MEMSTORE
,
*
PWINE_MEMSTORE
;
typedef
struct
_WINE_STORE_LIST_ENTRY
{
PWINECRYPT_CERTSTORE
store
;
DWORD
dwUpdateFlags
;
DWORD
dwPriority
;
struct
list
entry
;
}
WINE_STORE_LIST_ENTRY
,
*
PWINE_STORE_LIST_ENTRY
;
/* Returned by a collection store during enumeration.
* Note: relies on the list entry being valid after use, which a number of
* conditions might make untrue (reentrancy, closing a collection store before
* continuing an enumeration on it, ...). The tests seem to indicate this
* sort of unsafety is okay, since Windows isn't well-behaved in these
* scenarios either.
*/
typedef
struct
_WINE_COLLECTION_CERT_CONTEXT
{
WINE_CERT_CONTEXT_REF
cert
;
PWINE_STORE_LIST_ENTRY
entry
;
PWINE_CERT_CONTEXT_REF
childContext
;
}
WINE_COLLECTION_CERT_CONTEXT
,
*
PWINE_COLLECTION_CERT_CONTEXT
;
typedef
struct
_WINE_COLLECTIONSTORE
{
WINECRYPT_CERTSTORE
hdr
;
CRITICAL_SECTION
cs
;
struct
list
stores
;
}
WINE_COLLECTIONSTORE
,
*
PWINE_COLLECTIONSTORE
;
/* Like CertGetCertificateContextProperty, but operates directly on the
/* Like CertGetCertificateContextProperty, but operates directly on the
* WINE_CERT_CONTEXT. Doesn't support special-case properties, since they
* WINE_CERT_CONTEXT. Doesn't support special-case properties, since they
* are handled by CertGetCertificateContextProperty, and are particular to the
* are handled by CertGetCertificateContextProperty, and are particular to the
...
@@ -444,6 +473,249 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
...
@@ -444,6 +473,249 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
return
(
PWINECRYPT_CERTSTORE
)
store
;
return
(
PWINECRYPT_CERTSTORE
)
store
;
}
}
static
BOOL
WINAPI
CRYPT_CollectionAddCert
(
HCERTSTORE
store
,
PCCERT_CONTEXT
pCert
,
DWORD
dwAddDisposition
)
{
PWINE_COLLECTIONSTORE
cs
=
(
PWINE_COLLECTIONSTORE
)
store
;
PWINE_STORE_LIST_ENTRY
entry
,
next
;
BOOL
ret
;
TRACE
(
"(%p, %p, %ld)
\n
"
,
store
,
pCert
,
dwAddDisposition
);
ret
=
FALSE
;
EnterCriticalSection
(
&
cs
->
cs
);
LIST_FOR_EACH_ENTRY_SAFE
(
entry
,
next
,
&
cs
->
stores
,
WINE_STORE_LIST_ENTRY
,
entry
)
{
if
(
entry
->
dwUpdateFlags
&
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
)
{
ret
=
entry
->
store
->
addCert
(
entry
->
store
,
pCert
,
dwAddDisposition
);
break
;
}
}
LeaveCriticalSection
(
&
cs
->
cs
);
SetLastError
(
ret
?
ERROR_SUCCESS
:
HRESULT_FROM_WIN32
(
ERROR_ACCESS_DENIED
));
return
ret
;
}
static
PWINE_CERT_CONTEXT_REF
CRYPT_CollectionCreateCertRef
(
PWINE_CERT_CONTEXT
context
,
HCERTSTORE
store
)
{
PWINE_COLLECTION_CERT_CONTEXT
ret
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WINE_COLLECTION_CERT_CONTEXT
));
if
(
ret
)
{
/* Initialize to empty for now, just make sure the size is right */
CRYPT_InitCertRef
((
PWINE_CERT_CONTEXT_REF
)
ret
,
context
,
store
);
ret
->
entry
=
NULL
;
ret
->
childContext
=
NULL
;
}
return
(
PWINE_CERT_CONTEXT_REF
)
ret
;
}
static
void
WINAPI
CRYPT_CollectionCloseStore
(
HCERTSTORE
store
,
DWORD
dwFlags
)
{
PWINE_COLLECTIONSTORE
cs
=
(
PWINE_COLLECTIONSTORE
)
store
;
PWINE_STORE_LIST_ENTRY
entry
,
next
;
TRACE
(
"(%p, %08lx)
\n
"
,
store
,
dwFlags
);
LIST_FOR_EACH_ENTRY_SAFE
(
entry
,
next
,
&
cs
->
stores
,
WINE_STORE_LIST_ENTRY
,
entry
)
{
TRACE
(
"closing %p
\n
"
,
entry
);
CertCloseStore
((
HCERTSTORE
)
entry
->
store
,
dwFlags
);
HeapFree
(
GetProcessHeap
(),
0
,
entry
);
}
DeleteCriticalSection
(
&
cs
->
cs
);
HeapFree
(
GetProcessHeap
(),
0
,
cs
);
}
/* Advances a collection enumeration by one cert, if possible, where advancing
* means:
* - calling the current store's enumeration function once, and returning
* the enumerated cert if one is returned
* - moving to the next store if the current store has no more items, and
* recursively calling itself to get the next item.
* Returns NULL if the collection contains no more items or on error.
* Assumes the collection store's lock is held.
*/
static
PWINE_COLLECTION_CERT_CONTEXT
CRYPT_CollectionAdvanceEnum
(
PWINE_COLLECTIONSTORE
store
,
PWINE_STORE_LIST_ENTRY
storeEntry
,
PWINE_COLLECTION_CERT_CONTEXT
pPrev
)
{
PWINE_COLLECTION_CERT_CONTEXT
ret
;
PWINE_CERT_CONTEXT_REF
child
;
TRACE
(
"(%p, %p, %p)
\n
"
,
store
,
storeEntry
,
pPrev
);
if
(
pPrev
)
{
child
=
storeEntry
->
store
->
enumCert
((
HCERTSTORE
)
storeEntry
->
store
,
pPrev
->
childContext
);
if
(
child
)
{
ret
=
pPrev
;
memcpy
(
&
ret
->
cert
,
child
,
sizeof
(
WINE_CERT_CONTEXT_REF
));
ret
->
cert
.
cert
.
hCertStore
=
(
HCERTSTORE
)
store
;
InterlockedIncrement
(
&
ret
->
cert
.
context
->
ref
);
ret
->
childContext
=
child
;
}
else
{
struct
list
*
storeNext
=
list_next
(
&
store
->
stores
,
&
storeEntry
->
entry
);
pPrev
->
childContext
=
NULL
;
CertFreeCertificateContext
((
PCCERT_CONTEXT
)
pPrev
);
if
(
storeNext
)
{
storeEntry
=
LIST_ENTRY
(
storeNext
,
WINE_STORE_LIST_ENTRY
,
entry
);
ret
=
CRYPT_CollectionAdvanceEnum
(
store
,
storeEntry
,
NULL
);
}
else
{
SetLastError
(
CRYPT_E_NOT_FOUND
);
ret
=
NULL
;
}
}
}
else
{
child
=
storeEntry
->
store
->
enumCert
((
HCERTSTORE
)
storeEntry
->
store
,
NULL
);
if
(
child
)
{
ret
=
(
PWINE_COLLECTION_CERT_CONTEXT
)
CRYPT_CollectionCreateCertRef
(
child
->
context
,
store
);
if
(
ret
)
{
ret
->
entry
=
storeEntry
;
ret
->
childContext
=
child
;
}
else
CertFreeCertificateContext
((
PCCERT_CONTEXT
)
child
);
}
else
{
struct
list
*
storeNext
=
list_next
(
&
store
->
stores
,
&
storeEntry
->
entry
);
if
(
storeNext
)
{
storeEntry
=
LIST_ENTRY
(
storeNext
,
WINE_STORE_LIST_ENTRY
,
entry
);
ret
=
CRYPT_CollectionAdvanceEnum
(
store
,
storeEntry
,
NULL
);
}
else
{
SetLastError
(
CRYPT_E_NOT_FOUND
);
ret
=
NULL
;
}
}
}
TRACE
(
"returning %p
\n
"
,
ret
);
return
ret
;
}
static
PWINE_CERT_CONTEXT_REF
CRYPT_CollectionEnumCert
(
PWINECRYPT_CERTSTORE
store
,
PWINE_CERT_CONTEXT_REF
pPrev
)
{
PWINE_COLLECTIONSTORE
cs
=
(
PWINE_COLLECTIONSTORE
)
store
;
PWINE_COLLECTION_CERT_CONTEXT
prevEntry
=
(
PWINE_COLLECTION_CERT_CONTEXT
)
pPrev
,
ret
;
TRACE
(
"(%p, %p)
\n
"
,
store
,
pPrev
);
if
(
prevEntry
)
{
EnterCriticalSection
(
&
cs
->
cs
);
ret
=
CRYPT_CollectionAdvanceEnum
(
cs
,
prevEntry
->
entry
,
prevEntry
);
LeaveCriticalSection
(
&
cs
->
cs
);
}
else
{
EnterCriticalSection
(
&
cs
->
cs
);
if
(
!
list_empty
(
&
cs
->
stores
))
{
PWINE_STORE_LIST_ENTRY
storeEntry
;
storeEntry
=
LIST_ENTRY
(
cs
->
stores
.
next
,
WINE_STORE_LIST_ENTRY
,
entry
);
ret
=
CRYPT_CollectionAdvanceEnum
(
cs
,
storeEntry
,
prevEntry
);
}
else
{
SetLastError
(
CRYPT_E_NOT_FOUND
);
ret
=
NULL
;
}
LeaveCriticalSection
(
&
cs
->
cs
);
}
TRACE
(
"returning %p
\n
"
,
ret
);
return
(
PWINE_CERT_CONTEXT_REF
)
ret
;
}
static
BOOL
WINAPI
CRYPT_CollectionDeleteCert
(
HCERTSTORE
hCertStore
,
PCCERT_CONTEXT
pCertContext
,
DWORD
dwFlags
)
{
PWINE_COLLECTION_CERT_CONTEXT
context
=
(
PWINE_COLLECTION_CERT_CONTEXT
)
pCertContext
;
BOOL
ret
;
TRACE
(
"(%p, %p, %08lx)
\n
"
,
hCertStore
,
pCertContext
,
dwFlags
);
ret
=
CertDeleteCertificateFromStore
((
PCCERT_CONTEXT
)
context
->
childContext
);
if
(
ret
)
{
context
->
childContext
=
NULL
;
CertFreeCertificateContext
((
PCCERT_CONTEXT
)
context
);
}
return
ret
;
}
static
void
CRYPT_CollectionFreeCert
(
PWINE_CERT_CONTEXT_REF
ref
)
{
PWINE_COLLECTION_CERT_CONTEXT
context
=
(
PWINE_COLLECTION_CERT_CONTEXT
)
ref
;
TRACE
(
"(%p)
\n
"
,
ref
);
if
(
context
->
childContext
)
CertFreeCertificateContext
((
PCCERT_CONTEXT
)
context
->
childContext
);
}
static
WINECRYPT_CERTSTORE
*
CRYPT_CollectionOpenStore
(
HCRYPTPROV
hCryptProv
,
DWORD
dwFlags
,
const
void
*
pvPara
)
{
PWINE_COLLECTIONSTORE
store
;
if
(
dwFlags
&
CERT_STORE_DELETE_FLAG
)
{
SetLastError
(
ERROR_CALL_NOT_IMPLEMENTED
);
store
=
NULL
;
}
else
{
store
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
WINE_COLLECTIONSTORE
));
if
(
store
)
{
CRYPT_InitStore
(
&
store
->
hdr
,
hCryptProv
,
dwFlags
,
StoreTypeCollection
);
store
->
hdr
.
closeStore
=
CRYPT_CollectionCloseStore
;
store
->
hdr
.
addCert
=
CRYPT_CollectionAddCert
;
store
->
hdr
.
createCertRef
=
CRYPT_CollectionCreateCertRef
;
store
->
hdr
.
enumCert
=
CRYPT_CollectionEnumCert
;
store
->
hdr
.
deleteCert
=
CRYPT_CollectionDeleteCert
;
store
->
hdr
.
freeCert
=
CRYPT_CollectionFreeCert
;
InitializeCriticalSection
(
&
store
->
cs
);
list_init
(
&
store
->
stores
);
}
}
return
(
PWINECRYPT_CERTSTORE
)
store
;
}
static
void
WINAPI
CRYPT_DummyCloseStore
(
HCERTSTORE
hCertStore
,
DWORD
dwFlags
)
static
void
WINAPI
CRYPT_DummyCloseStore
(
HCERTSTORE
hCertStore
,
DWORD
dwFlags
)
{
{
HeapFree
(
GetProcessHeap
(),
0
,
(
PWINECRYPT_CERTSTORE
)
hCertStore
);
HeapFree
(
GetProcessHeap
(),
0
,
(
PWINECRYPT_CERTSTORE
)
hCertStore
);
...
@@ -515,10 +787,12 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
...
@@ -515,10 +787,12 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
case
(
int
)
CERT_STORE_PROV_MEMORY
:
case
(
int
)
CERT_STORE_PROV_MEMORY
:
openFunc
=
CRYPT_MemOpenStore
;
openFunc
=
CRYPT_MemOpenStore
;
break
;
break
;
case
(
int
)
CERT_STORE_PROV_COLLECTION
:
openFunc
=
CRYPT_CollectionOpenStore
;
break
;
case
(
int
)
CERT_STORE_PROV_REG
:
case
(
int
)
CERT_STORE_PROV_REG
:
case
(
int
)
CERT_STORE_PROV_SYSTEM_A
:
case
(
int
)
CERT_STORE_PROV_SYSTEM_A
:
case
(
int
)
CERT_STORE_PROV_SYSTEM_W
:
case
(
int
)
CERT_STORE_PROV_SYSTEM_W
:
case
(
int
)
CERT_STORE_PROV_COLLECTION
:
openFunc
=
CRYPT_DummyOpenStore
;
openFunc
=
CRYPT_DummyOpenStore
;
break
;
break
;
default:
default:
...
@@ -531,7 +805,7 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
...
@@ -531,7 +805,7 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
else
if
(
!
strcasecmp
(
lpszStoreProvider
,
sz_CERT_STORE_PROV_SYSTEM
))
else
if
(
!
strcasecmp
(
lpszStoreProvider
,
sz_CERT_STORE_PROV_SYSTEM
))
openFunc
=
CRYPT_DummyOpenStore
;
openFunc
=
CRYPT_DummyOpenStore
;
else
if
(
!
strcasecmp
(
lpszStoreProvider
,
sz_CERT_STORE_PROV_COLLECTION
))
else
if
(
!
strcasecmp
(
lpszStoreProvider
,
sz_CERT_STORE_PROV_COLLECTION
))
openFunc
=
CRYPT_
Dummy
OpenStore
;
openFunc
=
CRYPT_
Collection
OpenStore
;
else
else
{
{
FIXME
(
"unimplemented type %s
\n
"
,
lpszStoreProvider
);
FIXME
(
"unimplemented type %s
\n
"
,
lpszStoreProvider
);
...
@@ -1429,15 +1703,107 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
...
@@ -1429,15 +1703,107 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
BOOL
WINAPI
CertAddStoreToCollection
(
HCERTSTORE
hCollectionStore
,
BOOL
WINAPI
CertAddStoreToCollection
(
HCERTSTORE
hCollectionStore
,
HCERTSTORE
hSiblingStore
,
DWORD
dwUpdateFlags
,
DWORD
dwPriority
)
HCERTSTORE
hSiblingStore
,
DWORD
dwUpdateFlags
,
DWORD
dwPriority
)
{
{
FIXME
(
"(%p, %p, %08lx, %ld): stub
\n
"
,
hCollectionStore
,
hSiblingStore
,
PWINE_COLLECTIONSTORE
collection
=
(
PWINE_COLLECTIONSTORE
)
hCollectionStore
;
WINECRYPT_CERTSTORE
*
sibling
=
(
WINECRYPT_CERTSTORE
*
)
hSiblingStore
;
PWINE_STORE_LIST_ENTRY
entry
;
BOOL
ret
;
TRACE
(
"(%p, %p, %08lx, %ld)
\n
"
,
hCollectionStore
,
hSiblingStore
,
dwUpdateFlags
,
dwPriority
);
dwUpdateFlags
,
dwPriority
);
if
(
!
collection
||
!
sibling
)
return
TRUE
;
return
TRUE
;
if
(
collection
->
hdr
.
dwMagic
!=
WINE_CRYPTCERTSTORE_MAGIC
)
{
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
return
FALSE
;
}
if
(
collection
->
hdr
.
type
!=
StoreTypeCollection
)
{
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
return
FALSE
;
}
if
(
sibling
->
dwMagic
!=
WINE_CRYPTCERTSTORE_MAGIC
)
{
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
return
FALSE
;
}
entry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WINE_STORE_LIST_ENTRY
));
if
(
entry
)
{
InterlockedIncrement
(
&
sibling
->
ref
);
TRACE
(
"sibling %p's ref count is %ld
\n
"
,
sibling
,
sibling
->
ref
);
entry
->
store
=
sibling
;
entry
->
dwUpdateFlags
=
dwUpdateFlags
;
entry
->
dwPriority
=
dwPriority
;
list_init
(
&
entry
->
entry
);
TRACE
(
"%p: adding %p, priority %ld
\n
"
,
collection
,
entry
,
dwPriority
);
EnterCriticalSection
(
&
collection
->
cs
);
if
(
dwPriority
)
{
PWINE_STORE_LIST_ENTRY
cursor
;
BOOL
added
=
FALSE
;
LIST_FOR_EACH_ENTRY
(
cursor
,
&
collection
->
stores
,
WINE_STORE_LIST_ENTRY
,
entry
)
{
if
(
cursor
->
dwPriority
<
dwPriority
)
{
list_add_before
(
&
cursor
->
entry
,
&
entry
->
entry
);
added
=
TRUE
;
break
;
}
}
if
(
!
added
)
list_add_tail
(
&
collection
->
stores
,
&
entry
->
entry
);
}
else
list_add_tail
(
&
collection
->
stores
,
&
entry
->
entry
);
LeaveCriticalSection
(
&
collection
->
cs
);
ret
=
TRUE
;
}
else
ret
=
FALSE
;
return
ret
;
}
}
void
WINAPI
CertRemoveStoreFromCollection
(
HCERTSTORE
hCollectionStore
,
void
WINAPI
CertRemoveStoreFromCollection
(
HCERTSTORE
hCollectionStore
,
HCERTSTORE
hSiblingStore
)
HCERTSTORE
hSiblingStore
)
{
{
FIXME
(
"(%p, %p): stub
\n
"
,
hCollectionStore
,
hSiblingStore
);
PWINE_COLLECTIONSTORE
collection
=
(
PWINE_COLLECTIONSTORE
)
hCollectionStore
;
WINECRYPT_CERTSTORE
*
sibling
=
(
WINECRYPT_CERTSTORE
*
)
hSiblingStore
;
PWINE_STORE_LIST_ENTRY
store
,
next
;
TRACE
(
"(%p, %p)
\n
"
,
hCollectionStore
,
hSiblingStore
);
if
(
!
collection
||
!
sibling
)
return
;
if
(
collection
->
hdr
.
dwMagic
!=
WINE_CRYPTCERTSTORE_MAGIC
)
{
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
return
;
}
if
(
collection
->
hdr
.
type
!=
StoreTypeCollection
)
return
;
if
(
sibling
->
dwMagic
!=
WINE_CRYPTCERTSTORE_MAGIC
)
{
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
return
;
}
EnterCriticalSection
(
&
collection
->
cs
);
LIST_FOR_EACH_ENTRY_SAFE
(
store
,
next
,
&
collection
->
stores
,
WINE_STORE_LIST_ENTRY
,
entry
)
{
if
(
store
->
store
==
sibling
)
{
list_remove
(
&
store
->
entry
);
CertCloseStore
(
store
->
store
,
0
);
HeapFree
(
GetProcessHeap
(),
0
,
store
);
break
;
}
}
LeaveCriticalSection
(
&
collection
->
cs
);
}
}
PCRYPT_ATTRIBUTE
WINAPI
CertFindAttribute
(
LPCSTR
pszObjId
,
DWORD
cAttr
,
PCRYPT_ATTRIBUTE
WINAPI
CertFindAttribute
(
LPCSTR
pszObjId
,
DWORD
cAttr
,
...
...
dlls/crypt32/tests/cert.c
View file @
9e8c0bbd
...
@@ -254,6 +254,312 @@ static void testMemStore(void)
...
@@ -254,6 +254,312 @@ static void testMemStore(void)
CertCloseStore
(
store1
,
0
);
CertCloseStore
(
store1
,
0
);
}
}
static
const
BYTE
bigCert2
[]
=
"
\x30\x7a\x02\x01\x01\x30\x02\x06\x00
"
"
\x30\x15\x31\x13\x30\x11\x06\x03\x55\x04\x03\x13\x0a\x41\x6c\x65\x78\x20\x4c
"
"
\x61\x6e\x67\x00\x30\x22\x18\x0f\x31\x36\x30\x31\x30\x31\x30\x31\x30\x30\x30
"
"
\x30\x30\x30\x5a\x18\x0f\x31\x36\x30\x31\x30\x31\x30\x31\x30\x30\x30\x30\x30
"
"
\x30\x5a\x30\x15\x31\x13\x30\x11\x06\x03\x55\x04\x03\x13\x0a\x41\x6c\x65\x78
"
"
\x20\x4c\x61\x6e\x67\x00\x30\x07\x30\x02\x06\x00\x03\x01\x00\xa3\x16\x30\x14
"
"
\x30\x12\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x08\x30\x06\x01\x01\xff\x02\x01
"
"
\x01
"
;
static
void
testCollectionStore
(
void
)
{
HCERTSTORE
store1
,
store2
,
collection
,
collection2
;
PCCERT_CONTEXT
context
;
BOOL
ret
;
collection
=
CertOpenStore
(
CERT_STORE_PROV_COLLECTION
,
0
,
0
,
CERT_STORE_CREATE_NEW_FLAG
,
NULL
);
/* Try adding a cert to any empty collection */
ret
=
CertAddEncodedCertificateToStore
(
collection
,
X509_ASN_ENCODING
,
bigCert
,
sizeof
(
bigCert
)
-
1
,
CERT_STORE_ADD_ALWAYS
,
NULL
);
ok
(
!
ret
&&
GetLastError
()
==
HRESULT_FROM_WIN32
(
ERROR_ACCESS_DENIED
),
"Expected HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), got %08lx
\n
"
,
GetLastError
());
/* Create and add a cert to a memory store */
store1
=
CertOpenStore
(
CERT_STORE_PROV_MEMORY
,
0
,
0
,
CERT_STORE_CREATE_NEW_FLAG
,
NULL
);
ret
=
CertAddEncodedCertificateToStore
(
store1
,
X509_ASN_ENCODING
,
bigCert
,
sizeof
(
bigCert
)
-
1
,
CERT_STORE_ADD_ALWAYS
,
NULL
);
ok
(
ret
,
"CertAddEncodedCertificateToStore failed: %08lx
\n
"
,
GetLastError
());
/* Add the memory store to the collection, without allowing adding */
ret
=
CertAddStoreToCollection
(
collection
,
store1
,
0
,
0
);
ok
(
ret
,
"CertAddStoreToCollection failed: %08lx
\n
"
,
GetLastError
());
/* Verify the cert is in the collection */
context
=
CertEnumCertificatesInStore
(
collection
,
NULL
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection
,
"Unexpected store
\n
"
);
CertFreeCertificateContext
(
context
);
}
/* Check that adding to the collection isn't allowed */
ret
=
CertAddEncodedCertificateToStore
(
collection
,
X509_ASN_ENCODING
,
bigCert2
,
sizeof
(
bigCert2
)
-
1
,
CERT_STORE_ADD_ALWAYS
,
NULL
);
ok
(
!
ret
&&
GetLastError
()
==
HRESULT_FROM_WIN32
(
ERROR_ACCESS_DENIED
),
"Expected HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), got %08lx
\n
"
,
GetLastError
());
/* Create a new memory store */
store2
=
CertOpenStore
(
CERT_STORE_PROV_MEMORY
,
0
,
0
,
CERT_STORE_CREATE_NEW_FLAG
,
NULL
);
/* Try adding a store to a non-collection store */
ret
=
CertAddStoreToCollection
(
store1
,
store2
,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
,
0
);
ok
(
!
ret
&&
GetLastError
()
==
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
),
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx
\n
"
,
GetLastError
());
/* Try adding some bogus stores */
/* This crashes in Windows
ret = CertAddStoreToCollection(0, store2,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
*/
/* This "succeeds"... */
ret
=
CertAddStoreToCollection
(
collection
,
0
,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
,
0
);
ok
(
ret
,
"CertAddStoreToCollection failed: %08lx
\n
"
,
GetLastError
());
/* while this crashes.
ret = CertAddStoreToCollection(collection, 1,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
*/
/* Add it to the collection, this time allowing adding */
ret
=
CertAddStoreToCollection
(
collection
,
store2
,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
,
0
);
ok
(
ret
,
"CertAddStoreToCollection failed: %08lx
\n
"
,
GetLastError
());
/* Check that adding to the collection is allowed */
ret
=
CertAddEncodedCertificateToStore
(
collection
,
X509_ASN_ENCODING
,
bigCert2
,
sizeof
(
bigCert2
)
-
1
,
CERT_STORE_ADD_ALWAYS
,
NULL
);
ok
(
ret
,
"CertAddEncodedCertificateToStore failed: %08lx
\n
"
,
GetLastError
());
/* Now check that it was actually added to store2 */
context
=
CertEnumCertificatesInStore
(
store2
,
NULL
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
store2
,
"Unexpected store
\n
"
);
CertFreeCertificateContext
(
context
);
}
/* Check that the collection has both bigCert and bigCert2. bigCert comes
* first because store1 was added first.
*/
context
=
CertEnumCertificatesInStore
(
collection
,
NULL
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection
,
"Unexpected store
\n
"
);
ok
(
context
->
cbCertEncoded
==
sizeof
(
bigCert
)
-
1
,
"Expected size %d, got %ld
\n
"
,
sizeof
(
bigCert
)
-
1
,
context
->
cbCertEncoded
);
ok
(
!
memcmp
(
context
->
pbCertEncoded
,
bigCert
,
context
->
cbCertEncoded
),
"Unexpected cert
\n
"
);
context
=
CertEnumCertificatesInStore
(
collection
,
context
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection
,
"Unexpected store
\n
"
);
ok
(
context
->
cbCertEncoded
==
sizeof
(
bigCert2
)
-
1
,
"Expected size %d, got %ld
\n
"
,
sizeof
(
bigCert2
)
-
1
,
context
->
cbCertEncoded
);
ok
(
!
memcmp
(
context
->
pbCertEncoded
,
bigCert2
,
context
->
cbCertEncoded
),
"Unexpected cert
\n
"
);
context
=
CertEnumCertificatesInStore
(
collection
,
context
);
ok
(
!
context
,
"Unexpected cert
\n
"
);
}
}
/* close store2, and check that the collection is unmodified */
CertCloseStore
(
store2
,
0
);
context
=
CertEnumCertificatesInStore
(
collection
,
NULL
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection
,
"Unexpected store
\n
"
);
ok
(
context
->
cbCertEncoded
==
sizeof
(
bigCert
)
-
1
,
"Expected size %d, got %ld
\n
"
,
sizeof
(
bigCert
)
-
1
,
context
->
cbCertEncoded
);
ok
(
!
memcmp
(
context
->
pbCertEncoded
,
bigCert
,
context
->
cbCertEncoded
),
"Unexpected cert
\n
"
);
context
=
CertEnumCertificatesInStore
(
collection
,
context
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection
,
"Unexpected store
\n
"
);
ok
(
context
->
cbCertEncoded
==
sizeof
(
bigCert2
)
-
1
,
"Expected size %d, got %ld
\n
"
,
sizeof
(
bigCert2
)
-
1
,
context
->
cbCertEncoded
);
ok
(
!
memcmp
(
context
->
pbCertEncoded
,
bigCert2
,
context
->
cbCertEncoded
),
"Unexpected cert
\n
"
);
context
=
CertEnumCertificatesInStore
(
collection
,
context
);
ok
(
!
context
,
"Unexpected cert
\n
"
);
}
}
/* Adding a collection to a collection is legal */
collection2
=
CertOpenStore
(
CERT_STORE_PROV_COLLECTION
,
0
,
0
,
CERT_STORE_CREATE_NEW_FLAG
,
NULL
);
ret
=
CertAddStoreToCollection
(
collection2
,
collection
,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
,
0
);
ok
(
ret
,
"CertAddStoreToCollection failed: %08lx
\n
"
,
GetLastError
());
/* check the contents of collection2 */
context
=
CertEnumCertificatesInStore
(
collection2
,
NULL
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection2
,
"Unexpected store
\n
"
);
ok
(
context
->
cbCertEncoded
==
sizeof
(
bigCert
)
-
1
,
"Expected size %d, got %ld
\n
"
,
sizeof
(
bigCert
)
-
1
,
context
->
cbCertEncoded
);
ok
(
!
memcmp
(
context
->
pbCertEncoded
,
bigCert
,
context
->
cbCertEncoded
),
"Unexpected cert
\n
"
);
context
=
CertEnumCertificatesInStore
(
collection2
,
context
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection2
,
"Unexpected store
\n
"
);
ok
(
context
->
cbCertEncoded
==
sizeof
(
bigCert2
)
-
1
,
"Expected size %d, got %ld
\n
"
,
sizeof
(
bigCert2
)
-
1
,
context
->
cbCertEncoded
);
ok
(
!
memcmp
(
context
->
pbCertEncoded
,
bigCert2
,
context
->
cbCertEncoded
),
"Unexpected cert
\n
"
);
context
=
CertEnumCertificatesInStore
(
collection2
,
context
);
ok
(
!
context
,
"Unexpected cert
\n
"
);
}
}
/* I'd like to test closing the collection in the middle of enumeration,
* but my tests have been inconsistent. The first time calling
* CertEnumCertificatesInStore on a closed collection succeeded, while the
* second crashed. So anything appears to be fair game.
* I'd also like to test removing a store from a collection in the middle
* of an enumeration, but my tests in Windows have been inconclusive.
* In one scenario it worked. In another scenario, about a third of the
* time this leads to "random" crashes elsewhere in the code. This
* probably means this is not allowed.
*/
CertCloseStore
(
store1
,
0
);
CertCloseStore
(
collection
,
0
);
CertCloseStore
(
collection2
,
0
);
/* Add the same cert to two memory stores, then put them in a collection */
store1
=
CertOpenStore
(
CERT_STORE_PROV_MEMORY
,
0
,
0
,
CERT_STORE_CREATE_NEW_FLAG
,
NULL
);
ok
(
store1
!=
0
,
"CertOpenStore failed: %08lx
\n
"
,
GetLastError
());
store2
=
CertOpenStore
(
CERT_STORE_PROV_MEMORY
,
0
,
0
,
CERT_STORE_CREATE_NEW_FLAG
,
NULL
);
ok
(
store2
!=
0
,
"CertOpenStore failed: %08lx
\n
"
,
GetLastError
());
ret
=
CertAddEncodedCertificateToStore
(
store1
,
X509_ASN_ENCODING
,
bigCert
,
sizeof
(
bigCert
)
-
1
,
CERT_STORE_ADD_ALWAYS
,
NULL
);
ok
(
ret
,
"CertAddEncodedCertificateToStore failed: %08lx
\n
"
,
GetLastError
());
ret
=
CertAddEncodedCertificateToStore
(
store2
,
X509_ASN_ENCODING
,
bigCert
,
sizeof
(
bigCert
)
-
1
,
CERT_STORE_ADD_ALWAYS
,
NULL
);
ok
(
ret
,
"CertAddEncodedCertificateToStore failed: %08lx
\n
"
,
GetLastError
());
collection
=
CertOpenStore
(
CERT_STORE_PROV_COLLECTION
,
0
,
0
,
CERT_STORE_CREATE_NEW_FLAG
,
NULL
);
ok
(
collection
!=
0
,
"CertOpenStore failed: %08lx
\n
"
,
GetLastError
());
ret
=
CertAddStoreToCollection
(
collection
,
store1
,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
,
0
);
ok
(
ret
,
"CertAddStoreToCollection failed: %08lx
\n
"
,
GetLastError
());
ret
=
CertAddStoreToCollection
(
collection
,
store2
,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
,
0
);
ok
(
ret
,
"CertAddStoreToCollection failed: %08lx
\n
"
,
GetLastError
());
/* Check that the collection has two copies of the same cert */
context
=
CertEnumCertificatesInStore
(
collection
,
NULL
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection
,
"Unexpected store
\n
"
);
ok
(
context
->
cbCertEncoded
==
sizeof
(
bigCert
)
-
1
,
"Expected size %d, got %ld
\n
"
,
sizeof
(
bigCert
)
-
1
,
context
->
cbCertEncoded
);
ok
(
!
memcmp
(
context
->
pbCertEncoded
,
bigCert
,
context
->
cbCertEncoded
),
"Unexpected cert
\n
"
);
context
=
CertEnumCertificatesInStore
(
collection
,
context
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection
,
"Unexpected store
\n
"
);
ok
(
context
->
cbCertEncoded
==
sizeof
(
bigCert
)
-
1
,
"Expected size %d, got %ld
\n
"
,
sizeof
(
bigCert
)
-
1
,
context
->
cbCertEncoded
);
ok
(
!
memcmp
(
context
->
pbCertEncoded
,
bigCert
,
context
->
cbCertEncoded
),
"Unexpected cert
\n
"
);
context
=
CertEnumCertificatesInStore
(
collection
,
context
);
ok
(
context
==
NULL
,
"Unexpected cert
\n
"
);
}
}
/* The following would check whether I can delete an identical cert, rather
* than one enumerated from the store. It crashes, so that means I must
* only call CertDeleteCertificateFromStore with contexts enumerated from
* the store.
context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
sizeof(bigCert) - 1);
ok(context != NULL, "CertCreateCertificateContext failed: %08lx\n",
GetLastError());
if (context)
{
ret = CertDeleteCertificateFromStore(collection, context);
printf("ret is %d, GetLastError is %08lx\n", ret, GetLastError());
CertFreeCertificateContext(context);
}
*/
/* Now check deleting from the collection. */
context
=
CertEnumCertificatesInStore
(
collection
,
NULL
);
ok
(
context
!=
NULL
,
"Expected a valid context
\n
"
);
if
(
context
)
{
CertDeleteCertificateFromStore
(
context
);
/* store1 should now be empty */
context
=
CertEnumCertificatesInStore
(
store1
,
NULL
);
ok
(
!
context
,
"Unexpected cert
\n
"
);
/* and there should be one certificate in the collection */
context
=
CertEnumCertificatesInStore
(
collection
,
NULL
);
ok
(
context
!=
NULL
,
"Expected a valid cert
\n
"
);
if
(
context
)
{
ok
(
context
->
hCertStore
==
collection
,
"Unexpected store
\n
"
);
ok
(
context
->
cbCertEncoded
==
sizeof
(
bigCert
)
-
1
,
"Expected size %d, got %ld
\n
"
,
sizeof
(
bigCert
)
-
1
,
context
->
cbCertEncoded
);
ok
(
!
memcmp
(
context
->
pbCertEncoded
,
bigCert
,
context
->
cbCertEncoded
),
"Unexpected cert
\n
"
);
}
context
=
CertEnumCertificatesInStore
(
collection
,
context
);
ok
(
context
==
NULL
,
"Unexpected cert
\n
"
);
}
/* Finally, test removing stores from the collection. No return value, so
* it's a bit funny to test.
*/
/* This crashes
CertRemoveStoreFromCollection(NULL, NULL);
*/
/* This "succeeds," no crash, no last error set */
SetLastError
(
0xdeadbeef
);
CertRemoveStoreFromCollection
(
store2
,
collection
);
ok
(
GetLastError
()
==
0xdeadbeef
,
"Didn't expect an error to be set: %08lx
\n
"
,
GetLastError
());
/* After removing store2, the collection should be empty */
SetLastError
(
0xdeadbeef
);
CertRemoveStoreFromCollection
(
collection
,
store2
);
ok
(
GetLastError
()
==
0xdeadbeef
,
"Didn't expect an error to be set: %08lx
\n
"
,
GetLastError
());
context
=
CertEnumCertificatesInStore
(
collection
,
NULL
);
ok
(
!
context
,
"Unexpected cert
\n
"
);
CertCloseStore
(
collection
,
0
);
CertCloseStore
(
store2
,
0
);
CertCloseStore
(
store1
,
0
);
}
static
void
testCertProperties
(
void
)
static
void
testCertProperties
(
void
)
{
{
PCCERT_CONTEXT
context
=
CertCreateCertificateContext
(
X509_ASN_ENCODING
,
PCCERT_CONTEXT
context
=
CertCreateCertificateContext
(
X509_ASN_ENCODING
,
...
@@ -367,6 +673,7 @@ START_TEST(cert)
...
@@ -367,6 +673,7 @@ START_TEST(cert)
/* various combinations of CertOpenStore */
/* various combinations of CertOpenStore */
testMemStore
();
testMemStore
();
testCollectionStore
();
testCertProperties
();
testCertProperties
();
}
}
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