Skip to main content

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::KeyInit;
25use hmac::Mac;
26use sha1::Sha1;
27use sha2::Digest;
28use sha2::Sha256;
29
30/// Base64 encode
31pub fn base64_encode(content: &[u8]) -> String {
32    BASE64_STANDARD.encode(content)
33}
34
35/// Base64 decode
36pub fn base64_decode(content: &str) -> crate::Result<Vec<u8>> {
37    BASE64_STANDARD
38        .decode(content)
39        .map_err(|e| Error::unexpected("base64 decode failed").with_source(e))
40}
41
42/// Hex encoded SHA1 hash.
43///
44/// Use this function instead of `hex::encode(sha1(content))` can reduce
45/// extra copy.
46pub fn hex_sha1(content: &[u8]) -> String {
47    hex::encode(Sha1::digest(content))
48}
49
50/// Hex encoded SHA256 hash.
51///
52/// Use this function instead of `hex::encode(sha256(content))` can reduce
53/// extra copy.
54pub fn hex_sha256(content: &[u8]) -> String {
55    hex::encode(Sha256::digest(content))
56}
57
58/// HMAC with SHA256 hash.
59pub fn hmac_sha256(key: &[u8], content: &[u8]) -> Vec<u8> {
60    // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
61    let mut h = Hmac::<Sha256>::new_from_slice(key).unwrap();
62    h.update(content);
63
64    h.finalize().into_bytes().to_vec()
65}
66
67/// Base64 encoded HMAC with SHA256 hash.
68pub fn base64_hmac_sha256(key: &[u8], content: &[u8]) -> String {
69    // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
70    let mut h = Hmac::<Sha256>::new_from_slice(key).unwrap();
71    h.update(content);
72
73    base64_encode(&h.finalize().into_bytes())
74}
75
76/// Hex encoded HMAC with SHA1 hash.
77///
78/// Use this function instead of `hex::encode(hmac_sha1(key, content))` can
79/// reduce extra copy.
80pub fn hex_hmac_sha1(key: &[u8], content: &[u8]) -> String {
81    // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
82    let mut h = Hmac::<Sha1>::new_from_slice(key).unwrap();
83    h.update(content);
84
85    hex::encode(h.finalize().into_bytes())
86}
87
88/// Hex encoded HMAC with SHA256 hash.
89///
90/// Use this function instead of `hex::encode(hmac_sha256(key, content))` can
91/// reduce extra copy.
92pub fn hex_hmac_sha256(key: &[u8], content: &[u8]) -> String {
93    // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
94    let mut h = Hmac::<Sha256>::new_from_slice(key).unwrap();
95    h.update(content);
96
97    hex::encode(h.finalize().into_bytes())
98}
99
100/// Base64 encoded HMAC with SHA1 hash.
101pub fn base64_hmac_sha1(key: &[u8], content: &[u8]) -> String {
102    // SAFETY: HMAC's new_from_slice always returns Ok - it handles any key length
103    let mut h = Hmac::<Sha1>::new_from_slice(key).unwrap();
104    h.update(content);
105
106    base64_encode(&h.finalize().into_bytes())
107}