Merge pull request #3163 from afpro/main

android SSL support system certs
This commit is contained in:
Jeong YunWon
2021-09-30 02:03:37 +09:00
committed by GitHub

View File

@@ -283,6 +283,9 @@ impl SlotConstructor for PySslContext {
let mut builder =
SslContextBuilder::new(method).map_err(|e| convert_openssl_error(vm, e))?;
#[cfg(target_os = "android")]
android::load_client_ca_list(vm, &mut builder)?;
let check_hostname = proto == SslVersion::TlsClient;
builder.set_verify(if check_hostname {
SslVerifyMode::PEER | SslVerifyMode::FAIL_IF_NO_PEER_CERT
@@ -1252,3 +1255,66 @@ impl Write for SocketStream {
socket.flush()
}
}
#[cfg(target_os = "android")]
mod android {
use crate::{
exceptions::PyBaseExceptionRef, stdlib::ssl::convert_openssl_error, VirtualMachine,
};
use openssl::{
ssl::SslContextBuilder,
x509::{store::X509StoreBuilder, X509},
};
use std::{
fs::{read_dir, File},
io::Read,
path::Path,
};
static CERT_DIR: &'static str = "/system/etc/security/cacerts";
pub(super) fn load_client_ca_list(
vm: &VirtualMachine,
b: &mut SslContextBuilder,
) -> Result<(), PyBaseExceptionRef> {
let root = Path::new(CERT_DIR);
if !root.is_dir() {
return Err(vm.new_exception_msg(
vm.ctx.exceptions.file_not_found_error.clone(),
CERT_DIR.to_string(),
));
}
let mut combined_pem = String::new();
let entries =
read_dir(root).map_err(|err| vm.new_os_error(format!("read cert root: {}", err)))?;
for entry in entries {
let entry = entry.map_err(|err| vm.new_os_error(format!("iter cert root: {}", err)))?;
let path = entry.path();
if !path.is_file() {
continue;
}
File::open(&path)
.and_then(|mut file| file.read_to_string(&mut combined_pem))
.map_err(|err| {
vm.new_os_error(format!("open cert file {}: {}", path.display(), err))
})?;
combined_pem.push('\n');
}
let mut store_b = X509StoreBuilder::new().map_err(|err| convert_openssl_error(vm, err))?;
let x509_vec = X509::stack_from_pem(combined_pem.as_bytes())
.map_err(|err| convert_openssl_error(vm, err))?;
for x509 in x509_vec {
store_b
.add_cert(x509)
.map_err(|err| convert_openssl_error(vm, err))?;
}
b.set_cert_store(store_b.build());
Ok(())
}
}