CStr UTF-8 improvements
This commit is contained in:
parent
330bf825d4
commit
79338a99ea
|
|
@ -63,20 +63,19 @@ foreign_type_and_impl_send_sync! {
|
||||||
|
|
||||||
impl fmt::Display for Asn1GeneralizedTimeRef {
|
impl fmt::Display for Asn1GeneralizedTimeRef {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
unsafe {
|
let bio = MemBio::new().ok();
|
||||||
let mem_bio = match MemBio::new() {
|
let msg = bio
|
||||||
Err(_) => return f.write_str("error"),
|
.as_ref()
|
||||||
Ok(m) => m,
|
.and_then(|mem_bio| unsafe {
|
||||||
};
|
cvt(ffi::ASN1_GENERALIZEDTIME_print(
|
||||||
let print_result = cvt(ffi::ASN1_GENERALIZEDTIME_print(
|
|
||||||
mem_bio.as_ptr(),
|
mem_bio.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
));
|
))
|
||||||
match print_result {
|
.ok()?;
|
||||||
Err(_) => f.write_str("error"),
|
str::from_utf8(mem_bio.get_buf()).ok()
|
||||||
Ok(_) => f.write_str(str::from_utf8_unchecked(mem_bio.get_buf())),
|
})
|
||||||
}
|
.unwrap_or("error");
|
||||||
}
|
f.write_str(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -528,7 +527,20 @@ impl Asn1BitStringRef {
|
||||||
#[corresponds(ASN1_STRING_get0_data)]
|
#[corresponds(ASN1_STRING_get0_data)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) }
|
unsafe {
|
||||||
|
let ptr = ASN1_STRING_get0_data(self.as_ptr().cast());
|
||||||
|
if ptr.is_null() {
|
||||||
|
return &[];
|
||||||
|
}
|
||||||
|
slice::from_raw_parts(ptr, self.len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the Asn1BitString as a str, if possible.
|
||||||
|
#[corresponds(ASN1_STRING_get0_data)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn to_str(&self) -> Option<&str> {
|
||||||
|
str::from_utf8(self.as_slice()).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of bytes in the string.
|
/// Returns the number of bytes in the string.
|
||||||
|
|
@ -601,10 +613,11 @@ impl fmt::Display for Asn1ObjectRef {
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
match str::from_utf8(&buf[..len as usize]) {
|
fmt.write_str(
|
||||||
Err(_) => fmt.write_str("error"),
|
buf.get(..len as usize)
|
||||||
Ok(s) => fmt.write_str(s),
|
.and_then(|s| str::from_utf8(s).ok())
|
||||||
}
|
.unwrap_or("error"),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,10 @@ impl MemBio {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ptr = ptr::null_mut();
|
let mut ptr = ptr::null_mut();
|
||||||
let len = ffi::BIO_get_mem_data(self.0, &mut ptr);
|
let len = ffi::BIO_get_mem_data(self.0, &mut ptr);
|
||||||
slice::from_raw_parts(ptr as *const _ as *const _, len as usize)
|
if ptr.is_null() {
|
||||||
|
return &[];
|
||||||
|
}
|
||||||
|
slice::from_raw_parts(ptr.cast_const().cast(), len as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,9 +146,9 @@ impl Error {
|
||||||
// The memory referenced by data is only valid until that slot is overwritten
|
// The memory referenced by data is only valid until that slot is overwritten
|
||||||
// in the error stack, so we'll need to copy it off if it's dynamic
|
// in the error stack, so we'll need to copy it off if it's dynamic
|
||||||
let data = if flags & ffi::ERR_FLAG_STRING != 0 {
|
let data = if flags & ffi::ERR_FLAG_STRING != 0 {
|
||||||
let bytes = CStr::from_ptr(data as *const _).to_bytes();
|
Some(Cow::Owned(
|
||||||
let data = String::from_utf8_lossy(bytes).into_owned();
|
CStr::from_ptr(data.cast()).to_string_lossy().into_owned(),
|
||||||
Some(data.into())
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
@ -214,8 +214,10 @@ impl Error {
|
||||||
if cstr.is_null() {
|
if cstr.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
CStr::from_ptr(cstr.cast())
|
||||||
str::from_utf8(bytes).ok()
|
.to_str()
|
||||||
|
.ok()
|
||||||
|
.filter(|&msg| msg != "unknown library")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,8 +242,7 @@ impl Error {
|
||||||
if cstr.is_null() {
|
if cstr.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
CStr::from_ptr(cstr.cast()).to_str().ok()
|
||||||
str::from_utf8(bytes).ok()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -263,8 +264,9 @@ impl Error {
|
||||||
if self.file.is_null() {
|
if self.file.is_null() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
let bytes = CStr::from_ptr(self.file as *const _).to_bytes();
|
CStr::from_ptr(self.file.cast())
|
||||||
str::from_utf8(bytes).unwrap_or_default()
|
.to_str()
|
||||||
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,9 @@ impl Nid {
|
||||||
pub fn long_name(&self) -> Result<&'static str, ErrorStack> {
|
pub fn long_name(&self) -> Result<&'static str, ErrorStack> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let nameptr = cvt_p(ffi::OBJ_nid2ln(self.0) as *mut c_char)?;
|
let nameptr = cvt_p(ffi::OBJ_nid2ln(self.0) as *mut c_char)?;
|
||||||
str::from_utf8(CStr::from_ptr(nameptr).to_bytes()).map_err(ErrorStack::internal_error)
|
CStr::from_ptr(nameptr)
|
||||||
|
.to_str()
|
||||||
|
.map_err(ErrorStack::internal_error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,7 +100,9 @@ impl Nid {
|
||||||
pub fn short_name(&self) -> Result<&'static str, ErrorStack> {
|
pub fn short_name(&self) -> Result<&'static str, ErrorStack> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let nameptr = cvt_p(ffi::OBJ_nid2sn(self.0) as *mut c_char)?;
|
let nameptr = cvt_p(ffi::OBJ_nid2sn(self.0) as *mut c_char)?;
|
||||||
str::from_utf8(CStr::from_ptr(nameptr).to_bytes()).map_err(ErrorStack::internal_error)
|
CStr::from_ptr(nameptr)
|
||||||
|
.to_str()
|
||||||
|
.map_err(ErrorStack::internal_error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -451,14 +451,14 @@ where
|
||||||
{
|
{
|
||||||
// SAFETY: boring provides valid inputs.
|
// SAFETY: boring provides valid inputs.
|
||||||
let ssl = unsafe { SslRef::from_ptr(ssl as *mut _) };
|
let ssl = unsafe { SslRef::from_ptr(ssl as *mut _) };
|
||||||
let line = unsafe { str::from_utf8_unchecked(CStr::from_ptr(line).to_bytes()) };
|
let line = unsafe { CStr::from_ptr(line).to_string_lossy() };
|
||||||
|
|
||||||
let callback = ssl
|
let callback = ssl
|
||||||
.ssl_context()
|
.ssl_context()
|
||||||
.ex_data(SslContext::cached_ex_index::<F>())
|
.ex_data(SslContext::cached_ex_index::<F>())
|
||||||
.expect("BUG: get session callback missing");
|
.expect("BUG: get session callback missing");
|
||||||
|
|
||||||
callback(ssl, line);
|
callback(ssl, &line);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) unsafe extern "C" fn raw_sign<M>(
|
pub(super) unsafe extern "C" fn raw_sign<M>(
|
||||||
|
|
|
||||||
|
|
@ -2564,7 +2564,7 @@ impl SslCipherRef {
|
||||||
CStr::from_ptr(ptr as *const _)
|
CStr::from_ptr(ptr as *const _)
|
||||||
};
|
};
|
||||||
|
|
||||||
str::from_utf8(version.to_bytes()).unwrap()
|
version.to_str().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of bits used for the cipher.
|
/// Returns the number of bits used for the cipher.
|
||||||
|
|
@ -2590,7 +2590,7 @@ impl SslCipherRef {
|
||||||
// SSL_CIPHER_description requires a buffer of at least 128 bytes.
|
// SSL_CIPHER_description requires a buffer of at least 128 bytes.
|
||||||
let mut buf = [0; 128];
|
let mut buf = [0; 128];
|
||||||
let ptr = ffi::SSL_CIPHER_description(self.as_ptr(), buf.as_mut_ptr(), 128);
|
let ptr = ffi::SSL_CIPHER_description(self.as_ptr(), buf.as_mut_ptr(), 128);
|
||||||
String::from_utf8(CStr::from_ptr(ptr as *const _).to_bytes().to_vec()).unwrap()
|
CStr::from_ptr(ptr.cast()).to_string_lossy().into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3216,6 +3216,8 @@ impl SslRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a short string describing the state of the session.
|
/// Returns a short string describing the state of the session.
|
||||||
|
///
|
||||||
|
/// Returns empty string if the state wasn't valid UTF-8
|
||||||
#[corresponds(SSL_state_string)]
|
#[corresponds(SSL_state_string)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn state_string(&self) -> &'static str {
|
pub fn state_string(&self) -> &'static str {
|
||||||
|
|
@ -3224,10 +3226,12 @@ impl SslRef {
|
||||||
CStr::from_ptr(ptr as *const _)
|
CStr::from_ptr(ptr as *const _)
|
||||||
};
|
};
|
||||||
|
|
||||||
str::from_utf8(state.to_bytes()).unwrap()
|
state.to_str().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a longer string describing the state of the session.
|
/// Returns a longer string describing the state of the session.
|
||||||
|
///
|
||||||
|
/// Returns empty string if the state wasn't valid UTF-8
|
||||||
#[corresponds(SSL_state_string_long)]
|
#[corresponds(SSL_state_string_long)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn state_string_long(&self) -> &'static str {
|
pub fn state_string_long(&self) -> &'static str {
|
||||||
|
|
@ -3236,7 +3240,7 @@ impl SslRef {
|
||||||
CStr::from_ptr(ptr as *const _)
|
CStr::from_ptr(ptr as *const _)
|
||||||
};
|
};
|
||||||
|
|
||||||
str::from_utf8(state.to_bytes()).unwrap()
|
state.to_str().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the host name to be sent to the server for Server Name Indication (SNI).
|
/// Sets the host name to be sent to the server for Server Name Indication (SNI).
|
||||||
|
|
@ -3348,6 +3352,8 @@ impl SslRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a string describing the protocol version of the session.
|
/// Returns a string describing the protocol version of the session.
|
||||||
|
///
|
||||||
|
/// This may panic if the string isn't valid UTF-8 for some reason. Use [`Self::version2`] instead.
|
||||||
#[corresponds(SSL_get_version)]
|
#[corresponds(SSL_get_version)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn version_str(&self) -> &'static str {
|
pub fn version_str(&self) -> &'static str {
|
||||||
|
|
@ -3356,7 +3362,7 @@ impl SslRef {
|
||||||
CStr::from_ptr(ptr as *const _)
|
CStr::from_ptr(ptr as *const _)
|
||||||
};
|
};
|
||||||
|
|
||||||
str::from_utf8(version.to_bytes()).unwrap()
|
version.to_str().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the minimum supported protocol version.
|
/// Sets the minimum supported protocol version.
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ foreign_type_and_impl_send_sync! {
|
||||||
type CType = c_char;
|
type CType = c_char;
|
||||||
fn drop = free;
|
fn drop = free;
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// MUST be UTF-8
|
||||||
pub struct OpensslString;
|
pub struct OpensslString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ use std::mem;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::sync::{LazyLock, Once};
|
use std::sync::{LazyLock, Once};
|
||||||
|
|
||||||
|
|
@ -1535,6 +1534,8 @@ impl X509VerifyError {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a human readable error string from the verification error.
|
/// Return a human readable error string from the verification error.
|
||||||
|
///
|
||||||
|
/// Returns empty string if the message was not UTF-8
|
||||||
#[corresponds(X509_verify_cert_error_string)]
|
#[corresponds(X509_verify_cert_error_string)]
|
||||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
@ -1543,7 +1544,7 @@ impl X509VerifyError {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let s = ffi::X509_verify_cert_error_string(c_long::from(self.0));
|
let s = ffi::X509_verify_cert_error_string(c_long::from(self.0));
|
||||||
str::from_utf8(CStr::from_ptr(s).to_bytes()).unwrap()
|
CStr::from_ptr(s).to_str().unwrap_or_default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1695,14 +1696,12 @@ impl GeneralNameRef {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d.ia5 as *mut _);
|
let asn = Asn1BitStringRef::from_ptr((*self.as_ptr()).d.ia5);
|
||||||
let len = ffi::ASN1_STRING_length((*self.as_ptr()).d.ia5 as *mut _);
|
|
||||||
|
|
||||||
let slice = slice::from_raw_parts(ptr, len as usize);
|
|
||||||
// IA5Strings are stated to be ASCII (specifically IA5). Hopefully
|
// IA5Strings are stated to be ASCII (specifically IA5). Hopefully
|
||||||
// OpenSSL checks that when loading a certificate but if not we'll
|
// OpenSSL checks that when loading a certificate but if not we'll
|
||||||
// use this instead of from_utf8_unchecked just in case.
|
// use this instead of from_utf8_unchecked just in case.
|
||||||
str::from_utf8(slice).ok()
|
asn.to_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1732,10 +1731,7 @@ impl GeneralNameRef {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d.ip as *mut _);
|
Some(Asn1BitStringRef::from_ptr((*self.as_ptr()).d.ip).as_slice())
|
||||||
let len = ffi::ASN1_STRING_length((*self.as_ptr()).d.ip as *mut _);
|
|
||||||
|
|
||||||
Some(slice::from_raw_parts(ptr, len as usize))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1811,8 +1807,8 @@ impl Stackable for X509Object {
|
||||||
use crate::ffi::{X509_get0_signature, X509_getm_notAfter, X509_getm_notBefore, X509_up_ref};
|
use crate::ffi::{X509_get0_signature, X509_getm_notAfter, X509_getm_notBefore, X509_up_ref};
|
||||||
|
|
||||||
use crate::ffi::{
|
use crate::ffi::{
|
||||||
ASN1_STRING_get0_data, X509_ALGOR_get0, X509_REQ_get_subject_name, X509_REQ_get_version,
|
X509_ALGOR_get0, X509_REQ_get_subject_name, X509_REQ_get_version, X509_STORE_CTX_get0_chain,
|
||||||
X509_STORE_CTX_get0_chain, X509_set1_notAfter, X509_set1_notBefore,
|
X509_set1_notAfter, X509_set1_notBefore,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::ffi::X509_OBJECT_get0_X509;
|
use crate::ffi::X509_OBJECT_get0_X509;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue