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
c3a12517
Commit
c3a12517
authored
Mar 03, 2006
by
Juan Lang
Committed by
Alexandre Julliard
Mar 04, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
crypt32: Move serialization functions to serialize.c.
parent
ad4af126
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
530 additions
and
434 deletions
+530
-434
Makefile.in
dlls/crypt32/Makefile.in
+1
-0
crypt32_private.h
dlls/crypt32/crypt32_private.h
+14
-0
serialize.c
dlls/crypt32/serialize.c
+515
-0
store.c
dlls/crypt32/store.c
+0
-434
No files found.
dlls/crypt32/Makefile.in
View file @
c3a12517
...
...
@@ -12,6 +12,7 @@ C_SRCS = \
encode.c
\
oid.c
\
protectdata.c
\
serialize.c
\
store.c
\
str.c
\
main.c
...
...
dlls/crypt32/crypt32_private.h
View file @
c3a12517
...
...
@@ -19,6 +19,11 @@
#ifndef __CRYPT32_PRIVATE_H__
#define __CRYPT32_PRIVATE_H__
/* The following aren't defined in wincrypt.h, as they're "reserved" */
#define CERT_CERT_PROP_ID 32
#define CERT_CRL_PROP_ID 33
#define CERT_CTL_PROP_ID 34
/* Returns a handle to the default crypto provider; loads it if necessary.
* Returns NULL on failure.
*/
...
...
@@ -27,4 +32,13 @@ HCRYPTPROV CRYPT_GetDefaultProvider(void);
void
crypt_oid_init
(
HINSTANCE
hinst
);
void
crypt_oid_free
(
void
);
/* Helper function for store reading functions and
* CertAddSerializedElementToStore. Returns a context of the appropriate type
* if it can, or NULL otherwise. Doesn't validate any of the properties in
* the serialized context (for example, bad hashes are retained.)
* *pdwContentType is set to the type of the returned context.
*/
const
void
*
CRYPT_ReadSerializedElement
(
const
BYTE
*
pbElement
,
DWORD
cbElement
,
DWORD
dwContextTypeFlags
,
DWORD
*
pdwContentType
);
#endif
dlls/crypt32/serialize.c
0 → 100644
View file @
c3a12517
/*
* Copyright 2004-2006 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "wine/debug.h"
#include "excpt.h"
#include "wine/exception.h"
#include "crypt32_private.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
crypt
);
/* Some typedefs that make it easier to abstract which type of context we're
* working with.
*/
typedef
const
void
*
(
WINAPI
*
CreateContextFunc
)(
DWORD
dwCertEncodingType
,
const
BYTE
*
pbCertEncoded
,
DWORD
cbCertEncoded
);
typedef
BOOL
(
WINAPI
*
AddContextToStoreFunc
)(
HCERTSTORE
hCertStore
,
const
void
*
context
,
DWORD
dwAddDisposition
,
const
void
**
ppStoreContext
);
typedef
BOOL
(
WINAPI
*
AddEncodedContextToStoreFunc
)(
HCERTSTORE
hCertStore
,
DWORD
dwCertEncodingType
,
const
BYTE
*
pbEncoded
,
DWORD
cbEncoded
,
DWORD
dwAddDisposition
,
const
void
**
ppContext
);
typedef
const
void
*
(
WINAPI
*
EnumContextsInStoreFunc
)(
HCERTSTORE
hCertStore
,
const
void
*
pPrevContext
);
typedef
BOOL
(
WINAPI
*
GetContextPropertyFunc
)(
const
void
*
context
,
DWORD
dwPropID
,
void
*
pvData
,
DWORD
*
pcbData
);
typedef
BOOL
(
WINAPI
*
SetContextPropertyFunc
)(
const
void
*
context
,
DWORD
dwPropID
,
DWORD
dwFlags
,
const
void
*
pvData
);
typedef
BOOL
(
WINAPI
*
SerializeElementFunc
)(
const
void
*
context
,
DWORD
dwFlags
,
BYTE
*
pbElement
,
DWORD
*
pcbElement
);
typedef
BOOL
(
WINAPI
*
FreeContextFunc
)(
const
void
*
context
);
typedef
BOOL
(
WINAPI
*
DeleteContextFunc
)(
const
void
*
context
);
/* An abstract context (certificate, CRL, or CTL) interface */
typedef
struct
_WINE_CONTEXT_INTERFACE
{
CreateContextFunc
create
;
AddContextToStoreFunc
addContextToStore
;
AddEncodedContextToStoreFunc
addEncodedToStore
;
EnumContextsInStoreFunc
enumContextsInStore
;
GetContextPropertyFunc
getProp
;
SetContextPropertyFunc
setProp
;
SerializeElementFunc
serialize
;
FreeContextFunc
free
;
DeleteContextFunc
deleteFromStore
;
}
WINE_CONTEXT_INTERFACE
,
*
PWINE_CONTEXT_INTERFACE
;
static
const
WINE_CONTEXT_INTERFACE
gCertInterface
=
{
(
CreateContextFunc
)
CertCreateCertificateContext
,
(
AddContextToStoreFunc
)
CertAddCertificateContextToStore
,
(
AddEncodedContextToStoreFunc
)
CertAddEncodedCertificateToStore
,
(
EnumContextsInStoreFunc
)
CertEnumCertificatesInStore
,
(
GetContextPropertyFunc
)
CertGetCertificateContextProperty
,
(
SetContextPropertyFunc
)
CertSetCertificateContextProperty
,
(
SerializeElementFunc
)
CertSerializeCertificateStoreElement
,
(
FreeContextFunc
)
CertFreeCertificateContext
,
(
DeleteContextFunc
)
CertDeleteCertificateFromStore
,
};
static
const
WINE_CONTEXT_INTERFACE
gCRLInterface
=
{
(
CreateContextFunc
)
CertCreateCRLContext
,
(
AddContextToStoreFunc
)
CertAddCRLContextToStore
,
(
AddEncodedContextToStoreFunc
)
CertAddEncodedCRLToStore
,
(
EnumContextsInStoreFunc
)
CertEnumCRLsInStore
,
(
GetContextPropertyFunc
)
CertGetCRLContextProperty
,
(
SetContextPropertyFunc
)
CertSetCRLContextProperty
,
(
SerializeElementFunc
)
CertSerializeCRLStoreElement
,
(
FreeContextFunc
)
CertFreeCRLContext
,
(
DeleteContextFunc
)
CertDeleteCRLFromStore
,
};
static
const
WINE_CONTEXT_INTERFACE
gCTLInterface
=
{
(
CreateContextFunc
)
CertCreateCTLContext
,
(
AddContextToStoreFunc
)
CertAddCTLContextToStore
,
(
AddEncodedContextToStoreFunc
)
CertAddEncodedCTLToStore
,
(
EnumContextsInStoreFunc
)
CertEnumCTLsInStore
,
(
GetContextPropertyFunc
)
CertGetCTLContextProperty
,
(
SetContextPropertyFunc
)
CertSetCTLContextProperty
,
(
SerializeElementFunc
)
CertSerializeCTLStoreElement
,
(
FreeContextFunc
)
CertFreeCTLContext
,
(
DeleteContextFunc
)
CertDeleteCTLFromStore
,
};
/* An extended certificate property in serialized form is prefixed by this
* header.
*/
typedef
struct
_WINE_CERT_PROP_HEADER
{
DWORD
propID
;
DWORD
unknown
;
/* always 1 */
DWORD
cb
;
}
WINE_CERT_PROP_HEADER
,
*
PWINE_CERT_PROP_HEADER
;
BOOL
WINAPI
CertSerializeCRLStoreElement
(
PCCRL_CONTEXT
pCrlContext
,
DWORD
dwFlags
,
BYTE
*
pbElement
,
DWORD
*
pcbElement
)
{
FIXME
(
"(%p, %08lx, %p, %p): stub
\n
"
,
pCrlContext
,
dwFlags
,
pbElement
,
pcbElement
);
return
FALSE
;
}
BOOL
WINAPI
CertSerializeCTLStoreElement
(
PCCTL_CONTEXT
pCtlContext
,
DWORD
dwFlags
,
BYTE
*
pbElement
,
DWORD
*
pcbElement
)
{
FIXME
(
"(%p, %08lx, %p, %p): stub
\n
"
,
pCtlContext
,
dwFlags
,
pbElement
,
pcbElement
);
return
FALSE
;
}
BOOL
WINAPI
CertSerializeCertificateStoreElement
(
PCCERT_CONTEXT
pCertContext
,
DWORD
dwFlags
,
BYTE
*
pbElement
,
DWORD
*
pcbElement
)
{
BOOL
ret
;
TRACE
(
"(%p, %08lx, %p, %p)
\n
"
,
pCertContext
,
dwFlags
,
pbElement
,
pcbElement
);
if
(
pCertContext
)
{
DWORD
bytesNeeded
=
sizeof
(
WINE_CERT_PROP_HEADER
)
+
pCertContext
->
cbCertEncoded
;
DWORD
prop
=
0
;
ret
=
TRUE
;
do
{
prop
=
CertEnumCertificateContextProperties
(
pCertContext
,
prop
);
if
(
prop
)
{
DWORD
propSize
=
0
;
ret
=
CertGetCertificateContextProperty
(
pCertContext
,
prop
,
NULL
,
&
propSize
);
if
(
ret
)
bytesNeeded
+=
sizeof
(
WINE_CERT_PROP_HEADER
)
+
propSize
;
}
}
while
(
ret
&&
prop
!=
0
);
if
(
!
pbElement
)
{
*
pcbElement
=
bytesNeeded
;
ret
=
TRUE
;
}
else
if
(
*
pcbElement
<
bytesNeeded
)
{
*
pcbElement
=
bytesNeeded
;
SetLastError
(
ERROR_MORE_DATA
);
ret
=
FALSE
;
}
else
{
PWINE_CERT_PROP_HEADER
hdr
;
DWORD
bufSize
=
0
;
LPBYTE
buf
=
NULL
;
prop
=
0
;
do
{
prop
=
CertEnumCertificateContextProperties
(
pCertContext
,
prop
);
if
(
prop
)
{
DWORD
propSize
=
0
;
ret
=
CertGetCertificateContextProperty
(
pCertContext
,
prop
,
NULL
,
&
propSize
);
if
(
ret
)
{
if
(
bufSize
<
propSize
)
{
if
(
buf
)
buf
=
CryptMemRealloc
(
buf
,
propSize
);
else
buf
=
CryptMemAlloc
(
propSize
);
bufSize
=
propSize
;
}
if
(
buf
)
{
ret
=
CertGetCertificateContextProperty
(
pCertContext
,
prop
,
buf
,
&
propSize
);
if
(
ret
)
{
hdr
=
(
PWINE_CERT_PROP_HEADER
)
pbElement
;
hdr
->
propID
=
prop
;
hdr
->
unknown
=
1
;
hdr
->
cb
=
propSize
;
pbElement
+=
sizeof
(
WINE_CERT_PROP_HEADER
);
if
(
propSize
)
{
memcpy
(
pbElement
,
buf
,
propSize
);
pbElement
+=
propSize
;
}
}
}
else
ret
=
FALSE
;
}
}
}
while
(
ret
&&
prop
!=
0
);
CryptMemFree
(
buf
);
hdr
=
(
PWINE_CERT_PROP_HEADER
)
pbElement
;
hdr
->
propID
=
CERT_CERT_PROP_ID
;
hdr
->
unknown
=
1
;
hdr
->
cb
=
pCertContext
->
cbCertEncoded
;
memcpy
(
pbElement
+
sizeof
(
WINE_CERT_PROP_HEADER
),
pCertContext
->
pbCertEncoded
,
pCertContext
->
cbCertEncoded
);
}
}
else
ret
=
FALSE
;
return
ret
;
}
/* Looks for the property with ID propID in the buffer buf. Returns a pointer
* to its header if a valid header is found, NULL if not. Valid means the
* length of thte property won't overrun buf, and the unknown field is 1.
*/
static
const
WINE_CERT_PROP_HEADER
*
CRYPT_findPropID
(
const
BYTE
*
buf
,
DWORD
size
,
DWORD
propID
)
{
const
WINE_CERT_PROP_HEADER
*
ret
=
NULL
;
BOOL
done
=
FALSE
;
while
(
size
&&
!
ret
&&
!
done
)
{
if
(
size
<
sizeof
(
WINE_CERT_PROP_HEADER
))
{
SetLastError
(
CRYPT_E_FILE_ERROR
);
done
=
TRUE
;
}
else
{
const
WINE_CERT_PROP_HEADER
*
hdr
=
(
const
WINE_CERT_PROP_HEADER
*
)
buf
;
size
-=
sizeof
(
WINE_CERT_PROP_HEADER
);
buf
+=
sizeof
(
WINE_CERT_PROP_HEADER
);
if
(
size
<
hdr
->
cb
)
{
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
done
=
TRUE
;
}
else
if
(
!
hdr
->
propID
)
{
/* assume a zero prop ID means the data are uninitialized, so
* stop looking.
*/
done
=
TRUE
;
}
else
if
(
hdr
->
unknown
!=
1
)
{
SetLastError
(
ERROR_FILE_NOT_FOUND
);
done
=
TRUE
;
}
else
if
(
hdr
->
propID
==
propID
)
ret
=
hdr
;
else
{
buf
+=
hdr
->
cb
;
size
-=
hdr
->
cb
;
}
}
}
return
ret
;
}
const
void
*
CRYPT_ReadSerializedElement
(
const
BYTE
*
pbElement
,
DWORD
cbElement
,
DWORD
dwContextTypeFlags
,
DWORD
*
pdwContentType
)
{
const
void
*
context
;
TRACE
(
"(%p, %ld, %08lx, %p)
\n
"
,
pbElement
,
cbElement
,
dwContextTypeFlags
,
pdwContentType
);
if
(
!
cbElement
)
{
SetLastError
(
ERROR_END_OF_MEDIA
);
return
NULL
;
}
__TRY
{
const
WINE_CONTEXT_INTERFACE
*
contextInterface
=
NULL
;
const
WINE_CERT_PROP_HEADER
*
hdr
=
NULL
;
DWORD
type
=
0
;
BOOL
ret
;
ret
=
TRUE
;
context
=
NULL
;
if
(
dwContextTypeFlags
==
CERT_STORE_ALL_CONTEXT_FLAG
)
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CERT_PROP_ID
);
if
(
hdr
)
type
=
CERT_STORE_CERTIFICATE_CONTEXT
;
else
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CRL_PROP_ID
);
if
(
hdr
)
type
=
CERT_STORE_CRL_CONTEXT
;
else
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CTL_PROP_ID
);
if
(
hdr
)
type
=
CERT_STORE_CTL_CONTEXT
;
}
}
}
else
if
(
dwContextTypeFlags
&
CERT_STORE_CERTIFICATE_CONTEXT_FLAG
)
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CERT_PROP_ID
);
type
=
CERT_STORE_CERTIFICATE_CONTEXT
;
}
else
if
(
dwContextTypeFlags
&
CERT_STORE_CRL_CONTEXT_FLAG
)
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CRL_PROP_ID
);
type
=
CERT_STORE_CRL_CONTEXT
;
}
else
if
(
dwContextTypeFlags
&
CERT_STORE_CTL_CONTEXT_FLAG
)
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CTL_PROP_ID
);
type
=
CERT_STORE_CTL_CONTEXT
;
}
switch
(
type
)
{
case
CERT_STORE_CERTIFICATE_CONTEXT
:
contextInterface
=
&
gCertInterface
;
break
;
case
CERT_STORE_CRL_CONTEXT
:
contextInterface
=
&
gCRLInterface
;
break
;
case
CERT_STORE_CTL_CONTEXT
:
contextInterface
=
&
gCTLInterface
;
break
;
default:
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
ret
=
FALSE
;
}
if
(
!
hdr
)
ret
=
FALSE
;
if
(
ret
)
context
=
contextInterface
->
create
(
X509_ASN_ENCODING
,
(
BYTE
*
)
hdr
+
sizeof
(
WINE_CERT_PROP_HEADER
),
hdr
->
cb
);
if
(
ret
&&
context
)
{
BOOL
noMoreProps
=
FALSE
;
while
(
!
noMoreProps
&&
ret
)
{
if
(
cbElement
<
sizeof
(
WINE_CERT_PROP_HEADER
))
ret
=
FALSE
;
else
{
const
WINE_CERT_PROP_HEADER
*
hdr
=
(
const
WINE_CERT_PROP_HEADER
*
)
pbElement
;
TRACE
(
"prop is %ld
\n
"
,
hdr
->
propID
);
cbElement
-=
sizeof
(
WINE_CERT_PROP_HEADER
);
pbElement
+=
sizeof
(
WINE_CERT_PROP_HEADER
);
if
(
cbElement
<
hdr
->
cb
)
{
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
ret
=
FALSE
;
}
else
if
(
!
hdr
->
propID
)
{
/* Like in CRYPT_findPropID, stop if the propID is zero
*/
noMoreProps
=
TRUE
;
}
else
if
(
hdr
->
unknown
!=
1
)
{
SetLastError
(
ERROR_FILE_NOT_FOUND
);
ret
=
FALSE
;
}
else
if
(
hdr
->
propID
!=
CERT_CERT_PROP_ID
&&
hdr
->
propID
!=
CERT_CRL_PROP_ID
&&
hdr
->
propID
!=
CERT_CTL_PROP_ID
)
{
/* Have to create a blob for most types, but not
* for all.. arghh.
*/
switch
(
hdr
->
propID
)
{
case
CERT_AUTO_ENROLL_PROP_ID
:
case
CERT_CTL_USAGE_PROP_ID
:
case
CERT_DESCRIPTION_PROP_ID
:
case
CERT_FRIENDLY_NAME_PROP_ID
:
case
CERT_HASH_PROP_ID
:
case
CERT_KEY_IDENTIFIER_PROP_ID
:
case
CERT_MD5_HASH_PROP_ID
:
case
CERT_NEXT_UPDATE_LOCATION_PROP_ID
:
case
CERT_PUBKEY_ALG_PARA_PROP_ID
:
case
CERT_PVK_FILE_PROP_ID
:
case
CERT_SIGNATURE_HASH_PROP_ID
:
case
CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID
:
case
CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID
:
case
CERT_ENROLLMENT_PROP_ID
:
case
CERT_CROSS_CERT_DIST_POINTS_PROP_ID
:
case
CERT_RENEWAL_PROP_ID
:
{
CRYPT_DATA_BLOB
blob
=
{
hdr
->
cb
,
(
LPBYTE
)
pbElement
};
ret
=
contextInterface
->
setProp
(
context
,
hdr
->
propID
,
0
,
&
blob
);
break
;
}
case
CERT_DATE_STAMP_PROP_ID
:
ret
=
contextInterface
->
setProp
(
context
,
hdr
->
propID
,
0
,
pbElement
);
break
;
default:
FIXME
(
"prop ID %ld: stub
\n
"
,
hdr
->
propID
);
}
}
pbElement
+=
hdr
->
cb
;
cbElement
-=
hdr
->
cb
;
if
(
!
cbElement
)
noMoreProps
=
TRUE
;
}
}
if
(
ret
)
{
if
(
pdwContentType
)
*
pdwContentType
=
type
;
}
else
{
contextInterface
->
free
(
context
);
context
=
NULL
;
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError
(
STATUS_ACCESS_VIOLATION
);
context
=
NULL
;
}
__ENDTRY
return
context
;
}
BOOL
WINAPI
CertAddSerializedElementToStore
(
HCERTSTORE
hCertStore
,
const
BYTE
*
pbElement
,
DWORD
cbElement
,
DWORD
dwAddDisposition
,
DWORD
dwFlags
,
DWORD
dwContextTypeFlags
,
DWORD
*
pdwContentType
,
const
void
**
ppvContext
)
{
const
void
*
context
;
DWORD
type
;
BOOL
ret
;
TRACE
(
"(%p, %p, %ld, %08lx, %08lx, %08lx, %p, %p)
\n
"
,
hCertStore
,
pbElement
,
cbElement
,
dwAddDisposition
,
dwFlags
,
dwContextTypeFlags
,
pdwContentType
,
ppvContext
);
/* Call the internal function, then delete the hashes. Tests show this
* function uses real hash values, not whatever's stored in the hash
* property.
*/
context
=
CRYPT_ReadSerializedElement
(
pbElement
,
cbElement
,
dwContextTypeFlags
,
&
type
);
if
(
context
)
{
const
WINE_CONTEXT_INTERFACE
*
contextInterface
=
NULL
;
switch
(
type
)
{
case
CERT_STORE_CERTIFICATE_CONTEXT
:
contextInterface
=
&
gCertInterface
;
break
;
case
CERT_STORE_CRL_CONTEXT
:
contextInterface
=
&
gCRLInterface
;
break
;
case
CERT_STORE_CTL_CONTEXT
:
contextInterface
=
&
gCTLInterface
;
break
;
default:
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
}
if
(
contextInterface
)
{
contextInterface
->
setProp
(
context
,
CERT_HASH_PROP_ID
,
0
,
NULL
);
contextInterface
->
setProp
(
context
,
CERT_MD5_HASH_PROP_ID
,
0
,
NULL
);
contextInterface
->
setProp
(
context
,
CERT_SIGNATURE_HASH_PROP_ID
,
0
,
NULL
);
if
(
pdwContentType
)
*
pdwContentType
=
type
;
ret
=
contextInterface
->
addContextToStore
(
hCertStore
,
context
,
dwAddDisposition
,
ppvContext
);
contextInterface
->
free
(
context
);
}
else
ret
=
FALSE
;
}
else
ret
=
FALSE
;
return
ret
;
}
dlls/crypt32/store.c
View file @
c3a12517
...
...
@@ -43,10 +43,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
crypt
);
#define WINE_CRYPTCERTSTORE_MAGIC 0x74726563
/* The following aren't defined in wincrypt.h, as they're "reserved" */
#define CERT_CERT_PROP_ID 32
#define CERT_CRL_PROP_ID 33
#define CERT_CTL_PROP_ID 34
/* Some typedefs that make it easier to abstract which type of context we're
* working with.
...
...
@@ -201,16 +197,6 @@ typedef struct _WINE_CERT_CONTEXT_REF
WINE_CERT_CONTEXT
*
context
;
}
WINE_CERT_CONTEXT_REF
,
*
PWINE_CERT_CONTEXT_REF
;
/* An extended certificate property in serialized form is prefixed by this
* header.
*/
typedef
struct
_WINE_CERT_PROP_HEADER
{
DWORD
propID
;
DWORD
unknown
;
/* always 1 */
DWORD
cb
;
}
WINE_CERT_PROP_HEADER
,
*
PWINE_CERT_PROP_HEADER
;
/* Stores an extended property in a cert. */
typedef
struct
_WINE_CERT_PROPERTY
{
...
...
@@ -316,15 +302,6 @@ static BOOL WINAPI CRYPT_GetCertificateContextProperty(
static
BOOL
WINAPI
CRYPT_SetCertificateContextProperty
(
PWINE_CERT_CONTEXT
context
,
DWORD
dwPropId
,
DWORD
dwFlags
,
const
void
*
pvData
);
/* Helper function for store reading functions and
* CertAddSerializedElementToStore. Returns a context of the appropriate type
* if it can, or NULL otherwise. Doesn't validate any of the properties in
* the serialized context (for example, bad hashes are retained.)
* *pdwContentType is set to the type of the returned context.
*/
static
const
void
*
WINAPI
CRYPT_ReadSerializedElement
(
const
BYTE
*
pbElement
,
DWORD
cbElement
,
DWORD
dwContextTypeFlags
,
DWORD
*
pdwContentType
);
static
void
CRYPT_InitStore
(
WINECRYPT_CERTSTORE
*
store
,
HCRYPTPROV
hCryptProv
,
DWORD
dwFlags
,
CertStoreType
type
)
{
...
...
@@ -2700,14 +2677,6 @@ BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
return
FALSE
;
}
BOOL
WINAPI
CertSerializeCRLStoreElement
(
PCCRL_CONTEXT
pCrlContext
,
DWORD
dwFlags
,
BYTE
*
pbElement
,
DWORD
*
pcbElement
)
{
FIXME
(
"(%p, %08lx, %p, %p): stub
\n
"
,
pCrlContext
,
dwFlags
,
pbElement
,
pcbElement
);
return
FALSE
;
}
BOOL
WINAPI
CertGetCTLContextProperty
(
PCCTL_CONTEXT
pCTLContext
,
DWORD
dwPropId
,
void
*
pvData
,
DWORD
*
pcbData
)
{
...
...
@@ -2723,409 +2692,6 @@ BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
return
FALSE
;
}
BOOL
WINAPI
CertSerializeCTLStoreElement
(
PCCTL_CONTEXT
pCtlContext
,
DWORD
dwFlags
,
BYTE
*
pbElement
,
DWORD
*
pcbElement
)
{
FIXME
(
"(%p, %08lx, %p, %p): stub
\n
"
,
pCtlContext
,
dwFlags
,
pbElement
,
pcbElement
);
return
FALSE
;
}
BOOL
WINAPI
CertSerializeCertificateStoreElement
(
PCCERT_CONTEXT
pCertContext
,
DWORD
dwFlags
,
BYTE
*
pbElement
,
DWORD
*
pcbElement
)
{
BOOL
ret
;
TRACE
(
"(%p, %08lx, %p, %p)
\n
"
,
pCertContext
,
dwFlags
,
pbElement
,
pcbElement
);
if
(
pCertContext
)
{
PWINE_CERT_CONTEXT_REF
ref
=
(
PWINE_CERT_CONTEXT_REF
)
pCertContext
;
DWORD
bytesNeeded
=
sizeof
(
WINE_CERT_PROP_HEADER
)
+
pCertContext
->
cbCertEncoded
;
DWORD
prop
=
0
;
EnterCriticalSection
(
&
ref
->
context
->
cs
);
ret
=
TRUE
;
do
{
prop
=
CertEnumCertificateContextProperties
(
pCertContext
,
prop
);
if
(
prop
)
{
DWORD
propSize
=
0
;
ret
=
CertGetCertificateContextProperty
(
pCertContext
,
prop
,
NULL
,
&
propSize
);
if
(
ret
)
bytesNeeded
+=
sizeof
(
WINE_CERT_PROP_HEADER
)
+
propSize
;
}
}
while
(
ret
&&
prop
!=
0
);
if
(
!
pbElement
)
{
*
pcbElement
=
bytesNeeded
;
ret
=
TRUE
;
}
else
if
(
*
pcbElement
<
bytesNeeded
)
{
*
pcbElement
=
bytesNeeded
;
SetLastError
(
ERROR_MORE_DATA
);
ret
=
FALSE
;
}
else
{
PWINE_CERT_PROP_HEADER
hdr
;
DWORD
bufSize
=
0
;
LPBYTE
buf
=
NULL
;
prop
=
0
;
do
{
prop
=
CertEnumCertificateContextProperties
(
pCertContext
,
prop
);
if
(
prop
)
{
DWORD
propSize
=
0
;
ret
=
CertGetCertificateContextProperty
(
pCertContext
,
prop
,
NULL
,
&
propSize
);
if
(
ret
)
{
if
(
bufSize
<
propSize
)
{
if
(
buf
)
buf
=
CryptMemRealloc
(
buf
,
propSize
);
else
buf
=
CryptMemAlloc
(
propSize
);
bufSize
=
propSize
;
}
if
(
buf
)
{
ret
=
CertGetCertificateContextProperty
(
pCertContext
,
prop
,
buf
,
&
propSize
);
if
(
ret
)
{
hdr
=
(
PWINE_CERT_PROP_HEADER
)
pbElement
;
hdr
->
propID
=
prop
;
hdr
->
unknown
=
1
;
hdr
->
cb
=
propSize
;
pbElement
+=
sizeof
(
WINE_CERT_PROP_HEADER
);
if
(
propSize
)
{
memcpy
(
pbElement
,
buf
,
propSize
);
pbElement
+=
propSize
;
}
}
}
else
ret
=
FALSE
;
}
}
}
while
(
ret
&&
prop
!=
0
);
CryptMemFree
(
buf
);
hdr
=
(
PWINE_CERT_PROP_HEADER
)
pbElement
;
hdr
->
propID
=
CERT_CERT_PROP_ID
;
hdr
->
unknown
=
1
;
hdr
->
cb
=
pCertContext
->
cbCertEncoded
;
memcpy
(
pbElement
+
sizeof
(
WINE_CERT_PROP_HEADER
),
pCertContext
->
pbCertEncoded
,
pCertContext
->
cbCertEncoded
);
}
LeaveCriticalSection
(
&
ref
->
context
->
cs
);
}
else
ret
=
FALSE
;
return
ret
;
}
/* Looks for the property with ID propID in the buffer buf. Returns a pointer
* to its header if a valid header is found, NULL if not. Valid means the
* length of thte property won't overrun buf, and the unknown field is 1.
*/
static
const
WINE_CERT_PROP_HEADER
*
CRYPT_findPropID
(
const
BYTE
*
buf
,
DWORD
size
,
DWORD
propID
)
{
const
WINE_CERT_PROP_HEADER
*
ret
=
NULL
;
BOOL
done
=
FALSE
;
while
(
size
&&
!
ret
&&
!
done
)
{
if
(
size
<
sizeof
(
WINE_CERT_PROP_HEADER
))
{
SetLastError
(
CRYPT_E_FILE_ERROR
);
done
=
TRUE
;
}
else
{
const
WINE_CERT_PROP_HEADER
*
hdr
=
(
const
WINE_CERT_PROP_HEADER
*
)
buf
;
size
-=
sizeof
(
WINE_CERT_PROP_HEADER
);
buf
+=
sizeof
(
WINE_CERT_PROP_HEADER
);
if
(
size
<
hdr
->
cb
)
{
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
done
=
TRUE
;
}
else
if
(
!
hdr
->
propID
)
{
/* assume a zero prop ID means the data are uninitialized, so
* stop looking.
*/
done
=
TRUE
;
}
else
if
(
hdr
->
unknown
!=
1
)
{
SetLastError
(
ERROR_FILE_NOT_FOUND
);
done
=
TRUE
;
}
else
if
(
hdr
->
propID
==
propID
)
ret
=
hdr
;
else
{
buf
+=
hdr
->
cb
;
size
-=
hdr
->
cb
;
}
}
}
return
ret
;
}
static
const
void
*
WINAPI
CRYPT_ReadSerializedElement
(
const
BYTE
*
pbElement
,
DWORD
cbElement
,
DWORD
dwContextTypeFlags
,
DWORD
*
pdwContentType
)
{
const
void
*
context
;
TRACE
(
"(%p, %ld, %08lx, %p)
\n
"
,
pbElement
,
cbElement
,
dwContextTypeFlags
,
pdwContentType
);
if
(
!
cbElement
)
{
SetLastError
(
ERROR_END_OF_MEDIA
);
return
NULL
;
}
__TRY
{
const
WINE_CONTEXT_INTERFACE
*
contextInterface
=
NULL
;
const
WINE_CERT_PROP_HEADER
*
hdr
=
NULL
;
DWORD
type
=
0
;
BOOL
ret
;
ret
=
TRUE
;
context
=
NULL
;
if
(
dwContextTypeFlags
==
CERT_STORE_ALL_CONTEXT_FLAG
)
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CERT_PROP_ID
);
if
(
hdr
)
type
=
CERT_STORE_CERTIFICATE_CONTEXT
;
else
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CRL_PROP_ID
);
if
(
hdr
)
type
=
CERT_STORE_CRL_CONTEXT
;
else
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CTL_PROP_ID
);
if
(
hdr
)
type
=
CERT_STORE_CTL_CONTEXT
;
}
}
}
else
if
(
dwContextTypeFlags
&
CERT_STORE_CERTIFICATE_CONTEXT_FLAG
)
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CERT_PROP_ID
);
type
=
CERT_STORE_CERTIFICATE_CONTEXT
;
}
else
if
(
dwContextTypeFlags
&
CERT_STORE_CRL_CONTEXT_FLAG
)
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CRL_PROP_ID
);
type
=
CERT_STORE_CRL_CONTEXT
;
}
else
if
(
dwContextTypeFlags
&
CERT_STORE_CTL_CONTEXT_FLAG
)
{
hdr
=
CRYPT_findPropID
(
pbElement
,
cbElement
,
CERT_CTL_PROP_ID
);
type
=
CERT_STORE_CTL_CONTEXT
;
}
switch
(
type
)
{
case
CERT_STORE_CERTIFICATE_CONTEXT
:
contextInterface
=
&
gCertInterface
;
break
;
case
CERT_STORE_CRL_CONTEXT
:
contextInterface
=
&
gCRLInterface
;
break
;
case
CERT_STORE_CTL_CONTEXT
:
contextInterface
=
&
gCTLInterface
;
break
;
default:
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
ret
=
FALSE
;
}
if
(
!
hdr
)
ret
=
FALSE
;
if
(
ret
)
context
=
contextInterface
->
create
(
X509_ASN_ENCODING
,
(
BYTE
*
)
hdr
+
sizeof
(
WINE_CERT_PROP_HEADER
),
hdr
->
cb
);
if
(
ret
&&
context
)
{
BOOL
noMoreProps
=
FALSE
;
while
(
!
noMoreProps
&&
ret
)
{
if
(
cbElement
<
sizeof
(
WINE_CERT_PROP_HEADER
))
ret
=
FALSE
;
else
{
const
WINE_CERT_PROP_HEADER
*
hdr
=
(
const
WINE_CERT_PROP_HEADER
*
)
pbElement
;
TRACE
(
"prop is %ld
\n
"
,
hdr
->
propID
);
cbElement
-=
sizeof
(
WINE_CERT_PROP_HEADER
);
pbElement
+=
sizeof
(
WINE_CERT_PROP_HEADER
);
if
(
cbElement
<
hdr
->
cb
)
{
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
ret
=
FALSE
;
}
else
if
(
!
hdr
->
propID
)
{
/* Like in CRYPT_findPropID, stop if the propID is zero
*/
noMoreProps
=
TRUE
;
}
else
if
(
hdr
->
unknown
!=
1
)
{
SetLastError
(
ERROR_FILE_NOT_FOUND
);
ret
=
FALSE
;
}
else
if
(
hdr
->
propID
!=
CERT_CERT_PROP_ID
&&
hdr
->
propID
!=
CERT_CRL_PROP_ID
&&
hdr
->
propID
!=
CERT_CTL_PROP_ID
)
{
/* Have to create a blob for most types, but not
* for all.. arghh.
*/
switch
(
hdr
->
propID
)
{
case
CERT_AUTO_ENROLL_PROP_ID
:
case
CERT_CTL_USAGE_PROP_ID
:
case
CERT_DESCRIPTION_PROP_ID
:
case
CERT_FRIENDLY_NAME_PROP_ID
:
case
CERT_HASH_PROP_ID
:
case
CERT_KEY_IDENTIFIER_PROP_ID
:
case
CERT_MD5_HASH_PROP_ID
:
case
CERT_NEXT_UPDATE_LOCATION_PROP_ID
:
case
CERT_PUBKEY_ALG_PARA_PROP_ID
:
case
CERT_PVK_FILE_PROP_ID
:
case
CERT_SIGNATURE_HASH_PROP_ID
:
case
CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID
:
case
CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID
:
case
CERT_ENROLLMENT_PROP_ID
:
case
CERT_CROSS_CERT_DIST_POINTS_PROP_ID
:
case
CERT_RENEWAL_PROP_ID
:
{
CRYPT_DATA_BLOB
blob
=
{
hdr
->
cb
,
(
LPBYTE
)
pbElement
};
ret
=
contextInterface
->
setProp
(
context
,
hdr
->
propID
,
0
,
&
blob
);
break
;
}
case
CERT_DATE_STAMP_PROP_ID
:
ret
=
contextInterface
->
setProp
(
context
,
hdr
->
propID
,
0
,
pbElement
);
break
;
default:
FIXME
(
"prop ID %ld: stub
\n
"
,
hdr
->
propID
);
}
}
pbElement
+=
hdr
->
cb
;
cbElement
-=
hdr
->
cb
;
if
(
!
cbElement
)
noMoreProps
=
TRUE
;
}
}
if
(
ret
)
{
if
(
pdwContentType
)
*
pdwContentType
=
type
;
}
else
{
contextInterface
->
free
(
context
);
context
=
NULL
;
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError
(
STATUS_ACCESS_VIOLATION
);
context
=
NULL
;
}
__ENDTRY
return
context
;
}
BOOL
WINAPI
CertAddSerializedElementToStore
(
HCERTSTORE
hCertStore
,
const
BYTE
*
pbElement
,
DWORD
cbElement
,
DWORD
dwAddDisposition
,
DWORD
dwFlags
,
DWORD
dwContextTypeFlags
,
DWORD
*
pdwContentType
,
const
void
**
ppvContext
)
{
const
void
*
context
;
DWORD
type
;
BOOL
ret
;
TRACE
(
"(%p, %p, %ld, %08lx, %08lx, %08lx, %p, %p)
\n
"
,
hCertStore
,
pbElement
,
cbElement
,
dwAddDisposition
,
dwFlags
,
dwContextTypeFlags
,
pdwContentType
,
ppvContext
);
/* Call the internal function, then delete the hashes. Tests show this
* function uses real hash values, not whatever's stored in the hash
* property.
*/
context
=
CRYPT_ReadSerializedElement
(
pbElement
,
cbElement
,
dwContextTypeFlags
,
&
type
);
if
(
context
)
{
const
WINE_CONTEXT_INTERFACE
*
contextInterface
=
NULL
;
switch
(
type
)
{
case
CERT_STORE_CERTIFICATE_CONTEXT
:
contextInterface
=
&
gCertInterface
;
break
;
case
CERT_STORE_CRL_CONTEXT
:
contextInterface
=
&
gCRLInterface
;
break
;
case
CERT_STORE_CTL_CONTEXT
:
contextInterface
=
&
gCTLInterface
;
break
;
default:
SetLastError
(
HRESULT_FROM_WIN32
(
ERROR_INVALID_PARAMETER
));
}
if
(
contextInterface
)
{
contextInterface
->
setProp
(
context
,
CERT_HASH_PROP_ID
,
0
,
NULL
);
contextInterface
->
setProp
(
context
,
CERT_MD5_HASH_PROP_ID
,
0
,
NULL
);
contextInterface
->
setProp
(
context
,
CERT_SIGNATURE_HASH_PROP_ID
,
0
,
NULL
);
if
(
pdwContentType
)
*
pdwContentType
=
type
;
ret
=
contextInterface
->
addContextToStore
(
hCertStore
,
context
,
dwAddDisposition
,
ppvContext
);
contextInterface
->
free
(
context
);
}
else
ret
=
FALSE
;
}
else
ret
=
FALSE
;
return
ret
;
}
static
void
CRYPT_UnrefCertificateContext
(
PWINE_CERT_CONTEXT_REF
ref
)
{
if
(
InterlockedDecrement
(
&
ref
->
context
->
ref
)
==
0
)
...
...
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