| ||||
| ||||
Уважаемые специ, у меня при обращении к CryptSignMessage выпадает программа с ошибкой Access violation.... read adress 00000001. подскажите что тут не так. текст проги ниже var param:CRYPT_SIGN_MESSAGE_PARA; pUserCert :PCCERT_CONTEXT; { /* User certificate to be used*/} ret:integer; mem_tbs :Pbyte; mem_len :dword; MessageSizeArray :array [0..1] of dword; MessageArray :array [0..1] of pbyte; signed_len :DWORD; signed_mem :PBYTE; pCryptKeyProvInfo :CRYPT_KEY_PROV_INFO ; cbData :DWORD; cablob: array [0..1] of CRYPT_ATTR_BLOB; ca : array [0..1] of CRYPT_ATTRIBUTE; pbAuth :PBYTE; cbAuth : DWORD; fileTime :TFILETIME; systemTime :TTIME; {--} OID:Pchar; subj: PWideChar; hCertStore :pointer; res1,bOol:boolean; infile,outfile:file; nameString: PChar; begin hCertStore:=CertOpenSystemStore(0,’MY’); nameString:=’2508033345-250801001.250800844850@25.atkas-2.ru’; GetMem (subj, 2 * length (nameString) + 1); StringToWideChar (nameString, subj, 2 * length (nameString) + 1); pUserCert:= CertFindCertificateInStore (hCertStore, PKCS_7_ASN_ENCODING or X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, subj, nil); if (pUserCert^.pCertInfo^.SubjectPublicKeyInfo.Algorithm.pszObjId<> szOID_CP_GOST_R3410) then ShowMessage(’Ошибка алгаритма шифрования’); freeMem(subj); CertCloseStore(hCertStore, 0); OID:= szOID_CP_GOST_R3411; {===============================================================================} { ==================================================================} OpenDlg.Title := ’Укажите исходный файл для подписи’; if OpenDlg.Execute then AssignFile(infile, OpenDlg.FileName) else exit; reset(infile,1); mem_len:=FileSize(infile); GetMem(mem_tbs,mem_len); BlockRead(infile,mem_tbs^,mem_len); { /*--------------------------------------------------------------------*/ /* Установим параметры*/ /* Обязательно ныжно обнулить все поля структуры. */ /* Иначе это может привести к access violation в функциях CryptoAPI*/ /* В примере из MSDN это отсутствует*/} { GetMem(param, sizeof(CRYPT_SIGN_MESSAGE_PARA));} FillChar(param, sizeof(CRYPT_SIGN_MESSAGE_PARA),0); param.cbSize:= sizeof(CRYPT_SIGN_MESSAGE_PARA); param.dwMsgEncodingType:= TYPE_DER; param.pSigningCert:= pUserCert; param.HashAlgorithm.pszObjId:=szOID_CP_GOST_R3411_R3410; param.HashAlgorithm.Parameters.cbData := 0; param.HashAlgorithm.Parameters.pbData := nil; param.pvHashAuxInfo := nil; {/* не используется*/} {!!!!!!!!!!!!!!!!!} param.cMsgCert := 0; { /* не вклачаем сертификат отправителя*/} param.rgpMsgCert := nil; param.cAuthAttr := 0; param.dwInnerContentType := 0; param.cMsgCrl := 0; param.cUnauthAttr := 0; { /*--------------------------------------------------------------------------------- Определим системное время и добавим его в список аутентифицируемых (подписанных) атрибутов PKCS#7 сообщения с идентификатором szOID_RSA_signingTime. ---------------------------------------------------------------------------------*/} systemTime:=Date; fileTime:=DateTimeToFileTime(date); { /* Определим требуемую длину для хранения времени*/} if not CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, nil, @cbAuth) then ShowMessage(’Cannot encode object’); GetMem(pbAuth,cbAuth); { /* Кодирование времени в атрибут типа szOID_RSA_signingTime */} if not CryptEncodeObject(TYPE_DER, szOID_RSA_signingTime, @fileTime, pbAuth, @cbAuth) then ShowMessage(’"Cannot encode object"’); cablob[0].cbData := cbAuth; cablob[0].pbData := pbAuth; ca[0].pszObjId := szOID_RSA_signingTime; ca[0].cValue := 1; ca[0].rgValue := @cablob; param.cAuthAttr := 1; param.rgAuthAttr := @ca; { /*--------------------------------------------------------------------------------- dwFlags Normally zero. If the encoded output is to be a CMSG_SIGNED inner content of an outer cryptographic message such as a CMSG_ENVELOPED message, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG must be set. If it is not set, the message will be encoded as an inner content type of CMSG_DATA. With Windows 2000, CRYPT_MESSAGE_ENCAPSULATED_CONTENT_OUT_FLAG can be set to encapsulate non-data inner content into an OCTET STRING. Also, CRYPT_MESSAGE_KEYID_SINGER_FLAG can be set to identify signers by their Key Identifier and not their Issuer and Serial Number. ---------------------------------------------------------------------------------*/} param.dwFlags :=0 ; MessageArray[0] := mem_tbs; MessageSizeArray[0] := mem_len; { /* Возможен вариант использования функции CryptSignMessage в двухпроходной схеме*/ /* с передачей вместо исходных данных нуля для определения длины подписанных данных*/ /* (см. раздел Возвращение данных неопределенной длины в Руководстве программиста).*/ /* В этом случае функция CryptSignMessage производит инициализацию провайдера, соответствующего сертификату и */ /* подпись данных для определения длины, что приводит к необходимости двойной загрузки ключа.*/ /**/ /* Для того чтобы этого избежать приложение может заранее зарезервировать определенное */ /* количество памяти, достаточное для создания подписанного сообщения.*/ /*--------------------------------------------------------------------*/ /* Определение длины подписанного сообщения*/} { CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);} RES1:=false; if not CryptSignMessage( @param, res1, 1, MessageArray, MessageSizeArray, nil, @signed_len) then ShowMessage(’Signature creation error’);; | ||||
Ответы: | ||||
| ||||
Перепишите данную функцию на C/C++ :) Возможно, пока будете переписывать ошибка и исправиться :) | ||||