Использование сертификата и закрытого ключа из хранилища сертификатов Windows с OpenSSL - PullRequest
27 голосов
/ 27 октября 2011

Я пытаюсь создать программу, которая использует некоторые веб-службы в 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.

1 Ответ

1 голос
/ 09 июня 2012

Мне представляется, что наиболее разумные причины, по которым вы получите эти ошибки, включают:

  1. Неправильная версия OpenSSL dll (libeay32 ssleay.dll) или ошибка в объявлении оболочек SSL (в этомна случай, если вам понадобится обновление Indy до версии 10).

  2. Как уже сказано Кеном, освободив блок памяти, который вы передаете в DLL.

  3. Некоторая небольшая ошибка разыменования указателя в размещенном вами коде.При вызове CopyMemory может отсутствовать уровень косвенности указателя через «PointerVariableName ^» вместо просто «PointerVariableName».Читайте "нетипизированные параметры var и указатели на паскале", если вам неясно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...