Множественная подпись CryptoAPI

Тема в разделе "WASM.CRYPTO", создана пользователем Keva, 9 июл 2007.

  1. Keva

    Keva New Member

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    130
    Кто-нибудь занимался вопросом множественной подписи с использованием CryptoAPI? Помогите разобраться, подписываю и дописываю сообщение следующим образом:
    Код (Text):
    1. DWORD cbContent;
    2.         HCRYPTPROV hCryptProv;
    3.         HCERTSTORE hStoreHandle;
    4.         PCCERT_CONTEXT pSignerCert;
    5.  
    6.         CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
    7.         CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
    8.         CERT_BLOB SignerCertBlob;
    9.         CERT_BLOB SignerCertBlobArray[1];
    10.         CMSG_SIGNED_ENCODE_INFO         SignedMsgEncodeInfo;
    11.  
    12.         DWORD                           cbEncodedBlob;
    13.         DWORD                           cbMessageBlob;
    14.  
    15.         BYTE*                           pbEncodedBlob;
    16.         BYTE*                           pbMessageBlob;
    17.  
    18.         HCRYPTMSG                       hMsg;
    19.         HCRYPTMSG                       cryptMsg;
    20.         DWORD                           dwKeySpec;
    21.         CRYPT_VERIFY_MESSAGE_PARA       msgPara;
    22.  
    23.  
    24.         const BYTE* pbContent = (BYTE*)"Test Message.";
    25.         cbContent = strlen((char *) pbContent)+1;
    26.  
    27.         //îòêðûâàåì õðàíèëèùå MY
    28.         hStoreHandle = CertOpenStore(
    29.                 CERT_STORE_PROV_SYSTEM,
    30.                 0,
    31.                 NULL,
    32.                 CERT_SYSTEM_STORE_CURRENT_USER,
    33.                 L"MY");
    34.         if(!hStoreHandle)
    35.         {
    36.                 MyHandleError( "Could not open the MY system store.");
    37.         }
    38.  
    39.         //ïîëó÷àåì êîíòåêñò ñåðòèôèêàòà êîòîðûì áóäåì ïîäïèñûâàòü
    40.         pSignerCert = CertFindCertificateInStore(
    41.                 hStoreHandle,
    42.                 MY_ENCODING_TYPE,
    43.                 0,
    44.                 CERT_FIND_SUBJECT_STR,
    45.                 SIGNER_NAME,
    46.                 NULL);
    47.         if (!pSignerCert)
    48.         {
    49.                 MyHandleError("Cert not found.\n");
    50.         }
    51.  
    52.         //ïîëó÷åíèå äåñêðèïòîðà çàêðûòîãî êëþ÷à
    53.         if(!(CryptAcquireCertificatePrivateKey(
    54.                 pSignerCert,
    55.                 0,
    56.                 NULL,
    57.                 &hCryptProv,
    58.                 &dwKeySpec,
    59.                 NULL)))
    60.         {
    61.                 MyHandleError("CryptAcquireContext failed");
    62.         }
    63.  
    64.         memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
    65.  
    66.         SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
    67.         SignerEncodeInfo.pCertInfo = pSignerCert->pCertInfo;
    68.         SignerEncodeInfo.hCryptProv = hCryptProv;
    69.         SignerEncodeInfo.dwKeySpec = dwKeySpec;
    70.         SignerEncodeInfo.HashAlgorithm.pszObjId = szOID_RSA_MD5;
    71.         SignerEncodeInfo.pvHashAuxInfo = NULL;
    72.  
    73.         SignerEncodeInfoArray[0] = SignerEncodeInfo;
    74.  
    75.         SignerCertBlob.cbData = pSignerCert->cbCertEncoded;
    76.         SignerCertBlob.pbData = pSignerCert->pbCertEncoded;
    77.  
    78.         SignerCertBlobArray[0] = SignerCertBlob;
    79.         memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
    80.         SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
    81.         SignedMsgEncodeInfo.cSigners = 1;
    82.         SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
    83.         SignedMsgEncodeInfo.cCertEncoded = 1;
    84.         SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
    85.  
    86.         if(!(cbEncodedBlob = CryptMsgCalculateEncodedLength(
    87.                 MY_ENCODING_TYPE,     // Message encoding type
    88.                 0,                    // Flags
    89.                 CMSG_SIGNED,          // Message type
    90.                 &SignedMsgEncodeInfo, // Pointer to structure
    91.                 NULL,                 // Inner content OID
    92.                 cbContent)))          // Size of content
    93.         {
    94.                 MyHandleError("Getting cbEncodedBlob length failed.");
    95.         }
    96.  
    97.         if(!(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob)))
    98.         {
    99.                 MyHandleError("Malloc operation failed.");
    100.         }
    101.         //----------------------------------------------------------------
    102.         if(!(cbEncodedBlob = CryptMsgCalculateEncodedLength(
    103.                 MY_ENCODING_TYPE,     // Message encoding type
    104.                 0,                    // Flags
    105.                 CMSG_SIGNED,          // Message type
    106.                 &SignedMsgEncodeInfo, // Pointer to structure
    107.                 NULL,                 // Inner content OID
    108.                 cbContent)))          // Size of content
    109.         {
    110.                 MyHandleError("Getting cbEncodedBlob length failed.");
    111.         }
    112.  
    113.         if(!(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob)))
    114.         {
    115.                 MyHandleError("Malloc operation failed.");
    116.         }
    117.  
    118.         //----------------------------------------------------------------
    119.         if(!(hMsg = CryptMsgOpenToEncode(
    120.                 MY_ENCODING_TYPE,      // Encoding type
    121.                 CMSG_DETACHED_FLAG,    // Flags
    122.                 CMSG_SIGNED,           // Message type
    123.                 &SignedMsgEncodeInfo,  // Pointer to structure
    124.                 NULL,                  // Inner content OID
    125.                 NULL)))                // Stream information (not used)
    126.         {
    127.                 MyHandleError("OpenToEncode failed");
    128.         }
    129.  
    130.         if(!(CryptMsgUpdate(
    131.                 hMsg,       // Handle to the message
    132.                 pbContent,  // Pointer to the content
    133.                 cbContent,  // Size of the content
    134.                 TRUE)))     // Last call
    135.         {
    136.                 MyHandleError("MsgUpdate failed");
    137.         }
    138.         if(!CryptMsgGetParam(
    139.                 hMsg,               // Handle to the message
    140.                 CMSG_CONTENT_PARAM, // Parameter type
    141.                 0,                  // Index
    142.                 pbEncodedBlob,      // Pointer to the BLOB
    143.                 &cbEncodedBlob))    // Size of the BLOB
    144.         {
    145.                 MyHandleError("MsgGetParam failed.");
    146.         }
    147.         print_signature("C:\\sign",cbEncodedBlob, pbEncodedBlob);
    148.         CryptReleaseContext(hCryptProv, 0);
    149.  
    150.         //-------------------------------------------------------------
    151.         //äîáàâëÿåì åùå îäíó ïîäïèñü
    152.         //-------------------------------------------------------------
    153.         DWORD                           Spec;
    154.         HCRYPTPROV                      hProv;
    155.         PCCERT_CONTEXT                  pSecondSigner=NULL;
    156.  
    157.         CMSG_SIGNER_ENCODE_INFO         CmsgSignerEncodeInfo;
    158.         CMSG_SIGNER_ENCODE_INFO         CmsgSignerEncodeInfoArray[1];
    159.         CERT_BLOB                       CertBlob;
    160.         CERT_BLOB                       CertBlobArray[1];
    161.         CMSG_SIGNED_ENCODE_INFO         CmsgSignedEncodeInfo;
    162.         pSecondSigner = CertFindCertificateInStore(
    163.                 hStoreHandle,
    164.                 MY_ENCODING_TYPE,
    165.                 0,
    166.                 CERT_FIND_SUBJECT_STR,
    167.                 SIGNER_NAME1,
    168.                 NULL);
    169.         if (!pSecondSigner)
    170.         {
    171.                 MyHandleError("Cert not found.\n");
    172.         }
    173.  
    174.         if(!(CryptAcquireCertificatePrivateKey(
    175.                 pSecondSigner,
    176.                 0,
    177.                 NULL,
    178.                 &hProv,
    179.                 &Spec,
    180.                 NULL)))
    181.         {
    182.                 MyHandleError("CryptAcquireContext failed");
    183.         }
    184.  
    185.         memset(&CmsgSignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
    186.  
    187.         CmsgSignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
    188.         CmsgSignerEncodeInfo.pCertInfo = pSecondSigner->pCertInfo;
    189.         CmsgSignerEncodeInfo.hCryptProv = hProv;
    190.         CmsgSignerEncodeInfo.dwKeySpec = dwKeySpec;
    191.         CmsgSignerEncodeInfo.HashAlgorithm.pszObjId = szOID_RSA_MD5;
    192.         CmsgSignerEncodeInfo.pvHashAuxInfo = NULL;
    193.         CmsgSignerEncodeInfoArray[0] = CmsgSignerEncodeInfo;
    194.  
    195.         CertBlob.cbData = pSecondSigner->cbCertEncoded;
    196.         CertBlob.pbData = pSecondSigner->pbCertEncoded;
    197.         CertBlobArray[0] = CertBlob;
    198.  
    199.         memset(&CmsgSignedEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
    200.         CmsgSignedEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
    201.         CmsgSignedEncodeInfo.cSigners = 1;
    202.         CmsgSignedEncodeInfo.rgSigners = CmsgSignerEncodeInfoArray;
    203.         CmsgSignedEncodeInfo.cCertEncoded = 1;
    204.         CmsgSignedEncodeInfo.rgCertEncoded = CertBlobArray;
    205.  
    206.         if(!(cbMessageBlob = CryptMsgCalculateEncodedLength(
    207.                 MY_ENCODING_TYPE,     // Message encoding type
    208.                 0,                    // Flags
    209.                 CMSG_SIGNED,          // Message type
    210.                 &CmsgSignedEncodeInfo, // Pointer to structure
    211.                 NULL,                 // Inner content OID
    212.                 cbContent)))          // Size of content
    213.         {
    214.                 MyHandleError("Getting cbEncodedBlob length failed.");
    215.         }
    216.  
    217.         if(!(pbMessageBlob = (BYTE *) malloc(cbMessageBlob)))
    218.         {
    219.                 MyHandleError("Malloc operation failed.");
    220.         }
    221.  
    222.         cryptMsg = CryptMsgOpenToDecode(
    223.                 MY_ENCODING_TYPE,
    224.                 CMSG_DETACHED_FLAG,
    225.                 0,
    226.                 NULL,
    227.                 NULL,
    228.                 NULL);
    229.  
    230.         if (!CryptMsgUpdate(
    231.                 cryptMsg,
    232.                 pbEncodedBlob,
    233.                 cbEncodedBlob,
    234.                 TRUE))
    235.         {
    236.                 printf("Error CryptMsgUpdate with encoded");
    237.         }
    238.         if (!CryptMsgControl(
    239.                 cryptMsg,
    240.                 0,
    241.                 CMSG_CTRL_ADD_SIGNER,
    242.                 &CmsgSignerEncodeInfo))
    243.         {
    244.                 printf("Error CryptMsgControl");
    245.         }
    246.  
    247.         if (!CryptMsgGetParam(
    248.                 cryptMsg,
    249.                 CMSG_ENCODED_MESSAGE,
    250.                 0,
    251.                 pbMessageBlob,
    252.                 &cbMessageBlob))
    253.         {
    254.                 printf("CryptMsgGetParam failed");
    255.                 DWORD   i=GetLastError();
    256.                 return 0;
    257.         }
    258.  
    259.         CryptMsgClose(hMsg);
    260.         CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG);
    261.         CryptReleaseContext(hCryptProv, 0);
    Но функция CryptMsgGetParam отрабатывает с ошибкой ERROR_MORE_DATA - слишком маленький размер буфера под возращаемые данные. Что делаю не так?
     
  2. Jupiter

    Jupiter Jupiter

    Публикаций:
    0
    Регистрация:
    12 авг 2004
    Сообщения:
    532
    Адрес:
    Russia
    так сначала нужно получить желаемый размер буфера, а потом уже этот буфер использовать!
    см. описание CryptMsgGetParam в MSDN, там как раз этот вопрос рассмотрен/
    фактически ты вызываешь ф-цию два раза: сначала для выяснения размера буфера, а потом собсно по делу
     
  3. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Ещё не будет лишним вдумчивое чтение Рихтера - "Программирование серверных приложений".
     
  4. Keva

    Keva New Member

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    130
    Создал вторую подпись для сообщения, но при проверке
    Код (Text):
    1. CryptVerifyDetachedMessageSignature(
    2.                 &msgPara,
    3.                 1,
    4.                 pbMessageBlob,                
    5.                 cbMessageBlob,                1,
    6.                 &pbContent,
    7.                 &cbContent,
    8.                 &pTestCer)
    проверяется только первая если индекс равен 1, если его сделать равным 0 то функция отработает с ошибкой 80092004 Object or property not found, если больше еденицы то 8009200e The signed message doesn't have a signer for the specified signer index, но ведь я добавлял подпись!