10
10
import fnmatch
11
11
import logging
12
12
import os
13
- from typing import BinaryIO , Dict , Optional , TextIO
13
+ from typing import Dict , Optional
14
14
15
15
from securesystemslib import exceptions as sslib_exceptions
16
16
from securesystemslib import hash as sslib_hash
@@ -158,9 +158,8 @@ def download_target(self, target: Dict, destination_directory: str):
158
158
temp_obj = download .download_file (
159
159
file_mirror , target ["fileinfo" ]["length" ], self ._fetcher
160
160
)
161
-
162
- temp_obj .seek (0 )
163
- self ._verify_target_file (temp_obj , target )
161
+ _check_file_length (temp_obj , target ["fileinfo" ]["length" ])
162
+ _check_hashes_obj (temp_obj , target ["fileinfo" ]["hashes" ])
164
163
break
165
164
166
165
except Exception as exception :
@@ -297,7 +296,7 @@ def _root_mirrors_download(self, root_mirrors: Dict) -> "RootWrapper":
297
296
)
298
297
299
298
temp_obj .seek (0 )
300
- intermediate_root = self ._verify_root (temp_obj )
299
+ intermediate_root = self ._verify_root (temp_obj . read () )
301
300
# When we reach this point, a root file has been successfully
302
301
# downloaded and verified so we can exit the loop.
303
302
break
@@ -344,7 +343,7 @@ def _load_timestamp(self) -> None:
344
343
)
345
344
346
345
temp_obj .seek (0 )
347
- verified_timestamp = self ._verify_timestamp (temp_obj )
346
+ verified_timestamp = self ._verify_timestamp (temp_obj . read () )
348
347
break
349
348
350
349
except Exception as exception : # pylint: disable=broad-except
@@ -397,7 +396,7 @@ def _load_snapshot(self) -> None:
397
396
)
398
397
399
398
temp_obj .seek (0 )
400
- verified_snapshot = self ._verify_snapshot (temp_obj )
399
+ verified_snapshot = self ._verify_snapshot (temp_obj . read () )
401
400
break
402
401
403
402
except Exception as exception : # pylint: disable=broad-except
@@ -451,7 +450,7 @@ def _load_targets(self, targets_role: str, parent_role: str) -> None:
451
450
452
451
temp_obj .seek (0 )
453
452
verified_targets = self ._verify_targets (
454
- temp_obj , targets_role , parent_role
453
+ temp_obj . read () , targets_role , parent_role
455
454
)
456
455
break
457
456
@@ -472,12 +471,12 @@ def _load_targets(self, targets_role: str, parent_role: str) -> None:
472
471
self ._get_full_meta_name (targets_role , extension = ".json" )
473
472
)
474
473
475
- def _verify_root (self , temp_obj : TextIO ) -> RootWrapper :
474
+ def _verify_root (self , file_content : bytes ) -> RootWrapper :
476
475
"""
477
476
TODO
478
477
"""
479
478
480
- intermediate_root = RootWrapper .from_json_object (temp_obj )
479
+ intermediate_root = RootWrapper .from_json_object (file_content )
481
480
482
481
# Check for an arbitrary software attack
483
482
trusted_root = self ._metadata ["root" ]
@@ -490,7 +489,6 @@ def _verify_root(self, temp_obj: TextIO) -> RootWrapper:
490
489
491
490
# Check for a rollback attack.
492
491
if intermediate_root .version < trusted_root .version :
493
- temp_obj .close ()
494
492
raise exceptions .ReplayedMetadataError (
495
493
"root" , intermediate_root .version (), trusted_root .version ()
496
494
)
@@ -499,11 +497,11 @@ def _verify_root(self, temp_obj: TextIO) -> RootWrapper:
499
497
500
498
return intermediate_root
501
499
502
- def _verify_timestamp (self , temp_obj : TextIO ) -> TimestampWrapper :
500
+ def _verify_timestamp (self , file_content : bytes ) -> TimestampWrapper :
503
501
"""
504
502
TODO
505
503
"""
506
- intermediate_timestamp = TimestampWrapper .from_json_object (temp_obj )
504
+ intermediate_timestamp = TimestampWrapper .from_json_object (file_content )
507
505
508
506
# Check for an arbitrary software attack
509
507
trusted_root = self ._metadata ["root" ]
@@ -517,7 +515,6 @@ def _verify_timestamp(self, temp_obj: TextIO) -> TimestampWrapper:
517
515
intermediate_timestamp .signed .version
518
516
<= self ._metadata ["timestamp" ].version
519
517
):
520
- temp_obj .close ()
521
518
raise exceptions .ReplayedMetadataError (
522
519
"root" ,
523
520
intermediate_timestamp .version (),
@@ -529,7 +526,6 @@ def _verify_timestamp(self, temp_obj: TextIO) -> TimestampWrapper:
529
526
intermediate_timestamp .snapshot .version
530
527
<= self ._metadata ["timestamp" ].snapshot ["version" ]
531
528
):
532
- temp_obj .close ()
533
529
raise exceptions .ReplayedMetadataError (
534
530
"root" ,
535
531
intermediate_timestamp .snapshot .version (),
@@ -540,24 +536,23 @@ def _verify_timestamp(self, temp_obj: TextIO) -> TimestampWrapper:
540
536
541
537
return intermediate_timestamp
542
538
543
- def _verify_snapshot (self , temp_obj : TextIO ) -> SnapshotWrapper :
539
+ def _verify_snapshot (self , file_content : bytes ) -> SnapshotWrapper :
544
540
"""
545
541
TODO
546
542
"""
547
543
548
544
# Check against timestamp metadata
549
545
if self ._metadata ["timestamp" ].snapshot .get ("hash" ):
550
546
_check_hashes (
551
- temp_obj , self ._metadata ["timestamp" ].snapshot .get ("hash" )
547
+ file_content , self ._metadata ["timestamp" ].snapshot .get ("hash" )
552
548
)
553
549
554
- intermediate_snapshot = SnapshotWrapper .from_json_object (temp_obj )
550
+ intermediate_snapshot = SnapshotWrapper .from_json_object (file_content )
555
551
556
552
if (
557
553
intermediate_snapshot .version
558
554
!= self ._metadata ["timestamp" ].snapshot ["version" ]
559
555
):
560
- temp_obj .close ()
561
556
raise exceptions .BadVersionNumberError
562
557
563
558
# Check for an arbitrary software attack
@@ -573,15 +568,14 @@ def _verify_snapshot(self, temp_obj: TextIO) -> SnapshotWrapper:
573
568
target_role ["version" ]
574
569
!= self ._metadata ["snapshot" ].meta [target_role ]["version" ]
575
570
):
576
- temp_obj .close ()
577
571
raise exceptions .BadVersionNumberError
578
572
579
573
intermediate_snapshot .expires ()
580
574
581
575
return intermediate_snapshot
582
576
583
577
def _verify_targets (
584
- self , temp_obj : TextIO , filename : str , parent_role : str
578
+ self , file_content : bytes , filename : str , parent_role : str
585
579
) -> TargetsWrapper :
586
580
"""
587
581
TODO
@@ -590,15 +584,14 @@ def _verify_targets(
590
584
# Check against timestamp metadata
591
585
if self ._metadata ["snapshot" ].role (filename ).get ("hash" ):
592
586
_check_hashes (
593
- temp_obj , self ._metadata ["snapshot" ].targets .get ("hash" )
587
+ file_content , self ._metadata ["snapshot" ].targets .get ("hash" )
594
588
)
595
589
596
- intermediate_targets = TargetsWrapper .from_json_object (temp_obj )
590
+ intermediate_targets = TargetsWrapper .from_json_object (file_content )
597
591
if (
598
592
intermediate_targets .version
599
593
!= self ._metadata ["snapshot" ].role (filename )["version" ]
600
594
):
601
- temp_obj .close ()
602
595
raise exceptions .BadVersionNumberError
603
596
604
597
# Check for an arbitrary software attack
@@ -612,15 +605,6 @@ def _verify_targets(
612
605
613
606
return intermediate_targets
614
607
615
- @staticmethod
616
- def _verify_target_file (temp_obj : BinaryIO , targetinfo : Dict ) -> None :
617
- """
618
- TODO
619
- """
620
-
621
- _check_file_length (temp_obj , targetinfo ["fileinfo" ]["length" ])
622
- _check_hashes (temp_obj , targetinfo ["fileinfo" ]["hashes" ])
623
-
624
608
def _preorder_depth_first_walk (self , target_filepath ) -> Dict :
625
609
"""
626
610
TODO
@@ -849,19 +833,24 @@ def _check_file_length(file_object, trusted_file_length):
849
833
)
850
834
851
835
852
- def _check_hashes (file_object , trusted_hashes ):
836
+ def _check_hashes_obj (file_object , trusted_hashes ):
837
+ """
838
+ TODO
839
+ """
840
+ file_object .seek (0 )
841
+ return _check_hashes (file_object .read (), trusted_hashes )
842
+
843
+
844
+ def _check_hashes (file_content , trusted_hashes ):
853
845
"""
854
846
TODO
855
847
"""
856
848
# Verify each trusted hash of 'trusted_hashes'. If all are valid, simply
857
849
# return.
858
850
for algorithm , trusted_hash in trusted_hashes .items ():
859
851
digest_object = sslib_hash .digest (algorithm )
860
- # Ensure we read from the beginning of the file object
861
- # TODO: should we store file position (before the loop) and reset
862
- # after we seek about?
863
- file_object .seek (0 )
864
- digest_object .update (file_object .read ())
852
+
853
+ digest_object .update (file_content )
865
854
computed_hash = digest_object .hexdigest ()
866
855
867
856
# Raise an exception if any of the hashes are incorrect.
0 commit comments