@@ -26,6 +26,7 @@ pub trait VHeader {
26
26
}
27
27
28
28
use crate :: s3:: error:: Error ;
29
+ use crate :: utils:: consts:: * ;
29
30
use crate :: utils:: GenericResult ;
30
31
#[ derive( Debug ) ]
31
32
pub struct BaseArgs {
@@ -103,7 +104,7 @@ pub fn extract_args<R: VHeader>(r: &R) -> Result<BaseArgs, AuthError> {
103
104
// Special handling for common S3 content hash values
104
105
let normalized_content_hash = match content_hash. as_str ( ) {
105
106
"UNSIGNED-PAYLOAD" => content_hash,
106
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" => content_hash,
107
+ EMPTY_PAYLOAD_HASH => content_hash,
107
108
_ => content_hash,
108
109
} ;
109
110
@@ -223,7 +224,7 @@ pub fn get_v4_signature<T: VHeader, S: ToString>(
223
224
fn get_v4_ksigning ( secretkey : & str , region : & str , xamz_date : & str ) -> GenericResult < [ u8 ; 32 ] > {
224
225
let mut ksign = [ 0u8 ; 32 ] ;
225
226
circle_hmac_sha256 (
226
- format ! ( "AWS4{secretkey}" ) . as_str ( ) ,
227
+ format ! ( "{}{}" , "AWS4" , secretkey ) . as_str ( ) ,
227
228
vec ! [
228
229
& xamz_date. as_bytes( ) [ ..8 ] ,
229
230
region. as_bytes( ) ,
@@ -285,8 +286,16 @@ impl HmacSha256CircleHasher {
285
286
}
286
287
let mut hsh = ans. unwrap ( ) ;
287
288
let tosign = format ! (
288
- "AWS4-HMAC-SHA256-PAYLOAD\n {}\n {}/{}/s3/aws4_request\n {}\n e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n {}" ,
289
- self . xamz_date, self . date, self . region, self . last_hash, curr_hsh
289
+ "{}\n {}\n {}/{}/{}/{}\n {}\n {}\n {}" ,
290
+ "AWS4-HMAC-SHA256-PAYLOAD" ,
291
+ self . xamz_date,
292
+ self . date,
293
+ self . region,
294
+ "s3" ,
295
+ "aws4_request" ,
296
+ self . last_hash,
297
+ EMPTY_PAYLOAD_HASH ,
298
+ curr_hsh
290
299
) ;
291
300
hsh. update ( tosign. as_bytes ( ) ) ;
292
301
let ans = hsh. finalize ( ) . into_bytes ( ) ;
@@ -331,169 +340,3 @@ impl V4Head {
331
340
& mut self . circle_hasher
332
341
}
333
342
}
334
-
335
- #[ cfg( test) ]
336
- mod v4test {
337
- use std:: { collections:: HashMap , io:: Write } ;
338
- extern crate sha1;
339
- use self :: sha1:: Digest ;
340
-
341
- use crate :: utils:: { BaseKv , GenericResult } ;
342
-
343
- use super :: VHeader ;
344
- impl VHeader for HashMap < String , String > {
345
- fn get_header ( & self , key : & str ) -> Option < String > {
346
- let ans = self . get ( key) ;
347
- ans. cloned ( )
348
- }
349
-
350
- fn set_header ( & mut self , key : & str , val : & str ) {
351
- self . insert ( key. to_string ( ) , val. to_string ( ) ) ;
352
- }
353
-
354
- fn delete_header ( & mut self , key : & str ) {
355
- self . remove ( key) ;
356
- }
357
-
358
- fn rng_header ( & self , mut cb : impl FnMut ( & str , & str ) -> bool ) {
359
- self . iter ( ) . all ( |( k, v) | cb ( k, v) ) ;
360
- }
361
- }
362
- #[ test]
363
- fn v4_signature_test ( ) -> GenericResult < ( ) > {
364
- //case1
365
- let mut hm = HashMap :: new ( ) ;
366
- hm. insert ( "x-amz-date" . to_string ( ) , "20250407T021123Z" . to_string ( ) ) ;
367
- hm. insert (
368
- "x-amz-content-sha256" . to_string ( ) ,
369
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" . to_string ( ) ,
370
- ) ;
371
- hm. insert ( "host" . to_string ( ) , "127.0.0.1:9000" . to_string ( ) ) ;
372
- let ( signature, _) = super :: get_v4_signature (
373
- & hm,
374
- "GET" ,
375
- "us-east-1" ,
376
- "s3" ,
377
- "/" ,
378
- "root12345" ,
379
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ,
380
- & [ "host" , "x-amz-content-sha256" , "x-amz-date" ] ,
381
- vec ! [ ] ,
382
- ) ?;
383
- assert ! (
384
- signature == "2e3e50b8ab771944088edcda925d886a078ec2442e8504f58e1ac3ef8a2f40fc" ,
385
- "expect 2e3e50b8ab771944088edcda925d886a078ec2442e8504f58e1ac3ef8a2f40fc, get {}" ,
386
- signature,
387
- ) ;
388
- //case2
389
- let mut hm = HashMap :: new ( ) ;
390
- hm. insert ( "x-amz-date" . to_string ( ) , "20250407T060526Z" . to_string ( ) ) ;
391
- hm. insert (
392
- "x-amz-content-sha256" . to_string ( ) ,
393
- "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" . to_string ( ) ,
394
- ) ;
395
- hm. insert ( "host" . to_string ( ) , "127.0.0.1:9000" . to_string ( ) ) ;
396
- hm. insert ( "x-amz-decoded-content-length" . to_string ( ) , "6" . to_string ( ) ) ;
397
- let ( signature, _) = super :: get_v4_signature (
398
- & hm,
399
- "PUT" ,
400
- "us-east-1" ,
401
- "s3" ,
402
- "/test/hello.txt" ,
403
- "root12345" ,
404
- "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" ,
405
- & [
406
- "host" ,
407
- "x-amz-content-sha256" ,
408
- "x-amz-date" ,
409
- "x-amz-decoded-content-length" ,
410
- ] ,
411
- vec ! [ ] ,
412
- ) ?;
413
- assert ! (
414
- signature == "ae05fb994613c1a72e9f1d3bf14de119155587b955ca7d5589a056e7ffab680f" ,
415
- "expect ae05fb994613c1a72e9f1d3bf14de119155587b955ca7d5589a056e7ffab680f,get {}" ,
416
- signature
417
- ) ;
418
- //case3
419
- let mut hm = HashMap :: new ( ) ;
420
- hm. insert ( "x-amz-date" . to_string ( ) , "20250410T124056Z" . to_string ( ) ) ;
421
- hm. insert (
422
- "x-amz-content-sha256" . to_string ( ) ,
423
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" . to_string ( ) ,
424
- ) ;
425
- hm. insert ( "host" . to_string ( ) , "127.0.0.1:9000" . to_string ( ) ) ;
426
- let ( signature, _) = super :: get_v4_signature (
427
- & hm,
428
- "GET" ,
429
- "us-east-1" ,
430
- "s3" ,
431
- "/test/" ,
432
- "root12345" ,
433
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ,
434
- & [ "host" , "x-amz-content-sha256" , "x-amz-date" ] ,
435
- vec ! [ BaseKv {
436
- key: "location" . to_string( ) ,
437
- val: "" . to_string( ) ,
438
- } ] ,
439
- ) ?;
440
- assert ! (
441
- signature == "f51cf31bf489474692475a74706f9382c7ba0e93e0d657dc9696efa83fc3906a" ,
442
- "expect f51cf31bf489474692475a74706f9382c7ba0e93e0d657dc9696efa83fc3906a, get {}" ,
443
- signature,
444
- ) ;
445
- Ok ( ( ) )
446
- }
447
- #[ test]
448
- fn v4_chunk_signature_test ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
449
- let mut hm = HashMap :: new ( ) ;
450
- hm. insert ( "x-amz-date" . to_string ( ) , "20250407T060526Z" . to_string ( ) ) ;
451
- hm. insert (
452
- "x-amz-content-sha256" . to_string ( ) ,
453
- "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" . to_string ( ) ,
454
- ) ;
455
- hm. insert ( "host" . to_string ( ) , "127.0.0.1:9000" . to_string ( ) ) ;
456
- hm. insert ( "x-amz-decoded-content-length" . to_string ( ) , "6" . to_string ( ) ) ;
457
- let ( headersignature, _) = super :: get_v4_signature (
458
- & hm,
459
- "PUT" ,
460
- "us-east-1" ,
461
- "s3" ,
462
- "/test/hello.txt" ,
463
- "root12345" ,
464
- "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" ,
465
- & [
466
- "host" ,
467
- "x-amz-content-sha256" ,
468
- "x-amz-date" ,
469
- "x-amz-decoded-content-length" ,
470
- ] ,
471
- vec ! [ ] ,
472
- ) ?;
473
- let ksigning = super :: get_v4_ksigning ( "root12345" , "us-east-1" , "20250407T060526Z" ) ?;
474
-
475
- let mut hsch = super :: HmacSha256CircleHasher :: new (
476
- ksigning,
477
- headersignature,
478
- "20250407T060526Z" . to_string ( ) ,
479
- "us-east-1" . to_string ( ) ,
480
- ) ;
481
- let mut hsh = sha2:: Sha256 :: default ( ) ;
482
- let _ = hsh. write_all ( "hello\n " . as_bytes ( ) ) ;
483
- let ans = hsh. finalize ( ) ;
484
- let hsh = hsch. next ( hex:: encode ( ans) . as_str ( ) ) ?;
485
- assert ! (
486
- hsh == "fe78329ef4be9a33af1ffb23c435cf9d985c79dc65911ac78a66317f5a0521bb" ,
487
- "expect fe78329ef4be9a33af1ffb23c435cf9d985c79dc65911ac78a66317f5a0521bb,get {}" ,
488
- hsh
489
- ) ;
490
- let final_chunk_hsh =
491
- hsch. next ( "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ) ?;
492
- assert ! (
493
- final_chunk_hsh == "9095844b0da3ae2e9fe65b372662c4beadfc38ebe5a709b16ea9b03d427d03ad" ,
494
- "expect 9095844b0da3ae2e9fe65b372662c4beadfc38ebe5a709b16ea9b03d427d03ad,get {}" ,
495
- final_chunk_hsh
496
- ) ;
497
- Ok ( ( ) )
498
- }
499
- }
0 commit comments