:( can somebody please help me with the "CertFindCertificateInStore" API? I want to use it in VB but I can only find C samples in MSDN. THANKS VERY MUCH!
:( can somebody please help me with the "CertFindCertificateInStore" API? I want to use it in VB but I can only find C samples in MSDN. THANKS VERY MUCH!
any body please?
C declaration:
which is documented on this MSDN page and is exported by Crypt32.lib...Code:WINCRYPT32API
PCCERT_CONTEXT
WINAPI
CertFindCertificateInStore(
IN HCERTSTORE hCertStore,
IN DWORD dwCertEncodingType,
IN DWORD dwFindFlags,
IN DWORD dwFindType,
IN const void *pvFindPara,
IN PCCERT_CONTEXT pPrevCertContext
);
Therefore in VB this would be:
VB Code:
Private Type CERT_CONTEXT dwCertEncodingType As Long pbCertEncoded As Long '<-Pointer to byte... cbCertEncoded As Long pCertInfo As Long '<--Pointer to CERT_INFO hCertStore As Long End Type Private Declare Function CertFindCertificateInStore Lib "Crypt32.dll" ( ByVal hCertStore As Long , _ ByVal dwCertEncodingType As Long, _ ByVal dwFindFlags As Long, _ ByVal dwFindType As Long, _ ByVal pvFindPara As Long, pPrevCertContext As CERT_CONTEXT ) As Long Private Declare Function CertFindCertificateInStoreByLong Lib "Crypt32.dll" _ Alias "CertFindCertificateInStore "( ByVal hCertStore As Long , _ ByVal dwCertEncodingType As Long, _ ByVal dwFindFlags As Long, _ ByVal dwFindType As Long, _ ByVal pvFindPara As Long, ByVal pPrevCertContext As Long ) As Long
Hope this helps...
Duncan
:D Let me try try , thanks Merrion
I have finished the following types declarations :
It will be better if i can find C type mapping to Visual Basics...Code:
' Converted from c structs
Type CRYPT_INTEGER_BLOB
cbData As Long
pbData() As Byte
End Type
Type CERT_NAME_BLOB
cbData As Long
pbData() As Byte
End Type
Type CRYPT_OBJID_BLOB
cbData As Long
pbData() As Byte
End Type
Type CRYPT_BIT_BLOB
cbData As Long
pbData() As Byte
cUnusedBits As Long
End Type
Type CERT_EXTENSION
pszObjId As String
fCritical As Boolean
Value As CRYPT_OBJID_BLOB
End Type
Type CRYPT_ALGORITHM_IDENTIFIER
pszObjId As String
Parameters As CRYPT_OBJID_BLOB
End Type
Type CERT_PUBLIC_KEY_INFO
Algorithm As CRYPT_ALGORITHM_IDENTIFIER
PublicKey As CRYPT_BIT_BLOB
End Type
Type CERT_INFO
dwVersion As Long
SerialNumber As CRYPT_INTEGER_BLOB
SignatureAlgorithm As CRYPT_ALGORITHM_IDENTIFIER
Issuer As CERT_NAME_BLOB
NotBefore As Date
NotAfter As Date
Subject As CERT_NAME_BLOB
SubjectPublicKeyInfo As CERT_PUBLIC_KEY_INFO
IssuerUniqueId As CRYPT_BIT_BLOB
SubjectUniqueId As CRYPT_BIT_BLOB
cExtension As Long
rgExtension As CERT_EXTENSION
End Type
Public Type CERT_CONTEXT
dwCertEncodingType As Long
pbCertEncoded As Byte
cbCertEncoded As Long
pCertInfo As CERT_INFO
hCertStore As Long
End Type
My target is find user's cert to use private to encrypt data, by now i only can do 2 steps :
1. Get CSP context
2. Get System Store handler
3. (stucked) Find certificate in store
Code as follows :
Code:
private sub Form_Load()
' Get CSP context
Dim context_Handler As Long
CryptAcquireContext context_Handler, "administrator", _
"Microsoft Base Cryptographic Provider v1.0", 1, 0
' Get System Store handler, can use MY or CA or ROOT or SPC
Dim system_Store_Handler as Long
system_Store_Handler = CertOpenSystemStore(context_Handler, "MY")
' This is the hard part... Find cert in store
Dim i as Long
Dim j As CERT_CONTEXT
i = CertFindCertificateInStore( _
CLng(system_Store_Handler), _
CLng(MY_ENCODING_TYPE), _
0, _
CLng(CERT_FIND_ANY), _
"", _
j)
' always get 0, help
End Sub
API declarations :
Any Hints Please?Code:
Public Declare Function CryptAcquireContext Lib "advapi32.dll" Alias "CryptAcquireContextA" _
(ByRef phProv As Long, _
ByVal pszContainer As String, _
ByVal pszProvider As String, _
ByVal dwProvType As Long, _
ByVal dwFlags As Long) As Long
Public Declare Function CertOpenSystemStore Lib "Crypt32" Alias "CertOpenSystemStoreA" ( _
hCryptProv As Long, _
szSubsystemProtocol As String) As Long
Public Declare Function CertFindCertificateInStore Lib "Crypt32" ( _
hCertStore As Long, _
dwCertEncodingType As Long, _
dwFindFlags As Long, _
dwFindType As Long, _
pvFindPara As String, _
pPrevCertContext As CERT_CONTEXT _
) As Long
The first time you call CertFindCertificateInStore you need to pass NULL in pPrevContext - which is why you need the CertFindCertificateInStoreByLong Alias.
VB Code:
Dim i as Long Dim j As CERT_CONTEXT i = CertFindCertificateInStoreByLong( _ CLng(system_Store_Handler), _ CLng(MY_ENCODING_TYPE), _ 0, _ CLng(CERT_FIND_ANY), _ "", _ vbNull) '<--This must be null the first time... '\\ i now points to a memory address...you need to use RTLMovememory to get the data thence...
I usually ALIAS RtlMovememory to prevent GPFs - for CERT_CONTEXT it woulkd be thus:
VB Code:
Private Declare Sub CopyMemoryCERT_CONTEXT Lib "kernel32" Alias "RtlMoveMemory" (Destination As CERT_CONTEXT, ByVal Source As Long, ByVal Length As Long) Private Declare Function IsBadReadPtr Lib "kernel32" (ByVal lp As Long, ByVal ucb As Long) As Long Private Declare Function IsBadWritePtr Lib "kernel32" (ByVal lp As Long, ByVal ucb As Long) As Long
which you would add to your code thus:
VB Code:
'... If Not IsBadReadPtr(i, Len(j)) Then Call CopyMemoryCERT_CONTEXT(j,i,Len(j)) End If
HTH,
Duncan
:D Many thanks, Merrion!