我試圖在RHEL 4系統編寫一個Web服務客戶端(OpenSSL的0.9.8b)(升級不是一個選項)。我拿到了CA證書文件,使用兩個證書,一個是自簽名根證書。它適用於「openssl s_client」,但不適用於代碼。我從SSL_get_verify_result收到錯誤7(SSL證書驗證失敗)。SSL服務器證書驗證代碼失敗,但不使用OpenSSL
我做了一個測試程序,這裏的基本部分:
SSL_library_init();
SSL_load_error_strings();
ctx = SSL_CTX_new(SSLv23_method());
SSL_CTX_load_verify_locations(ctx, "/etc/pki/mycert/cacert.pem", 0);
ssl = SSL_new(ctx);
sbio = BIO_new_socket(sock, BIO_NOCLOSE); /* The socket is already connected */
SSL_set_bio(ssl, sbio, sbio);
SSL_connect(ssl);
err = SSL_get_verify_result(ssl);
連接工程和服務器發送其證書;我已經用PEM_write_X509將它拋棄了,並證實它被「openssl verify」接受。
我用
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
寫出來的回調函數的驗證步驟:
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
{
char buf[256];
X509 *err_cert;
int err, depth;
err_cert = X509_STORE_CTX_get_current_cert(ctx);
err = X509_STORE_CTX_get_error(ctx);
depth = X509_STORE_CTX_get_error_depth(ctx);
X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
if (!preverify_ok)
printf("verify error:num=%d:%s:depth=%d:%s\n", err,
X509_verify_cert_error_string(err), depth, buf);
else
printf("Preverify OK, depth=%d:%s, err=%d\n", depth, buf, err);
...
這樣做的輸出(替換爲一些證書數據「...」 ):
Preverify OK, depth=2:/ST=GP/L=JHB/C ... QA Root CA 01, err=0
Preverify OK, depth=1:/C=ZA/DC=za/DC ... QA Issue CA 01, err=0
verify error:num=7:certificate signature failure:depth=0:/C=ZA ...
當此CA證書文件運行「openssl s_client」爲「-CAfile」時,輸出開始於:
depth=2 /ST=GP/L=JHB/C ... QA Root CA 01
verify return:1
depth=1 /C=ZA/DC=za/DC ... QA Issue CA 01
verify return:1
depth=0 /C=ZA/ST ...
verify return:1
那麼「openssl s_client」在做什麼和代碼在做什麼之間有什麼區別?