Форум: "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.046 c