feat: updates
This commit is contained in:
@@ -7,9 +7,11 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
hmac-sha1 = "0.1.3"
|
||||||
hmac-sha256 = "1.1.7"
|
hmac-sha256 = "1.1.7"
|
||||||
hmac-sm3 = "0.1.0"
|
hmac-sm3 = "0.1.0"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
sha1 = "0.10.5"
|
||||||
sha256 = "1.4.0"
|
sha256 = "1.4.0"
|
||||||
sm3 = "0.4.2"
|
sm3 = "0.4.2"
|
||||||
zeroize = "1.6.0"
|
zeroize = "1.6.0"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
mod v4;
|
mod v4;
|
||||||
mod util;
|
mod map_util;
|
||||||
// mod v4_algorithm;
|
mod common_util;
|
||||||
|
mod sign_algorithm;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use sha1::Sha1;
|
||||||
use sm3::{Digest, Sm3};
|
use sm3::{Digest, Sm3};
|
||||||
|
|
||||||
const ACS4_HMAC_SHA256: &str = "ACS4-HMAC-SHA256";
|
const ACS4_HMAC_SHA256: &str = "ACS4-HMAC-SHA256";
|
||||||
@@ -6,7 +7,11 @@ const ACS4_HMAC_SM3: &str = "ACS4-HMAC-SM3";
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum SignAlgorithm {
|
pub enum SignAlgorithm {
|
||||||
|
/// SHA1 is used for Signatures before V4
|
||||||
|
Sha1,
|
||||||
|
// V4 NIST Signature Algorithm
|
||||||
Sha256,
|
Sha256,
|
||||||
|
// V4 SM Signature Algorithm
|
||||||
Sm3,
|
Sm3,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,14 +25,15 @@ impl SignAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_aliyun_name(&self) -> &'static str {
|
pub fn as_aliyun_name_v4(&self) -> &'static str {
|
||||||
inner_as_aliyun_name(self)
|
inner_as_aliyun_name_v4(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inner_as_aliyun_name(sign_algorithm: &SignAlgorithm) -> &'static str {
|
fn inner_as_aliyun_name_v4(sign_algorithm: &SignAlgorithm) -> &'static str {
|
||||||
match sign_algorithm {
|
match sign_algorithm {
|
||||||
|
SignAlgorithm::Sha1 => "N/A",
|
||||||
SignAlgorithm::Sha256 => ACS4_HMAC_SHA256,
|
SignAlgorithm::Sha256 => ACS4_HMAC_SHA256,
|
||||||
SignAlgorithm::Sm3 => ACS4_HMAC_SM3,
|
SignAlgorithm::Sm3 => ACS4_HMAC_SM3,
|
||||||
}
|
}
|
||||||
@@ -36,11 +42,16 @@ fn inner_as_aliyun_name(sign_algorithm: &SignAlgorithm) -> &'static str {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn inner_digest(sign_algorithm: &SignAlgorithm, message: &[u8]) -> String {
|
fn inner_digest(sign_algorithm: &SignAlgorithm, message: &[u8]) -> String {
|
||||||
match sign_algorithm {
|
match sign_algorithm {
|
||||||
|
SignAlgorithm::Sha1 => {
|
||||||
|
let mut h = Sha1::new();
|
||||||
|
h.update(message);
|
||||||
|
hex::encode(h.finalize().as_slice())
|
||||||
|
}
|
||||||
SignAlgorithm::Sha256 => sha256::digest(message),
|
SignAlgorithm::Sha256 => sha256::digest(message),
|
||||||
SignAlgorithm::Sm3 => {
|
SignAlgorithm::Sm3 => {
|
||||||
let mut sm3 = Sm3::new();
|
let mut h = Sm3::new();
|
||||||
sm3.update(&message);
|
h.update(&message);
|
||||||
hex::encode(sm3.finalize().as_slice())
|
hex::encode(h.finalize().as_slice())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,6 +59,7 @@ fn inner_digest(sign_algorithm: &SignAlgorithm, message: &[u8]) -> String {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn inner_hmac_sign(sign_algorithm: &SignAlgorithm, message: &[u8], key: &[u8]) -> Vec<u8> {
|
fn inner_hmac_sign(sign_algorithm: &SignAlgorithm, message: &[u8], key: &[u8]) -> Vec<u8> {
|
||||||
match sign_algorithm {
|
match sign_algorithm {
|
||||||
|
SignAlgorithm::Sha1 => hmacsha1::hmac_sha1(key, message).to_vec(),
|
||||||
SignAlgorithm::Sha256 => {
|
SignAlgorithm::Sha256 => {
|
||||||
let mut hsha256 = hmac_sha256::HMAC::new(key);
|
let mut hsha256 = hmac_sha256::HMAC::new(key);
|
||||||
hsha256.update(message);
|
hsha256.update(message);
|
||||||
@@ -59,6 +71,10 @@ fn inner_hmac_sign(sign_algorithm: &SignAlgorithm, message: &[u8], key: &[u8]) -
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_digest() {
|
fn test_digest() {
|
||||||
|
assert_eq!(
|
||||||
|
"0a4d55a8d778e5022fab701977c5d840bbc486d0",
|
||||||
|
SignAlgorithm::Sha1.digest(b"Hello World")
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e",
|
"a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e",
|
||||||
SignAlgorithm::Sha256.digest(b"Hello World")
|
SignAlgorithm::Sha256.digest(b"Hello World")
|
||||||
@@ -4,11 +4,11 @@ use std::time::SystemTime;
|
|||||||
|
|
||||||
use rand::random;
|
use rand::random;
|
||||||
|
|
||||||
use crate::util::BTreeMapAddKv;
|
use crate::common_util::{join_slices, percent_encode};
|
||||||
|
use crate::map_util::BTreeMapAddKv;
|
||||||
|
use crate::sign_algorithm::SignAlgorithm;
|
||||||
use crate::v4::access_key::{AccessKey, DerivedAccessKey};
|
use crate::v4::access_key::{AccessKey, DerivedAccessKey};
|
||||||
use crate::v4::common_util::{join_slices, percent_encode};
|
|
||||||
use crate::v4::constant::{ALIYUN_V4, ALIYUN_V4_REQUEST, CONTENT_TYPE_APPLICATION_JSON, HEADER_ACCEPT, HEADER_AUTHORIZATION, HEADER_CONTENT_TYPE, HEADER_HOST, HEADER_USER_AGENT, HEADER_X_ACS_PREFIX, HEADER_X_ASC_ACCESS_KEY_ID, HEADER_X_ASC_ACTION, HEADER_X_ASC_CONTENT_SHA256, HEADER_X_ASC_CONTENT_SM3, HEADER_X_ASC_DATE, HEADER_X_ASC_SECURITY_TOKEN, HEADER_X_ASC_SIGNATURE_NONCE, HEADER_X_ASC_VERSION, REGION_CENTER};
|
use crate::v4::constant::{ALIYUN_V4, ALIYUN_V4_REQUEST, CONTENT_TYPE_APPLICATION_JSON, HEADER_ACCEPT, HEADER_AUTHORIZATION, HEADER_CONTENT_TYPE, HEADER_HOST, HEADER_USER_AGENT, HEADER_X_ACS_PREFIX, HEADER_X_ASC_ACCESS_KEY_ID, HEADER_X_ASC_ACTION, HEADER_X_ASC_CONTENT_SHA256, HEADER_X_ASC_CONTENT_SM3, HEADER_X_ASC_DATE, HEADER_X_ASC_SECURITY_TOKEN, HEADER_X_ASC_SIGNATURE_NONCE, HEADER_X_ASC_VERSION, REGION_CENTER};
|
||||||
use crate::v4::sign_algorithm::SignAlgorithm;
|
|
||||||
|
|
||||||
const SEQ: AtomicU64 = AtomicU64::new(0);
|
const SEQ: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
@@ -27,18 +27,21 @@ struct Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_common_headers(header: &mut BTreeMap<String, String>, request: &Request) {
|
fn add_common_headers(header: &mut BTreeMap<String, String>, request: &Request) {
|
||||||
|
let (ymd, date) = get_timestamp();
|
||||||
|
|
||||||
header.insert_kv(HEADER_HOST, "endpoint"); // TODO
|
header.insert_kv(HEADER_HOST, "endpoint"); // TODO
|
||||||
header.insert_kv(HEADER_X_ASC_VERSION, &request.version);
|
header.insert_kv(HEADER_X_ASC_VERSION, &request.version);
|
||||||
header.insert_kv(HEADER_X_ASC_ACTION, &request.action);
|
header.insert_kv(HEADER_X_ASC_ACTION, &request.action);
|
||||||
header.insert_kv(HEADER_USER_AGENT, &request.user_agent);
|
header.insert_kv(HEADER_USER_AGENT, &request.user_agent);
|
||||||
header.insert_kv(HEADER_X_ASC_DATE, get_timestamp());
|
header.insert_kv(HEADER_X_ASC_DATE, date);
|
||||||
header.insert_kv(HEADER_X_ASC_SIGNATURE_NONCE, get_nonce());
|
header.insert_kv(HEADER_X_ASC_SIGNATURE_NONCE, get_nonce());
|
||||||
header.insert_kv(HEADER_ACCEPT, CONTENT_TYPE_APPLICATION_JSON);
|
header.insert_kv(HEADER_ACCEPT, CONTENT_TYPE_APPLICATION_JSON);
|
||||||
|
|
||||||
// TODO BODY ...
|
// TODO BODY ...
|
||||||
|
|
||||||
|
// TODO signature ...
|
||||||
match &request.sign_algorithm {
|
match &request.sign_algorithm {
|
||||||
// TODO ...
|
SignAlgorithm::Sha1 => panic!("SHA1 in V4 is NOT supported!"),
|
||||||
SignAlgorithm::Sha256 => {
|
SignAlgorithm::Sha256 => {
|
||||||
header.insert_kv(HEADER_X_ASC_CONTENT_SHA256, "");
|
header.insert_kv(HEADER_X_ASC_CONTENT_SHA256, "");
|
||||||
}
|
}
|
||||||
@@ -111,7 +114,7 @@ fn get_authorization(sign_algorithm: &SignAlgorithm,
|
|||||||
let signed_headers_str = get_signed_headers(headers).iter().map(|(k, _)| k.as_str()).collect::<Vec<_>>().join(";");
|
let signed_headers_str = get_signed_headers(headers).iter().map(|(k, _)| k.as_str()).collect::<Vec<_>>().join(";");
|
||||||
|
|
||||||
let mut authorization = String::with_capacity(512);
|
let mut authorization = String::with_capacity(512);
|
||||||
authorization.push_str(sign_algorithm.as_aliyun_name());
|
authorization.push_str(sign_algorithm.as_aliyun_name_v4());
|
||||||
authorization.push_str(" Credential=");
|
authorization.push_str(" Credential=");
|
||||||
authorization.push_str(&access_key.access_key_id);
|
authorization.push_str(&access_key.access_key_id);
|
||||||
authorization.push('/');
|
authorization.push('/');
|
||||||
@@ -153,7 +156,7 @@ fn get_signature(sign_algorithm: &SignAlgorithm,
|
|||||||
string_to_sign.push_str(payload);
|
string_to_sign.push_str(payload);
|
||||||
|
|
||||||
let string_to_sign_digest_hex = sign_algorithm.digest(string_to_sign.as_bytes());
|
let string_to_sign_digest_hex = sign_algorithm.digest(string_to_sign.as_bytes());
|
||||||
string_to_sign.push_str(sign_algorithm.as_aliyun_name());
|
string_to_sign.push_str(sign_algorithm.as_aliyun_name_v4());
|
||||||
string_to_sign.push('\n');
|
string_to_sign.push('\n');
|
||||||
string_to_sign.push_str(&string_to_sign_digest_hex);
|
string_to_sign.push_str(&string_to_sign_digest_hex);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
mod constant;
|
mod constant;
|
||||||
mod sign_algorithm;
|
|
||||||
mod access_key;
|
mod access_key;
|
||||||
mod common_util;
|
|
||||||
mod aliyun_util;
|
mod aliyun_util;
|
||||||
|
|||||||
Reference in New Issue
Block a user