Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x509 verify params + safety fixes #297

Merged
merged 3 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions boring/src/aes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
//!
use crate::ffi;
use libc::{c_int, c_uint, size_t};
use openssl_macros::corresponds;
use std::mem::MaybeUninit;
use std::ptr;

Expand All @@ -55,7 +56,7 @@ impl AesKey {
/// # Failure
///
/// Returns an error if the key is not 128, 192, or 256 bits.
#[allow(deprecated)] // https://github.com/rust-lang/rust/issues/63566
#[corresponds(AES_set_encrypt_key)]
pub fn new_encrypt(key: &[u8]) -> Result<AesKey, KeyError> {
unsafe {
assert!(key.len() <= c_int::MAX as usize / 8);
Expand All @@ -79,7 +80,7 @@ impl AesKey {
/// # Failure
///
/// Returns an error if the key is not 128, 192, or 256 bits.
#[allow(deprecated)] // https://github.com/rust-lang/rust/issues/63566
#[corresponds(AES_set_decrypt_key)]
pub fn new_decrypt(key: &[u8]) -> Result<AesKey, KeyError> {
unsafe {
assert!(key.len() <= c_int::MAX as usize / 8);
Expand Down Expand Up @@ -113,6 +114,7 @@ impl AesKey {
///
/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or if
/// `out` is not 8 bytes longer than `in_`
#[corresponds(AES_wrap_key)]
pub fn wrap_key(
key: &AesKey,
iv: Option<[u8; 8]>,
Expand Down Expand Up @@ -151,6 +153,7 @@ pub fn wrap_key(
///
/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or
/// if `in_` is not 8 bytes longer than `out`
#[corresponds(AES_unwrap_key)]
pub fn unwrap_key(
key: &AesKey,
iv: Option<[u8; 8]>,
Expand Down
43 changes: 16 additions & 27 deletions boring/src/asn1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use crate::nid::Nid;
use crate::stack::Stackable;
use crate::string::OpensslString;
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;

foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_GENERALIZEDTIME;
Expand Down Expand Up @@ -187,10 +188,7 @@ foreign_type_and_impl_send_sync! {

impl Asn1TimeRef {
/// Find difference between two times
///
/// This corresponds to [`ASN1_TIME_diff`].
///
/// [`ASN1_TIME_diff`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_TIME_diff.html
#[corresponds(ASN1_TIME_diff)]
pub fn diff(&self, compare: &Self) -> Result<TimeDiff, ErrorStack> {
let mut days = 0;
let mut secs = 0;
Expand All @@ -205,12 +203,7 @@ impl Asn1TimeRef {
}

/// Compare two times
///
/// This corresponds to [`ASN1_TIME_compare`] but is implemented using [`diff`] so that it is
/// also supported on older versions of OpenSSL.
///
/// [`ASN1_TIME_compare`]: https://www.openssl.org/docs/man1.1.1/man3/ASN1_TIME_compare.html
/// [`diff`]: struct.Asn1TimeRef.html#method.diff
#[corresponds(ASN1_TIME_compare)]
pub fn compare(&self, other: &Self) -> Result<Ordering, ErrorStack> {
let d = self.diff(other)?;
if d.days > 0 || d.secs > 0 {
Expand Down Expand Up @@ -289,6 +282,7 @@ impl fmt::Debug for Asn1TimeRef {
}

impl Asn1Time {
#[corresponds(ASN1_TIME_new)]
fn new() -> Result<Asn1Time, ErrorStack> {
ffi::init();

Expand All @@ -298,6 +292,7 @@ impl Asn1Time {
}
}

#[corresponds(X509_gmtime_adj)]
fn from_period(period: c_long) -> Result<Asn1Time, ErrorStack> {
ffi::init();

Expand All @@ -313,6 +308,7 @@ impl Asn1Time {
}

/// Creates a new time from the specified `time_t` value
#[corresponds(ASN1_TIME_set)]
pub fn from_unix(time: time_t) -> Result<Asn1Time, ErrorStack> {
ffi::init();

Expand All @@ -323,10 +319,7 @@ impl Asn1Time {
}

/// Creates a new time corresponding to the specified ASN1 time string.
///
/// This corresponds to [`ASN1_TIME_set_string`].
///
/// [`ASN1_TIME_set_string`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html
#[corresponds(ASN1_TIME_set_string)]
#[allow(clippy::should_implement_trait)]
pub fn from_str(s: &str) -> Result<Asn1Time, ErrorStack> {
unsafe {
Expand Down Expand Up @@ -401,6 +394,7 @@ impl Asn1StringRef {
/// ASN.1 strings may utilize UTF-16, ASCII, BMP, or UTF8. This is important to
/// consume the string in a meaningful way without knowing the underlying
/// format.
#[corresponds(ASN1_STRING_to_UTF8)]
pub fn as_utf8(&self) -> Result<OpensslString, ErrorStack> {
unsafe {
let mut ptr = ptr::null_mut();
Expand All @@ -419,11 +413,13 @@ impl Asn1StringRef {
/// strings in rust, it is preferable to use [`as_utf8`]
///
/// [`as_utf8`]: struct.Asn1String.html#method.as_utf8
#[corresponds(ASN1_STRING_get0_data)]
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) }
}

/// Returns the number of bytes in the string.
#[corresponds(ASN1_STRING_length)]
pub fn len(&self) -> usize {
unsafe { ffi::ASN1_STRING_length(self.as_ptr()) as usize }
}
Expand Down Expand Up @@ -481,10 +477,7 @@ impl Asn1IntegerRef {
}

/// Converts the integer to a `BigNum`.
///
/// This corresponds to [`ASN1_INTEGER_to_BN`].
///
/// [`ASN1_INTEGER_to_BN`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_get.html
#[corresponds(ASN1_INTEGER_to_BN)]
pub fn to_bn(&self) -> Result<BigNum, ErrorStack> {
unsafe {
cvt_p(crate::ffi::ASN1_INTEGER_to_BN(
Expand All @@ -498,10 +491,8 @@ impl Asn1IntegerRef {
/// Sets the ASN.1 value to the value of a signed 32-bit integer, for larger numbers
/// see [`bn`].
///
/// OpenSSL documentation at [`ASN1_INTEGER_set`]
///
/// [`bn`]: ../bn/struct.BigNumRef.html#method.to_asn1_integer
/// [`ASN1_INTEGER_set`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_set.html
#[corresponds(ASN1_INTEGER_set)]
pub fn set(&mut self, value: i32) -> Result<(), ErrorStack> {
unsafe { cvt(crate::ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ()) }
}
Expand All @@ -521,11 +512,13 @@ foreign_type_and_impl_send_sync! {

impl Asn1BitStringRef {
/// Returns the Asn1BitString as a slice.
#[corresponds(ASN1_STRING_get0_data)]
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) }
}

/// Returns the number of bytes in the string.
#[corresponds(ASN1_STRING_length)]
pub fn len(&self) -> usize {
unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize }
}
Expand Down Expand Up @@ -561,12 +554,8 @@ impl Stackable for Asn1Object {
}

impl Asn1Object {
/// Constructs an ASN.1 Object Identifier from a string representation of
/// the OID.
///
/// This corresponds to [`OBJ_txt2obj`].
///
/// [`OBJ_txt2obj`]: https://www.openssl.org/docs/man1.1.0/man3/OBJ_txt2obj.html
/// Constructs an ASN.1 Object Identifier from a string representation of the OID.
#[corresponds(OBJ_txt2obj)]
#[allow(clippy::should_implement_trait)]
pub fn from_str(txt: &str) -> Result<Asn1Object, ErrorStack> {
unsafe {
Expand Down
11 changes: 3 additions & 8 deletions boring/src/base64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ use crate::cvt_n;
use crate::error::ErrorStack;
use crate::ffi;
use libc::c_int;
use openssl_macros::corresponds;

/// Encodes a slice of bytes to a base64 string.
///
/// This corresponds to [`EVP_EncodeBlock`].
///
/// # Panics
///
/// Panics if the input length or computed output length overflow a signed C integer.
///
/// [`EVP_EncodeBlock`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DecodeBlock.html
#[corresponds(EVP_EncodeBlock)]
pub fn encode_block(src: &[u8]) -> String {
assert!(src.len() <= c_int::MAX as usize);
let src_len = src.len();
Expand All @@ -33,13 +31,10 @@ pub fn encode_block(src: &[u8]) -> String {

/// Decodes a base64-encoded string to bytes.
///
/// This corresponds to [`EVP_DecodeBlock`].
///
/// # Panics
///
/// Panics if the input length or computed output length overflow a signed C integer.
///
/// [`EVP_DecodeBlock`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DecodeBlock.html
#[corresponds(EVP_DecodeBlock)]
pub fn decode_block(src: &str) -> Result<Vec<u8>, ErrorStack> {
let src = src.trim();

Expand Down
Loading
Loading