/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aws-lc-rs-1.12.4/src/cbb.rs
Line | Count | Source |
1 | | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
2 | | // SPDX-License-Identifier: Apache-2.0 OR ISC |
3 | | |
4 | | use crate::aws_lc::{CBB_cleanup, CBB_finish, CBB_init, CBB_init_fixed, CBB}; |
5 | | use crate::error::Unspecified; |
6 | | use crate::ptr::LcPtr; |
7 | | use core::marker::PhantomData; |
8 | | use core::mem::MaybeUninit; |
9 | | use core::ptr::null_mut; |
10 | | |
11 | | pub(crate) struct LcCBB<'a>(CBB, PhantomData<&'a CBB>); |
12 | | |
13 | | impl LcCBB<'static> { |
14 | 0 | pub(crate) fn new(initial_capacity: usize) -> LcCBB<'static> { |
15 | 0 | let mut cbb = MaybeUninit::<CBB>::uninit(); |
16 | 0 | let cbb = unsafe { |
17 | 0 | CBB_init(cbb.as_mut_ptr(), initial_capacity); |
18 | 0 | cbb.assume_init() |
19 | | }; |
20 | 0 | Self(cbb, PhantomData) |
21 | 0 | } |
22 | | |
23 | 0 | pub(crate) fn into_vec(mut self) -> Result<Vec<u8>, Unspecified> { |
24 | 0 | let mut out_data = null_mut::<u8>(); |
25 | 0 | let mut out_len: usize = 0; |
26 | | |
27 | 0 | if 1 != unsafe { CBB_finish(self.as_mut_ptr(), &mut out_data, &mut out_len) } { |
28 | 0 | return Err(Unspecified); |
29 | 0 | } |
30 | | |
31 | 0 | let out_data = LcPtr::new(out_data)?; |
32 | 0 | let slice = unsafe { std::slice::from_raw_parts(*out_data.as_const(), out_len) }; |
33 | | // `to_vec()` copies the data into a new `Vec` |
34 | 0 | Ok(slice.to_vec()) |
35 | 0 | } |
36 | | } |
37 | | |
38 | | impl<'a> LcCBB<'a> { |
39 | 0 | pub(crate) fn new_from_slice(buffer: &'a mut [u8]) -> LcCBB<'a> { |
40 | 0 | let mut cbb = MaybeUninit::<CBB>::uninit(); |
41 | 0 | let cbb = unsafe { |
42 | 0 | CBB_init_fixed(cbb.as_mut_ptr(), buffer.as_mut_ptr(), buffer.len()); |
43 | 0 | cbb.assume_init() |
44 | | }; |
45 | 0 | Self(cbb, PhantomData) |
46 | 0 | } |
47 | | |
48 | 0 | pub(crate) fn finish(mut self) -> Result<usize, Unspecified> { |
49 | 0 | let mut pkcs8_bytes_ptr = null_mut::<u8>(); |
50 | 0 | let mut out_len: usize = 0; |
51 | 0 | if 1 != unsafe { CBB_finish(self.as_mut_ptr(), &mut pkcs8_bytes_ptr, &mut out_len) } { |
52 | 0 | return Err(Unspecified); |
53 | 0 | } |
54 | 0 | Ok(out_len) |
55 | 0 | } |
56 | | } |
57 | | impl LcCBB<'_> { |
58 | 0 | pub(crate) fn as_mut_ptr(&mut self) -> *mut CBB { |
59 | 0 | &mut self.0 |
60 | 0 | } |
61 | | } |
62 | | |
63 | | impl Drop for LcCBB<'_> { |
64 | 0 | fn drop(&mut self) { |
65 | 0 | unsafe { |
66 | 0 | CBB_cleanup(&mut self.0); |
67 | 0 | } |
68 | 0 | } |
69 | | } |
70 | | |
71 | | #[cfg(test)] |
72 | | mod tests { |
73 | | use super::LcCBB; |
74 | | use crate::aws_lc::CBB_add_asn1_bool; |
75 | | |
76 | | #[test] |
77 | | fn dynamic_vec() { |
78 | | let mut cbb = LcCBB::new(4); |
79 | | assert_eq!(1, unsafe { CBB_add_asn1_bool(cbb.as_mut_ptr(), 1) }); |
80 | | let vec = cbb.into_vec().expect("be copied to buffer"); |
81 | | assert_eq!(vec.as_slice(), &[1, 1, 255]); |
82 | | } |
83 | | |
84 | | #[test] |
85 | | fn dynamic_buffer_grows() { |
86 | | let mut cbb = LcCBB::new(1); |
87 | | assert_eq!(1, unsafe { CBB_add_asn1_bool(cbb.as_mut_ptr(), 1) }); |
88 | | let vec = cbb.into_vec().expect("be copied to buffer"); |
89 | | assert_eq!(vec.as_slice(), &[1, 1, 255]); |
90 | | } |
91 | | |
92 | | #[test] |
93 | | fn fixed_buffer() { |
94 | | let mut buffer = [0u8; 4]; |
95 | | let mut cbb = LcCBB::new_from_slice(&mut buffer); |
96 | | assert_eq!(1, unsafe { CBB_add_asn1_bool(cbb.as_mut_ptr(), 1) }); |
97 | | let out_len = cbb.finish().expect("cbb finishable"); |
98 | | assert_eq!(&buffer[..out_len], &[1, 1, 255]); |
99 | | } |
100 | | |
101 | | #[test] |
102 | | fn fixed_buffer_no_growth() { |
103 | | let mut buffer = [0u8; 1]; |
104 | | let mut cbb = LcCBB::new_from_slice(&mut buffer); |
105 | | assert_ne!(1, unsafe { CBB_add_asn1_bool(cbb.as_mut_ptr(), 1) }); |
106 | | } |
107 | | } |