2011-10-27 162 views
27

我正在試圖製作一個在Delphi XE中使用某些Web服務的程序。要連接到Web服務,我必須使用存儲在Windows證書存儲中的自簽名證書。我使用CertOpenSystemStore打開證書存儲區,獲取CertFindCertificateInStore的證書並將其設置爲SSL_CTX_use_certificate。這沒有問題。然後我得到的公共密鑰團與CryptExportKey和彌補這樣的私鑰:從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; 

然後,我SSL_CTX_use_PrivateKeySSL_CTX_check_private_key設置它 - 沒有問題爲止。但是當數據傳輸開始時,我在libeay32.dll中遇到訪問衝突。如果我從.pem文件加載密鑰,一切都很好。我什麼也看不見,我做錯了,請幫助:)

這裏是確切的錯誤信息:

訪問衝突在模塊「的libeay32.dll」地址09881C5F。閱讀 地址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大數,他們是正確的,一切看起來確定。是的,當調用功能ssl_read時發生錯誤。

+3

歡迎來到StackOverflow。我擔心「我在libea32.dll中遇到訪問衝突」讓我們沒有任何信息可以繼續嘗試和幫助您。如果您收到錯誤消息或異常或AV,則包含** exact **錯誤消息(以及任何內存地址)非常重要。如果我們沒有提供這個意思,我們已經要求它,然後等到你把它交給我們,然後才能嘗試和幫助。如果您在原始問題中提供了錯誤信息(以及您提供的代碼和問題文本),您將得到更快的答案。請編輯並添加它。謝謝。 :) –

+2

Delphi中讀取地址0x00000000的例外幾乎總是(不是100%的時間,但幾乎是)在創建對象之前訪問一個對象或從未指定任何指向的指針(無指針)。你能縮小導致訪問違規的代碼嗎? (編輯後的+1問題,順便說一下。) –

+0

@Ken White 感謝您的回答。不知何故,我不能很好地對代碼進行評論,所以我編輯了這個問題。我得到的RSA結構對我來說看起來不錯。 – Andrejs

回答

1

在我看來,最合理的理由,你會得到這些錯誤包括:

  1. OpenSSL的dll文件的版本錯誤(libeay32 ssleay.dll),或在宣告SSL包裝錯誤(在這種情況下,你可能需要Indy版本10升級)。

  2. 根據Ken的評論,已經釋放了要傳入DLL的內存塊。

  3. 您發佈的代碼中的一些微妙的指針解引用錯誤。對CopyMemory的調用可能會通過「PointerVariableName ^」而不是「PointerVariableName」丟失指針間接級別。如果您不清楚,請閱讀「無類型var參數和pascal指針」。

相關問題