/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aws-lc-rs-1.14.1/src/rsa/encoding.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 | | /// [RFC 8017](https://www.rfc-editor.org/rfc/rfc8017.html) |
5 | | /// |
6 | | /// PKCS #1: RSA Cryptography Specifications Version 2.2 |
7 | | pub(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 | 0 | pub(in crate::rsa) fn encode_public_key_der( |
19 | 0 | pubkey: &LcPtr<EVP_PKEY>, |
20 | 0 | ) -> Result<Box<[u8]>, Unspecified> { |
21 | 0 | let mut pubkey_bytes = null_mut::<u8>(); |
22 | 0 | let mut outlen: usize = 0; |
23 | | if 1 != unsafe { |
24 | 0 | RSA_public_key_to_bytes( |
25 | 0 | &mut pubkey_bytes, |
26 | 0 | &mut outlen, |
27 | 0 | *pubkey.as_const().get_rsa()?, |
28 | | ) |
29 | | } { |
30 | 0 | return Err(Unspecified); |
31 | 0 | } |
32 | 0 | let pubkey_bytes = LcPtr::new(pubkey_bytes)?; |
33 | 0 | let pubkey_slice = unsafe { pubkey_bytes.as_slice(outlen) }; |
34 | 0 | let pubkey_vec = Vec::from(pubkey_slice); |
35 | 0 | Ok(pubkey_vec.into_boxed_slice()) |
36 | 0 | } |
37 | | |
38 | | /// Decode a DER encoded `RSAPublicKey` structure. |
39 | | #[inline] |
40 | 0 | pub(in crate::rsa) fn decode_public_key_der( |
41 | 0 | public_key: &[u8], |
42 | 0 | ) -> Result<LcPtr<EVP_PKEY>, KeyRejected> { |
43 | 0 | let rsa = DetachableLcPtr::new(unsafe { |
44 | 0 | RSA_public_key_from_bytes(public_key.as_ptr(), public_key.len()) |
45 | 0 | })?; |
46 | | |
47 | 0 | let mut pkey = LcPtr::new(unsafe { EVP_PKEY_new() })?; |
48 | | |
49 | 0 | if 1 != unsafe { EVP_PKEY_assign_RSA(*pkey.as_mut(), *rsa) } { |
50 | 0 | return Err(KeyRejected::unspecified()); |
51 | 0 | } |
52 | | |
53 | 0 | rsa.detach(); |
54 | | |
55 | 0 | Ok(pkey) |
56 | 0 | } |
57 | | |
58 | | /// Decodes a DER encoded `RSAPrivateKey` structure. |
59 | | #[inline] |
60 | 0 | pub(in crate::rsa) fn decode_private_key_der( |
61 | 0 | private_key: &[u8], |
62 | 0 | ) -> Result<LcPtr<EVP_PKEY>, KeyRejected> { |
63 | 0 | let mut cbs = cbs::build_CBS(private_key); |
64 | | |
65 | 0 | let rsa = DetachableLcPtr::new(unsafe { RSA_parse_private_key(&mut cbs) })?; |
66 | | |
67 | 0 | let mut pkey = LcPtr::new(unsafe { EVP_PKEY_new() })?; |
68 | | |
69 | 0 | if 1 != unsafe { EVP_PKEY_assign_RSA(*pkey.as_mut(), *rsa) } { |
70 | 0 | return Err(KeyRejected::unspecified()); |
71 | 0 | } |
72 | | |
73 | 0 | rsa.detach(); |
74 | | |
75 | 0 | Ok(pkey) |
76 | 0 | } |
77 | | } |
78 | | |
79 | | /// [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280.html) |
80 | | /// |
81 | | /// Encodings that use the `SubjectPublicKeyInfo` structure. |
82 | | pub(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 | 0 | pub(in crate::rsa) fn encode_public_key_der( |
90 | 0 | key: &LcPtr<EVP_PKEY>, |
91 | 0 | ) -> Result<PublicKeyX509Der<'static>, Unspecified> { |
92 | 0 | let der = key.as_const().marshal_rfc5280_public_key()?; |
93 | 0 | Ok(PublicKeyX509Der::from(Buffer::new(der))) |
94 | 0 | } |
95 | | |
96 | 0 | pub(in crate::rsa) fn decode_public_key_der( |
97 | 0 | value: &[u8], |
98 | 0 | ) -> Result<LcPtr<EVP_PKEY>, KeyRejected> { |
99 | 0 | LcPtr::<EVP_PKEY>::parse_rfc5280_public_key(value, EVP_PKEY_RSA).or( |
100 | | // Does anyone encode with this OID? |
101 | 0 | LcPtr::<EVP_PKEY>::parse_rfc5280_public_key(value, EVP_PKEY_RSA_PSS), |
102 | | ) |
103 | 0 | } |
104 | | } |