From ef7316b92f94831721e399cdb77b4166e6cebfd7 Mon Sep 17 00:00:00 2001 From: Tiga Ultraman Date: Sat, 30 May 2026 11:04:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AF=81=E4=B9=A6=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E5=AE=89=E5=85=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tiga Ultraman Change-Id: I6f0dd948e8fd09e9bd9117a0c14980cbeaf468bc --- .../src/util/c_openssl/ffi/x509.rs | 8 +++--- .../src/util/c_openssl/ssl/stream.rs | 12 ++++++-- .../src/util/c_openssl/verify/pinning.rs | 28 ++++++++++++++----- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/ylong_http_client/src/util/c_openssl/ffi/x509.rs b/ylong_http_client/src/util/c_openssl/ffi/x509.rs index 2f046aa..9936cfd 100644 --- a/ylong_http_client/src/util/c_openssl/ffi/x509.rs +++ b/ylong_http_client/src/util/c_openssl/ffi/x509.rs @@ -36,9 +36,9 @@ extern "C" { pub(crate) fn EVP_DigestFinal_ex( ctx: *mut EVP_MD_CTX, - buf: *const c_uchar, - start: *const c_uint, - ); + buf: *mut c_uchar, + out_len: *mut c_uint, + ) -> c_int; } pub(crate) enum C_X509 {} @@ -149,5 +149,5 @@ extern "C" { pub(crate) fn X509_PUBKEY_free(x509: *mut X509_PUBKEY); - pub(crate) fn i2d_X509_PUBKEY(pubkey: *const X509_PUBKEY, buf: *mut *const c_uchar) -> c_int; + pub(crate) fn i2d_X509_PUBKEY(pubkey: *const X509_PUBKEY, buf: *mut *mut c_uchar) -> c_int; } diff --git a/ylong_http_client/src/util/c_openssl/ssl/stream.rs b/ylong_http_client/src/util/c_openssl/ssl/stream.rs index 01a7dc7..c0703c1 100644 --- a/ylong_http_client/src/util/c_openssl/ssl/stream.rs +++ b/ylong_http_client/src/util/c_openssl/ssl/stream.rs @@ -305,6 +305,13 @@ pub(crate) fn verify_server_cert(ssl: *const SSL, pinned_key: &str) -> Result<() fn verify_pinned_pubkey(pinned_key: &str, certificate: *mut C_X509) -> Result<(), SslError> { let pubkey = unsafe { X509_get_X509_PUBKEY(certificate) }; + if pubkey.is_null() { + unsafe { X509_free(certificate) }; + return Err(SslError { + code: SslErrorCode::SSL, + internal: Some(InternalError::Ssl(ErrorStack::get())), + }); + } // Get the length of the serialized data let buf_size = unsafe { i2d_X509_PUBKEY(pubkey, ptr::null_mut()) }; @@ -315,9 +322,10 @@ fn verify_pinned_pubkey(pinned_key: &str, certificate: *mut C_X509) -> Result<() internal: Some(InternalError::Ssl(ErrorStack::get())), }); } - let key = vec![0u8; buf_size as usize]; + let mut key = vec![0u8; buf_size as usize]; + let mut key_ptr = key.as_mut_ptr(); // The actual serialization - let serialized_data_size = unsafe { i2d_X509_PUBKEY(pubkey, &mut key.as_ptr()) }; + let serialized_data_size = unsafe { i2d_X509_PUBKEY(pubkey, &mut key_ptr) }; if buf_size != serialized_data_size || serialized_data_size <= 0 { unsafe { X509_free(certificate) }; diff --git a/ylong_http_client/src/util/c_openssl/verify/pinning.rs b/ylong_http_client/src/util/c_openssl/verify/pinning.rs index 2b4984a..1a4315c 100644 --- a/ylong_http_client/src/util/c_openssl/verify/pinning.rs +++ b/ylong_http_client/src/util/c_openssl/verify/pinning.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; -use libc::c_int; +use libc::{c_int, c_uint}; use ylong_http::request::uri::Uri; use crate::util::c_openssl::error::ErrorStack; @@ -25,6 +25,9 @@ use crate::util::c_openssl::ssl::{InternalError, SslError, SslErrorCode}; use crate::ErrorKind::Build; use crate::HttpClientError; +/// OpenSSL EVP digest functions convention: 1 for success, 0 for failure. +const EVP_DIGEST_SUCCESS: c_int = 1; + /// A structure that serves Certificate and Public Key Pinning. /// The map key is server authority(host:port), value is Base64(sha256(Server's /// Public Key)). @@ -248,21 +251,32 @@ pub(crate) unsafe fn sha256_digest( internal: Some(InternalError::Ssl(ErrorStack::get())), }); } - let init = EVP_DigestInit(md_ctx, EVP_sha256()); - if init == 0 { + if EVP_DigestInit(md_ctx, EVP_sha256()) != EVP_DIGEST_SUCCESS { + EVP_MD_CTX_free(md_ctx); + return Err(SslError { + code: SslErrorCode::SSL, + internal: Some(InternalError::Ssl(ErrorStack::get())), + }); + } + if EVP_DigestUpdate(md_ctx, pub_key.as_ptr(), len) != EVP_DIGEST_SUCCESS { EVP_MD_CTX_free(md_ctx); return Err(SslError { code: SslErrorCode::SSL, internal: Some(InternalError::Ssl(ErrorStack::get())), }); } - EVP_DigestUpdate(md_ctx, pub_key.as_ptr(), len); - - let start = 0; - EVP_DigestFinal_ex(md_ctx, digest.as_mut_ptr(), &start); + let mut out_len: c_uint = 0; + let final_ret = EVP_DigestFinal_ex(md_ctx, digest.as_mut_ptr(), &mut out_len); EVP_MD_CTX_free(md_ctx); + if final_ret != EVP_DIGEST_SUCCESS { + return Err(SslError { + code: SslErrorCode::SSL, + internal: Some(InternalError::Ssl(ErrorStack::get())), + }); + } + Ok(()) }