crypt32: Correct the implementation of CertCreateSelfSignCertificate.
This commit is contained in:
parent
d7596086bc
commit
204bdb8755
|
@ -1970,9 +1970,9 @@ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size = sizeof(info.dwKeySpec);
|
size = sizeof(info.dwKeySpec);
|
||||||
ret = CryptGetProvParam(hProv, PP_KEYSPEC, (LPBYTE)&info.dwKeySpec,
|
/* in case no CRYPT_KEY_PROV_INFO given,
|
||||||
&size, 0);
|
* we always use AT_SIGNATURE key spec
|
||||||
if (!ret)
|
*/
|
||||||
info.dwKeySpec = AT_SIGNATURE;
|
info.dwKeySpec = AT_SIGNATURE;
|
||||||
size = sizeof(info.dwProvType);
|
size = sizeof(info.dwProvType);
|
||||||
ret = CryptGetProvParam(hProv, PP_PROVTYPE, (LPBYTE)&info.dwProvType,
|
ret = CryptGetProvParam(hProv, PP_PROVTYPE, (LPBYTE)&info.dwProvType,
|
||||||
|
@ -1996,19 +1996,19 @@ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context,
|
||||||
* in blob, using the crypto provider hProv and the signature algorithm sigAlgo.
|
* in blob, using the crypto provider hProv and the signature algorithm sigAlgo.
|
||||||
*/
|
*/
|
||||||
static PCCERT_CONTEXT CRYPT_CreateSignedCert(const CRYPT_DER_BLOB *blob,
|
static PCCERT_CONTEXT CRYPT_CreateSignedCert(const CRYPT_DER_BLOB *blob,
|
||||||
HCRYPTPROV hProv, PCRYPT_ALGORITHM_IDENTIFIER sigAlgo)
|
HCRYPTPROV hProv, DWORD dwKeySpec, PCRYPT_ALGORITHM_IDENTIFIER sigAlgo)
|
||||||
{
|
{
|
||||||
PCCERT_CONTEXT context = NULL;
|
PCCERT_CONTEXT context = NULL;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
DWORD sigSize = 0;
|
DWORD sigSize = 0;
|
||||||
|
|
||||||
ret = CryptSignCertificate(hProv, AT_SIGNATURE, X509_ASN_ENCODING,
|
ret = CryptSignCertificate(hProv, dwKeySpec, X509_ASN_ENCODING,
|
||||||
blob->pbData, blob->cbData, sigAlgo, NULL, NULL, &sigSize);
|
blob->pbData, blob->cbData, sigAlgo, NULL, NULL, &sigSize);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
LPBYTE sig = CryptMemAlloc(sigSize);
|
LPBYTE sig = CryptMemAlloc(sigSize);
|
||||||
|
|
||||||
ret = CryptSignCertificate(hProv, AT_SIGNATURE, X509_ASN_ENCODING,
|
ret = CryptSignCertificate(hProv, dwKeySpec, X509_ASN_ENCODING,
|
||||||
blob->pbData, blob->cbData, sigAlgo, NULL, sig, &sigSize);
|
blob->pbData, blob->cbData, sigAlgo, NULL, sig, &sigSize);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
@ -2168,24 +2168,80 @@ PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV hProv,
|
||||||
PCCERT_CONTEXT context = NULL;
|
PCCERT_CONTEXT context = NULL;
|
||||||
BOOL ret, releaseContext = FALSE;
|
BOOL ret, releaseContext = FALSE;
|
||||||
PCERT_PUBLIC_KEY_INFO pubKey = NULL;
|
PCERT_PUBLIC_KEY_INFO pubKey = NULL;
|
||||||
DWORD pubKeySize = 0;
|
DWORD pubKeySize = 0,dwKeySpec = AT_SIGNATURE;
|
||||||
|
|
||||||
TRACE("(%08lx, %p, %08x, %p, %p, %p, %p, %p)\n", hProv,
|
TRACE("(%08lx, %p, %08x, %p, %p, %p, %p, %p)\n", hProv,
|
||||||
pSubjectIssuerBlob, dwFlags, pKeyProvInfo, pSignatureAlgorithm, pStartTime,
|
pSubjectIssuerBlob, dwFlags, pKeyProvInfo, pSignatureAlgorithm, pStartTime,
|
||||||
pExtensions, pExtensions);
|
pExtensions, pExtensions);
|
||||||
|
|
||||||
|
if(!pSubjectIssuerBlob)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!hProv)
|
if (!hProv)
|
||||||
|
{
|
||||||
|
if (!pKeyProvInfo)
|
||||||
{
|
{
|
||||||
hProv = CRYPT_CreateKeyProv();
|
hProv = CRYPT_CreateKeyProv();
|
||||||
releaseContext = TRUE;
|
releaseContext = TRUE;
|
||||||
}
|
}
|
||||||
|
else if (pKeyProvInfo->dwFlags & CERT_SET_KEY_PROV_HANDLE_PROP_ID)
|
||||||
|
{
|
||||||
|
SetLastError(NTE_BAD_FLAGS);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HCRYPTKEY hKey = 0;
|
||||||
|
/* acquire the context using the given information*/
|
||||||
|
ret = CryptAcquireContextW(&hProv,pKeyProvInfo->pwszContainerName,
|
||||||
|
pKeyProvInfo->pwszProvName,pKeyProvInfo->dwProvType,
|
||||||
|
pKeyProvInfo->dwFlags);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
if(GetLastError() != NTE_BAD_KEYSET)
|
||||||
|
return NULL;
|
||||||
|
/* create the key set */
|
||||||
|
ret = CryptAcquireContextW(&hProv,pKeyProvInfo->pwszContainerName,
|
||||||
|
pKeyProvInfo->pwszProvName,pKeyProvInfo->dwProvType,
|
||||||
|
pKeyProvInfo->dwFlags|CRYPT_NEWKEYSET);
|
||||||
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dwKeySpec = pKeyProvInfo->dwKeySpec;
|
||||||
|
/* check if the key is here */
|
||||||
|
ret = CryptGetUserKey(hProv,dwKeySpec,&hKey);
|
||||||
|
if(!ret)
|
||||||
|
{
|
||||||
|
if (NTE_NO_KEY == GetLastError())
|
||||||
|
{ /* generate the key */
|
||||||
|
ret = CryptGenKey(hProv,dwKeySpec,0,&hKey);
|
||||||
|
}
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
CryptReleaseContext(hProv,0);
|
||||||
|
SetLastError(NTE_BAD_KEYSET);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CryptDestroyKey(hKey);
|
||||||
|
releaseContext = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pKeyProvInfo)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
|
CryptExportPublicKeyInfo(hProv, dwKeySpec, X509_ASN_ENCODING, NULL,
|
||||||
&pubKeySize);
|
&pubKeySize);
|
||||||
pubKey = CryptMemAlloc(pubKeySize);
|
pubKey = CryptMemAlloc(pubKeySize);
|
||||||
if (pubKey)
|
if (pubKey)
|
||||||
{
|
{
|
||||||
ret = CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING,
|
ret = CryptExportPublicKeyInfo(hProv, dwKeySpec, X509_ASN_ENCODING,
|
||||||
pubKey, &pubKeySize);
|
pubKey, &pubKeySize);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
@ -2203,7 +2259,7 @@ PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV hProv,
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
if (!(dwFlags & CERT_CREATE_SELFSIGN_NO_SIGN))
|
if (!(dwFlags & CERT_CREATE_SELFSIGN_NO_SIGN))
|
||||||
context = CRYPT_CreateSignedCert(&blob, hProv,
|
context = CRYPT_CreateSignedCert(&blob, hProv,dwKeySpec,
|
||||||
&info.SignatureAlgorithm);
|
&info.SignatureAlgorithm);
|
||||||
else
|
else
|
||||||
context = CertCreateCertificateContext(X509_ASN_ENCODING,
|
context = CertCreateCertificateContext(X509_ASN_ENCODING,
|
||||||
|
|
|
@ -1157,6 +1157,7 @@ static void testCreateSelfSignCert(void)
|
||||||
HCRYPTPROV csp;
|
HCRYPTPROV csp;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
HCRYPTKEY key;
|
HCRYPTKEY key;
|
||||||
|
CRYPT_KEY_PROV_INFO info;
|
||||||
|
|
||||||
/* This crashes:
|
/* This crashes:
|
||||||
context = CertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
|
context = CertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
|
||||||
|
@ -1228,6 +1229,54 @@ static void testCreateSelfSignCert(void)
|
||||||
CryptReleaseContext(csp, 0);
|
CryptReleaseContext(csp, 0);
|
||||||
ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
|
ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
|
||||||
CRYPT_DELETEKEYSET);
|
CRYPT_DELETEKEYSET);
|
||||||
|
|
||||||
|
/* do the same test with AT_KEYEXCHANGE and key info*/
|
||||||
|
memset(&info,0,sizeof(info));
|
||||||
|
info.dwProvType = PROV_RSA_FULL;
|
||||||
|
info.dwKeySpec = AT_KEYEXCHANGE;
|
||||||
|
info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
|
||||||
|
info.pwszContainerName = cspNameW;
|
||||||
|
context = CertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL,
|
||||||
|
NULL, NULL);
|
||||||
|
ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
|
||||||
|
GetLastError());
|
||||||
|
if (context)
|
||||||
|
{
|
||||||
|
DWORD size = 0;
|
||||||
|
PCRYPT_KEY_PROV_INFO info;
|
||||||
|
|
||||||
|
/* The context must have a key provider info property */
|
||||||
|
ret = CertGetCertificateContextProperty(context,
|
||||||
|
CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
|
||||||
|
ok(ret && size, "Expected non-zero key provider info\n");
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
info = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
ret = CertGetCertificateContextProperty(context,
|
||||||
|
CERT_KEY_PROV_INFO_PROP_ID, info, &size);
|
||||||
|
ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
|
||||||
|
GetLastError());
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
/* Sanity-check the key provider */
|
||||||
|
ok(!lstrcmpW(info->pwszContainerName, cspNameW),
|
||||||
|
"Unexpected key container\n");
|
||||||
|
ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
|
||||||
|
"Unexpected provider\n");
|
||||||
|
ok(info->dwKeySpec == AT_KEYEXCHANGE,
|
||||||
|
"Expected AT_KEYEXCHANGE, got %d\n", info->dwKeySpec);
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CertFreeCertificateContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
|
||||||
|
CRYPT_DELETEKEYSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
|
static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
|
||||||
|
|
Loading…
Reference in New Issue