2 * Copyright 2004-2006 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wine/debug.h"
26 #include "crypt32_private.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
30 PCRYPT_ATTRIBUTE WINAPI
CertFindAttribute(LPCSTR pszObjId
, DWORD cAttr
,
31 CRYPT_ATTRIBUTE rgAttr
[])
33 PCRYPT_ATTRIBUTE ret
= NULL
;
36 TRACE("%s %ld %p\n", debugstr_a(pszObjId
), cAttr
, rgAttr
);
42 SetLastError(ERROR_INVALID_PARAMETER
);
46 for (i
= 0; !ret
&& i
< cAttr
; i
++)
47 if (rgAttr
[i
].pszObjId
&& !strcmp(pszObjId
, rgAttr
[i
].pszObjId
))
52 PCERT_EXTENSION WINAPI
CertFindExtension(LPCSTR pszObjId
, DWORD cExtensions
,
53 CERT_EXTENSION rgExtensions
[])
55 PCERT_EXTENSION ret
= NULL
;
58 TRACE("%s %ld %p\n", debugstr_a(pszObjId
), cExtensions
, rgExtensions
);
64 SetLastError(ERROR_INVALID_PARAMETER
);
68 for (i
= 0; !ret
&& i
< cExtensions
; i
++)
69 if (rgExtensions
[i
].pszObjId
&& !strcmp(pszObjId
,
70 rgExtensions
[i
].pszObjId
))
71 ret
= &rgExtensions
[i
];
75 PCERT_RDN_ATTR WINAPI
CertFindRDNAttr(LPCSTR pszObjId
, PCERT_NAME_INFO pName
)
77 PCERT_RDN_ATTR ret
= NULL
;
80 TRACE("%s %p\n", debugstr_a(pszObjId
), pName
);
84 SetLastError(ERROR_INVALID_PARAMETER
);
88 for (i
= 0; !ret
&& i
< pName
->cRDN
; i
++)
89 for (j
= 0; !ret
&& j
< pName
->rgRDN
[i
].cRDNAttr
; j
++)
90 if (pName
->rgRDN
[i
].rgRDNAttr
[j
].pszObjId
&& !strcmp(pszObjId
,
91 pName
->rgRDN
[i
].rgRDNAttr
[j
].pszObjId
))
92 ret
= &pName
->rgRDN
[i
].rgRDNAttr
[j
];
96 LONG WINAPI
CertVerifyTimeValidity(LPFILETIME pTimeToVerify
,
106 GetSystemTime(&sysTime
);
107 SystemTimeToFileTime(&sysTime
, &fileTime
);
108 pTimeToVerify
= &fileTime
;
110 if ((ret
= CompareFileTime(pTimeToVerify
, &pCertInfo
->NotBefore
)) >= 0)
112 ret
= CompareFileTime(pTimeToVerify
, &pCertInfo
->NotAfter
);
119 BOOL WINAPI
CryptHashCertificate(HCRYPTPROV hCryptProv
, ALG_ID Algid
,
120 DWORD dwFlags
, const BYTE
*pbEncoded
, DWORD cbEncoded
, BYTE
*pbComputedHash
,
121 DWORD
*pcbComputedHash
)
124 HCRYPTHASH hHash
= 0;
126 TRACE("(%ld, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv
, Algid
, dwFlags
,
127 pbEncoded
, cbEncoded
, pbComputedHash
, pcbComputedHash
);
130 hCryptProv
= CRYPT_GetDefaultProvider();
135 ret
= CryptCreateHash(hCryptProv
, Algid
, 0, 0, &hHash
);
138 ret
= CryptHashData(hHash
, pbEncoded
, cbEncoded
, 0);
140 ret
= CryptGetHashParam(hHash
, HP_HASHVAL
, pbComputedHash
,
142 CryptDestroyHash(hHash
);
148 BOOL WINAPI
CryptSignCertificate(HCRYPTPROV hCryptProv
, DWORD dwKeySpec
,
149 DWORD dwCertEncodingType
, const BYTE
*pbEncodedToBeSigned
,
150 DWORD cbEncodedToBeSigned
, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm
,
151 const void *pvHashAuxInfo
, BYTE
*pbSignature
, DWORD
*pcbSignature
)
157 TRACE("(%08lx, %ld, %ld, %p, %ld, %p, %p, %p, %p)\n", hCryptProv
,
158 dwKeySpec
, dwCertEncodingType
, pbEncodedToBeSigned
, cbEncodedToBeSigned
,
159 pSignatureAlgorithm
, pvHashAuxInfo
, pbSignature
, pcbSignature
);
161 algID
= CertOIDToAlgId(pSignatureAlgorithm
->pszObjId
);
164 SetLastError(NTE_BAD_ALGID
);
169 SetLastError(ERROR_INVALID_PARAMETER
);
173 ret
= CryptCreateHash(hCryptProv
, algID
, 0, 0, &hHash
);
176 ret
= CryptHashData(hHash
, pbEncodedToBeSigned
, cbEncodedToBeSigned
, 0);
178 ret
= CryptSignHashW(hHash
, dwKeySpec
, NULL
, 0, pbSignature
,
180 CryptDestroyHash(hHash
);
185 BOOL WINAPI
CryptVerifyCertificateSignature(HCRYPTPROV hCryptProv
,
186 DWORD dwCertEncodingType
, const BYTE
*pbEncoded
, DWORD cbEncoded
,
187 PCERT_PUBLIC_KEY_INFO pPublicKey
)
189 return CryptVerifyCertificateSignatureEx(hCryptProv
, dwCertEncodingType
,
190 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB
, (void *)pbEncoded
,
191 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY
, pPublicKey
, 0, NULL
);
194 BOOL WINAPI
CryptVerifyCertificateSignatureEx(HCRYPTPROV hCryptProv
,
195 DWORD dwCertEncodingType
, DWORD dwSubjectType
, void *pvSubject
,
196 DWORD dwIssuerType
, void *pvIssuer
, DWORD dwFlags
, void *pvReserved
)
199 CRYPT_DATA_BLOB subjectBlob
;
201 TRACE("(%08lx, %ld, %ld, %p, %ld, %p, %08lx, %p)\n", hCryptProv
,
202 dwCertEncodingType
, dwSubjectType
, pvSubject
, dwIssuerType
, pvIssuer
,
203 dwFlags
, pvReserved
);
205 switch (dwSubjectType
)
207 case CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB
:
209 PCRYPT_DATA_BLOB blob
= (PCRYPT_DATA_BLOB
)pvSubject
;
211 subjectBlob
.pbData
= blob
->pbData
;
212 subjectBlob
.cbData
= blob
->cbData
;
215 case CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT
:
217 PCERT_CONTEXT context
= (PCERT_CONTEXT
)pvSubject
;
219 subjectBlob
.pbData
= context
->pbCertEncoded
;
220 subjectBlob
.cbData
= context
->cbCertEncoded
;
223 case CRYPT_VERIFY_CERT_SIGN_SUBJECT_CRL
:
225 PCRL_CONTEXT context
= (PCRL_CONTEXT
)pvSubject
;
227 subjectBlob
.pbData
= context
->pbCrlEncoded
;
228 subjectBlob
.cbData
= context
->cbCrlEncoded
;
232 SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER
));
238 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
241 ret
= CryptDecodeObjectEx(dwCertEncodingType
, X509_CERT
,
242 subjectBlob
.pbData
, subjectBlob
.cbData
,
243 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_NOCOPY_FLAG
, NULL
,
244 (BYTE
*)&signedCert
, &size
);
247 switch (dwIssuerType
)
249 case CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY
:
251 PCERT_PUBLIC_KEY_INFO pubKeyInfo
=
252 (PCERT_PUBLIC_KEY_INFO
)pvIssuer
;
253 ALG_ID algID
= CertOIDToAlgId(pubKeyInfo
->Algorithm
.pszObjId
);
259 ret
= CryptImportPublicKeyInfoEx(hCryptProv
,
260 dwCertEncodingType
, pubKeyInfo
, algID
, 0, NULL
, &key
);
265 ret
= CryptCreateHash(hCryptProv
, algID
, 0, 0, &hash
);
268 ret
= CryptHashData(hash
,
269 signedCert
->ToBeSigned
.pbData
,
270 signedCert
->ToBeSigned
.cbData
, 0);
273 ret
= CryptVerifySignatureW(hash
,
274 signedCert
->Signature
.pbData
,
275 signedCert
->Signature
.cbData
, key
, NULL
, 0);
277 CryptDestroyHash(hash
);
279 CryptDestroyKey(key
);
284 SetLastError(NTE_BAD_ALGID
);
289 case CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT
:
290 case CRYPT_VERIFY_CERT_SIGN_ISSUER_CHAIN
:
291 FIXME("issuer type %ld: stub\n", dwIssuerType
);
294 case CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL
:
297 SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER
));
302 FIXME("unimplemented for NULL signer\n");
303 SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER
));
308 SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER
));
311 LocalFree(signedCert
);
317 BOOL WINAPI
CryptVerifyMessageSignature(/*PCRYPT_VERIFY_MESSAGE_PARA*/ void* pVerifyPara
,
318 DWORD dwSignerIndex
, const BYTE
* pbSignedBlob
, DWORD cbSignedBlob
,
319 BYTE
* pbDecoded
, DWORD
* pcbDecoded
, PCCERT_CONTEXT
* ppSignerCert
)
321 FIXME("stub: %p, %ld, %p, %ld, %p, %p, %p\n",
322 pVerifyPara
, dwSignerIndex
, pbSignedBlob
, cbSignedBlob
,
323 pbDecoded
, pcbDecoded
, ppSignerCert
);