Skip to content

Commit

Permalink
Merge pull request #1893 from reaperhulk/asn1octetstring
Browse files Browse the repository at this point in the history
add asn1octetstring creation support
  • Loading branch information
alex committed Apr 20, 2023
2 parents a882c69 + 2ac0d83 commit e59ab31
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
6 changes: 6 additions & 0 deletions openssl-sys/src/handwritten/asn1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,15 @@ extern "C" {
#[cfg(any(all(ossl101, not(ossl110)), libressl))]
pub fn ASN1_STRING_data(x: *mut ASN1_STRING) -> *mut c_uchar;
pub fn ASN1_STRING_new() -> *mut ASN1_STRING;
pub fn ASN1_OCTET_STRING_new() -> *mut ASN1_OCTET_STRING;
pub fn ASN1_STRING_free(x: *mut ASN1_STRING);
pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int;
pub fn ASN1_STRING_set(x: *mut ASN1_STRING, data: *const c_void, len_in: c_int) -> c_int;
pub fn ASN1_OCTET_STRING_set(
x: *mut ASN1_OCTET_STRING,
data: *const c_uchar,
len_in: c_int,
) -> c_int;

pub fn ASN1_BIT_STRING_free(x: *mut ASN1_BIT_STRING);
pub fn ASN1_OCTET_STRING_free(x: *mut ASN1_OCTET_STRING);
Expand Down
48 changes: 48 additions & 0 deletions openssl/src/asn1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_char, c_int, c_long, time_t};
use std::cmp::Ordering;
use std::convert::TryInto;
use std::ffi::CString;
use std::fmt;
use std::ptr;
Expand Down Expand Up @@ -611,6 +612,46 @@ impl Asn1BitStringRef {
}
}

foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_OCTET_STRING;
fn drop = ffi::ASN1_OCTET_STRING_free;
/// ASN.1 OCTET STRING type
pub struct Asn1OctetString;
/// A reference to an [`Asn1OctetString`].
pub struct Asn1OctetStringRef;
}

impl Asn1OctetString {
/// Creates an Asn1OctetString from bytes
pub fn new_from_bytes(value: &[u8]) -> Result<Self, ErrorStack> {
ffi::init();
unsafe {
let s = cvt_p(ffi::ASN1_OCTET_STRING_new())?;
ffi::ASN1_OCTET_STRING_set(s, value.as_ptr(), value.len().try_into().unwrap());
Ok(Self::from_ptr(s))
}
}
}

impl Asn1OctetStringRef {
/// Returns the octet string as an array of bytes.
#[corresponds(ASN1_STRING_get0_data)]
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr().cast()), self.len()) }
}

/// Returns the number of bytes in the octet string.
#[corresponds(ASN1_STRING_length)]
pub fn len(&self) -> usize {
unsafe { ffi::ASN1_STRING_length(self.as_ptr().cast()) as usize }
}

/// Determines if the string is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}

foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_OBJECT;
fn drop = ffi::ASN1_OBJECT_free;
Expand Down Expand Up @@ -859,4 +900,11 @@ mod tests {
&[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01],
);
}

#[test]
fn asn1_octet_string() {
let octet_string = Asn1OctetString::new_from_bytes(b"hello world").unwrap();
assert_eq!(octet_string.as_slice(), b"hello world");
assert_eq!(octet_string.len(), 11);
}
}

0 comments on commit e59ab31

Please sign in to comment.