@@ -33,9 +33,25 @@ pub(crate) struct SnapshotIntegrityKey {
3333 source_path : std:: path:: PathBuf ,
3434}
3535
36+ #[ derive( Debug , Clone , Eq , PartialEq , Deserialize , Serialize ) ]
37+ #[ serde( untagged) ]
38+ pub ( crate ) enum SnapshotIntegrityManifest {
39+ V2 ( SnapshotIntegrityManifestV2 ) ,
40+ V1 ( SnapshotIntegrityManifestV1 ) ,
41+ }
42+
43+ #[ derive( Debug , Clone , Eq , PartialEq , Deserialize , Serialize ) ]
44+ #[ serde( deny_unknown_fields) ]
45+ pub ( crate ) struct SnapshotIntegrityManifestV1 {
46+ pub algorithm : String ,
47+ pub key_id : String ,
48+ pub config_sha256 : String ,
49+ pub metadata_hmac_sha256 : String ,
50+ }
51+
3652#[ derive( Debug , Clone , Eq , PartialEq , Deserialize , Serialize ) ]
3753#[ serde( deny_unknown_fields) ]
38- pub ( crate ) struct SnapshotIntegrityManifest {
54+ pub ( crate ) struct SnapshotIntegrityManifestV2 {
3955 pub algorithm : String ,
4056 pub key_id : String ,
4157 pub config_sha256 : String ,
@@ -101,14 +117,14 @@ impl SnapshotIntegrityKey {
101117 . map_err ( SnapshotError :: CryptoProvider ) ?;
102118 let signature = self . sign_result ( id, config, metadata) ?;
103119 let generation_signature = self . sign_generation_witness ( id, generation) ?;
104- Ok ( SnapshotIntegrityManifest {
120+ Ok ( SnapshotIntegrityManifest :: V2 ( SnapshotIntegrityManifestV2 {
105121 algorithm : "hmac-sha256" . to_owned ( ) ,
106122 key_id : self . key_id . clone ( ) ,
107123 config_sha256 : hex ( & config_digest) ,
108124 metadata_hmac_sha256 : hex ( & signature) ,
109125 generation,
110126 generation_hmac_sha256 : hex ( & generation_signature) ,
111- } )
127+ } ) )
112128 }
113129
114130 pub ( crate ) fn key_id ( & self ) -> & str {
@@ -164,22 +180,25 @@ impl SnapshotIntegrityKey {
164180 generation : u64 ,
165181 manifest : & SnapshotIntegrityManifest ,
166182 ) -> Result < ( ) , SnapshotError > {
167- if manifest. algorithm != "hmac-sha256" || manifest. key_id != self . key_id {
183+ let common = manifest. common ( ) ;
184+ if common. algorithm != "hmac-sha256" || common. key_id != self . key_id {
168185 return Err ( SnapshotError :: IntegrityVerificationFailed { id : id. to_owned ( ) } ) ;
169186 }
170187 let config_digest = self
171188 . provider
172189 . sha256 ( & [ config] )
173190 . map_err ( SnapshotError :: CryptoProvider )
174191 . map ( |digest| hex ( & digest) ) ?;
175- if config_digest != manifest . config_sha256 {
192+ if config_digest != common . config_sha256 {
176193 return Err ( SnapshotError :: IntegrityVerificationFailed { id : id. to_owned ( ) } ) ;
177194 }
178- if manifest. generation != generation {
179- return Err ( SnapshotError :: IntegrityVerificationFailed { id : id. to_owned ( ) } ) ;
195+ if let SnapshotIntegrityManifest :: V2 ( witness) = manifest {
196+ if witness. generation != generation {
197+ return Err ( SnapshotError :: IntegrityVerificationFailed { id : id. to_owned ( ) } ) ;
198+ }
199+ self . verify_generation_witness ( id, witness) ?;
180200 }
181- self . verify_generation_witness ( id, manifest) ?;
182- let expected = decode_hex_32 ( & manifest. metadata_hmac_sha256 )
201+ let expected = decode_hex_32 ( common. metadata_hmac_sha256 )
183202 . ok_or_else ( || SnapshotError :: IntegrityVerificationFailed { id : id. to_owned ( ) } ) ?;
184203 if self
185204 . sign_result ( id, config, metadata) ?
@@ -195,7 +214,7 @@ impl SnapshotIntegrityKey {
195214 pub ( crate ) fn verify_generation_witness (
196215 & self ,
197216 id : & str ,
198- manifest : & SnapshotIntegrityManifest ,
217+ manifest : & SnapshotIntegrityManifestV2 ,
199218 ) -> Result < u64 , SnapshotError > {
200219 crate :: metadata:: validate_snapshot_id ( id) ?;
201220 if manifest. algorithm != "hmac-sha256" || manifest. key_id != self . key_id {
@@ -263,6 +282,32 @@ impl SnapshotIntegrityKey {
263282 }
264283}
265284
285+ impl SnapshotIntegrityManifest {
286+ fn common ( & self ) -> SnapshotIntegrityManifestCommon < ' _ > {
287+ match self {
288+ Self :: V2 ( manifest) => SnapshotIntegrityManifestCommon {
289+ algorithm : & manifest. algorithm ,
290+ key_id : & manifest. key_id ,
291+ config_sha256 : & manifest. config_sha256 ,
292+ metadata_hmac_sha256 : & manifest. metadata_hmac_sha256 ,
293+ } ,
294+ Self :: V1 ( manifest) => SnapshotIntegrityManifestCommon {
295+ algorithm : & manifest. algorithm ,
296+ key_id : & manifest. key_id ,
297+ config_sha256 : & manifest. config_sha256 ,
298+ metadata_hmac_sha256 : & manifest. metadata_hmac_sha256 ,
299+ } ,
300+ }
301+ }
302+ }
303+
304+ struct SnapshotIntegrityManifestCommon < ' a > {
305+ algorithm : & ' a str ,
306+ key_id : & ' a str ,
307+ config_sha256 : & ' a str ,
308+ metadata_hmac_sha256 : & ' a str ,
309+ }
310+
266311fn encoded_length ( length : usize ) -> Result < [ u8 ; 8 ] , SnapshotError > {
267312 u64:: try_from ( length)
268313 . map ( u64:: to_be_bytes)
0 commit comments