!225 merge bugfix into master

修复证书校验安全问题

Created-by: tiga-ultraman
Commit-by: Tiga Ultraman
Merged-by: openharmony_ci
Description: ### 一、内容说明(相关的Issue)
修复证书校验安全问题
![image.png](https://raw.gitcode.com/user-images/assets/4379787/eb82abae-3e4e-4965-8883-7f31feba131e/image.png 'image.png')

### 二、建议测试周期和提测地址  
  建议测试完成时间:xxxx.xx.xx  
  投产上线时间:xxxx.xx.xx  
  提测地址:CI环境/压测环境  
  测试账号:  

### 三、变更内容
  * 3.1 关联PR列表

  * 3.2 数据库和部署说明  
    1. 常规更新 
    2. 重启unicorn
    3. 重启sidekiq
    4. 迁移任务:是否有迁移任务,没有写 "无"
    5. rake脚本:`bundle exec xxx RAILS_ENV = production`;没有写 "无"

  * 3.4 其他技术优化内容(做了什么,变更了什么)
    - 重构了 xxxx 代码
    - xxxx 算法优化


  * 3.5 废弃通知(什么字段、方法弃用?)



  * 3.6  后向不兼容变更(是否有无法向后兼容的变更?)


  
### 四、研发自测点(自测哪些?冒烟用例全部自测?)
  自测测试结论:


### 五、测试关注点(需要提醒QA重点关注的、可能会忽略的地方)
  检查点:

| 需求名称 | 是否影响xx公共模块 | 是否需要xx功能 | 需求升级是否依赖其他子产品 |
|------|------------|----------|---------------|
| xxx  | 否          | 需要       | 不需要           |
|      |            |          |               |

  接口测试:

  性能测试:

  并发测试:

  其他:



See merge request: openharmony/commonlibrary_rust_ylong_http!225
This commit is contained in:
openharmony_ci
2026-06-05 16:03:43 +08:00
3 changed files with 35 additions and 13 deletions
@@ -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;
}
@@ -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) };
@@ -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(())
}