2011-10-27 14 views
27

के साथ विंडोज प्रमाण स्टोर से प्रमाणपत्र और निजी कुंजी का उपयोग करना मैं डेल्फी एक्सई में कुछ वेब सेवाओं का उपयोग करने वाला प्रोग्राम बनाने की कोशिश कर रहा हूं। वेब सेवाओं से कनेक्ट करने के लिए, मुझे एक स्व-हस्ताक्षरित प्रमाणपत्र का उपयोग करना होगा, जो कि विंडोज प्रमाणपत्र स्टोर में संग्रहीत है। मैं 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 फ़ाइल से कुंजी लोड करता हूं, तो सब कुछ ठीक है। मैं नहीं देख सकता मैं गलत क्या कर रहा हूँ, कृपया मदद :)

यहाँ सटीक त्रुटि संदेश है: मॉड्यूल 'libeay32.dll' में पता 09881C5F पर

पहुँच उल्लंघन। पता 00000000 का पढ़ें।

libeay32.dll संस्करण 1.0.0.5 है। संस्करण 0.9 के साथ कोशिश की। कुछ भी - एक ही त्रुटि, बस अलग पता मिला।

नीचे आरएसए संरचना मैं 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 और ई bignums जाँच की, और वे सही हैं, और सब कुछ और कुछ ठीक लग रहा है। और हां, त्रुटि ssl_read पर कॉल करते समय त्रुटि होती है।

+3

स्टैक ओवरव्लो में आपका स्वागत है। मुझे डर है "मुझे libea32.dll में प्रवेश उल्लंघन मिलता है" हमें आपकी कोशिश करने और आपकी सहायता करने के लिए कोई जानकारी नहीं देती है। अगर आपको कोई त्रुटि संदेश या अपवाद या एवी मिलता है, तो ** ** ** ** ** ** ** ** ** ** ** ** संदेश (किसी भी स्मृति पते के साथ) शामिल करना महत्वपूर्ण है। इसका मुकाबला करने में नाकाम रहने का मतलब है कि हमने इसके लिए पूछना है, और तब तक प्रतीक्षा करें जब तक कि हम इसे करने और मदद करने से पहले इसे हमारे पास न दें। यदि आप अपने मूल प्रश्न में त्रुटि जानकारी देते हैं (आपके द्वारा प्रदान किए गए कोड और प्रश्न पाठ के साथ), तो आपको एक उत्तर बहुत तेज़ मिलेगा। कृपया इसे संपादित करें और जोड़ें। धन्यवाद। :) –

+2

डेल्फी में '0x00000000' पता' के साथ अपवाद लगभग हमेशा (100% समय नहीं, लेकिन लगभग) किसी ऑब्जेक्ट को बनाने से पहले किसी ऑब्जेक्ट तक पहुंचने के कारण होते हैं, या एक पॉइंटर जो कभी भी इंगित करने के लिए कुछ भी निर्दिष्ट नहीं करता है (एक शून्य सूचक)। क्या आप उस कोड में स्पॉट को सीमित कर सकते हैं जिससे पहुंच उल्लंघन हो रहा है? (संपादन के बाद एक अच्छे प्रश्न के लिए +1, बीटीडब्लू।) –

+0

@ केन व्हाइट उत्तर के लिए धन्यवाद। किसी भी तरह से मैं टिप्पणी में अच्छी तरह से कोड संरेखित नहीं कर सकता, इसलिए मैंने सवाल संपादित किया। मुझे लगता है कि आरएसए संरचना मुझे ठीक लग रहा है .. – Andrejs

उत्तर

1

यह मेरे लिए सबसे उचित कारणों से आप इन त्रुटियों को मिलेगा लगता है शामिल हैं:

  1. OpenSSL DLLs का गलत संस्करण (libeay32 ssleay.dll) या SSL रैपर घोषित करने में त्रुटि (इस मामले में आप की आवश्यकता हो सकती एक इंडी संस्करण 10 अपग्रेड)।

  2. केन की टिप्पणी के अनुसार, डीएलएल में गुजरने वाली स्मृति के ब्लॉक को पहले से ही मुक्त कर दिया गया है।

  3. आपके द्वारा पोस्ट किए गए कोड में कुछ सूक्ष्म सूचक डीरफ्रेंसिंग बग। CopyMemory के लिए एक कॉल को "पॉइंटर वैरिएबलनाम" के बजाय "पॉइंटर वैरिएबलनाम ^" के माध्यम से पॉइंटर इंडिकेशन का स्तर खो सकता है। यदि आप अस्पष्ट हैं तो "अनियमित var पैरामीटर और पास्कल में पॉइंटर्स" पर पढ़ें।

संबंधित मुद्दे