Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];

Вниз

Access Violation при вызове CryptSignAndEncryptMessage   Найти похожие ветки 

 
DmitrySukach ©   (2006-07-27 14:58) [0]

Подскажите, что я делаю неправильно?
Вот полностью код после получения pCertContext:
const
CERT_ENCODING_TYPE = X509_ASN_ENCODING or PKCS_7_ASN_ENCODING;
var
pCertContext: PCCERT_CONTEXT;
SignPara: CRYPT_SIGN_MESSAGE_PARA;
EncryptPara: CRYPT_ENCRYPT_MESSAGE_PARA;
pbSignedAndEncryptedBlob: PBYTE;
dwKeySpec: DWORD;
hCryptProv: HCRYPTPROV;
bToBeSignedAndEncrypted: array[0..1] of BYTE;
cbToBeSignedAndEncrypted: DWORD;
cbSignedAndEncryptedBlob: DWORD;
begin
CryptAcquireCertificatePrivateKey(
pCertContext,
0,
nil,
@hCryptProv,
@dwKeySpec,
nil);

FillChar(SignPara, SizeOf(CRYPT_SIGN_MESSAGE_PARA), 0);
SignPara.cbSize := SizeOf(CRYPT_SIGN_MESSAGE_PARA);
SignPara.dwMsgEncodingType := CERT_ENCODING_TYPE;
SignPara.pSigningCert := pCertContext;
SignPara.HashAlgorithm.pszObjId := szOID_RSA_MD2;
SignPara.cMsgCert := 1;
SignPara.rgpMsgCert := @pCertContext;

FillChar(EncryptPara, SizeOf(CRYPT_SIGN_MESSAGE_PARA), 0);
EncryptPara.cbSize := SizeOf(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptPara.dwMsgEncodingType := CERT_ENCODING_TYPE;
EncryptPara.ContentEncryptionAlgorithm.pszObjId := szOID_RSA_RC4;
EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData := 0;
EncryptPara.pvEncryptionAuxInfo := nil;
EncryptPara.dwFlags := 0;
EncryptPara.dwInnerContentType := 0;

cbToBeSignedAndEncrypted := 1;
bToBeSignedAndEncrypted[0] := 33;
bToBeSignedAndEncrypted[1] := 44;
cbSignedAndEncryptedBlob := 0;
pbSignedAndEncryptedBlob := nil;

CryptSignAndEncryptMessage(
@SignPara,
@EncryptPara,
1,
pCertContext,
@bToBeSignedAndEncrypted,
cbToBeSignedAndEncrypted,
nil,
@cbSignedAndEncryptedBlob);
...

На этом вызове и вылетает.


 
Сергей М. ©   (2006-07-27 15:13) [1]


> что я делаю неправильно?


Как минимум одно - не выделяешь память под CCERT_CONTEXT


 
Reindeer Moss Eater ©   (2006-07-27 15:17) [2]

Нарисуй сюда свой прототип CryptSignAndEncryptMessage


 
DmitrySukach ©   (2006-07-27 15:18) [3]

Я же написал: "Вот полностью код после получения pCertContext". Сертификат я получил нормально:

 pCertContext := CertFindCertificateInStore(hStore, CERT_ENCODING_TYPE, 0,
   CERT_FIND_ANY, nil, nil);

 CertNameToStr(CERT_ENCODING_TYPE, @(pCertCtx^.pCertInfo^.Subject),
   CERT_SIMPLE_NAME_STR, szName, MAXBUFF);
 ShowMessage("Subject: " + szName);

Это всё работает, субъект показывает.


 
DmitrySukach ©   (2006-07-27 15:19) [4]

function CryptSignAndEncryptMessage(pSignPara :PCRYPT_SIGN_MESSAGE_PARA;
                                   pEncryptPara :PCRYPT_ENCRYPT_MESSAGE_PARA;
                                   cRecipientCert :DWORD;
                                   rgpRecipientCert :array of PCCERT_CONTEXT;
                             const pbToBeSignedAndEncrypted :PBYTE;
                                   cbToBeSignedAndEncrypted :DWORD;
                                   pbSignedAndEncryptedBlob :PBYTE;
                                   pcbSignedAndEncryptedBlob :PDWORD
                                   ):BOOL ; stdcall;


 
Reindeer Moss Eater ©   (2006-07-27 15:20) [5]

Засада вот здесь :

rgpRecipientCert :array of PCCERT_CONTEXT;


 
DmitrySukach ©   (2006-07-27 15:24) [6]

Я делал и так:

 cRecipientCert: DWORD;
 rgpRecipientCert: array[0..4] of PCCERT_CONTEXT;

 cRecipientCert := 1;
 rgpRecipientCert[0] := pCertContext;

 CryptSignAndEncryptMessage(
     @SignPara,
     @EncryptPara,
     cRecipientCert,
     rgpRecipientCert,
     @bToBeSignedAndEncrypted,
     cbToBeSignedAndEncrypted,
     nil,
     @cbSignedAndEncryptedBlob);

Тот же результат...


 
DmitrySukach ©   (2006-07-27 15:27) [7]

На Visual C++ это работает:

СryptAcquireCertificatePrivateKey(
       pSignerCertContext,
       0,
       NULL,
       &hCryptProv,
       &dwKeySpec,
       NULL);

   SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
   SignPara.dwMsgEncodingType = MY_ENCODING_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_ENCODING_TYPE;
   EncryptPara.hCryptProv = 0;
   EncryptPara.ContentEncryptionAlgorithm.pszObjId = szOID_RSA_RC4;
   EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData = 0;
   EncryptPara.pvEncryptionAuxInfo = NULL;
   EncryptPara.dwFlags = 0;
   EncryptPara.dwInnerContentType = 0;

   cRecipientCert = 1;
   rgpRecipientCert[0] = pSignerCertContext;
   *pcbSignedAndEncryptedBlob = 0;
   pbSignedAndEncryptedBlob = NULL;

   CryptSignAndEncryptMessage(
       &SignPara,
       &EncryptPara,
       cRecipientCert,
       rgpRecipientCert,
       pbToBeSignedAndEncrypted,
       cbToBeSignedAndEncrypted,
       NULL,
       pcbSignedAndEncryptedBlob)


 
Reindeer Moss Eater ©   (2006-07-27 15:28) [8]

Про декларацию я уже говорил. Это одна из причин.
На джедаях выложена кривая трансяция Wincrypt2.h
Исходные параметры типа таких PCCERT_CONTEXT rgpRecipientCert[] везде заменены открытыми массивами Delphi. Но там совсем другая физическая организация.

Дальше надо искать ошибку в заполнении структур.


 
Reindeer Moss Eater ©   (2006-07-27 15:33) [9]

Вот моя переделка одной из деклараций

function CryptEncryptMessageMy(pEncryptPara          : PCRYPT_ENCRYPT_MESSAGE_PARA;
                              cRecipientCert        : DWORD;
                              rgpRecipientCert      : PCCERT_CONTEXT; //array of PCCERT_CONTEXT;
                              const pbToBeEncrypted : PBYTE;
                              cbToBeEncrypted       : DWORD;
                              pbEncryptedBlob       : PBYTE;
                              pcbEncryptedBlob      : PDWORD) : BOOL; stdcall;

То есть я использую просто скалярный параметр PCCERT_CONTEXT.
Если получателей больше одного, я "руками" распределяю память под несколько указателей и руками же рассовываю туда все PCCERT_CONTEXT.
А в качестве параметра идет первый из них.


 
DmitrySukach ©   (2006-07-27 15:46) [10]

Заменил прототип. Теперь вызов возвращает False и GetLastError даёт E_INVALIDARG...


 
DmitrySukach ©   (2006-07-27 15:56) [11]

Reindeer Moss Eater,
Вы не могли написать какой-нибудь работающий пример с CryptSignAndEncryptMessage?


 
Reindeer Moss Eater ©   (2006-07-27 16:14) [12]

>Теперь вызов возвращает False и GetLastError даёт E_INVALIDARG...

Остается побороть заполнение параметров.
Примера с CryptSignAndEncryptMessage нет.
Только по отдельности.


 
DmitrySukach ©   (2006-07-27 17:17) [13]

А рабютающий пример с CryptSignMessage есть?


 
Reindeer Moss Eater ©   (2006-07-27 18:00) [14]

procedure SignMessage(const AFileIn, AFileOut: string);
var
SignParams     : CRYPT_SIGN_MESSAGE_PARA;
pAuthorCert    : PCCERT_CONTEXT;
hStoreHandle   : HCERTSTORE;
hProv             : HCRYPTPROV;
bDetached      : boolean;
dwToBeSigned   : DWORD;
pbToBeSigned   : PBYTE;
dwSigned       : DWORD;
pbSigned       : PBYTE;
pbDummyArray   : Pointer;
cbDummyElem    : PByte;
cbDummyArray   : Pointer;
begin
bDetached := False;
get_file_data(AFileIn,dwToBeSigned,pbToBeSigned);
pbDummyArray   := @pbToBeSigned;
cbDummyArray   := @dwToBeSigned;
hStoreHandle   := CertOpenSystemStore(hProv,"MY");
if hStoreHandle = nil then Exit;
pAuthorCert := GetCertificateByTypeAndName("ИмяВладельца",hStoreHandle,AT_SIGNATURE); //пользовательская ф-ция, возвращающая сертификат по имени владельца
if pAuthorCert = nil then Exit;
ZeroMemory(@SignParams,SizeOf(CRYPT_SIGN_MESSAGE_PARA));
SignParams.cbSize                   := SizeOf(CRYPT_SIGN_MESSAGE_PARA);
SignParams.dwMsgEncodingType        := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
SignParams.pSigningCert             := pAuthorCert;
SignParams.HashAlgorithm.pszObjId   := szOID_CP_GOST_R3411;// szOID_RSA_MD5;
SignParams.HashAlgorithm.Parameters.cbData := 0;
SignParams.cMsgCert                 := 0;
SignParams.rgpMsgCert               := nil;
SignParams.cAuthAttr                := 0;
SignParams.dwInnerContentType       := 0;
SignParams.cMsgCrl                  := 0;
SignParams.cUnauthAttr              := 0;
SignParams.dwFlags                  := 0;
if not CryptSignMessage(@SignParams,bDetached,1,pbDummyArray,cbDummyArray,nil,@dwSigned ) then Exit;
GetMem(pbSigned,dwSigned);
if CryptSignMessage(@SignParams,bDetached,1,pbDummyArray,cbDummyArray,pbSigned,@dwS igned) then
 SaveDataToFile(AFileOut,pbSigned^,dwSigned);
FreeMem(pbToBeSigned,dwToBeSigned);
FreeMem(pbSigned,dwSigned);
CertFreeCertificateContext(pAuthorCert);
CertCloseStore(hStoreHandle,0);
end;



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.044 c
2-1162976091
first_may
2006-11-08 11:54
2006.12.10
Директива $IFDEF


6-1153402716
Каг дила?
2006-07-20 17:38
2006.12.10
проблемка IdSMTP


2-1164545653
Jimmy
2006-11-26 15:54
2006.12.10
Повернутый эллипс.


2-1164310772
Kostafey
2006-11-23 22:39
2006.12.10
Экспорт из TBDGridEh в Excel


15-1163867719
XP UserR-rr
2006-11-18 19:35
2006.12.10
Васик, и все с ним связанное





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский