@@ -1412,9 +1412,81 @@ def _verify_root_self_signed(self, signable):
1412
1412
1413
1413
1414
1414
1415
+ def _validate_metadata_version (self , expected_version , metadata_role ,
1416
+ version_downloaded ):
1417
+ """
1418
+ Validates the metadata version number.
1419
+ If the version number is unspecified, ensure that the version number
1420
+ downloaded is greater than the currently trusted version number for
1421
+ 'metadata_role'.
1422
+ """
1423
+
1424
+ if expected_version is not None :
1425
+ if version_downloaded != expected_version :
1426
+ raise tuf .exceptions .BadVersionNumberError ('Downloaded'
1427
+ ' version number: ' + repr (version_downloaded ) + '. Version'
1428
+ ' number MUST be: ' + repr (expected_version ))
1429
+
1430
+ # The caller does not know which version to download.
1431
+ # Verify that the downloaded version is at least greater
1432
+ # than the one locally available.
1433
+ else :
1434
+ try :
1435
+ current_version = self .metadata ['current' ][metadata_role ]['version' ]
1436
+
1437
+ if version_downloaded < current_version :
1438
+ raise tuf .exceptions .ReplayedMetadataError (metadata_role ,
1439
+ version_downloaded , current_version )
1440
+
1441
+ except KeyError :
1442
+ logger .info (metadata_role + ' not available locally.' )
1443
+
1444
+
1445
+
1446
+ def _validate_spec_version (self , metadata_spec_version ):
1447
+ """
1448
+ Validates if the specification version number is supported.
1449
+ It is assumed that "spec_version" is in (major.minor.fix) format,
1450
+ (for example: "1.4.3") and that releases with the same major version
1451
+ number maintain backward compatibility.
1452
+ Consequently, if the major version number of new metadata equals our
1453
+ expected major version number, the new metadata is safe to parse.
1454
+ """
1455
+
1456
+ try :
1457
+ metadata_spec_version_split = metadata_spec_version .split ('.' )
1458
+ metadata_spec_major_version = int (metadata_spec_version_split [0 ])
1459
+ metadata_spec_minor_version = int (metadata_spec_version_split [1 ])
1460
+
1461
+ code_spec_version_split = tuf .SPECIFICATION_VERSION .split ('.' )
1462
+ code_spec_major_version = int (code_spec_version_split [0 ])
1463
+ code_spec_minor_version = int (code_spec_version_split [1 ])
1464
+
1465
+ if metadata_spec_major_version != code_spec_major_version :
1466
+ raise tuf .exceptions .UnsupportedSpecificationError (
1467
+ 'Downloaded metadata that specifies an unsupported spec_version. '
1468
+ 'This code supports major version number: ' +
1469
+ repr (code_spec_major_version ) + '; however,'
1470
+ 'metadata spec version is: ' + str (metadata_spec_version ))
1471
+
1472
+ # report to user if minor versions do not match, continue with update
1473
+ if metadata_spec_minor_version != code_spec_minor_version :
1474
+ logger .info ("Downloaded metadata that specifies a different minor " +
1475
+ "spec_version." )
1476
+ logger .info ("This code has version " + tuf .SPECIFICATION_VERSION +
1477
+ " and the metadata lists version number " +
1478
+ str (metadata_spec_version ) + "." )
1479
+ logger .info ("The update will continue as the major versions match." )
1480
+
1481
+ except (ValueError , TypeError ) as error :
1482
+ six .raise_from (securesystemslib .exceptions .FormatError ('Improperly'
1483
+ ' formatted spec_version, which must be in major.minor.fix format' ),
1484
+ error )
1485
+
1486
+
1415
1487
1416
1488
def _verify_metadata_file (self , metadata_file_object ,
1417
- metadata_role ):
1489
+ metadata_role , expected_version ):
1418
1490
"""
1419
1491
<Purpose>
1420
1492
Non-public method that verifies a metadata file. An exception is
@@ -1429,6 +1501,10 @@ def _verify_metadata_file(self, metadata_file_object,
1429
1501
The role name of the metadata (e.g., 'root', 'targets',
1430
1502
'unclaimed').
1431
1503
1504
+ expected_version:
1505
+ An integer representing the expected and required version number
1506
+ of the 'metadata_role' file downloaded.
1507
+
1432
1508
<Exceptions>
1433
1509
securesystemslib.exceptions.FormatError:
1434
1510
In case the metadata file is valid JSON, but not valid TUF metadata.
@@ -1468,6 +1544,11 @@ def _verify_metadata_file(self, metadata_file_object,
1468
1544
# 'securesystemslib.exceptions.FormatError' if not.
1469
1545
tuf .formats .check_signable_object_format (metadata_signable )
1470
1546
1547
+ self ._validate_spec_version (metadata_signable ['signed' ]['spec_version' ])
1548
+
1549
+ self ._validate_metadata_version (expected_version , metadata_role ,
1550
+ metadata_signable ['signed' ]['version' ])
1551
+
1471
1552
# Is 'metadata_signable' expired?
1472
1553
self ._ensure_not_expired (metadata_signable ['signed' ], metadata_role )
1473
1554
@@ -1521,8 +1602,8 @@ def _get_metadata_file(self, metadata_role, remote_filename,
1521
1602
downloaded.
1522
1603
1523
1604
expected_version:
1524
- The expected and required version number of the 'metadata_role' file
1525
- downloaded. 'expected_version' is an integer .
1605
+ An integer representing the expected and required version number
1606
+ of the 'metadata_role' file downloaded .
1526
1607
1527
1608
<Exceptions>
1528
1609
tuf.exceptions.NoWorkingMirrorError:
@@ -1549,85 +1630,9 @@ def _get_metadata_file(self, metadata_role, remote_filename,
1549
1630
try :
1550
1631
file_object = tuf .download .unsafe_download (file_mirror ,
1551
1632
upperbound_filelength )
1552
- file_object .seek (0 )
1553
-
1554
- # Verify 'file_object' according to the callable function.
1555
- # 'file_object' is also verified if decompressed above (i.e., the
1556
- # uncompressed version).
1557
- metadata_signable = \
1558
- securesystemslib .util .load_json_string (file_object .read ().decode ('utf-8' ))
1559
-
1560
- # Determine if the specification version number is supported. It is
1561
- # assumed that "spec_version" is in (major.minor.fix) format, (for
1562
- # example: "1.4.3") and that releases with the same major version
1563
- # number maintain backwards compatibility. Consequently, if the major
1564
- # version number of new metadata equals our expected major version
1565
- # number, the new metadata is safe to parse.
1566
- try :
1567
- metadata_spec_version = metadata_signable ['signed' ]['spec_version' ]
1568
- metadata_spec_version_split = metadata_spec_version .split ('.' )
1569
- metadata_spec_major_version = int (metadata_spec_version_split [0 ])
1570
- metadata_spec_minor_version = int (metadata_spec_version_split [1 ])
1571
-
1572
- code_spec_version_split = tuf .SPECIFICATION_VERSION .split ('.' )
1573
- code_spec_major_version = int (code_spec_version_split [0 ])
1574
- code_spec_minor_version = int (code_spec_version_split [1 ])
1575
-
1576
- if metadata_spec_major_version != code_spec_major_version :
1577
- raise tuf .exceptions .UnsupportedSpecificationError (
1578
- 'Downloaded metadata that specifies an unsupported '
1579
- 'spec_version. This code supports major version number: ' +
1580
- repr (code_spec_major_version ) + '; however, the obtained '
1581
- 'metadata lists version number: ' + str (metadata_spec_version ))
1582
-
1583
- #report to user if minor versions do not match, continue with update
1584
- if metadata_spec_minor_version != code_spec_minor_version :
1585
- logger .info ("Downloaded metadata that specifies a different minor " +
1586
- "spec_version. This code has version " +
1587
- str (tuf .SPECIFICATION_VERSION ) +
1588
- " and the metadata lists version number " +
1589
- str (metadata_spec_version ) +
1590
- ". The update will continue as the major versions match." )
1591
-
1592
- except (ValueError , TypeError ) as error :
1593
- six .raise_from (securesystemslib .exceptions .FormatError ('Improperly'
1594
- ' formatted spec_version, which must be in major.minor.fix format' ),
1595
- error )
1596
-
1597
- # If the version number is unspecified, ensure that the version number
1598
- # downloaded is greater than the currently trusted version number for
1599
- # 'metadata_role'.
1600
- version_downloaded = metadata_signable ['signed' ]['version' ]
1601
-
1602
- if expected_version is not None :
1603
- # Verify that the downloaded version matches the version expected by
1604
- # the caller.
1605
- if version_downloaded != expected_version :
1606
- raise tuf .exceptions .BadVersionNumberError ('Downloaded'
1607
- ' version number: ' + repr (version_downloaded ) + '. Version'
1608
- ' number MUST be: ' + repr (expected_version ))
1609
-
1610
- # The caller does not know which version to download. Verify that the
1611
- # downloaded version is at least greater than the one locally
1612
- # available.
1613
- else :
1614
- # Verify that the version number of the locally stored
1615
- # 'timestamp.json', if available, is less than what was downloaded.
1616
- # Otherwise, accept the new timestamp with version number
1617
- # 'version_downloaded'.
1618
-
1619
- try :
1620
- current_version = \
1621
- self .metadata ['current' ][metadata_role ]['version' ]
1622
-
1623
- if version_downloaded < current_version :
1624
- raise tuf .exceptions .ReplayedMetadataError (metadata_role ,
1625
- version_downloaded , current_version )
1626
-
1627
- except KeyError :
1628
- logger .info (metadata_role + ' not available locally.' )
1629
1633
1630
- self ._verify_metadata_file (file_object , metadata_role )
1634
+ self ._verify_metadata_file (file_object , metadata_role ,
1635
+ expected_version )
1631
1636
1632
1637
except Exception as exception :
1633
1638
# Remember the error from this mirror, and "reset" the target file.
0 commit comments