1
1
//! AWS API request signatures verification routines.
2
2
//!
3
- //! This is essentially the server-side complement of [rusoto_signature](https://crates.io/crates/rusoto_signature)
4
- //! but follows the implementation of [python-aws-sig](https://github.com/dacut/python-aws-sig).
5
- //!
6
3
//! This implements the AWS [SigV4](http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)
7
4
//! and [SigV4S3](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)
8
- //! algorithms.
5
+ //! server-side validation algorithms.
9
6
//!
7
+ //! **Stability of this module is not guaranteed except for items exposed at the crate root**.
8
+ //! The functions and types are subject to change in minor/patch versions. This is exposed for
9
+ //! testing purposes only.
10
10
11
11
use {
12
12
crate :: { crypto:: hmac_sha256, GetSigningKeyRequest , GetSigningKeyResponse , SignatureError } ,
@@ -49,15 +49,16 @@ const SHA256_EMPTY: &str = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495
49
49
const SHA256_HEX_LENGTH : usize = SHA256_EMPTY . len ( ) ;
50
50
51
51
/// Low-level structure for performing AWS SigV4 authentication after a canonical request has been generated.
52
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
52
53
#[ derive( Builder , Clone , Default ) ]
53
54
#[ builder( derive( Debug ) ) ]
54
55
pub struct SigV4Authenticator {
55
56
/// The SHA-256 hash of the canonical request.
56
57
canonical_request_sha256 : [ u8 ; SHA256_OUTPUT_LEN ] ,
57
58
58
59
/// The credential passed into the request, in the form of `keyid/date/region/service/aws4_request`.
59
- /// This is allowed to be invalid upon creation since the validation of the credential is performed _after_ the
60
- /// validation of the request timestamp .
60
+ /// The date must reflect that of the request timestamp in `YYYYMMDD` format, not the server's
61
+ /// date. Timestamp validation is performed separately .
61
62
credential : String ,
62
63
63
64
/// The optional session token.
@@ -73,43 +74,51 @@ pub struct SigV4Authenticator {
73
74
74
75
impl SigV4Authenticator {
75
76
/// Create a builder for `SigV4Authenticator`.
77
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
78
+ #[ inline( always) ]
76
79
pub fn builder ( ) -> SigV4AuthenticatorBuilder {
77
80
SigV4AuthenticatorBuilder :: default ( )
78
81
}
79
82
80
83
/// Retrieve the SHA-256 hash of the canonical request.
81
- #[ inline]
84
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
85
+ #[ inline( always) ]
82
86
pub fn canonical_request_sha256 ( & self ) -> [ u8 ; SHA256_OUTPUT_LEN ] {
83
87
self . canonical_request_sha256
84
88
}
85
89
86
90
/// Retrieve the credential passed into the request, in the form of `keyid/date/region/service/aws4_request`.
87
- #[ inline]
91
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
92
+ #[ inline( always) ]
88
93
pub fn credential ( & self ) -> & str {
89
94
& self . credential
90
95
}
91
96
92
97
/// Retrieve the optional session token.
93
- #[ inline]
98
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
99
+ #[ inline( always) ]
94
100
pub fn session_token ( & self ) -> Option < & str > {
95
101
self . session_token . as_deref ( )
96
102
}
97
103
98
104
/// Retrieve the signature passed into the request.
99
- #[ inline]
105
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
106
+ #[ inline( always) ]
100
107
pub fn signature ( & self ) -> & str {
101
108
& self . signature
102
109
}
103
110
104
111
/// Retrieve the timestamp of the request.
105
- #[ inline]
112
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
113
+ #[ inline( always) ]
106
114
pub fn request_timestamp ( & self ) -> DateTime < Utc > {
107
115
self . request_timestamp
108
116
}
109
117
110
118
/// Verify the request parameters make sense for the region, service, and specified timestamp.
111
- /// This must be called successfully before calling [validate_signature].
112
- fn prevalidate (
119
+ /// This must be called successfully before calling [validate_signature][Self::validate_signature].
120
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
121
+ pub fn prevalidate (
113
122
& self ,
114
123
region : & str ,
115
124
service : & str ,
@@ -205,8 +214,9 @@ impl SigV4Authenticator {
205
214
}
206
215
207
216
/// Return the signing key (`kSigning` from the [AWS documentation](https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html))
208
- /// for the re
209
- async fn get_signing_key < S , F > (
217
+ /// for the request.
218
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
219
+ pub async fn get_signing_key < S , F > (
210
220
& self ,
211
221
region : & str ,
212
222
service : & str ,
@@ -242,7 +252,9 @@ impl SigV4Authenticator {
242
252
}
243
253
}
244
254
245
- pub ( crate ) fn get_string_to_sign ( & self ) -> Vec < u8 > {
255
+ /// Return the string to sign for the request.
256
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
257
+ pub fn get_string_to_sign ( & self ) -> Vec < u8 > {
246
258
let mut result = Vec :: with_capacity (
247
259
AWS4_HMAC_SHA256 . len ( ) + 1 + ISO8601_UTC_LENGTH + 1 + self . credential . len ( ) + 1 + SHA256_HEX_LENGTH ,
248
260
) ;
@@ -263,6 +275,7 @@ impl SigV4Authenticator {
263
275
}
264
276
265
277
/// Validate the request signature.
278
+ #[ cfg_attr( doc, doc( cfg( feature = "unstable" ) ) ) ]
266
279
pub async fn validate_signature < S , F > (
267
280
& self ,
268
281
region : & str ,
@@ -303,18 +316,20 @@ impl Debug for SigV4Authenticator {
303
316
}
304
317
}
305
318
306
- #[ allow( dead_code) ] // used in tests
307
319
impl SigV4AuthenticatorBuilder {
308
- pub ( crate ) fn get_credential ( & self ) -> & Option < String > {
309
- & self . credential
320
+ /// Retrieve the credential passed into the request.
321
+ pub fn get_credential ( & self ) -> Option < & str > {
322
+ self . credential . as_deref ( )
310
323
}
311
324
312
- pub ( crate ) fn get_signature ( & self ) -> & Option < String > {
313
- & self . signature
325
+ /// Retrieve the signature passed into the request.
326
+ pub fn get_signature ( & self ) -> Option < & str > {
327
+ self . signature . as_deref ( )
314
328
}
315
329
316
- pub ( crate ) fn get_session_token ( & self ) -> & Option < Option < String > > {
317
- & self . session_token
330
+ /// Retrieve the session token passed into the request.
331
+ pub fn get_session_token ( & self ) -> Option < & str > {
332
+ self . session_token . as_ref ( ) ?. as_deref ( )
318
333
}
319
334
}
320
335
@@ -377,8 +392,8 @@ mod tests {
377
392
use {
378
393
super :: duration_to_string,
379
394
crate :: {
380
- service_for_signing_key_fn , GetSigningKeyRequest , GetSigningKeyResponse , KSecretKey , SigV4Authenticator ,
381
- SigV4AuthenticatorBuilder , SigV4AuthenticatorResponse , SignatureError ,
395
+ auth :: { SigV4Authenticator , SigV4AuthenticatorBuilder , SigV4AuthenticatorResponse } ,
396
+ service_for_signing_key_fn , GetSigningKeyRequest , GetSigningKeyResponse , KSecretKey , SignatureError ,
382
397
} ,
383
398
chrono:: { DateTime , Duration , NaiveDate , NaiveDateTime , NaiveTime , Utc } ,
384
399
log:: LevelFilter ,
0 commit comments