@@ -9,6 +9,7 @@ use thiserror::Error;
99type HmacSha256 = Hmac < Sha256 > ;
1010
1111pub const MIN_SIGNATURE_KEY_LENGTH : usize = 32 ;
12+ const SIGNATURE_MESSAGE_PREFIX : & [ u8 ] = b"artifact-signature:v2" ;
1213
1314#[ derive( Debug , Error ) ]
1415pub enum SignatureError {
@@ -76,18 +77,16 @@ impl ArtifactSignatureAuthenticator {
7677 . into_raw_vec ( ) )
7778 }
7879
79- fn construct_metadata ( & self , hash : & [ u8 ] ) -> Result < Vec < u8 > , SignatureError > {
80- let mut metadata = hash. to_vec ( ) ;
81- metadata. extend_from_slice ( & self . team_id ) ;
82-
83- Ok ( metadata)
84- }
85-
86- fn get_tag_generator ( & self , hash : & [ u8 ] ) -> Result < HmacSha256 , SignatureError > {
80+ fn get_tag_generator (
81+ & self ,
82+ hash : & [ u8 ] ,
83+ artifact_body : & [ u8 ] ,
84+ ) -> Result < HmacSha256 , SignatureError > {
8785 let mut mac = HmacSha256 :: new_from_slice ( & self . secret_key ( ) ?) ?;
88- let metadata = self . construct_metadata ( hash) ?;
89-
90- mac. update ( & metadata) ;
86+ update_message_field ( & mut mac, SIGNATURE_MESSAGE_PREFIX ) ;
87+ update_message_field ( & mut mac, hash) ;
88+ update_message_field ( & mut mac, & self . team_id ) ;
89+ update_message_field ( & mut mac, artifact_body) ;
9190
9291 Ok ( mac)
9392 }
@@ -98,9 +97,7 @@ impl ArtifactSignatureAuthenticator {
9897 hash : & [ u8 ] ,
9998 artifact_body : & [ u8 ] ,
10099 ) -> Result < Vec < u8 > , SignatureError > {
101- let mut mac = self . get_tag_generator ( hash) ?;
102-
103- mac. update ( artifact_body) ;
100+ let mac = self . get_tag_generator ( hash, artifact_body) ?;
104101 let hmac_output = mac. finalize ( ) ;
105102 Ok ( hmac_output. into_bytes ( ) . to_vec ( ) )
106103 }
@@ -111,9 +108,7 @@ impl ArtifactSignatureAuthenticator {
111108 hash : & [ u8 ] ,
112109 artifact_body : & [ u8 ] ,
113110 ) -> Result < String , SignatureError > {
114- let mut hmac_ctx = self . get_tag_generator ( hash) ?;
115-
116- hmac_ctx. update ( artifact_body) ;
111+ let hmac_ctx = self . get_tag_generator ( hash, artifact_body) ?;
117112 let hmac_output = hmac_ctx. finalize ( ) ;
118113 Ok ( BASE64_STANDARD . encode ( hmac_output. into_bytes ( ) ) )
119114 }
@@ -125,16 +120,18 @@ impl ArtifactSignatureAuthenticator {
125120 artifact_body : & [ u8 ] ,
126121 expected_tag : & str ,
127122 ) -> Result < bool , SignatureError > {
128- let mut mac = HmacSha256 :: new_from_slice ( & self . secret_key ( ) ?) ?;
129- let message = self . construct_metadata ( hash) ?;
130- mac. update ( & message) ;
131- mac. update ( artifact_body) ;
123+ let mac = self . get_tag_generator ( hash, artifact_body) ?;
132124
133125 let expected_bytes = BASE64_STANDARD . decode ( expected_tag) ?;
134126 Ok ( mac. verify_slice ( & expected_bytes) . is_ok ( ) )
135127 }
136128}
137129
130+ fn update_message_field ( mac : & mut HmacSha256 , field : & [ u8 ] ) {
131+ mac. update ( & ( field. len ( ) as u64 ) . to_le_bytes ( ) ) ;
132+ mac. update ( field) ;
133+ }
134+
138135#[ cfg( test) ]
139136mod tests {
140137 use anyhow:: Result ;
@@ -148,10 +145,7 @@ mod tests {
148145 artifact_body : & [ u8 ] ,
149146 expected_tag : & [ u8 ] ,
150147 ) -> Result < bool , SignatureError > {
151- let mut mac = HmacSha256 :: new_from_slice ( & self . secret_key ( ) ?) ?;
152- let message = self . construct_metadata ( hash) ?;
153- mac. update ( & message) ;
154- mac. update ( artifact_body) ;
148+ let mac = self . get_tag_generator ( hash, artifact_body) ?;
155149
156150 Ok ( mac. verify_slice ( expected_tag) . is_ok ( ) )
157151 }
@@ -354,4 +348,25 @@ mod tests {
354348 let tag = auth. generate_tag ( b"hash" , b"body" ) . unwrap ( ) ;
355349 assert ! ( auth. validate( b"hash" , b"body" , & tag) . unwrap( ) ) ;
356350 }
351+
352+ #[ test]
353+ fn test_signature_fields_are_separated ( ) {
354+ let secret_key = b"shared signing key" . to_vec ( ) ;
355+ let attacker = ArtifactSignatureAuthenticator {
356+ team_id : b"team_abc" . to_vec ( ) ,
357+ secret_key_override : Some ( secret_key. clone ( ) ) ,
358+ } ;
359+ let victim = ArtifactSignatureAuthenticator {
360+ team_id : b"team_ab" . to_vec ( ) ,
361+ secret_key_override : Some ( secret_key) ,
362+ } ;
363+
364+ let tag = attacker. generate_tag ( b"0123456789abcdef" , b"body" ) . unwrap ( ) ;
365+
366+ assert ! (
367+ !victim
368+ . validate( b"0123456789abcdef" , b"cbody" , & tag)
369+ . unwrap( )
370+ ) ;
371+ }
357372}
0 commit comments