python-tuf/tests/test_formats.py
Kainaat Singh ec68bd9316 Remove future module #1297
Signed-off-by: Kainaat Singh <kainaatsingh93@gmail.com>

remove unwanted lines
2021-04-11 11:37:45 +02:00

971 lines
36 KiB
Python
Executable file

#!/usr/bin/env python
# Copyright 2012 - 2017, New York University and the TUF contributors
# SPDX-License-Identifier: MIT OR Apache-2.0
"""
<Program Name>
test_formats.py
<Author>
Vladimir Diaz <vladimir.v.diaz@gmail.com>
<Started>
October 2012.
<Copyright>
See LICENSE-MIT OR LICENSE for licensing information.
<Purpose>
Unit test for 'formats.py'
"""
import unittest
import datetime
import sys
import os
import tuf
import tuf.formats
from tests import utils
import securesystemslib
import securesystemslib.util
class TestFormats(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_schemas(self):
# Test conditions for valid schemas.
valid_schemas = {
'ISO8601_DATETIME_SCHEMA': (securesystemslib.formats.ISO8601_DATETIME_SCHEMA,
'1985-10-21T13:20:00Z'),
'UNIX_TIMESTAMP_SCHEMA': (securesystemslib.formats.UNIX_TIMESTAMP_SCHEMA, 499137720),
'HASH_SCHEMA': (securesystemslib.formats.HASH_SCHEMA, 'A4582BCF323BCEF'),
'HASHDICT_SCHEMA': (securesystemslib.formats.HASHDICT_SCHEMA,
{'sha256': 'A4582BCF323BCEF'}),
'HEX_SCHEMA': (securesystemslib.formats.HEX_SCHEMA, 'A4582BCF323BCEF'),
'KEYID_SCHEMA': (securesystemslib.formats.KEYID_SCHEMA, '123456789abcdef'),
'KEYIDS_SCHEMA': (securesystemslib.formats.KEYIDS_SCHEMA,
['123456789abcdef', '123456789abcdef']),
'SCHEME_SCHEMA': (securesystemslib.formats.SCHEME_SCHEMA, 'rsassa-pss-sha256'),
'RELPATH_SCHEMA': (tuf.formats.RELPATH_SCHEMA, 'metadata/root/'),
'RELPATHS_SCHEMA': (tuf.formats.RELPATHS_SCHEMA,
['targets/role1/', 'targets/role2/']),
'PATH_SCHEMA': (securesystemslib.formats.PATH_SCHEMA, '/home/someuser/'),
'PATHS_SCHEMA': (securesystemslib.formats.PATHS_SCHEMA,
['/home/McFly/', '/home/Tannen/']),
'URL_SCHEMA': (securesystemslib.formats.URL_SCHEMA,
'https://www.updateframework.com/'),
'VERSION_SCHEMA': (tuf.formats.VERSION_SCHEMA,
{'major': 1, 'minor': 0, 'fix': 8}),
'LENGTH_SCHEMA': (tuf.formats.LENGTH_SCHEMA, 8),
'NAME_SCHEMA': (securesystemslib.formats.NAME_SCHEMA, 'Marty McFly'),
'BOOLEAN_SCHEMA': (securesystemslib.formats.BOOLEAN_SCHEMA, True),
'THRESHOLD_SCHEMA': (tuf.formats.THRESHOLD_SCHEMA, 1),
'ROLENAME_SCHEMA': (tuf.formats.ROLENAME_SCHEMA, 'Root'),
'RSAKEYBITS_SCHEMA': (securesystemslib.formats.RSAKEYBITS_SCHEMA, 4096),
'PASSWORD_SCHEMA': (securesystemslib.formats.PASSWORD_SCHEMA, 'secret'),
'PASSWORDS_SCHEMA': (securesystemslib.formats.PASSWORDS_SCHEMA, ['pass1', 'pass2']),
'KEYVAL_SCHEMA': (securesystemslib.formats.KEYVAL_SCHEMA,
{'public': 'pubkey', 'private': 'privkey'}),
'KEY_SCHEMA': (securesystemslib.formats.KEY_SCHEMA,
{'keytype': 'rsa',
'scheme': 'rsassa-pss-sha256',
'keyval': {'public': 'pubkey',
'private': 'privkey'}}),
'RSAKEY_SCHEMA': (securesystemslib.formats.RSAKEY_SCHEMA,
{'keytype': 'rsa',
'scheme': 'rsassa-pss-sha256',
'keyid': '123456789abcdef',
'keyval': {'public': 'pubkey',
'private': 'privkey'}}),
'TARGETS_FILEINFO_SCHEMA': (tuf.formats.TARGETS_FILEINFO_SCHEMA,
{'length': 1024,
'hashes': {'sha256': 'A4582BCF323BCEF'},
'custom': {'type': 'paintjob'}}),
'METADATA_FILEINFO_SCHEMA': (tuf.formats.METADATA_FILEINFO_SCHEMA,
{'length': 1024,
'hashes': {'sha256': 'A4582BCF323BCEF'},
'version': 1}),
'FILEDICT_SCHEMA': (tuf.formats.FILEDICT_SCHEMA,
{'metadata/root.json': {'length': 1024,
'hashes': {'sha256': 'ABCD123'},
'custom': {'type': 'metadata'}}}),
'TARGETINFO_SCHEMA': (tuf.formats.TARGETINFO_SCHEMA,
{'filepath': 'targets/target1.gif',
'fileinfo': {'length': 1024,
'hashes': {'sha256': 'ABCD123'},
'custom': {'type': 'target'}}}),
'TARGETINFOS_SCHEMA': (tuf.formats.TARGETINFOS_SCHEMA,
[{'filepath': 'targets/target1.gif',
'fileinfo': {'length': 1024,
'hashes': {'sha256': 'ABCD123'},
'custom': {'type': 'target'}}}]),
'SIGNATURE_SCHEMA': (securesystemslib.formats.SIGNATURE_SCHEMA,
{'keyid': '123abc',
'sig': 'A4582BCF323BCEF'}),
'SIGNATURESTATUS_SCHEMA': (tuf.formats.SIGNATURESTATUS_SCHEMA,
{'threshold': 1,
'good_sigs': ['123abc'],
'bad_sigs': ['123abc'],
'unknown_sigs': ['123abc'],
'untrusted_sigs': ['123abc'],
'unknown_signing_schemes': ['123abc']}),
'SIGNABLE_SCHEMA': (tuf.formats.SIGNABLE_SCHEMA,
{'signed': 'signer',
'signatures': [{'keyid': '123abc',
'sig': 'A4582BCF323BCEF'}]}),
'KEYDICT_SCHEMA': (securesystemslib.formats.KEYDICT_SCHEMA,
{'123abc': {'keytype': 'rsa',
'scheme': 'rsassa-pss-sha256',
'keyval': {'public': 'pubkey',
'private': 'privkey'}}}),
'KEYDB_SCHEMA': (tuf.formats.KEYDB_SCHEMA,
{'123abc': {'keytype': 'rsa',
'scheme': 'rsassa-pss-sha256',
'keyid': '123456789abcdef',
'keyval': {'public': 'pubkey',
'private': 'privkey'}}}),
'SCPCONFIG_SCHEMA': (tuf.formats.SCPCONFIG_SCHEMA,
{'general': {'transfer_module': 'scp',
'metadata_path': '/path/meta.json',
'targets_directory': '/targets'},
'scp': {'host': 'http://localhost:8001',
'user': 'McFly',
'identity_file': '/home/.ssh/file',
'remote_directory': '/home/McFly'}}),
'RECEIVECONFIG_SCHEMA': (tuf.formats.RECEIVECONFIG_SCHEMA,
{'general': {'transfer_module': 'scp',
'pushroots': ['/pushes'],
'repository_directory': '/repo',
'metadata_directory': '/repo/meta',
'targets_directory': '/repo/targets',
'backup_directory': '/repo/backup'}}),
'ROLE_SCHEMA': (tuf.formats.ROLE_SCHEMA,
{'keyids': ['123abc'],
'threshold': 1,
'paths': ['path1/', 'path2']}),
'ROLEDICT_SCHEMA': (tuf.formats.ROLEDICT_SCHEMA,
{'root': {'keyids': ['123abc'],
'threshold': 1,
'paths': ['path1/', 'path2']}}),
'ROOT_SCHEMA': (tuf.formats.ROOT_SCHEMA,
{'_type': 'root',
'spec_version': '1.0.0',
'version': 8,
'consistent_snapshot': False,
'expires': '1985-10-21T13:20:00Z',
'keys': {'123abc': {'keytype': 'rsa',
'scheme': 'rsassa-pss-sha256',
'keyval': {'public': 'pubkey',
'private': 'privkey'}}},
'roles': {'root': {'keyids': ['123abc'],
'threshold': 1,
'paths': ['path1/', 'path2']}}}),
'TARGETS_SCHEMA': (tuf.formats.TARGETS_SCHEMA,
{'_type': 'targets',
'spec_version': '1.0.0',
'version': 8,
'expires': '1985-10-21T13:20:00Z',
'targets': {'metadata/targets.json': {'length': 1024,
'hashes': {'sha256': 'ABCD123'},
'custom': {'type': 'metadata'}}},
'delegations': {'keys': {'123abc': {'keytype':'rsa',
'scheme': 'rsassa-pss-sha256',
'keyval': {'public': 'pubkey',
'private': 'privkey'}}},
'roles': [{'name': 'root', 'keyids': ['123abc'],
'threshold': 1,
'paths': ['path1/', 'path2']}]}}),
'SNAPSHOT_SCHEMA': (tuf.formats.SNAPSHOT_SCHEMA,
{'_type': 'snapshot',
'spec_version': '1.0.0',
'version': 8,
'expires': '1985-10-21T13:20:00Z',
'meta': {'snapshot.json': {'version': 1024}}}),
'TIMESTAMP_SCHEMA': (tuf.formats.TIMESTAMP_SCHEMA,
{'_type': 'timestamp',
'spec_version': '1.0.0',
'version': 8,
'expires': '1985-10-21T13:20:00Z',
'meta': {'metadattimestamp.json': {'length': 1024,
'hashes': {'sha256': 'AB1245'},
'version': 1}}}),
'MIRROR_SCHEMA': (tuf.formats.MIRROR_SCHEMA,
{'url_prefix': 'http://localhost:8001',
'metadata_path': 'metadata/',
'targets_path': 'targets/',
'confined_target_dirs': ['path1/', 'path2/'],
'custom': {'type': 'mirror'}}),
'MIRROR_SCHEMA_NO_CONFINED_TARGETS': (tuf.formats.MIRROR_SCHEMA,
{'url_prefix': 'http://localhost:8001',
'metadata_path': 'metadata/',
'targets_path': 'targets/',
'custom': {'type': 'mirror'}}),
'MIRRORDICT_SCHEMA': (tuf.formats.MIRRORDICT_SCHEMA,
{'mirror1': {'url_prefix': 'http://localhost:8001',
'metadata_path': 'metadata/',
'targets_path': 'targets/',
'confined_target_dirs': ['path1/', 'path2/'],
'custom': {'type': 'mirror'}}}),
'MIRRORLIST_SCHEMA': (tuf.formats.MIRRORLIST_SCHEMA,
{'_type': 'mirrors',
'version': 8,
'spec_version': '1.0.0',
'expires': '1985-10-21T13:20:00Z',
'mirrors': [{'url_prefix': 'http://localhost:8001',
'metadata_path': 'metadata/',
'targets_path': 'targets/',
'confined_target_dirs': ['path1/', 'path2/'],
'custom': {'type': 'mirror'}}]})}
# Iterate 'valid_schemas', ensuring each 'valid_schema' correctly matches
# its respective 'schema_type'.
for schema_name, (schema_type, valid_schema) in valid_schemas.items():
if not schema_type.matches(valid_schema):
print('bad schema: ' + repr(valid_schema))
self.assertEqual(True, schema_type.matches(valid_schema))
# Test conditions for invalid schemas.
# Set the 'valid_schema' of 'valid_schemas' to an invalid
# value and test that it does not match 'schema_type'.
for schema_name, (schema_type, valid_schema) in valid_schemas.items():
invalid_schema = 0xBAD
if isinstance(schema_type, securesystemslib.schema.Integer):
invalid_schema = 'BAD'
self.assertEqual(False, schema_type.matches(invalid_schema))
def test_specfication_version_schema(self):
"""Test valid and invalid SPECIFICATION_VERSION_SCHEMAs, using examples
from 'regex101.com/r/Ly7O1x/3/', referenced by
'semver.org/spec/v2.0.0.html'. """
valid_schemas = [
"0.0.4",
"1.2.3",
"10.20.30",
"1.1.2-prerelease+meta",
"1.1.2+meta",
"1.1.2+meta-valid",
"1.0.0-alpha",
"1.0.0-beta",
"1.0.0-alpha.beta",
"1.0.0-alpha.beta.1",
"1.0.0-alpha.1",
"1.0.0-alpha0.valid",
"1.0.0-alpha.0valid",
"1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay",
"1.0.0-rc.1+build.1",
"2.0.0-rc.1+build.123",
"1.2.3-beta",
"10.2.3-DEV-SNAPSHOT",
"1.2.3-SNAPSHOT-123",
"1.0.0",
"2.0.0",
"1.1.7",
"2.0.0+build.1848",
"2.0.1-alpha.1227",
"1.0.0-alpha+beta",
"1.2.3----RC-SNAPSHOT.12.9.1--.12+788",
"1.2.3----R-S.12.9.1--.12+meta",
"1.2.3----RC-SNAPSHOT.12.9.1--.12",
"1.0.0+0.build.1-rc.10000aaa-kk-0.1",
"99999999999999999999999.999999999999999999.99999999999999999",
"1.0.0-0A.is.legal"]
for valid_schema in valid_schemas:
self.assertTrue(
tuf.formats.SPECIFICATION_VERSION_SCHEMA.matches(valid_schema),
"'{}' should match 'SPECIFICATION_VERSION_SCHEMA'.".format(
valid_schema))
invalid_schemas = [
"1",
"1.2",
"1.2.3-0123",
"1.2.3-0123.0123",
"1.1.2+.123",
"+invalid",
"-invalid",
"-invalid+invalid",
"-invalid.01",
"alpha",
"alpha.beta",
"alpha.beta.1",
"alpha.1",
"alpha+beta",
"alpha_beta",
"alpha.",
"alpha..",
"beta",
"1.0.0-alpha_beta",
"-alpha.",
"1.0.0-alpha..",
"1.0.0-alpha..1",
"1.0.0-alpha...1",
"1.0.0-alpha....1",
"1.0.0-alpha.....1",
"1.0.0-alpha......1",
"1.0.0-alpha.......1",
"01.1.1",
"1.01.1",
"1.1.01",
"1.2",
"1.2.3.DEV",
"1.2-SNAPSHOT",
"1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788",
"1.2-RC-SNAPSHOT",
"-1.0.3-gamma+b7718",
"+justmeta",
"9.8.7+meta+meta",
"9.8.7-whatever+meta+meta",
"99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12"]
for invalid_schema in invalid_schemas:
self.assertFalse(
tuf.formats.SPECIFICATION_VERSION_SCHEMA.matches(invalid_schema),
"'{}' should not match 'SPECIFICATION_VERSION_SCHEMA'.".format(
invalid_schema))
def test_build_dict_conforming_to_schema(self):
# Test construction of a few metadata formats using
# build_dict_conforming_to_schema().
# Try the wrong type of schema object.
STRING_SCHEMA = securesystemslib.schema.AnyString()
with self.assertRaises(ValueError):
tuf.formats.build_dict_conforming_to_schema(
STRING_SCHEMA, string='some string')
# Try building Timestamp metadata.
spec_version = tuf.SPECIFICATION_VERSION
version = 8
length = 88
hashes = {'sha256': '3c7fe3eeded4a34'}
expires = '1985-10-21T13:20:00Z'
filedict = {'snapshot.json': {'length': length, 'hashes': hashes, 'version': 1}}
# Try with and without _type and spec_version, both of which are
# automatically populated if they are not included.
self.assertTrue(tuf.formats.TIMESTAMP_SCHEMA.matches( # both
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TIMESTAMP_SCHEMA,
_type='timestamp',
spec_version=spec_version,
version=version,
expires=expires,
meta=filedict)))
self.assertTrue(tuf.formats.TIMESTAMP_SCHEMA.matches( # neither
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TIMESTAMP_SCHEMA,
version=version,
expires=expires,
meta=filedict)))
self.assertTrue(tuf.formats.TIMESTAMP_SCHEMA.matches( # one
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TIMESTAMP_SCHEMA,
spec_version=spec_version,
version=version,
expires=expires,
meta=filedict)))
self.assertTrue(tuf.formats.TIMESTAMP_SCHEMA.matches( # the other
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TIMESTAMP_SCHEMA,
_type='timestamp',
version=version,
expires=expires,
meta=filedict)))
# Try test arguments for invalid Timestamp creation.
bad_spec_version = 123
bad_version = 'eight'
bad_expires = '2000'
bad_filedict = 123
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TIMESTAMP_SCHEMA,
_type='timestamp',
spec_version=bad_spec_version,
version=version,
expires=expires,
meta=filedict)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TIMESTAMP_SCHEMA,
_type='timestamp',
spec_version=spec_version,
version=bad_version,
expires=expires,
meta=filedict)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TIMESTAMP_SCHEMA,
_type='timestamp',
spec_version=spec_version,
version=version,
expires=bad_expires,
meta=filedict)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TIMESTAMP_SCHEMA,
_type='timestamp',
spec_version=spec_version,
version=version,
expires=expires,
meta=bad_filedict)
with self.assertRaises(ValueError):
tuf.formats.build_dict_conforming_to_schema(123)
# Try building Root metadata.
consistent_snapshot = False
keydict = {'123abc': {'keytype': 'rsa',
'scheme': 'rsassa-pss-sha256',
'keyval': {'public': 'pubkey',
'private': 'privkey'}}}
roledict = {'root': {'keyids': ['123abc'],
'threshold': 1,
'paths': ['path1/', 'path2']}}
self.assertTrue(tuf.formats.ROOT_SCHEMA.matches(
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.ROOT_SCHEMA,
_type='root',
spec_version=spec_version,
version=version,
expires=expires,
keys=keydict,
roles=roledict,
consistent_snapshot=consistent_snapshot)))
# Additional test arguments for invalid Root creation.
bad_keydict = 123
bad_roledict = 123
# TODO: Later on, write a test looper that takes pairs of key-value args
# to substitute in on each run to shorten this.... There's a lot of
# test code that looks like this, and it'd be easier to use a looper.
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.ROOT_SCHEMA,
_type='root',
spec_version=bad_spec_version,
version=version,
expires=expires,
keys=keydict,
roles=roledict,
consistent_snapshot=consistent_snapshot)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.ROOT_SCHEMA,
_type='root',
spec_version=spec_version,
version=bad_version,
expires=expires,
keys=keydict,
roles=roledict,
consistent_snapshot=consistent_snapshot)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.ROOT_SCHEMA,
_type='root',
spec_version=spec_version,
version=version,
expires=bad_expires,
keys=keydict,
roles=roledict,
consistent_snapshot=consistent_snapshot)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.ROOT_SCHEMA,
_type='root',
spec_version=spec_version,
version=version,
expires=expires,
keys=bad_keydict,
roles=roledict,
consistent_snapshot=consistent_snapshot)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.ROOT_SCHEMA,
_type='root',
spec_version=spec_version,
version=version,
expires=expires,
keys=keydict,
roles=bad_roledict,
consistent_snapshot=consistent_snapshot)
with self.assertRaises(TypeError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.ROOT_SCHEMA, 'bad')
with self.assertRaises(ValueError):
tuf.formats.build_dict_conforming_to_schema(
'bad',
_type='root',
spec_version=spec_version,
version=version,
expires=expires,
keys=keydict,
roles=roledict,
consistent_snapshot=consistent_snapshot)
# Try building Snapshot metadata.
versiondict = {'targets.json' : {'version': version}}
self.assertTrue(tuf.formats.SNAPSHOT_SCHEMA.matches(
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.SNAPSHOT_SCHEMA,
_type='snapshot',
spec_version=spec_version,
version=version,
expires=expires,
meta=versiondict)))
# Additional test arguments for invalid Snapshot creation.
bad_versiondict = 123
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.SNAPSHOT_SCHEMA,
_type='snapshot',
spec_version=bad_spec_version,
version=version,
expires=expires,
meta=versiondict)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.SNAPSHOT_SCHEMA,
_type='snapshot',
spec_version=spec_version,
version=bad_version,
expires=expires,
meta=versiondict)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.SNAPSHOT_SCHEMA,
_type='snapshot',
spec_version=spec_version,
version=version,
expires=bad_expires,
meta=versiondict)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.SNAPSHOT_SCHEMA,
_type='snapshot',
spec_version=spec_version,
version=version,
expires=expires,
meta=bad_versiondict)
# Try building Targets metadata.
filedict = {'metadata/targets.json': {'length': 1024,
'hashes': {'sha256': 'ABCD123'},
'custom': {'type': 'metadata'}}}
delegations = {'keys': {'123abc': {'keytype':'rsa',
'scheme': 'rsassa-pss-sha256',
'keyval': {'public': 'pubkey',
'private': 'privkey'}}},
'roles': [{'name': 'root', 'keyids': ['123abc'],
'threshold': 1, 'paths': ['path1/', 'path2']}]}
self.assertTrue(tuf.formats.TARGETS_SCHEMA.matches(
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TARGETS_SCHEMA,
_type='targets',
spec_version=spec_version,
version=version,
expires=expires,
targets=filedict,
delegations=delegations)))
# Try with no delegations included (should work, since they're optional).
self.assertTrue(tuf.formats.TARGETS_SCHEMA.matches(
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TARGETS_SCHEMA,
_type='targets',
spec_version=spec_version,
version=version,
expires=expires,
targets=filedict)))
# Additional test arguments for invalid Targets creation.
bad_filedict = 123
bad_delegations = 123
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TARGETS_SCHEMA,
_type='targets',
spec_version=spec_version,
version=bad_version,
expires=expires,
targets=filedict,
delegations=delegations)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TARGETS_SCHEMA,
_type='targets',
spec_version=spec_version,
version=version,
expires=bad_expires,
targets=filedict,
delegations=delegations)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TARGETS_SCHEMA,
_type='targets',
spec_version=spec_version,
version=version,
expires=expires,
targets=bad_filedict,
delegations=delegations)
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.build_dict_conforming_to_schema(
tuf.formats.TARGETS_SCHEMA,
_type='targets',
spec_version=spec_version,
version=version,
expires=expires,
targets=filedict,
delegations=bad_delegations)
def test_expiry_string_to_datetime(self):
dt = tuf.formats.expiry_string_to_datetime('1985-10-21T13:20:00Z')
self.assertEqual(dt, datetime.datetime(1985, 10, 21, 13, 20, 0))
dt = tuf.formats.expiry_string_to_datetime('2038-01-19T03:14:08Z')
self.assertEqual(dt, datetime.datetime(2038, 1, 19, 3, 14, 8))
# First 3 fail via securesystemslib schema, last one because of strptime()
invalid_inputs = [
'2038-1-19T03:14:08Z', # leading zeros not optional
'2038-01-19T031408Z', # strict time parsing
'2038-01-19T03:14:08Z-06:00', # timezone not allowed
'2038-13-19T03:14:08Z', # too many months
]
for invalid_input in invalid_inputs:
with self.assertRaises(securesystemslib.exceptions.FormatError):
tuf.formats.expiry_string_to_datetime(invalid_input)
def test_unix_timestamp_to_datetime(self):
# Test conditions for valid arguments.
UNIX_TIMESTAMP_SCHEMA = securesystemslib.formats.UNIX_TIMESTAMP_SCHEMA
self.assertTrue(datetime.datetime, tuf.formats.unix_timestamp_to_datetime(499137720))
datetime_object = datetime.datetime(1985, 10, 26, 1, 22)
self.assertEqual(datetime_object, tuf.formats.unix_timestamp_to_datetime(499137720))
# Test conditions for invalid arguments.
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.unix_timestamp_to_datetime, 'bad')
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.unix_timestamp_to_datetime, 1000000000000000000000)
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.unix_timestamp_to_datetime, -1)
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.unix_timestamp_to_datetime, ['5'])
def test_datetime_to_unix_timestamp(self):
# Test conditions for valid arguments.
datetime_object = datetime.datetime(2015, 10, 21, 19, 28)
self.assertEqual(1445455680, tuf.formats.datetime_to_unix_timestamp(datetime_object))
# Test conditions for invalid arguments.
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.datetime_to_unix_timestamp, 'bad')
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.datetime_to_unix_timestamp, 1000000000000000000000)
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.datetime_to_unix_timestamp, ['1'])
def test_format_base64(self):
# Test conditions for valid arguments.
data = 'updateframework'.encode('utf-8')
self.assertEqual('dXBkYXRlZnJhbWV3b3Jr', tuf.formats.format_base64(data))
self.assertTrue(isinstance(tuf.formats.format_base64(data), str))
# Test conditions for invalid arguments.
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.format_base64, 123)
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.format_base64, True)
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.format_base64, ['123'])
def test_parse_base64(self):
# Test conditions for valid arguments.
base64 = 'dXBkYXRlZnJhbWV3b3Jr'
self.assertEqual(b'updateframework', tuf.formats.parse_base64(base64))
self.assertTrue(isinstance(tuf.formats.parse_base64(base64), bytes))
# Test conditions for invalid arguments.
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.parse_base64, 123)
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.parse_base64, True)
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.parse_base64, ['123'])
self.assertRaises(securesystemslib.exceptions.FormatError, tuf.formats.parse_base64, '/')
def test_make_signable(self):
# Test conditions for expected make_signable() behavior.
SIGNABLE_SCHEMA = tuf.formats.SIGNABLE_SCHEMA
root_file = os.path.join('repository_data', 'repository', 'metadata',
'root.json')
root = securesystemslib.util.load_json_file(root_file)
self.assertTrue(SIGNABLE_SCHEMA.matches(tuf.formats.make_signable(root)))
signable = tuf.formats.make_signable(root)
self.assertEqual('root', tuf.formats.check_signable_object_format(signable))
self.assertEqual(signable, tuf.formats.make_signable(signable))
# Test conditions for miscellaneous arguments.
self.assertTrue(SIGNABLE_SCHEMA.matches(tuf.formats.make_signable('123')))
self.assertTrue(SIGNABLE_SCHEMA.matches(tuf.formats.make_signable(123)))
def test_make_targets_fileinfo(self):
# Test conditions for valid arguments.
length = 1024
hashes = {'sha256': 'A4582BCF323BCEF', 'sha512': 'A4582BCF323BFEF'}
custom = {'type': 'paintjob'}
TARGETS_FILEINFO_SCHEMA = tuf.formats.TARGETS_FILEINFO_SCHEMA
make_targets_fileinfo = tuf.formats.make_targets_fileinfo
self.assertTrue(TARGETS_FILEINFO_SCHEMA.matches(make_targets_fileinfo(length, hashes, custom)))
self.assertTrue(TARGETS_FILEINFO_SCHEMA.matches(make_targets_fileinfo(length, hashes)))
# Test conditions for invalid arguments.
bad_length = 'bad'
bad_hashes = 'bad'
bad_custom = 'bad'
self.assertRaises(securesystemslib.exceptions.FormatError, make_targets_fileinfo,
bad_length, hashes, custom)
self.assertRaises(securesystemslib.exceptions.FormatError, make_targets_fileinfo,
length, bad_hashes, custom)
self.assertRaises(securesystemslib.exceptions.FormatError, make_targets_fileinfo,
length, hashes, bad_custom)
self.assertRaises(securesystemslib.exceptions.FormatError, make_targets_fileinfo,
bad_length, hashes)
self.assertRaises(securesystemslib.exceptions.FormatError, make_targets_fileinfo,
length, bad_hashes)
def test_make_metadata_fileinfo(self):
# Test conditions for valid arguments.
length = 1024
hashes = {'sha256': 'A4582BCF323BCEF', 'sha512': 'A4582BCF323BFEF'}
version = 8
METADATA_FILEINFO_SCHEMA = tuf.formats.METADATA_FILEINFO_SCHEMA
make_metadata_fileinfo = tuf.formats.make_metadata_fileinfo
self.assertTrue(METADATA_FILEINFO_SCHEMA.matches(make_metadata_fileinfo(
version, length, hashes)))
self.assertTrue(METADATA_FILEINFO_SCHEMA.matches(make_metadata_fileinfo(version)))
# Test conditions for invalid arguments.
bad_version = 'bad'
bad_length = 'bad'
bad_hashes = 'bad'
self.assertRaises(securesystemslib.exceptions.FormatError, make_metadata_fileinfo,
bad_version, length, hashes)
self.assertRaises(securesystemslib.exceptions.FormatError, make_metadata_fileinfo,
version, bad_length, hashes)
self.assertRaises(securesystemslib.exceptions.FormatError, make_metadata_fileinfo,
version, length, bad_hashes)
self.assertRaises(securesystemslib.exceptions.FormatError, make_metadata_fileinfo,
bad_version)
def test_make_versioninfo(self):
# Test conditions for valid arguments.
version_number = 8
versioninfo = {'version': version_number}
VERSIONINFO_SCHEMA = tuf.formats.VERSIONINFO_SCHEMA
make_versioninfo = tuf.formats.make_versioninfo
self.assertTrue(VERSIONINFO_SCHEMA.matches(make_versioninfo(version_number)))
# Test conditions for invalid arguments.
bad_version_number = '8'
self.assertRaises(securesystemslib.exceptions.FormatError, make_versioninfo, bad_version_number)
def test_expected_meta_rolename(self):
# Test conditions for valid arguments.
expected_rolename = tuf.formats.expected_meta_rolename
self.assertEqual('root', expected_rolename('Root'))
self.assertEqual('targets', expected_rolename('Targets'))
self.assertEqual('snapshot', expected_rolename('Snapshot'))
self.assertEqual('timestamp', expected_rolename('Timestamp'))
self.assertEqual('mirrors', expected_rolename('Mirrors'))
self.assertEqual('targets role', expected_rolename('Targets Role'))
self.assertEqual('root', expected_rolename('Root'))
# Test conditions for invalid arguments.
self.assertRaises(securesystemslib.exceptions.FormatError, expected_rolename, 123)
self.assertRaises(securesystemslib.exceptions.FormatError, expected_rolename, tuf.formats.ROOT_SCHEMA)
self.assertRaises(securesystemslib.exceptions.FormatError, expected_rolename, True)
def test_check_signable_object_format(self):
# Test condition for a valid argument.
root_file = os.path.join('repository_data', 'repository', 'metadata',
'root.json')
root = securesystemslib.util.load_json_file(root_file)
root = tuf.formats.make_signable(root)
self.assertEqual('root', tuf.formats.check_signable_object_format(root))
# Test conditions for invalid arguments.
check_signable = tuf.formats.check_signable_object_format
self.assertRaises(securesystemslib.exceptions.FormatError, check_signable, 'root')
self.assertRaises(securesystemslib.exceptions.FormatError, check_signable, 123)
self.assertRaises(securesystemslib.exceptions.FormatError, check_signable, tuf.formats.ROOT_SCHEMA)
self.assertRaises(securesystemslib.exceptions.FormatError, check_signable, True)
saved_type = root['signed']['_type']
del root['signed']['_type']
self.assertRaises(securesystemslib.exceptions.FormatError, check_signable, root)
root['signed']['_type'] = saved_type
root['signed']['_type'] = 'Root'
self.assertRaises(securesystemslib.exceptions.FormatError, check_signable, root)
root['signed']['_type'] = 'root'
del root['signed']['expires']
self.assertRaises(securesystemslib.exceptions.FormatError, check_signable, root)
def test_encode_canonical(self):
# Test conditions for valid arguments.
encode = securesystemslib.formats.encode_canonical
result = []
output = result.append
bad_output = 123
self.assertEqual('""', encode(""))
self.assertEqual('[1,2,3]', encode([1, 2, 3]))
self.assertEqual('[1,2,3]', encode([1,2,3]))
self.assertEqual('[]', encode([]))
self.assertEqual('{"A":[99]}', encode({"A": [99]}))
self.assertEqual('{"x":3,"y":2}', encode({"x": 3, "y": 2}))
self.assertEqual('{"x":3,"y":null}', encode({"x": 3, "y": None}))
# Condition where 'encode()' sends the result to the callable
# 'output'.
self.assertEqual(None, encode([1, 2, 3], output))
self.assertEqual('[1,2,3]', ''.join(result))
# Test conditions for invalid arguments.
self.assertRaises(securesystemslib.exceptions.FormatError, encode, tuf.formats.ROOT_SCHEMA)
self.assertRaises(securesystemslib.exceptions.FormatError, encode, 8.0)
self.assertRaises(securesystemslib.exceptions.FormatError, encode, {"x": 8.0})
self.assertRaises(securesystemslib.exceptions.FormatError, encode, 8.0, output)
self.assertRaises(securesystemslib.exceptions.FormatError, encode, {"x": securesystemslib.exceptions.FormatError})
# Run unit test.
if __name__ == '__main__':
utils.configure_test_logging(sys.argv)
unittest.main()