2011-10-27 53 views
27

Delphi XEでいくつかのWebサービスを使用するプログラムを作成しようとしています。 Webサービスに接続するには、Windows証明書ストアに格納されている自己署名証明書を使用する必要があります。 CertOpenSystemStoreで証明書ストアを開き、CertFindCertificateInStoreで証明書を取得し、SSL_CTX_use_certificateと設定します。これは問題ありません。それから私はCryptExportKeyと公開鍵ブロブを取得し、このような秘密鍵を作る:私は、その後SSL_CTX_use_PrivateKeySSL_CTX_check_private_keyでそれを設定OpenSSLでWindows証明書ストアの証明書と秘密鍵を使用する

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; 

- これまでのところ問題はありません。しかし、データ転送が開始されると、libeay32.dllでアクセス違反が発生します。 .pemファイルからキーをロードすると、すべて正常です。モジュールのlibeay32.dll "のアドレス09881C5Fで

アクセス違反:私は、:)

はここで正確なエラーメッセージです助けてください私が間違っているのかを見ることができません。 アドレス00000000

libeay32.dllのバージョンは1.0.0.5です。バージョン0.9で試してみました。同じエラーが発生しました。別のアドレスです。

以下

は、私がPrivKeyBlob2RSAに入るRSA構造である:

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 

Iは、nおよび電子bignumsをチェックし、彼らは正しい、と他のすべてがOKになります。はい、関数ssl_readを呼び出すとエラーが発生します。

+3

ようこそStackOverflow。私は恐れている "私はlibea32.dllのアクセス違反を取得"私たちはあなたに手を差し伸べるために行く情報はありません。エラーメッセージまたは例外またはAVが発生した場合は、**正確**エラーメッセージ(メモリアドレスとともに)を含めることが重要です。それを提供することができないということは、私たちがそれを求めていることを意味しています。元の質問にエラー情報を指定した場合(提供されたコードと質問テキストとともに)、はるかに早く回答が得られます。編集して追加してください。ありがとう。 :) –

+2

Delphiの 'Read 0x00000000'の例外は、オブジェクトが作成される前にオブジェクトにアクセスすることによって発生するほとんどの場合(時間の100%ではありませんがほとんど)、ポイントするものが決して割り当てられていないポインタポインタ)。アクセス違反の原因となっているコードの範囲を絞り込むことはできますか? (編集後の良い質問のために+1、BTW。) –

+0

@Ken White 答えをありがとう。どういうわけか私はコメントにコードをきちんと並べることができないので、私は質問を編集しました。 RSAの構造体は私に見えるようになる.. – Andrejs

答えて

1

それは私にはあなたがこれらのエラーが含まなるだろう最も合理的な理由のようだ:SSLラッパーを宣言における

  1. のOpenSSLのDLL(libeay32 ssleay.dll)またはエラーの間違ったバージョン(この場合にはあなたが必要な場合がありますがインディーバージョン10のアップグレード)。

  2. Kenさんのコメントによると、すでにメモリブロックが解放されています。

  3. あなたが投稿したコードでは、微妙なポインタ逆参照バグがあります。 CopyMemoryを呼び出すと、単に "PointerVariableName"の代わりに "PointerVariableName ^"を介してポインタ間接のレベルが失われる可能性があります。あなたが不明な場合は、「型指定されていないvarパラメータとポインタをパスカルで読む」を読んでください。

関連する問題