Главная страница
    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.04 c
1-1162067771
Gear
2006-10-29 00:36
2006.12.10
Ошибки страниц памяти и неизвестное исключение 0EEDFADE


15-1163783232
TUser
2006-11-17 20:07
2006.12.10
Не сочтите за рекламу,


15-1164002887
balepa
2006-11-20 09:08
2006.12.10
FineReader8 and Word2003


15-1163942186
Zancik
2006-11-19 16:16
2006.12.10
Горячие клавиши


15-1163542754
Суслик
2006-11-15 01:19
2006.12.10
Готовые хуки для svn на PHP 5





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский