2011-10-27 3 views
27

Delphi XE에서 일부 웹 서비스를 사용하는 프로그램을 만들려고합니다. 웹 서비스에 연결하려면 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 

나는 N 및 전자 bignums를 확인, 그들은 올바른지, 그리고 모든 다른 괜찮아 보인다. 그리고 예, 함수 ssl_read을 호출 할 때 오류가 발생합니다.

가 은
+3

Welcome to StackOverflow. "libea32.dll에서 액세스 위반이 발생합니다."라는 질문에 대한 답변을 드릴 수있는 정보가 없습니다. 오류 메시지 나 예외 또는 AV가 발생하면 ** 정확한 ** 오류 메시지 (메모리 주소와 함께)를 포함하는 것이 중요합니다. 그것을 제공하지 않으면 우리가 그것을 요청하고, 우리가 시도하고 도울 수 있기 전에, 당신이 그것을 우리에게 줄 때까지 기다리는 것을 의미합니다. 코드와 질문 텍스트를 포함하여 원래 질문에 오류 정보를 제공하면 훨씬 빨리 대답 할 수 있습니다. 편집하고 추가하십시오. 감사. :) –

+2

델파이의'Read 0x00000000' 예외는 거의 항상 (시간의 100 %는 아니지만 거의) 객체를 생성하기 전에 객체에 접근함으로써 발생합니다. 바늘). 액세스 위반을 일으키는 코드의 범위를 좁힐 수 있습니까? (편집 후 좋은 질문에 대해 +1하십시오.) –

+0

@Ken White 답변 해 주셔서 감사합니다. 어떻게 든 코멘트에 멋지게 코드를 정렬 할 수 없으므로 질문을 편집했습니다. RSA 구조체는 나에게 좋아 보인다. .. – Andrejs

답변

1
그것은 나에게 당신이 이러한 오류를 얻을 것입니다 가장 합리적인 이유를 보인다

은 다음과 같습니다 : OpenSSL을 DLL을의

  1. 잘못된 버전 (libeay32 ssleay.dll) 또는 오류 SSL 래퍼 선언에 (이 경우 당신이해야 할 수도 있습니다 인디 버전 10 업그레이드).

  2. Ken 님의 의견에 따르면, DLL에 전달중인 메모리 블록이 이미 해제되었습니다.

  3. 게시 한 코드의 미묘한 포인터 역 참조 버그. CopyMemory에 대한 호출에서 "PointerVariableName"대신 "PointerVariableName ^"을 통해 포인터 간접 레벨이 누락되었을 수 있습니다. 불명확 한 경우 "유형이 지정되지 않은 var 매개 변수 및 포인터 (파스칼)"를 읽으십시오.