reqsign_core/hash.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Hash related utils.
19
20use crate::Error;
21use base64::Engine;
22use base64::prelude::BASE64_STANDARD;
23use hmac::Hmac;
24use hmac::Mac;
25use sha1::Sha1;
26use sha2::Digest;
27use sha2::Sha256;
28
29/// Base64 encode
30pub fn base64_encode(content: &[u8]) -> String {
31 BASE64_STANDARD.encode(content)
32}
33
34/// Base64 decode
35pub fn base64_decode(content: &str) -> crate::Result<Vec<u8>> {
36 BASE64_STANDARD
37 .decode(content)
38 .map_err(|e| Error::unexpected("base64 decode failed").with_source(e))
39}
40
41/// Hex encoded SHA1 hash.
42///
43/// Use this function instead of `hex::encode(sha1(content))` can reduce
44/// extra copy.
45pub fn hex_sha1(content: &[u8]) -> String {
46 hex::encode(Sha1::digest(content))
47}
48
49/// Hex encoded SHA256 hash.
50///
51/// Use this function instead of `hex::encode(sha256(content))` can reduce
52/// extra copy.
53pub fn hex_sha256(content: &[u8]) -> String {
54 hex::encode(Sha256::digest(content))
55}
56
57/// HMAC with SHA256 hash.
58pub fn hmac_sha256(key: &[u8], content: &[u8]) -> Vec<u8> {
59 // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
60 let mut h = Hmac::<Sha256>::new_from_slice(key).unwrap();
61 h.update(content);
62
63 h.finalize().into_bytes().to_vec()
64}
65
66/// Base64 encoded HMAC with SHA256 hash.
67pub fn base64_hmac_sha256(key: &[u8], content: &[u8]) -> String {
68 // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
69 let mut h = Hmac::<Sha256>::new_from_slice(key).unwrap();
70 h.update(content);
71
72 base64_encode(&h.finalize().into_bytes())
73}
74
75/// Hex encoded HMAC with SHA1 hash.
76///
77/// Use this function instead of `hex::encode(hmac_sha1(key, content))` can
78/// reduce extra copy.
79pub fn hex_hmac_sha1(key: &[u8], content: &[u8]) -> String {
80 // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
81 let mut h = Hmac::<Sha1>::new_from_slice(key).unwrap();
82 h.update(content);
83
84 hex::encode(h.finalize().into_bytes())
85}
86
87/// Hex encoded HMAC with SHA256 hash.
88///
89/// Use this function instead of `hex::encode(hmac_sha256(key, content))` can
90/// reduce extra copy.
91pub fn hex_hmac_sha256(key: &[u8], content: &[u8]) -> String {
92 // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
93 let mut h = Hmac::<Sha256>::new_from_slice(key).unwrap();
94 h.update(content);
95
96 hex::encode(h.finalize().into_bytes())
97}
98
99/// Base64 encoded HMAC with SHA1 hash.
100pub fn base64_hmac_sha1(key: &[u8], content: &[u8]) -> String {
101 // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
102 let mut h = Hmac::<Sha1>::new_from_slice(key).unwrap();
103 h.update(content);
104
105 base64_encode(&h.finalize().into_bytes())
106}