Skip to content

Commit 72a2574

Browse files
committed
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 82b958c commit 72a2574

File tree

8 files changed

+244
-4
lines changed

8 files changed

+244
-4
lines changed

openssl-sys/build/run_bindgen.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const INCLUDES: &str = "
5353
#endif
5454
5555
#if OPENSSL_VERSION_NUMBER >= 0x30000000
56+
#include <openssl/param_build.h>
5657
#include <openssl/provider.h>
5758
#endif
5859

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(boringssl))]

openssl/src/ossl_param.rs

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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+
#[corresponds(OSSL_PARAM_get_BN)]
49+
pub fn get_bn(&self) -> Result<BigNum, ErrorStack> {
50+
unsafe {
51+
let mut bn: *mut ffi::BIGNUM = ptr::null_mut();
52+
cvt(ffi::OSSL_PARAM_get_BN(self.as_ptr(), &mut bn))?;
53+
Ok(BigNum::from_ptr(bn))
54+
}
55+
}
56+
57+
/// Get `&str` from the current `OsslParam`
58+
#[corresponds(OSSL_PARAM_get_utf8_string)]
59+
pub fn get_utf8_string(&self) -> Result<&str, ErrorStack> {
60+
unsafe {
61+
let mut val: *const c_char = ptr::null_mut();
62+
cvt(ffi::OSSL_PARAM_get_utf8_string_ptr(self.as_ptr(), &mut val))?;
63+
Ok(CStr::from_ptr(val).to_str().unwrap())
64+
}
65+
}
66+
67+
/// Get octet string (as `&[u8]) from the current `OsslParam`
68+
#[corresponds(OSSL_PARAM_get_octet_string)]
69+
pub fn get_octet_string(&self) -> Result<&[u8], ErrorStack> {
70+
unsafe {
71+
let mut val: *const c_void = ptr::null_mut();
72+
let mut val_len: usize = 0;
73+
cvt(ffi::OSSL_PARAM_get_octet_string_ptr(
74+
self.as_ptr(),
75+
&mut val,
76+
&mut val_len,
77+
))?;
78+
Ok(util::from_raw_parts(val as *const u8, val_len))
79+
}
80+
}
81+
}
82+
83+
foreign_type_and_impl_send_sync! {
84+
type CType = ffi::OSSL_PARAM_BLD;
85+
fn drop = ffi::OSSL_PARAM_BLD_free;
86+
87+
/// Builder used to construct `OsslParam`.
88+
pub struct OsslParamBuilder;
89+
/// Reference to `OsslParamBuilder`.
90+
pub struct OsslParamBuilderRef;
91+
}
92+
93+
impl OsslParamBuilder {
94+
/// Returns a builder for a OsslParam arrays.
95+
///
96+
/// The array is initially empty.
97+
#[corresponds(OSSL_PARAM_BLD_new)]
98+
pub fn new() -> Result<OsslParamBuilder, ErrorStack> {
99+
unsafe {
100+
ffi::init();
101+
102+
cvt_p(ffi::OSSL_PARAM_BLD_new()).map(OsslParamBuilder)
103+
}
104+
}
105+
106+
/// Constructs the `OsslParam`.
107+
#[corresponds(OSSL_PARAM_BLD_to_param)]
108+
pub fn to_param(&self) -> Result<OsslParam, ErrorStack> {
109+
unsafe {
110+
let params = cvt_p(ffi::OSSL_PARAM_BLD_to_param(self.0))?;
111+
Ok(OsslParam::from_ptr(params))
112+
}
113+
}
114+
}
115+
116+
impl OsslParamBuilderRef {
117+
/// Adds a `BigNum` to `OsslParamBuilder`.
118+
///
119+
/// Note, that both key and bn need to exist until the `to_param` is called!
120+
#[corresponds(OSSL_PARAM_BLD_push_BN)]
121+
pub fn add_bn(&self, key: &[u8], bn: &BigNumRef) -> Result<(), ErrorStack> {
122+
unsafe {
123+
cvt(ffi::OSSL_PARAM_BLD_push_BN(
124+
self.as_ptr(),
125+
key.as_ptr() as *const c_char,
126+
bn.as_ptr(),
127+
))
128+
.map(|_| ())
129+
}
130+
}
131+
132+
/// Adds a utf8 string to `OsslParamBuilder`.
133+
///
134+
/// Note, that both `key` and `buf` need to exist until the `to_param` is called!
135+
#[corresponds(OSSL_PARAM_BLD_push_utf8_string)]
136+
pub fn add_utf8_string(&self, key: &[u8], buf: &str) -> Result<(), ErrorStack> {
137+
unsafe {
138+
cvt(ffi::OSSL_PARAM_BLD_push_utf8_string(
139+
self.as_ptr(),
140+
key.as_ptr() as *const c_char,
141+
buf.as_ptr() as *const c_char,
142+
buf.len(),
143+
))
144+
.map(|_| ())
145+
}
146+
}
147+
148+
/// Adds a octet string to `OsslParamBuilder`.
149+
///
150+
/// Note, that both `key` and `buf` need to exist until the `to_param` is called!
151+
#[corresponds(OSSL_PARAM_BLD_push_octet_string)]
152+
pub fn add_octet_string(&self, key: &[u8], buf: &[u8]) -> Result<(), ErrorStack> {
153+
unsafe {
154+
cvt(ffi::OSSL_PARAM_BLD_push_octet_string(
155+
self.as_ptr(),
156+
key.as_ptr() as *const c_char,
157+
buf.as_ptr() as *const c_void,
158+
buf.len(),
159+
))
160+
.map(|_| ())
161+
}
162+
}
163+
164+
/// Adds a unsigned int to `OsslParamBuilder`.
165+
///
166+
/// Note, that both `key` and `buf` need to exist until the `to_param` is called!
167+
#[corresponds(OSSL_PARAM_BLD_push_uint)]
168+
pub fn add_uint(&self, key: &[u8], val: u32) -> Result<(), ErrorStack> {
169+
unsafe {
170+
cvt(ffi::OSSL_PARAM_BLD_push_uint(
171+
self.as_ptr(),
172+
key.as_ptr() as *const c_char,
173+
val as c_uint,
174+
))
175+
.map(|_| ())
176+
}
177+
}
178+
}

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)