P
prem
Hello Everybody,
I have a problem using certificate APIs.
I have taken a piece of code from MSDN titled "Example C
Program: Sending and Receiving a Signed and Encrypted
Message". I did few customization to my needs and tried to
execute the program ( I had inlcuded the code also, see
below ).
I have two main functions SignAndEncrypt() and
DecryptAndVerify(). I wrote this as two separate program,
I execute SignAndEncrypt() on my w2k prof. mac which signs
the string using the users private key and encrypts using
the CAs public key.
The encrypted and encoded blob which I written into a file
and transfered to a w2k server ( domain controller with
Enterprise CA installed ). Form the w2k server I execute
the DecryptAndVerify() program which reads the encrypted
and encoded blob
from the file and decrypts it using the CA's private key.
Whenever I run DecryptAndVerify(), it fails during
CryptDecryptAndVerifyMessageSignature() and the error I am
getting using GetLastError() is "Cannot find the
certificate and private key to use for decryption".
error no: 2148081676
Also, the self signed certificate for my CA ( "myCA" )
does not say that it has a private key ( as it shows when
we view the personel certificates ).
I would really appreaciate anf kind of help.
Thanks.
-Prem
BYTE *SignAndEncrypt(
const BYTE *pbToBeSignedAndEncrypted,
DWORD cbToBeSignedAndEncrypted,
DWORD *pcbSignedAndEncryptedBlob)
{
//-------------------------------------------------
-------------------
// Declare and initialize local variables.
HCERTSTORE hCertStore, hCertStore1;
//-------------------------------------------------
-------------------
// pSignerCertContext will be the certificate of
the
// the message signer.
PCCERT_CONTEXT pSignerCertContext ;
//-------------------------------------------------
-------------------
// pReceiverCertContext will be the certificate
of the
// message receiver.
PCCERT_CONTEXT pReceiverCertContext;
char pszNameString[256];
CRYPT_SIGN_MESSAGE_PARA SignPara;
CRYPT_ENCRYPT_MESSAGE_PARA EncryptPara;
DWORD cRecipientCert;
PCCERT_CONTEXT rgpRecipientCert[5];
BYTE
*pbSignedAndEncryptedBlob = NULL;
CERT_NAME_BLOB *ReceiverNameBlob;
DWORD cbNameBlob;
DWORD dwKeySpec;
HCRYPTPROV hCryptProv;
CERT_NAME_BLOB CertBlob;
//-------------------------------------------------
-------------------
// Open the MY certificate store.
// For details, see CertOpenStore.
if ( !( hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"my")))
{
HandleError("The MY store could not be
opened.");
}
//-------------------------------------------------
-------------------
// Get the certificate for the signer.
PCCERT_CONTEXT pContext = NULL ;
while ( pContext = CertEnumCertificatesInStore
(hCertStore, pContext) )
{
//-------------------------------------------------
-------------------
// The following function call is not required.
It is place here to
// only to demonstrate a call to the
// CryptAcquireCertificatePrivateKey function.
if( CryptAcquireCertificatePrivateKey(
pContext,
0,
NULL,
&hCryptProv,
&dwKeySpec,
NULL))
{
printf("CryptAcquireCertificatePrivateKey
worked. \n");
CertBlob = pContext->pCertInfo->Issuer;
pSignerCertContext = pContext;
break;
}
else
{
//printf
("CryptAcquireCertificatePrivateKey failed.\n");
continue;
}
}
if ( !( hCertStore1 = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"my")))
{
HandleError("The MY store could not be
opened.");
return;
}
// Getting the certificate of the CA who issued
the user certificate
//
if(!(pReceiverCertContext =
CertFindCertificateInStore(
hCertStore1,
MY_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"myCA", // myCA is the name of the
Certificate Autority
NULL)))
{
HandleError("Cert not found.\n");
return;
}
//-------------------------------------------------
-------------------
// Initialize variables and data structures
// for the call to CryptSignAndEncryptMessage.
SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SignPara.dwMsgEncodingType = MY_TYPE;
SignPara.pSigningCert = pSignerCertContext ;
SignPara.HashAlgorithm.pszObjId = szOID_RSA_MD2;
SignPara.HashAlgorithm.Parameters.cbData = 0;
SignPara.pvHashAuxInfo = NULL;
SignPara.cMsgCert = 1;
SignPara.rgpMsgCert = &pSignerCertContext ;
SignPara.cMsgCrl = 0;
SignPara.rgpMsgCrl = NULL;
SignPara.cAuthAttr = 0;
SignPara.rgAuthAttr = NULL;
SignPara.cUnauthAttr = 0;
SignPara.rgUnauthAttr = NULL;
SignPara.dwFlags = 0;
SignPara.dwInnerContentType = 0;
EncryptPara.cbSize = sizeof
(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptPara.dwMsgEncodingType = MY_TYPE;
EncryptPara.hCryptProv = 0;
EncryptPara.ContentEncryptionAlgorithm.pszObjId =
szOID_RSA_RC4;
EncryptPara.ContentEncryptionAlgorithm.Parameters.c
bData = 0;
EncryptPara.pvEncryptionAuxInfo = NULL;
EncryptPara.dwFlags = 0;
EncryptPara.dwInnerContentType = 0;
cRecipientCert = 1;
rgpRecipientCert[0] = pReceiverCertContext;
*pcbSignedAndEncryptedBlob = 0;
pbSignedAndEncryptedBlob = NULL;
if( CryptSignAndEncryptMessage(
&SignPara,
&EncryptPara,
cRecipientCert,
rgpRecipientCert,
pbToBeSignedAndEncrypted,
cbToBeSignedAndEncrypted,
NULL, // the
pbSignedAndEncryptedBlob
pcbSignedAndEncryptedBlob))
{
printf("%d bytes for the
buffer .\n",*pcbSignedAndEncryptedBlob);
}
else
{
DWORD d = GetLastError();
HandleError("Getting the buffer length
failed.");
return;
}
//-------------------------------------------------
-------------------
// Allocated memory for the buffer
if(!(pbSignedAndEncryptedBlob=(unsigned char *)
malloc(*pcbSignedAndEncryptedBlob)))
HandleError("Memory allocation failed.");
//-------------------------------------------------
-------------------
// Call the function a second time to copy the
signed and encrypted
// message into the buffer
if( CryptSignAndEncryptMessage(
&SignPara,
&EncryptPara,
cRecipientCert,
rgpRecipientCert,
pbToBeSignedAndEncrypted,
cbToBeSignedAndEncrypted,
pbSignedAndEncryptedBlob,
pcbSignedAndEncryptedBlob))
{
printf("The message is signed and
enrypted.\n");
}
else
{
HandleError("The message failed to sign
and encrypt.");
}
FILE *fp=fopen("c:\\signedblob.txt","w");
fwrite
(pbSignedAndEncryptedBlob,*pcbSignedAndEncryptedBlob,1,fp);
fclose(fp);
//-------------------------------------------------
-------------------
// Clean up.
if(pSignerCertContext )
{
CertFreeCertificateContext
(pSignerCertContext );
}
if(pReceiverCertContext )
{
CertFreeCertificateContext
(pReceiverCertContext );
}
CertCloseStore(
hCertStore,
0);
//-------------------------------------------------
-------------------
// Return the signed and encrypted message.
return pbSignedAndEncryptedBlob;
} // End SignandEncrypt.
void CallDecryptAndVerify()
{
BYTE pbSignedAndEncryptedBlob[3500];
FILE *fp=fopen("c:\\signedblob.txt","w");
int nRead = fread
(pbSignedAndEncryptedBlob,1,3500,fp);
fclose(fp);
DecryptAndVerify(pbSignedAndEncryptedBlob,nRead);
}
BYTE *DecryptAndVerify(
BYTE *pbSignedAndEncryptedBlob,
DWORD cbSignedAndEncryptedBlob)
{
//-------------------------------------------------
-------------------
// Declare and initialize local variables.
HCERTSTORE hCertStore;
CRYPT_DECRYPT_MESSAGE_PARA DecryptPara;
CRYPT_VERIFY_MESSAGE_PARA VerifyPara;
DWORD dwSignerIndex = 0;
BYTE *pbDecrypted;
DWORD cbDecrypted;
//-------------------------------------------------
-------------------
// Open the certificate store
if ( !( hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE,
// L"root"))) // I trid with both "my"
and "root", no luck
L"my")))
{
HandleError("The MY store could not be
openned.");
return;
}
//-------------------------------------------------
-------------------
// Initialize the needed data structures.
DecryptPara.cbSize = sizeof
(CRYPT_DECRYPT_MESSAGE_PARA);
DecryptPara.dwMsgAndCertEncodingType = MY_TYPE;
DecryptPara.cCertStore = 1;
DecryptPara.rghCertStore = &hCertStore;
VerifyPara.cbSize = sizeof
(CRYPT_VERIFY_MESSAGE_PARA);
VerifyPara.dwMsgAndCertEncodingType = MY_TYPE;
VerifyPara.hCryptProv = 0;
VerifyPara.pfnGetSignerCertificate = NULL;
VerifyPara.pvGetArg = NULL;
pbDecrypted = NULL;
cbDecrypted = 0;
//-------------------------------------------------
-------------------
// Call CryptDecryptAndVerifyMessageSignature
a first time
// to determine the needed size of the buffer
to hold the
// decrypted message.
if(!(CryptDecryptAndVerifyMessageSignature(
&DecryptPara,
&VerifyPara,
dwSignerIndex,
pbSignedAndEncryptedBlob,
cbSignedAndEncryptedBlob,
NULL, // pbDecrypted
&cbDecrypted,
NULL,
NULL)))
{
HandleError("Failed."); // Here is
where it is failing
return;
}
//-------------------------------------------------
-------------------
// Allocate memory for the buffer to hold the
decrypted message.
if(!(pbDecrypted = (BYTE *)malloc(cbDecrypted)))
HandleError("Memory allocation failed.");
if(!(CryptDecryptAndVerifyMessageSignature(
&DecryptPara,
&VerifyPara,
dwSignerIndex,
pbSignedAndEncryptedBlob,
cbSignedAndEncryptedBlob,
pbDecrypted,
&cbDecrypted,
NULL,
NULL)))
{
pbDecrypted = NULL;
}
//-------------------------------------------------
-------------------
// Close the certificate store.
CertCloseStore(
hCertStore,
0);
//-------------------------------------------------
-------------------
// Return the decrypted string or NULL
return pbDecrypted;
} // end of DecryptandVerify
I have a problem using certificate APIs.
I have taken a piece of code from MSDN titled "Example C
Program: Sending and Receiving a Signed and Encrypted
Message". I did few customization to my needs and tried to
execute the program ( I had inlcuded the code also, see
below ).
I have two main functions SignAndEncrypt() and
DecryptAndVerify(). I wrote this as two separate program,
I execute SignAndEncrypt() on my w2k prof. mac which signs
the string using the users private key and encrypts using
the CAs public key.
The encrypted and encoded blob which I written into a file
and transfered to a w2k server ( domain controller with
Enterprise CA installed ). Form the w2k server I execute
the DecryptAndVerify() program which reads the encrypted
and encoded blob
from the file and decrypts it using the CA's private key.
Whenever I run DecryptAndVerify(), it fails during
CryptDecryptAndVerifyMessageSignature() and the error I am
getting using GetLastError() is "Cannot find the
certificate and private key to use for decryption".
error no: 2148081676
Also, the self signed certificate for my CA ( "myCA" )
does not say that it has a private key ( as it shows when
we view the personel certificates ).
I would really appreaciate anf kind of help.
Thanks.
-Prem
BYTE *SignAndEncrypt(
const BYTE *pbToBeSignedAndEncrypted,
DWORD cbToBeSignedAndEncrypted,
DWORD *pcbSignedAndEncryptedBlob)
{
//-------------------------------------------------
-------------------
// Declare and initialize local variables.
HCERTSTORE hCertStore, hCertStore1;
//-------------------------------------------------
-------------------
// pSignerCertContext will be the certificate of
the
// the message signer.
PCCERT_CONTEXT pSignerCertContext ;
//-------------------------------------------------
-------------------
// pReceiverCertContext will be the certificate
of the
// message receiver.
PCCERT_CONTEXT pReceiverCertContext;
char pszNameString[256];
CRYPT_SIGN_MESSAGE_PARA SignPara;
CRYPT_ENCRYPT_MESSAGE_PARA EncryptPara;
DWORD cRecipientCert;
PCCERT_CONTEXT rgpRecipientCert[5];
BYTE
*pbSignedAndEncryptedBlob = NULL;
CERT_NAME_BLOB *ReceiverNameBlob;
DWORD cbNameBlob;
DWORD dwKeySpec;
HCRYPTPROV hCryptProv;
CERT_NAME_BLOB CertBlob;
//-------------------------------------------------
-------------------
// Open the MY certificate store.
// For details, see CertOpenStore.
if ( !( hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"my")))
{
HandleError("The MY store could not be
opened.");
}
//-------------------------------------------------
-------------------
// Get the certificate for the signer.
PCCERT_CONTEXT pContext = NULL ;
while ( pContext = CertEnumCertificatesInStore
(hCertStore, pContext) )
{
//-------------------------------------------------
-------------------
// The following function call is not required.
It is place here to
// only to demonstrate a call to the
// CryptAcquireCertificatePrivateKey function.
if( CryptAcquireCertificatePrivateKey(
pContext,
0,
NULL,
&hCryptProv,
&dwKeySpec,
NULL))
{
printf("CryptAcquireCertificatePrivateKey
worked. \n");
CertBlob = pContext->pCertInfo->Issuer;
pSignerCertContext = pContext;
break;
}
else
{
//printf
("CryptAcquireCertificatePrivateKey failed.\n");
continue;
}
}
if ( !( hCertStore1 = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"my")))
{
HandleError("The MY store could not be
opened.");
return;
}
// Getting the certificate of the CA who issued
the user certificate
//
if(!(pReceiverCertContext =
CertFindCertificateInStore(
hCertStore1,
MY_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"myCA", // myCA is the name of the
Certificate Autority
NULL)))
{
HandleError("Cert not found.\n");
return;
}
//-------------------------------------------------
-------------------
// Initialize variables and data structures
// for the call to CryptSignAndEncryptMessage.
SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SignPara.dwMsgEncodingType = MY_TYPE;
SignPara.pSigningCert = pSignerCertContext ;
SignPara.HashAlgorithm.pszObjId = szOID_RSA_MD2;
SignPara.HashAlgorithm.Parameters.cbData = 0;
SignPara.pvHashAuxInfo = NULL;
SignPara.cMsgCert = 1;
SignPara.rgpMsgCert = &pSignerCertContext ;
SignPara.cMsgCrl = 0;
SignPara.rgpMsgCrl = NULL;
SignPara.cAuthAttr = 0;
SignPara.rgAuthAttr = NULL;
SignPara.cUnauthAttr = 0;
SignPara.rgUnauthAttr = NULL;
SignPara.dwFlags = 0;
SignPara.dwInnerContentType = 0;
EncryptPara.cbSize = sizeof
(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptPara.dwMsgEncodingType = MY_TYPE;
EncryptPara.hCryptProv = 0;
EncryptPara.ContentEncryptionAlgorithm.pszObjId =
szOID_RSA_RC4;
EncryptPara.ContentEncryptionAlgorithm.Parameters.c
bData = 0;
EncryptPara.pvEncryptionAuxInfo = NULL;
EncryptPara.dwFlags = 0;
EncryptPara.dwInnerContentType = 0;
cRecipientCert = 1;
rgpRecipientCert[0] = pReceiverCertContext;
*pcbSignedAndEncryptedBlob = 0;
pbSignedAndEncryptedBlob = NULL;
if( CryptSignAndEncryptMessage(
&SignPara,
&EncryptPara,
cRecipientCert,
rgpRecipientCert,
pbToBeSignedAndEncrypted,
cbToBeSignedAndEncrypted,
NULL, // the
pbSignedAndEncryptedBlob
pcbSignedAndEncryptedBlob))
{
printf("%d bytes for the
buffer .\n",*pcbSignedAndEncryptedBlob);
}
else
{
DWORD d = GetLastError();
HandleError("Getting the buffer length
failed.");
return;
}
//-------------------------------------------------
-------------------
// Allocated memory for the buffer
if(!(pbSignedAndEncryptedBlob=(unsigned char *)
malloc(*pcbSignedAndEncryptedBlob)))
HandleError("Memory allocation failed.");
//-------------------------------------------------
-------------------
// Call the function a second time to copy the
signed and encrypted
// message into the buffer
if( CryptSignAndEncryptMessage(
&SignPara,
&EncryptPara,
cRecipientCert,
rgpRecipientCert,
pbToBeSignedAndEncrypted,
cbToBeSignedAndEncrypted,
pbSignedAndEncryptedBlob,
pcbSignedAndEncryptedBlob))
{
printf("The message is signed and
enrypted.\n");
}
else
{
HandleError("The message failed to sign
and encrypt.");
}
FILE *fp=fopen("c:\\signedblob.txt","w");
fwrite
(pbSignedAndEncryptedBlob,*pcbSignedAndEncryptedBlob,1,fp);
fclose(fp);
//-------------------------------------------------
-------------------
// Clean up.
if(pSignerCertContext )
{
CertFreeCertificateContext
(pSignerCertContext );
}
if(pReceiverCertContext )
{
CertFreeCertificateContext
(pReceiverCertContext );
}
CertCloseStore(
hCertStore,
0);
//-------------------------------------------------
-------------------
// Return the signed and encrypted message.
return pbSignedAndEncryptedBlob;
} // End SignandEncrypt.
void CallDecryptAndVerify()
{
BYTE pbSignedAndEncryptedBlob[3500];
FILE *fp=fopen("c:\\signedblob.txt","w");
int nRead = fread
(pbSignedAndEncryptedBlob,1,3500,fp);
fclose(fp);
DecryptAndVerify(pbSignedAndEncryptedBlob,nRead);
}
BYTE *DecryptAndVerify(
BYTE *pbSignedAndEncryptedBlob,
DWORD cbSignedAndEncryptedBlob)
{
//-------------------------------------------------
-------------------
// Declare and initialize local variables.
HCERTSTORE hCertStore;
CRYPT_DECRYPT_MESSAGE_PARA DecryptPara;
CRYPT_VERIFY_MESSAGE_PARA VerifyPara;
DWORD dwSignerIndex = 0;
BYTE *pbDecrypted;
DWORD cbDecrypted;
//-------------------------------------------------
-------------------
// Open the certificate store
if ( !( hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE,
// L"root"))) // I trid with both "my"
and "root", no luck
L"my")))
{
HandleError("The MY store could not be
openned.");
return;
}
//-------------------------------------------------
-------------------
// Initialize the needed data structures.
DecryptPara.cbSize = sizeof
(CRYPT_DECRYPT_MESSAGE_PARA);
DecryptPara.dwMsgAndCertEncodingType = MY_TYPE;
DecryptPara.cCertStore = 1;
DecryptPara.rghCertStore = &hCertStore;
VerifyPara.cbSize = sizeof
(CRYPT_VERIFY_MESSAGE_PARA);
VerifyPara.dwMsgAndCertEncodingType = MY_TYPE;
VerifyPara.hCryptProv = 0;
VerifyPara.pfnGetSignerCertificate = NULL;
VerifyPara.pvGetArg = NULL;
pbDecrypted = NULL;
cbDecrypted = 0;
//-------------------------------------------------
-------------------
// Call CryptDecryptAndVerifyMessageSignature
a first time
// to determine the needed size of the buffer
to hold the
// decrypted message.
if(!(CryptDecryptAndVerifyMessageSignature(
&DecryptPara,
&VerifyPara,
dwSignerIndex,
pbSignedAndEncryptedBlob,
cbSignedAndEncryptedBlob,
NULL, // pbDecrypted
&cbDecrypted,
NULL,
NULL)))
{
HandleError("Failed."); // Here is
where it is failing
return;
}
//-------------------------------------------------
-------------------
// Allocate memory for the buffer to hold the
decrypted message.
if(!(pbDecrypted = (BYTE *)malloc(cbDecrypted)))
HandleError("Memory allocation failed.");
if(!(CryptDecryptAndVerifyMessageSignature(
&DecryptPara,
&VerifyPara,
dwSignerIndex,
pbSignedAndEncryptedBlob,
cbSignedAndEncryptedBlob,
pbDecrypted,
&cbDecrypted,
NULL,
NULL)))
{
pbDecrypted = NULL;
}
//-------------------------------------------------
-------------------
// Close the certificate store.
CertCloseStore(
hCertStore,
0);
//-------------------------------------------------
-------------------
// Return the decrypted string or NULL
return pbDecrypted;
} // end of DecryptandVerify