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 2bf766c..eeff9ec 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(()) }