CryptoAPI использует знак CryptSignMessage, но openssl не может проверить, как это сделать? - PullRequest
0 голосов
/ 28 февраля 2019

код знака cryptoapi:

пусто* PCRYPT_DATA_BLOB pEncodedBlob, LPWSTR pwszSignerName /) {/ --------------------------------------------------------------- Объявите и инициализируйте переменные.Это включает в себя получение указателя на содержимое сообщения.Этот пример создает содержимое сообщения и получает указатель на него.В большинстве случаев контент где-то существует, и указатель на него передается приложению.--------------------------------------------------------------- / CRYPT_DATA_BLOB pEncodedBlob; // = new CRYPT_DATA_BLOB;// pEncodedBlob-> cbData = contentsize;// pEncodedBlob-> pbData = (BYTE *) strcontext;

HCERTSTORE hSystemStoreHandle;
CRYPT_SIGN_MESSAGE_PARA SignMessagePara;

//---------------------------------------------------------------
//   The message to be signed and encoded.

//BYTE* pbContent = (BYTE*) "The quick brown fox jumped over " \
//    "the lazy dog.";

/*---------------------------------------------------------------
    The length of the message. This must be one more than the 
    value returned by strlen() to include the terminal NULL 
    character.
---------------------------------------------------------------*/
//DWORD cbContent = lstrlenA((char *) pbContent) + 1;

//---------------------------------------------------------------
//    Arrays to hold the message to be signed and its length.

//const BYTE *rgpbToBeSigned[1] ;
//DWORD rgcbToBeSigned[1];

//---------------------------------------------------------------
//    The signer's certificate.

PCCERT_CONTEXT pSignerCert = NULL ;//(PCCERT_CONTEXT *)malloc(sizeof(CERT_CONTEXT)) ; 
//memset((char *)pSignerCert, 0, sizeof(CERT_CONTEXT));
char * strmsg = (char *)malloc(contentsize + 1);
memset(strmsg, 0, contentsize + 1);
//---------------------------------------------------------------
//    Buffer to hold the name of the subject of a certificate.

char pszNameString[MAX_NAME];

//---------------------------------------------------------------
//  The following variables are used only in the decoding phase.

DWORD cbData = sizeof(DWORD);

//---------------------------------------------------------------
//  Begin processing. Display the original message.

//rgpbToBeSigned[0] = pbContent;
//rgcbToBeSigned[0] = cbContent;

//printf("The original message = \n%s\n\n",
//    rgpbToBeSigned[0]);

//---------------------------------------------------------------
// Open a certificate store.

if(hSystemStoreHandle = CertOpenStore(
    CERT_STORE_PROV_SYSTEM,
    0,
    NULL,
    CERT_SYSTEM_STORE_CURRENT_USER,
    CERTIFICATE_STORE_NAME))
{
    printf("The certificate store is open. \n");
}
else
{
    MyHandleError( "Error Getting Store Handle");
}

//_DecodePfxbCert( (LPBYTE)cerbuffer , cersize , cerpassword , pSignerCert);
{
    HCERTSTORE hCertStore = NULL;
    PCCERT_CONTEXT  pCertContext = NULL;  


    CRYPT_DATA_BLOB dataBlob = {cersize, (BYTE *)cerbuffer};
    WCHAR * PWDS = (WCHAR *)malloc(strlen(cerpassword) + 1);
    memset(PWDS , 0 , sizeof(WCHAR) * (strlen(cerpassword) + 1) );
    swprintf(PWDS , L"%hs" , cerpassword);
    hCertStore = PFXImportCertStore(&dataBlob, PWDS /*? TEXT(pwd) : NULL*/, CRYPT_EXPORTABLE);
    if (NULL == hCertStore)
    {
        hCertStore = PFXImportCertStore(&dataBlob, L"", CRYPT_EXPORTABLE);
    }
    if (NULL == hCertStore)
    {
        return;
    }


    while(pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext))
    {       
        if (pCertContext->pbCertEncoded && pCertContext->cbCertEncoded > 0)
        {
            pSignerCert = CertDuplicateCertificateContext(pCertContext);
            break;
        }
    }


    CertCloseStore(hCertStore, 0);
    hCertStore = NULL;

}



if(pSignerCert == NULL)
{
    MyHandleError("Signer certificate not found.");
}

/*---------------------------------------------------------------
Initialize the CRYPT_SIGN_MESSAGE_PARA structure. First, use 
memset to set all members to zero or NULL. Then set the values of
all members that must be nonzero.
---------------------------------------------------------------*/

memset(&SignMessagePara, 0, sizeof(CRYPT_SIGN_MESSAGE_PARA));
SignMessagePara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SignMessagePara.HashAlgorithm.pszObjId = szOID_RSA_MD2;
SignMessagePara.pSigningCert = pSignerCert;
SignMessagePara.dwMsgEncodingType = MY_ENCODING_TYPE;
SignMessagePara.cMsgCert = 1;
SignMessagePara.rgpMsgCert = &pSignerCert;

/*---------------------------------------------------------------
    In two steps, sign and encode the message. First, get the 
    number of bytes required for the buffer to hold the signed 
    and encoded message.
---------------------------------------------------------------*/
const BYTE *rgpbToBeSigned[1] ;
DWORD rgcbToBeSigned[1];

memcpy_s(strmsg , contentsize + 1 , strcontext , contentsize);
rgpbToBeSigned[0] = (const BYTE *)strmsg;
rgcbToBeSigned[0] = strlen(strmsg) + 1;

DWORD dwSize = 0;
if( CryptSignMessage(
        &SignMessagePara,
        FALSE,
        1,
        rgpbToBeSigned,
        rgcbToBeSigned,
        NULL,
        &dwSize))
{
    printf("The needed length is %d \n", dwSize);
}
else
{
    MyHandleError("Getting the length failed.\n");
}

//---------------------------------------------------------------
//   Allocate memory for the required buffer.
memset(&pEncodedBlob , 0 , sizeof(pEncodedBlob));
BYTE * p = (BYTE *)malloc(dwSize);
memset(p , 0 , dwSize);
pEncodedBlob.pbData = p;
pEncodedBlob.cbData = dwSize;
if(!pEncodedBlob.pbData)
{
    MyHandleError("Memory allocation failed.");
}

//---------------------------------------------------------------
//   Call CryptSignMessage a second time to
//   copy the signed and encoded message to the buffer.
if( CryptSignMessage(
    &SignMessagePara,
    FALSE,
    1,
    rgpbToBeSigned,
    rgcbToBeSigned,
    pEncodedBlob.pbData,
    &pEncodedBlob.cbData))
{
    *outdata = (char *)malloc(pEncodedBlob.cbData);
    if(!outdata)
    {
        return;
    }

    memcpy_s(*outdata ,pEncodedBlob.cbData , pEncodedBlob.pbData , pEncodedBlob.cbData);
    *outdatasize = pEncodedBlob.cbData;
    printf("Signing worked \n");
}
else
{
    MyHandleError("Signing failed.\n");
}

//---------------------------------------------------------------
//  Clean up after signing and encoding.

if(pSignerCert)
{
    CertFreeCertificateContext(pSignerCert);
}

if(hSystemStoreHandle)
{
    CertCloseStore(hSystemStoreHandle,
        CERT_CLOSE_STORE_FORCE_FLAG);
}

return ;

}

Я использую openssl cms или проверку smime не удалось.как сделать ?Спасибо!

...