Coverage Report

Created: 2025-10-29 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}