rustfs_rsc/
sse.rs

1//! Server-side encryption
2
3use hyper::HeaderMap;
4
5use crate::{
6    error::ValueError,
7    utils::{base64_encode, md5sum_hash},
8};
9
10/// Server-side encryption base trait.
11pub trait Sse {
12    /// Return headers.
13    fn headers(&self) -> HeaderMap;
14
15    /// Return copy headers.
16    fn copy_headers(&self) -> HeaderMap {
17        HeaderMap::new()
18    }
19
20    /// Return TLS required to use this server-side encryption.
21    fn tls_required(&self) -> bool {
22        true
23    }
24}
25
26/// Server-side encryption - customer key type.
27pub struct SseCustomerKey {
28    headers: HeaderMap,
29    copy_headers: HeaderMap,
30}
31
32impl SseCustomerKey {
33    pub fn new(key: &str) -> Result<Self, ValueError> {
34        if key.len() != 32 {
35            return Err(ValueError::from(
36                "SSE-C keys need to be 256 bit base64 encoded",
37            ));
38        }
39        let b64_key = base64_encode(key);
40        let md5_key = md5sum_hash(key.as_bytes());
41        let mut headers = HeaderMap::new();
42        headers.insert(
43            "X-Amz-Server-Side-Encryption-Customer-Algorithm",
44            "AES256".parse()?,
45        );
46        headers.insert(
47            "X-Amz-Server-Side-Encryption-Customer-Key",
48            b64_key.parse()?,
49        );
50        headers.insert(
51            "X-Amz-Server-Side-Encryption-Customer-Key-MD5",
52            md5_key.parse()?,
53        );
54        let mut copy_headers = HeaderMap::new();
55        copy_headers.insert(
56            "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm",
57            "AES256".parse()?,
58        );
59        copy_headers.insert(
60            "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key",
61            b64_key.parse()?,
62        );
63        copy_headers.insert(
64            "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-MD5",
65            md5_key.parse()?,
66        );
67        Ok(Self {
68            headers,
69            copy_headers,
70        })
71    }
72}
73
74impl Sse for SseCustomerKey {
75    fn headers(&self) -> HeaderMap {
76        self.headers.clone()
77    }
78
79    fn copy_headers(&self) -> HeaderMap {
80        self.copy_headers.clone()
81    }
82}
83
84/// Server-side encryption - KMS type.
85pub struct SseKMS(HeaderMap);
86
87impl SseKMS {
88    pub fn new(key: &str, content_json: Option<String>) -> Self {
89        let mut header = HeaderMap::new();
90        header.insert(
91            "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id",
92            key.parse().unwrap(),
93        );
94        if let Some(content) = content_json {
95            header.insert(
96                "X-Amz-Server-Side-Encryption-Context",
97                base64_encode(content.as_bytes()).parse().unwrap(),
98            );
99        }
100        Self(header)
101    }
102}
103
104impl Sse for SseKMS {
105    fn headers(&self) -> HeaderMap {
106        self.0.clone()
107    }
108}
109
110/// Server-side encryption - S3 type.
111pub struct SseS3(HeaderMap);
112
113impl SseS3 {
114    pub fn new() -> Self {
115        let mut header = HeaderMap::new();
116        header.insert("X-Amz-Server-Side-Encryption", "AES256".parse().unwrap());
117        Self(header)
118    }
119}
120
121impl Sse for SseS3 {
122    fn headers(&self) -> HeaderMap {
123        self.0.clone()
124    }
125
126    fn tls_required(&self) -> bool {
127        false
128    }
129}