aws_lc_rs/rsa/
encoding.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0 OR ISC
3
4/// [RFC 8017](https://www.rfc-editor.org/rfc/rfc8017.html)
5///
6/// PKCS #1: RSA Cryptography Specifications Version 2.2
7pub(in crate::rsa) mod rfc8017 {
8    use crate::aws_lc::{
9        EVP_PKEY_assign_RSA, EVP_PKEY_new, RSA_parse_private_key, RSA_public_key_from_bytes,
10        RSA_public_key_to_bytes, EVP_PKEY,
11    };
12    use crate::cbs;
13    use crate::error::{KeyRejected, Unspecified};
14    use crate::ptr::{DetachableLcPtr, LcPtr};
15    use std::ptr::null_mut;
16
17    /// DER encode a RSA public key to `RSAPublicKey` structure.
18    pub(in crate::rsa) fn encode_public_key_der(
19        pubkey: &LcPtr<EVP_PKEY>,
20    ) -> Result<Box<[u8]>, Unspecified> {
21        let mut pubkey_bytes = null_mut::<u8>();
22        let mut outlen: usize = 0;
23        if 1 != unsafe {
24            RSA_public_key_to_bytes(
25                &mut pubkey_bytes,
26                &mut outlen,
27                *pubkey.as_const().get_rsa()?,
28            )
29        } {
30            return Err(Unspecified);
31        }
32        let pubkey_bytes = LcPtr::new(pubkey_bytes)?;
33        let pubkey_slice = unsafe { pubkey_bytes.as_slice(outlen) };
34        let pubkey_vec = Vec::from(pubkey_slice);
35        Ok(pubkey_vec.into_boxed_slice())
36    }
37
38    /// Decode a DER encoded `RSAPublicKey` structure.
39    #[inline]
40    pub(in crate::rsa) fn decode_public_key_der(
41        public_key: &[u8],
42    ) -> Result<LcPtr<EVP_PKEY>, KeyRejected> {
43        let rsa = DetachableLcPtr::new(unsafe {
44            RSA_public_key_from_bytes(public_key.as_ptr(), public_key.len())
45        })?;
46
47        let mut pkey = LcPtr::new(unsafe { EVP_PKEY_new() })?;
48
49        if 1 != unsafe { EVP_PKEY_assign_RSA(*pkey.as_mut(), *rsa) } {
50            return Err(KeyRejected::unspecified());
51        }
52
53        rsa.detach();
54
55        Ok(pkey)
56    }
57
58    /// Decodes a DER encoded `RSAPrivateKey` structure.
59    #[inline]
60    pub(in crate::rsa) fn decode_private_key_der(
61        private_key: &[u8],
62    ) -> Result<LcPtr<EVP_PKEY>, KeyRejected> {
63        let mut cbs = cbs::build_CBS(private_key);
64
65        let rsa = DetachableLcPtr::new(unsafe { RSA_parse_private_key(&mut cbs) })?;
66
67        let mut pkey = LcPtr::new(unsafe { EVP_PKEY_new() })?;
68
69        if 1 != unsafe { EVP_PKEY_assign_RSA(*pkey.as_mut(), *rsa) } {
70            return Err(KeyRejected::unspecified());
71        }
72
73        rsa.detach();
74
75        Ok(pkey)
76    }
77}
78
79/// [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280.html)
80///
81/// Encodings that use the `SubjectPublicKeyInfo` structure.
82pub(in crate::rsa) mod rfc5280 {
83    use crate::aws_lc::{EVP_PKEY, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS};
84    use crate::buffer::Buffer;
85    use crate::encoding::PublicKeyX509Der;
86    use crate::error::{KeyRejected, Unspecified};
87    use crate::ptr::LcPtr;
88
89    pub(in crate::rsa) fn encode_public_key_der(
90        key: &LcPtr<EVP_PKEY>,
91    ) -> Result<PublicKeyX509Der<'static>, Unspecified> {
92        let der = key.as_const().marshal_rfc5280_public_key()?;
93        Ok(PublicKeyX509Der::from(Buffer::new(der)))
94    }
95
96    pub(in crate::rsa) fn decode_public_key_der(
97        value: &[u8],
98    ) -> Result<LcPtr<EVP_PKEY>, KeyRejected> {
99        LcPtr::<EVP_PKEY>::parse_rfc5280_public_key(value, EVP_PKEY_RSA).or(
100            // Does anyone encode with this OID?
101            LcPtr::<EVP_PKEY>::parse_rfc5280_public_key(value, EVP_PKEY_RSA_PSS),
102        )
103    }
104}