Skip to content

Commit 550d539

Browse files
Jakujeueno
authored andcommitted
Add internal module to simplify working with OSSL_PARAM structure
We discussed that this API is not well suitable for the end users but still, it required for several operations in OpenSSL 3.* so instead of calling to FFI for every use of this API, this introduces simple wrappers that allow building of the params and their usage. Signed-off-by: Jakub Jelen <[email protected]>
1 parent e6209d4 commit 550d539

File tree

8 files changed

+248
-4
lines changed

8 files changed

+248
-4
lines changed

openssl-sys/build/run_bindgen.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ const INCLUDES: &str = "
5858
#endif
5959
6060
#if OPENSSL_VERSION_NUMBER >= 0x30000000
61+
#include <openssl/param_build.h>
6162
#include <openssl/provider.h>
6263
#endif
6364

openssl-sys/src/handwritten/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ pub use self::hmac::*;
1515
pub use self::kdf::*;
1616
pub use self::object::*;
1717
pub use self::ocsp::*;
18+
#[cfg(ossl300)]
19+
pub use self::param_build::*;
20+
#[cfg(ossl300)]
1821
pub use self::params::*;
1922
pub use self::pem::*;
2023
pub use self::pkcs12::*;
@@ -54,6 +57,9 @@ mod hmac;
5457
mod kdf;
5558
mod object;
5659
mod ocsp;
60+
#[cfg(ossl300)]
61+
mod param_build;
62+
#[cfg(ossl300)]
5763
mod params;
5864
mod pem;
5965
mod pkcs12;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use super::super::*;
2+
use libc::*;
3+
4+
/* OpenSSL 3.* only */
5+
6+
extern "C" {
7+
pub fn OSSL_PARAM_BLD_new() -> *mut OSSL_PARAM_BLD;
8+
pub fn OSSL_PARAM_BLD_free(bld: *mut OSSL_PARAM_BLD);
9+
pub fn OSSL_PARAM_BLD_push_BN(
10+
bld: *mut OSSL_PARAM_BLD,
11+
key: *const c_char,
12+
bn: *const BIGNUM,
13+
) -> c_int;
14+
pub fn OSSL_PARAM_BLD_push_utf8_string(
15+
bld: *mut OSSL_PARAM_BLD,
16+
key: *const c_char,
17+
buf: *const c_char,
18+
bsize: usize,
19+
) -> c_int;
20+
pub fn OSSL_PARAM_BLD_push_octet_string(
21+
bld: *mut OSSL_PARAM_BLD,
22+
key: *const c_char,
23+
buf: *const c_void,
24+
bsize: usize,
25+
) -> c_int;
26+
pub fn OSSL_PARAM_BLD_push_uint(
27+
bld: *mut OSSL_PARAM_BLD,
28+
key: *const c_char,
29+
buf: c_uint,
30+
) -> c_int;
31+
pub fn OSSL_PARAM_BLD_to_param(bld: *mut OSSL_PARAM_BLD) -> *mut OSSL_PARAM;
32+
}

openssl-sys/src/handwritten/params.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,32 @@ use super::super::*;
22
use libc::*;
33

44
extern "C" {
5-
#[cfg(ossl300)]
5+
pub fn OSSL_PARAM_free(p: *mut OSSL_PARAM);
66
pub fn OSSL_PARAM_construct_uint(key: *const c_char, buf: *mut c_uint) -> OSSL_PARAM;
7-
#[cfg(ossl300)]
87
pub fn OSSL_PARAM_construct_end() -> OSSL_PARAM;
9-
#[cfg(ossl300)]
108
pub fn OSSL_PARAM_construct_octet_string(
119
key: *const c_char,
1210
buf: *mut c_void,
1311
bsize: size_t,
1412
) -> OSSL_PARAM;
1513

14+
pub fn OSSL_PARAM_locate(p: *mut OSSL_PARAM, key: *const c_char) -> *mut OSSL_PARAM;
15+
pub fn OSSL_PARAM_get_BN(p: *const OSSL_PARAM, val: *mut *mut BIGNUM) -> c_int;
16+
pub fn OSSL_PARAM_get_utf8_string(
17+
p: *const OSSL_PARAM,
18+
val: *mut *mut c_char,
19+
max_len: usize,
20+
) -> c_int;
21+
pub fn OSSL_PARAM_get_utf8_string_ptr(p: *const OSSL_PARAM, val: *mut *const c_char) -> c_int;
22+
pub fn OSSL_PARAM_get_octet_string(
23+
p: *const OSSL_PARAM,
24+
val: *mut *mut c_void,
25+
max_len: usize,
26+
used_len: *mut usize,
27+
) -> c_int;
28+
pub fn OSSL_PARAM_get_octet_string_ptr(
29+
p: *const OSSL_PARAM,
30+
val: *mut *const c_void,
31+
used_len: *mut usize,
32+
) -> c_int;
1633
}

openssl-sys/src/handwritten/types.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,9 @@ pub struct OSSL_PARAM {
11401140
return_size: size_t,
11411141
}
11421142

1143+
#[cfg(ossl300)]
1144+
pub enum OSSL_PARAM_BLD {}
1145+
11431146
#[cfg(ossl300)]
11441147
pub enum EVP_KDF {}
11451148
#[cfg(ossl300)]

openssl/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ pub mod memcmp;
177177
pub mod nid;
178178
#[cfg(not(osslconf = "OPENSSL_NO_OCSP"))]
179179
pub mod ocsp;
180+
#[cfg(ossl300)]
181+
mod ossl_param;
180182
pub mod pkcs12;
181183
pub mod pkcs5;
182184
#[cfg(not(any(boringssl, awslc)))]

openssl/src/ossl_param.rs

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
//! OSSL_PARAM management for OpenSSL 3.*
2+
//!
3+
//! The OSSL_PARAM structure represents generic attribute that can represent various
4+
//! properties in OpenSSL, including keys and operations.
5+
//!
6+
//! For convinience, the OSSL_PARAM_BLD builder can be used to dynamically construct
7+
//! these structure.
8+
//!
9+
//! Note, that this module is available only in OpenSSL 3.* and
10+
//! only internally for this crate!
11+
//!
12+
use crate::bn::{BigNum, BigNumRef};
13+
use crate::error::ErrorStack;
14+
use crate::util;
15+
use crate::{cvt, cvt_p};
16+
use foreign_types::{ForeignType, ForeignTypeRef};
17+
use libc::{c_char, c_uint, c_void};
18+
use openssl_macros::corresponds;
19+
use std::ffi::CStr;
20+
use std::ptr;
21+
22+
foreign_type_and_impl_send_sync! {
23+
type CType = ffi::OSSL_PARAM;
24+
fn drop = ffi::OSSL_PARAM_free;
25+
26+
/// `OsslParam` constructed using `OsslParamBuilder`.
27+
pub struct OsslParam;
28+
/// Reference to `OsslParam`.
29+
pub struct OsslParamRef;
30+
}
31+
32+
impl OsslParam {}
33+
34+
impl OsslParamRef {
35+
/// Locates the `OsslParam` in the `OsslParam` array
36+
#[corresponds(OSSL_PARAM_locate)]
37+
pub fn locate(&self, key: &[u8]) -> Result<&OsslParamRef, ErrorStack> {
38+
unsafe {
39+
let param = cvt_p(ffi::OSSL_PARAM_locate(
40+
self.as_ptr(),
41+
key.as_ptr() as *const c_char,
42+
))?;
43+
Ok(OsslParamRef::from_ptr(param))
44+
}
45+
}
46+
47+
/// Get `BigNum` from the current `OsslParam`
48+
#[allow(dead_code)]
49+
#[corresponds(OSSL_PARAM_get_BN)]
50+
pub fn get_bn(&self) -> Result<BigNum, ErrorStack> {
51+
unsafe {
52+
let mut bn: *mut ffi::BIGNUM = ptr::null_mut();
53+
cvt(ffi::OSSL_PARAM_get_BN(self.as_ptr(), &mut bn))?;
54+
Ok(BigNum::from_ptr(bn))
55+
}
56+
}
57+
58+
/// Get `&str` from the current `OsslParam`
59+
#[allow(dead_code)]
60+
#[corresponds(OSSL_PARAM_get_utf8_string)]
61+
pub fn get_utf8_string(&self) -> Result<&str, ErrorStack> {
62+
unsafe {
63+
let mut val: *const c_char = ptr::null_mut();
64+
cvt(ffi::OSSL_PARAM_get_utf8_string_ptr(self.as_ptr(), &mut val))?;
65+
Ok(CStr::from_ptr(val).to_str().unwrap())
66+
}
67+
}
68+
69+
/// Get octet string (as `&[u8]) from the current `OsslParam`
70+
#[corresponds(OSSL_PARAM_get_octet_string)]
71+
pub fn get_octet_string(&self) -> Result<&[u8], ErrorStack> {
72+
unsafe {
73+
let mut val: *const c_void = ptr::null_mut();
74+
let mut val_len: usize = 0;
75+
cvt(ffi::OSSL_PARAM_get_octet_string_ptr(
76+
self.as_ptr(),
77+
&mut val,
78+
&mut val_len,
79+
))?;
80+
Ok(util::from_raw_parts(val as *const u8, val_len))
81+
}
82+
}
83+
}
84+
85+
foreign_type_and_impl_send_sync! {
86+
type CType = ffi::OSSL_PARAM_BLD;
87+
fn drop = ffi::OSSL_PARAM_BLD_free;
88+
89+
/// Builder used to construct `OsslParam`.
90+
pub struct OsslParamBuilder;
91+
/// Reference to `OsslParamBuilder`.
92+
pub struct OsslParamBuilderRef;
93+
}
94+
95+
impl OsslParamBuilder {
96+
/// Returns a builder for a OsslParam arrays.
97+
///
98+
/// The array is initially empty.
99+
#[corresponds(OSSL_PARAM_BLD_new)]
100+
pub fn new() -> Result<OsslParamBuilder, ErrorStack> {
101+
unsafe {
102+
ffi::init();
103+
104+
cvt_p(ffi::OSSL_PARAM_BLD_new()).map(OsslParamBuilder)
105+
}
106+
}
107+
108+
/// Constructs the `OsslParam`.
109+
#[corresponds(OSSL_PARAM_BLD_to_param)]
110+
pub fn to_param(&self) -> Result<OsslParam, ErrorStack> {
111+
unsafe {
112+
let params = cvt_p(ffi::OSSL_PARAM_BLD_to_param(self.0))?;
113+
Ok(OsslParam::from_ptr(params))
114+
}
115+
}
116+
}
117+
118+
impl OsslParamBuilderRef {
119+
/// Adds a `BigNum` to `OsslParamBuilder`.
120+
///
121+
/// Note, that both key and bn need to exist until the `to_param` is called!
122+
#[allow(dead_code)]
123+
#[corresponds(OSSL_PARAM_BLD_push_BN)]
124+
pub fn add_bn(&self, key: &[u8], bn: &BigNumRef) -> Result<(), ErrorStack> {
125+
unsafe {
126+
cvt(ffi::OSSL_PARAM_BLD_push_BN(
127+
self.as_ptr(),
128+
key.as_ptr() as *const c_char,
129+
bn.as_ptr(),
130+
))
131+
.map(|_| ())
132+
}
133+
}
134+
135+
/// Adds a utf8 string to `OsslParamBuilder`.
136+
///
137+
/// Note, that both `key` and `buf` need to exist until the `to_param` is called!
138+
#[allow(dead_code)]
139+
#[corresponds(OSSL_PARAM_BLD_push_utf8_string)]
140+
pub fn add_utf8_string(&self, key: &[u8], buf: &str) -> Result<(), ErrorStack> {
141+
unsafe {
142+
cvt(ffi::OSSL_PARAM_BLD_push_utf8_string(
143+
self.as_ptr(),
144+
key.as_ptr() as *const c_char,
145+
buf.as_ptr() as *const c_char,
146+
buf.len(),
147+
))
148+
.map(|_| ())
149+
}
150+
}
151+
152+
/// Adds a octet string to `OsslParamBuilder`.
153+
///
154+
/// Note, that both `key` and `buf` need to exist until the `to_param` is called!
155+
#[corresponds(OSSL_PARAM_BLD_push_octet_string)]
156+
pub fn add_octet_string(&self, key: &[u8], buf: &[u8]) -> Result<(), ErrorStack> {
157+
unsafe {
158+
cvt(ffi::OSSL_PARAM_BLD_push_octet_string(
159+
self.as_ptr(),
160+
key.as_ptr() as *const c_char,
161+
buf.as_ptr() as *const c_void,
162+
buf.len(),
163+
))
164+
.map(|_| ())
165+
}
166+
}
167+
168+
/// Adds a unsigned int to `OsslParamBuilder`.
169+
///
170+
/// Note, that both `key` and `buf` need to exist until the `to_param` is called!
171+
#[corresponds(OSSL_PARAM_BLD_push_uint)]
172+
pub fn add_uint(&self, key: &[u8], val: u32) -> Result<(), ErrorStack> {
173+
unsafe {
174+
cvt(ffi::OSSL_PARAM_BLD_push_uint(
175+
self.as_ptr(),
176+
key.as_ptr() as *const c_char,
177+
val as c_uint,
178+
))
179+
.map(|_| ())
180+
}
181+
}
182+
}

systest/build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ fn main() {
8383
}
8484

8585
if version >= 0x30000000 {
86-
cfg.header("openssl/provider.h");
86+
cfg.header("openssl/provider.h")
87+
.header("openssl/param_build.h");
8788
}
8889
if version >= 0x30200000 {
8990
cfg.header("openssl/thread.h");

0 commit comments

Comments
 (0)