Я пытаюсь создать программу, которая использует некоторые веб-службы в Delphi XE. Чтобы подключиться к веб-службам, я должен использовать самозаверяющий сертификат, который хранится в хранилище сертификатов Windows. Я открываю хранилище сертификатов с помощью CertOpenSystemStore, получаю сертификат с CertFindCertificateInStore
и устанавливаю его с SSL_CTX_use_certificate
. Нет проблем с этим. Затем я получаю блоб с открытым ключом с помощью CryptExportKey
и создаю закрытый ключ, например:
function PrivKeyBlob2RSA(const AKeyBlob: PByte; const ALength: Integer; const ASSLCtx: PSSL_CTX): IdSSLOpenSSLHeaders.PEVP_PKEY;
var
modulus: PByte;
bh: PBLOBHEADER;
rp: PRSAPUBKEY;
rsa_modlen: DWORD;
rsa_modulus: PAnsiChar;
rkey: PRSA;
begin
bh := PBLOBHEADER(AKeyBlob);
Assert(bh^.bType = PUBLICKEYBLOB);
rp := PRSAPUBKEY(AKeyBlob + 8);
Assert(rp.magic = $31415352);
rsa_modulus := PAnsiChar(Integer(Pointer(rp))+12);
rkey := RSA_new_method(ASSLCtx.client_cert_engine);
rkey^.References := 1;
rkey^.e := BN_new;
rkey^.n := BN_new;
BN_set_word(rkey^.e, rp^.pubexp);
rsa_modlen := (rp^.bitlen div 8) + 1;
modulus := AllocMem(rsa_modlen);
CopyMemory(modulus, rsa_modulus, rsa_modlen);
RevBuffer(modulus, rsa_modlen);
BN_bin2bn(modulus, rsa_modlen, rkey^.n);
Result := EVP_PKEY_new;
EVP_PKEY_assign_RSA(Result, PAnsiChar(rkey));
end;
Затем я настроил его на SSL_CTX_use_PrivateKey
и SSL_CTX_check_private_key
- пока проблем нет. Но когда начинается передача данных, я получаю нарушение прав доступа в libeay32.dll. Если я загружаю ключ из файла .pem, все в порядке. Я не вижу, что я делаю не так, пожалуйста, помогите :)
Вот точное сообщение об ошибке:
Нарушение прав доступа по адресу 09881C5F в модуле libeay32.dll. Читать о
адрес 00000000.
Версия libeay32.dll: 1.0.0.5. Пробовал и с версией 0.9.что-то тоже - получил ту же ошибку, просто другой адрес.
Ниже приведена структура RSA, которую я получаю PrivKeyBlob2RSA
:
pad 0
version 0
meth $898030C
engine nil
n $A62D508
e $A62D4D8
d nil
p nil
q nil
dmp1 nil
dmq1 nil
iqmp nil
ex_data (nil, -1163005939 {$BAADF00D})
references 1
flags 6
_method_mod_n nil
_method_mod_p nil
_method_mod_q nil
bignum_data nil {#0}
blinding nil
mt_blinding nil
Я проверил n и e bignums, и они ПРАВИЛЬНЫЕ, а все остальное выглядит нормально. И да, ошибка возникает при вызове функции ssl_read
.