mirror of
https://github.com/theupdateframework/python-tuf
synced 2026-05-24 10:08:28 +00:00
Merge pull request #205 from vladimir-v-diaz/develop
Address Issue #146. Replace custom datetime format with ISO 8601.
This commit is contained in:
commit
ddb8b00948
176 changed files with 1048 additions and 13305 deletions
|
|
@ -476,7 +476,10 @@
|
|||
The KEYID of a key is the hexdigest of the SHA-256 hash of the
|
||||
canonical JSON form of the key, where the "private" object key is excluded.
|
||||
|
||||
All times are given as strings of the format "YYYY-MM-DD HH:MM:SS UTC".
|
||||
Metadata date-time data follows the ISO 8601 standard. The expected format
|
||||
of the combined date and time string is "YYYY-MM-DDTHH:MM:SSZ". Time is
|
||||
always in UTC, and the "Z" time zone designator is attached to indicate a
|
||||
zero UTC offset. An example date-time string is "1985-10-21T01:21:00Z".
|
||||
|
||||
|
||||
4.3. File formats: root.json
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
Vladimir Diaz <vladimir.v.diaz@gmail.com>
|
||||
|
||||
<Started>
|
||||
September 2012
|
||||
September 2012.
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
|
@ -16,13 +16,16 @@
|
|||
utilizing The Update Framework may write to securely update files.
|
||||
The 'basic_client.py' script can be used on the command-line to perform
|
||||
an update that will download and update all available targets; writing
|
||||
custom code is not required in this case.
|
||||
custom code is not required with 'basic_client.py'.
|
||||
|
||||
The custom examples below demonstrate:
|
||||
(1) updating all targets
|
||||
(2) updating all the targets of a specified role
|
||||
(3) updating a specific target explicitely named.
|
||||
|
||||
It assumes a server is listening on 'http://localhost:8001'. One can be
|
||||
started by navigating to the 'examples/repository/' and starting:
|
||||
$ python -m SimpleHTTPServer 8001
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
|
@ -30,7 +33,7 @@
|
|||
import tuf.client.updater
|
||||
|
||||
# Uncomment the line below to enable printing of debugging information.
|
||||
#tuf.log.set_log_level(logging.DEBUG)
|
||||
tuf.log.set_log_level(logging.INFO)
|
||||
|
||||
# Set the local repository directory containing the metadata files.
|
||||
tuf.conf.repository_directory = '.'
|
||||
|
|
@ -61,7 +64,8 @@
|
|||
for target in updated_targets:
|
||||
try:
|
||||
updater.download_target(target, destination_directory)
|
||||
except tuf.DownloadError, e:
|
||||
|
||||
except tuf.DownloadError as e:
|
||||
pass
|
||||
|
||||
# Remove any files from the destination directory that are no longer being
|
||||
|
|
@ -69,26 +73,22 @@
|
|||
updater.remove_obsolete_targets(destination_directory)
|
||||
|
||||
|
||||
"""
|
||||
# Example demonstrating an update that only downloads the targets of
|
||||
# a specific role (i.e., 'targets/role1')
|
||||
|
||||
# Example demonstrating an update that only downloads the targets of
|
||||
# a specific role (i.e., 'targets/project')
|
||||
updater.refresh()
|
||||
targets_of_role1 = updater.targets_of_role('targets/role1')
|
||||
targets_of_role1 = updater.targets_of_role('targets/project')
|
||||
updated_targets = updater.updated_targets(targets_of_role1, destination_directory)
|
||||
|
||||
for target in updated_targets:
|
||||
updater.download_target(target, destination_directory)
|
||||
"""
|
||||
|
||||
|
||||
"""
|
||||
|
||||
# Example demonstrating an update that downloads a specific target.
|
||||
|
||||
updater.refresh()
|
||||
target = updater.target('LICENSE.txt')
|
||||
target = updater.target('/file2.txt')
|
||||
updated_target = updater.updated_targets([target], destination_directory)
|
||||
|
||||
for target in updated_target:
|
||||
updater.download_target(target, destination_directory)
|
||||
"""
|
||||
BIN
examples/client/metadata/current/root.json
Normal file
BIN
examples/client/metadata/current/root.json
Normal file
Binary file not shown.
BIN
examples/client/metadata/previous/root.json
Normal file
BIN
examples/client/metadata/previous/root.json
Normal file
Binary file not shown.
1
examples/keystore/project_key
Normal file
1
examples/keystore/project_key
Normal file
|
|
@ -0,0 +1 @@
|
|||
5bc5cdc1e18ff3ccbfd7c33a88bec596@@@@313030303030@@@@39656230336534656264303863303733353832386465383466346232633863356362616234306430333863353239393966643333373730353231386262623339@@@@31caf11a40e9eb48f499dcc6f80c88e8@@@@0400a24989069098ce702d6a8f81826ba482ffd9a17fff5a10c6f986b9179bae1be4d246db2fceda93ce12bd465e896e4e4e847c934eb120c794e12fbcc8569e4aa6964995f1fda9af50057644236c4194ebb78a588804363dbce492db7e4ef2ce39391013a7c2d68260a0e785b6cec39fc02cdff11e9c7a168ae133292fdbe5f2f968d2a0ae098ca9453ec33d175de181f771b016c760ceba51d9c20c431702656e8b09ebda6cf884096b89d80dd6c2c1752c04312e934cd79d49b91e8c7ef4448bf3b969fa6ed9727cac48f91e3921f41d5bf8ec4130ff45fda51e07cd16a7fa8daca1feb6f2dced6881c736565a1b72dc705a97606a0480c0dd681e65bea82fc261762cdad203fd49d45f
|
||||
1
examples/keystore/project_key.pub
Normal file
1
examples/keystore/project_key.pub
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"keytype": "ed25519", "keyval": {"public": "b6e40fb71a6041212a3d84331336ecaa1f48a0c523f80ccc762a034c727606fa"}}
|
||||
1
examples/keystore/root_key
Normal file
1
examples/keystore/root_key
Normal file
|
|
@ -0,0 +1 @@
|
|||
70b05482c00cad0fccfcab4ac2b86b50@@@@313030303030@@@@62626137313336626662363862333962636161306561326437336237643436306162323966303038326636306363613965396161353566646330346666356635@@@@5f6612c00c8ed8627dd33754812bb7e1@@@@f651c3db5ac02aa8337264f0badd1f40fbe174ec3f8de8fd95188d31cf41b4863d7a28db297b8a5abd25e49d2af3c6cb2e25789088dce2b5113b7d7db16deea1eadf109d5ec004a2b5bcbdc29e13a9e4c803659def851800969918fb5930c56b816b119be490667f2d629309bc7578dad43c6b0ca6ef0c6f48ad68390fb1fc711b8a40bb5b1c197ae6f72d2b1e83bbc9050f46a3c69efe3b11c55a52d3f68f6e9fe58ad7e67dd6b136681b6d800fed22f15d31ee71ad1ed78f36b6d19b0771c22123f1dcb54a6b2e9742d2661014931cbab8fbbb001e3ac836bc5c64b19fa4cb881485acdafa6a0fd87044534608f50ae13920517c6f2ab2669f8edd4bc6cbe2fc1fc272264a819e2e34bc83
|
||||
1
examples/keystore/root_key.pub
Normal file
1
examples/keystore/root_key.pub
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"keytype": "ed25519", "keyval": {"public": "66dd78c5c2a78abc6fc6b267ff1a8017ba0e8bfc853dd97af351949bba021275"}}
|
||||
1
examples/keystore/snapshot_key
Normal file
1
examples/keystore/snapshot_key
Normal file
|
|
@ -0,0 +1 @@
|
|||
cff2ed748f0281d65c8eb535e81dbfd0@@@@313030303030@@@@30353732326564313863306632626336656631636635313666636330383537376466393833313937363261303638336632373530303938623665346239646230@@@@1eda960b65beefb9a2a4afcc9be973f6@@@@ea7c468f9e5ab91e874b2a0fa692a18056293261886400e5976a6c884b13cdd3905b0188f41b0c2b2846d36dabbeecf4d9d1c87123b5b236ccbce24f4b30c9ba25d00ccce270d3da1d202d2fd27a0a007381bf2284c58bb01a812050086264617f94a47cd3931b9129c6b105eec4ff56d1176e6fbde6bf5ade513a0f1c7551cecb04c678582e7fd0656936a1f232fa3a739df3dc4af07ad69580f54b1dd366c78e96c07249732621929aac056f4892af07772011246101cfb9886558fe2cfd1d09e9c280cbecdf2fb8dbeded4a628ef2fa04d5360dae327ccf15a12a00f2f32964ca03abaeaeb60bbece207e09c897413b8a630331df568822880be86359181664aa0806770ab11e30663594
|
||||
1
examples/keystore/snapshot_key.pub
Normal file
1
examples/keystore/snapshot_key.pub
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"keytype": "ed25519", "keyval": {"public": "01c61f8dc7d77fcef973f4267927541e355e8ceda757e2c402818dad850f856e"}}
|
||||
1
examples/keystore/targets_key
Normal file
1
examples/keystore/targets_key
Normal file
|
|
@ -0,0 +1 @@
|
|||
a0fdf15a675c849cc7bd4cfb46273164@@@@313030303030@@@@62303735356165326132633766333932633137643234323961636166356135666433333234376163356665656330306362366363383332386430356133663831@@@@0d7ce5bc8687edc1a292ebbe203284b6@@@@155dee106e192009ed4dace179e514f518d403d7a83d136047683683090c8dd1e80d6d5f6bd480e1e9e76bf63a265dfdc7e5bce07418039c6457c6d454fd0114fd7311c8508ead020e59e0b5b2ee55101d49535980e598c02c70ecb7bca77a54d04040080ca9403cd23bd0ae4cc5e33131321d2a4c8a4544553f5c54b7af0986a437f37696b4e7d76efed24be9a4c6928542fb93cfd88018537703a1ff0f6ac8fcb625714a161aaa7a548b39963ded1481b47020b1346544a8a9d96f1eb03a6cad326af0f5be43c6756dc1d4e6c7dee550077d7689949a671acd370680d6b29e594675ade9d7525a4ad8af7a1b13a3e4692192d70c189115d52b814af5a53bc9d0528aec6c6417f6f7d0bcb3
|
||||
1
examples/keystore/targets_key.pub
Normal file
1
examples/keystore/targets_key.pub
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"keytype": "ed25519", "keyval": {"public": "68ead6e54a43f8f36f9717b10669d1ef0ebb38cee6b05317669341309f1069cb"}}
|
||||
1
examples/keystore/timestamp_key
Normal file
1
examples/keystore/timestamp_key
Normal file
|
|
@ -0,0 +1 @@
|
|||
dd0f6b3bff19df2c4ab89e34a5b190e6@@@@313030303030@@@@37613435636666623966633230613439376661303631616635323365326636643039383236333638633162326262616231653531353066656262643265623566@@@@e6d72cc0a99144c4dbf509fa56092454@@@@10bb33112d4083f81d700740e78b315574a0d7b8c042921b1dcb7b8593caff1dbb10b8886ea2f4b7edcb49d3aabc9ec25db59dc0b121890555dc5d69291856f739b280de6fa6216e0ac92b9b95689b9f6ba1a414cb78ee6547968ea5ebd84e34972cf6d0e56cf0443b653f51d8e2742a7454e70039e548e4a69e97e73475940964307b5d5da440767531479b0c940dc8ffebafdf562e3a68d456f9438cb3c2253117180efd868b8b9fd4ea3e717501db8c0a9afe0bcdb34068eef4858103b2126b47d4c22a3d0f16cec0e5cd452201487eb6695139d8235a17a3c1a42fa7552d7ca45625b0000650f22851679ac00c7b71368d4dfc862a1823437b5cc244c282be0c01138fa39dc13511bd59
|
||||
1
examples/keystore/timestamp_key.pub
Normal file
1
examples/keystore/timestamp_key.pub
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"keytype": "ed25519", "keyval": {"public": "72378e5bc588793e58f81c8533da64a2e8f1565c1fcc7f253496394ffc52542c"}}
|
||||
BIN
examples/repository/metadata.staged/root.json
Normal file
BIN
examples/repository/metadata.staged/root.json
Normal file
Binary file not shown.
BIN
examples/repository/metadata.staged/snapshot.json
Normal file
BIN
examples/repository/metadata.staged/snapshot.json
Normal file
Binary file not shown.
BIN
examples/repository/metadata.staged/targets.json
Normal file
BIN
examples/repository/metadata.staged/targets.json
Normal file
Binary file not shown.
BIN
examples/repository/metadata.staged/targets.json.gz
Normal file
BIN
examples/repository/metadata.staged/targets.json.gz
Normal file
Binary file not shown.
BIN
examples/repository/metadata.staged/targets/project.json
Normal file
BIN
examples/repository/metadata.staged/targets/project.json
Normal file
Binary file not shown.
BIN
examples/repository/metadata.staged/timestamp.json
Normal file
BIN
examples/repository/metadata.staged/timestamp.json
Normal file
Binary file not shown.
BIN
examples/repository/metadata/root.json
Normal file
BIN
examples/repository/metadata/root.json
Normal file
Binary file not shown.
BIN
examples/repository/metadata/snapshot.json
Normal file
BIN
examples/repository/metadata/snapshot.json
Normal file
Binary file not shown.
BIN
examples/repository/metadata/targets.json
Normal file
BIN
examples/repository/metadata/targets.json
Normal file
Binary file not shown.
BIN
examples/repository/metadata/targets.json.gz
Normal file
BIN
examples/repository/metadata/targets.json.gz
Normal file
Binary file not shown.
BIN
examples/repository/metadata/targets/project.json
Normal file
BIN
examples/repository/metadata/targets/project.json
Normal file
Binary file not shown.
BIN
examples/repository/metadata/timestamp.json
Normal file
BIN
examples/repository/metadata/timestamp.json
Normal file
Binary file not shown.
1
examples/repository/targets/file1.txt
Normal file
1
examples/repository/targets/file1.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
This is an example target file.
|
||||
1
examples/repository/targets/file2.txt
Normal file
1
examples/repository/targets/file2.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
This is an another example target file.
|
||||
1
examples/repository/targets/project/file3.txt
Normal file
1
examples/repository/targets/project/file3.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
This is role1's target file.
|
||||
2
setup.py
2
setup.py
|
|
@ -101,7 +101,7 @@
|
|||
'Topic :: Software Development'
|
||||
],
|
||||
install_requires = [],
|
||||
packages = find_packages(exclude=['tests', 'tuf.tests']),
|
||||
packages = find_packages(exclude=['tests']),
|
||||
extras_require = extras,
|
||||
scripts = [
|
||||
'tuf/client/basic_client.py'
|
||||
|
|
|
|||
|
|
@ -1,541 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
<Program Name>
|
||||
test_delegations.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
|
||||
<Started>
|
||||
February 19, 2012
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
Ensure that TUF meets expectations about target delegations.
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import tuf.formats
|
||||
import tuf.repo.keystore as keystore
|
||||
import tuf.repo.signercli as signercli
|
||||
import tuf.repo.signerlib as signerlib
|
||||
import tuf.tests.util_test_tools as util_test_tools
|
||||
|
||||
version = 1
|
||||
# Modify the number of iterations (from the higher default count) so the unit
|
||||
# tests run faster.
|
||||
keystore._PBKDF2_ITERATIONS = 1000
|
||||
|
||||
|
||||
class TestDelegationFunctions(unittest.TestCase):
|
||||
|
||||
|
||||
def do_update(self):
|
||||
# Client side repository.
|
||||
tuf_client = os.path.join(self.root_repo, 'tuf_client')
|
||||
downloads_dir = os.path.join(self.root_repo, 'downloads')
|
||||
|
||||
# Adjust client's configuration file.
|
||||
tuf.conf.repository_directory = tuf_client
|
||||
|
||||
updater = tuf.client.updater.Updater('my_repo', self.mirrors)
|
||||
|
||||
# Refresh the repository's top-level roles, store the target information for
|
||||
# all the targets tracked, and determine which of these targets have been
|
||||
# updated.
|
||||
updater.refresh()
|
||||
|
||||
# Obtain a list of available targets.
|
||||
targets = []
|
||||
relative_target_filepaths = self.relpath_from_targets(self.target_filepaths)
|
||||
for target_filepath in relative_target_filepaths:
|
||||
target_info = updater.target(target_filepath)
|
||||
targets.append(target_info)
|
||||
|
||||
# Download each of these updated targets and save them locally.
|
||||
updated_targets = updater.updated_targets(targets, downloads_dir)
|
||||
for target in updated_targets:
|
||||
updater.download_target(target, downloads_dir)
|
||||
|
||||
# Return metadata about downloaded targets.
|
||||
make_fileinfo = signerlib.get_metadata_file_info
|
||||
targets_metadata = {}
|
||||
for target_filepath in relative_target_filepaths:
|
||||
download_filepath = os.path.join(downloads_dir, target_filepath)
|
||||
target_fileinfo = signerlib.get_metadata_file_info(download_filepath)
|
||||
targets_metadata[target_filepath] = target_fileinfo
|
||||
return targets_metadata
|
||||
|
||||
|
||||
def make_targets_metadata(self):
|
||||
"""Subclasses will override this method to generate metadata for all
|
||||
targets roles, with the understanding that there is a fixed structure of
|
||||
the targets roles."""
|
||||
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def relpath_from_targets(self, target_filepaths):
|
||||
"""Ex: 'targets/more_targets/somefile.txt' -> 'more_targets/somefile.txt'
|
||||
i.e. 'targets/' is removed from 'target'."""
|
||||
|
||||
new_target_filepaths = []
|
||||
for target in target_filepaths:
|
||||
relative_targetpath = os.path.sep.join(target.split(os.path.sep)[1:])
|
||||
new_target_filepaths.append(relative_targetpath)
|
||||
return new_target_filepaths
|
||||
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
The target delegations tree is fixed as such:
|
||||
targets -> [T1, T2]
|
||||
T1 -> [T3]
|
||||
"""
|
||||
global version
|
||||
version = version+1
|
||||
expiration = tuf.formats.format_time(time.time()+86400)
|
||||
|
||||
root_repo, url, server_proc, keyids = util_test_tools.init_repo(using_tuf=True)
|
||||
|
||||
# Server side repository.
|
||||
tuf_repo = os.path.join(root_repo, 'tuf_repo')
|
||||
keystore_dir = os.path.join(tuf_repo, 'keystore')
|
||||
metadata_dir = os.path.join(tuf_repo, 'metadata')
|
||||
targets_dir = os.path.join(tuf_repo, 'targets')
|
||||
|
||||
# We need to provide clients with a way to reach the tuf repository.
|
||||
tuf_repo_relpath = os.path.basename(tuf_repo)
|
||||
tuf_url = url+tuf_repo_relpath
|
||||
|
||||
# Add files to the server side repository.
|
||||
# target1 = 'targets_dir/[random].txt'
|
||||
# target2 = 'targets_dir/[random].txt'
|
||||
add_target = util_test_tools.add_file_to_repository
|
||||
target1_path = add_target(targets_dir, data='target1')
|
||||
target2_path = add_target(targets_dir, data='target2')
|
||||
|
||||
# Target paths relative to the 'targets_dir'.
|
||||
# Ex: targetX = 'targets/delegator/delegatee.txt'
|
||||
target1 = os.path.relpath(target1_path, tuf_repo)
|
||||
target2 = os.path.relpath(target2_path, tuf_repo)
|
||||
|
||||
# Relative to repository's targets directory.
|
||||
target_filepaths = [target1, target2]
|
||||
|
||||
# Store in self only the variables relevant for tests.
|
||||
self.root_repo = root_repo
|
||||
self.tuf_repo = tuf_repo
|
||||
self.server_proc = server_proc
|
||||
self.target_filepaths = target_filepaths
|
||||
# Targets delegated from A to B.
|
||||
self.delegated_targets = {}
|
||||
# Targets actually signed by B.
|
||||
self.signed_targets = {}
|
||||
self.mirrors = {
|
||||
"mirror1": {
|
||||
"url_prefix": tuf_url,
|
||||
"metadata_path": "metadata",
|
||||
"targets_path": "targets",
|
||||
"confined_target_dirs": [""]
|
||||
}
|
||||
}
|
||||
# Aliases for targets roles.
|
||||
self.T0 = 'targets'
|
||||
self.T1 = 'targets/T1'
|
||||
self.T2 = 'targets/T2'
|
||||
self.T3 = 'targets/T1/T3'
|
||||
|
||||
# Get tracked and assigned targets, and generate targets metadata.
|
||||
self.make_targets_metadata()
|
||||
assert hasattr(self, 'T0_metadata')
|
||||
assert hasattr(self, 'T1_metadata')
|
||||
assert hasattr(self, 'T2_metadata')
|
||||
assert hasattr(self, 'T3_metadata')
|
||||
|
||||
# Make delegation directories at the server's repository.
|
||||
metadata_targets_dir = os.path.join(metadata_dir, 'targets')
|
||||
metadata_T1_dir = os.path.join(metadata_targets_dir, 'T1')
|
||||
os.makedirs(metadata_T1_dir)
|
||||
|
||||
# Delegations metadata paths for the 3 delegated targets roles.
|
||||
T0_path = os.path.join(metadata_dir, 'targets.txt')
|
||||
T1_path = os.path.join(metadata_targets_dir, 'T1.txt')
|
||||
T2_path = os.path.join(metadata_targets_dir, 'T2.txt')
|
||||
T3_path = os.path.join(metadata_T1_dir, 'T3.txt')
|
||||
|
||||
# Generate RSA keys for the 3 delegatees.
|
||||
key1 = signerlib.generate_and_save_rsa_key(keystore_dir, 'T1')
|
||||
key2 = signerlib.generate_and_save_rsa_key(keystore_dir, 'T2')
|
||||
key3 = signerlib.generate_and_save_rsa_key(keystore_dir, 'T3')
|
||||
|
||||
# ID for each of the 3 keys.
|
||||
key1_id = key1['keyid']
|
||||
key2_id = key2['keyid']
|
||||
key3_id = key3['keyid']
|
||||
|
||||
# ID, in a list, for each of the 3 keys.
|
||||
key1_ids = [key1_id]
|
||||
key2_ids = [key2_id]
|
||||
key3_ids = [key3_id]
|
||||
|
||||
# Public-key JSON for each of the 3 keys.
|
||||
key1_val = tuf.rsa_key.create_in_metadata_format(key1['keyval'])
|
||||
key2_val = tuf.rsa_key.create_in_metadata_format(key2['keyval'])
|
||||
key3_val = tuf.rsa_key.create_in_metadata_format(key3['keyval'])
|
||||
|
||||
# Create delegation role metadata for each of the 3 delegated targets roles.
|
||||
make_role_metadata = tuf.formats.make_role_metadata
|
||||
|
||||
T1_targets = self.relpath_from_targets(self.delegated_targets[self.T1])
|
||||
T1_role = make_role_metadata(key1_ids, 1, name=self.T1, paths=T1_targets)
|
||||
|
||||
T2_targets = self.relpath_from_targets(self.delegated_targets[self.T2])
|
||||
T2_role = make_role_metadata(key2_ids, 1, name=self.T2, paths=T2_targets)
|
||||
|
||||
T3_targets = self.relpath_from_targets(self.delegated_targets[self.T3])
|
||||
T3_role = make_role_metadata(key3_ids, 1, name=self.T3, paths=T3_targets)
|
||||
|
||||
# Assign 'delegations' object for 'targets':
|
||||
self.T0_metadata['signed']['delegations'] = {
|
||||
'keys': {key1_id: key1_val, key2_id: key2_val},
|
||||
'roles': [T1_role, T2_role]
|
||||
}
|
||||
|
||||
# Assign 'delegations' object for 'targets/T1':
|
||||
self.T1_metadata['signed']['delegations'] = {
|
||||
'keys': {key3_id: key3_val},
|
||||
'roles': [T3_role]
|
||||
}
|
||||
|
||||
sign = signerlib.sign_metadata
|
||||
write = signerlib.write_metadata_file
|
||||
|
||||
# Sign new metadata objects.
|
||||
T0_signable = sign(self.T0_metadata, keyids, T0_path)
|
||||
T1_signable = sign(self.T1_metadata, key1_ids, T1_path)
|
||||
T2_signable = sign(self.T2_metadata, key2_ids, T2_path)
|
||||
T3_signable = sign(self.T3_metadata, key3_ids, T3_path)
|
||||
# Save new metadata objects.
|
||||
write(T0_signable, T0_path)
|
||||
write(T1_signable, T1_path)
|
||||
write(T2_signable, T2_path)
|
||||
write(T3_signable, T3_path)
|
||||
|
||||
# Timestamp a new release to reflect latest targets.
|
||||
signerlib.build_release_file(keyids, metadata_dir, version, expiration)
|
||||
signerlib.build_timestamp_file(keyids, metadata_dir, version, expiration)
|
||||
|
||||
# Unload all keys.
|
||||
keystore.clear_keystore()
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
util_test_tools.cleanup(self.root_repo, server_process=self.server_proc)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TestInitialUpdateWithTargetDelegations(TestDelegationFunctions):
|
||||
"""We show that making target delegations results in a successful initial
|
||||
update of targets."""
|
||||
|
||||
|
||||
def make_targets_metadata(self):
|
||||
global version
|
||||
version = version+1
|
||||
expiration = tuf.formats.format_time(time.time()+86400)
|
||||
make_metadata = signerlib.generate_targets_metadata
|
||||
target1, target2 = self.target_filepaths
|
||||
|
||||
# Targets signed for by each of the targets roles.
|
||||
self.signed_targets[self.T0] = [target1]
|
||||
self.signed_targets[self.T1] = [target1]
|
||||
self.signed_targets[self.T2] = [target2]
|
||||
self.signed_targets[self.T3] = [target1, target2]
|
||||
|
||||
# Targets delegated to each of the delegated targets roles.
|
||||
self.delegated_targets[self.T1] = [target1]
|
||||
self.delegated_targets[self.T2] = [target2]
|
||||
self.delegated_targets[self.T3] = [target1, target2]
|
||||
|
||||
self.T0_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T0],
|
||||
version, expiration)
|
||||
self.T1_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T1],
|
||||
version, expiration)
|
||||
self.T2_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T2],
|
||||
version, expiration)
|
||||
self.T3_metadata = \
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T3],
|
||||
version, expiration)
|
||||
|
||||
|
||||
def test_that_initial_update_works_with_target_delegations(self):
|
||||
# Get relative target paths, because that is what TUF recognizes.
|
||||
relative_target_filepaths = self.relpath_from_targets(self.target_filepaths)
|
||||
# Get metadata about downloaded targets.
|
||||
targets_metadata = self.do_update()
|
||||
# Do we have metadata about all the expected targets?
|
||||
for target_filepath in relative_target_filepaths:
|
||||
self.assertIn(target_filepath, targets_metadata)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TestBreachOfTargetDelegation(TestDelegationFunctions):
|
||||
"""We show that a delegated targets role B cannot talk about targets that A
|
||||
did not delegate to B."""
|
||||
|
||||
|
||||
def make_targets_metadata(self):
|
||||
global version
|
||||
version = version+1
|
||||
expiration = tuf.formats.format_time(time.time()+86400)
|
||||
|
||||
make_metadata = signerlib.generate_targets_metadata
|
||||
target1, target2 = self.target_filepaths
|
||||
|
||||
# Targets signed for by each of the targets roles.
|
||||
self.signed_targets[self.T0] = []
|
||||
self.signed_targets[self.T1] = [target2]
|
||||
self.signed_targets[self.T2] = [target1]
|
||||
self.signed_targets[self.T3] = []
|
||||
|
||||
# Targets delegated to each of the delegated targets roles.
|
||||
self.delegated_targets[self.T1] = [target1]
|
||||
self.delegated_targets[self.T2] = [target2]
|
||||
self.delegated_targets[self.T3] = []
|
||||
|
||||
self.T0_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T0],
|
||||
version, expiration)
|
||||
self.T1_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T1],
|
||||
version, expiration)
|
||||
self.T2_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T2],
|
||||
version, expiration)
|
||||
self.T3_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T3],
|
||||
version, expiration)
|
||||
|
||||
|
||||
def test_that_initial_update_fails_with_undelegated_signing_of_targets(self):
|
||||
"""We expect to see ForbiddenTargetError on initial update because
|
||||
delegated targets roles sign for targets that they were not delegated
|
||||
to."""
|
||||
|
||||
# http://docs.python.org/2/library/unittest.html#unittest.TestCase.assertRaises
|
||||
with self.assertRaises(tuf.NoWorkingMirrorError) as context_manager:
|
||||
self.do_update()
|
||||
|
||||
mirror_errors = context_manager.exception.mirror_errors
|
||||
forbidden_target_error = False
|
||||
|
||||
for mirror_url, mirror_error in mirror_errors.iteritems():
|
||||
if isinstance(mirror_error, tuf.ForbiddenTargetError):
|
||||
forbidden_target_error = True
|
||||
break
|
||||
|
||||
self.assertEqual(forbidden_target_error, True)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TestOrderOfTargetDelegationWithSuccess(TestDelegationFunctions):
|
||||
"""We show that when multiple delegated targets roles talk about a target,
|
||||
the first one in order of appearance of delegation wins.
|
||||
|
||||
In this case, the first role has the correct metadata about the target."""
|
||||
|
||||
|
||||
def make_targets_metadata(self):
|
||||
global version
|
||||
version = version+1
|
||||
expiration = tuf.formats.format_time(time.time()+86400)
|
||||
|
||||
make_metadata = signerlib.generate_targets_metadata
|
||||
target1, target2 = self.target_filepaths
|
||||
|
||||
# Targets signed for by each of the targets roles.
|
||||
self.signed_targets[self.T0] = [target2]
|
||||
self.signed_targets[self.T1] = []
|
||||
self.signed_targets[self.T2] = [target1]
|
||||
self.signed_targets[self.T3] = [target1]
|
||||
|
||||
# Targets delegated to each of the delegated targets roles.
|
||||
self.delegated_targets[self.T1] = [target1]
|
||||
self.delegated_targets[self.T2] = [target1]
|
||||
self.delegated_targets[self.T3] = [target1]
|
||||
|
||||
self.T0_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T0],
|
||||
version, expiration)
|
||||
self.T1_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T1],
|
||||
version, expiration)
|
||||
self.T2_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T2],
|
||||
version, expiration)
|
||||
self.T3_metadata = \
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T3],
|
||||
version, expiration)
|
||||
|
||||
# Modify the hash for target1 in T2.
|
||||
for target_filepath in self.relpath_from_targets([target1]):
|
||||
target_metadata = self.T2_metadata['signed']['targets'][target_filepath]
|
||||
sha256_hash = target_metadata['hashes']['sha256']
|
||||
last_character = sha256_hash[-1]
|
||||
last_character = chr(ord(last_character)-1)
|
||||
# "Subtract" the last character of the hash.
|
||||
target_metadata['hashes']['sha256'] = sha256_hash[:-1] + last_character
|
||||
|
||||
|
||||
def test_that_initial_update_works_with_many_roles_sharing_a_target(self):
|
||||
# Get relative target paths, because that is what TUF recognizes.
|
||||
relative_target_filepaths = self.relpath_from_targets(self.target_filepaths)
|
||||
# Get metadata about downloaded targets.
|
||||
targets_metadata = self.do_update()
|
||||
# Do we have metadata about all the expected targets?
|
||||
for target_filepath in relative_target_filepaths:
|
||||
self.assertIn(target_filepath, targets_metadata)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TestOrderOfTargetDelegationWithFailure(TestDelegationFunctions):
|
||||
"""We show that when multiple delegated targets roles talk about a target,
|
||||
the first one in order of appearance of delegation wins.
|
||||
|
||||
In this case, the first role has the wrong metadata about the target."""
|
||||
|
||||
|
||||
def make_targets_metadata(self):
|
||||
global version
|
||||
version = version+1
|
||||
expiration = tuf.formats.format_time(time.time()+86400)
|
||||
make_metadata = signerlib.generate_targets_metadata
|
||||
target1, target2 = self.target_filepaths
|
||||
|
||||
# Targets signed for by each of the targets roles.
|
||||
self.signed_targets[self.T0] = [target2]
|
||||
self.signed_targets[self.T1] = []
|
||||
self.signed_targets[self.T2] = [target1]
|
||||
self.signed_targets[self.T3] = [target1]
|
||||
|
||||
# Targets delegated to each of the delegated targets roles.
|
||||
self.delegated_targets[self.T1] = [target1]
|
||||
self.delegated_targets[self.T2] = [target1]
|
||||
self.delegated_targets[self.T3] = [target1]
|
||||
|
||||
self.T0_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T0],
|
||||
version, expiration)
|
||||
self.T1_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T1],
|
||||
version, expiration)
|
||||
self.T2_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T2],
|
||||
version, expiration)
|
||||
self.T3_metadata = \
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T3],
|
||||
version, expiration)
|
||||
|
||||
# Modify the hash for target1 in T3.
|
||||
for target_filepath in self.relpath_from_targets([target1]):
|
||||
target_metadata = self.T3_metadata['signed']['targets'][target_filepath]
|
||||
sha256_hash = target_metadata['hashes']['sha256']
|
||||
last_character = sha256_hash[-1]
|
||||
last_character = chr(ord(last_character)-1)
|
||||
# "Subtract" the last character of the hash.
|
||||
target_metadata['hashes']['sha256'] = sha256_hash[:-1] + last_character
|
||||
|
||||
|
||||
def test_that_initial_update_fails_with_many_roles_sharing_a_target(self):
|
||||
"""We expect to see BadHashError on initial update because the hash
|
||||
metadata mismatches the target."""
|
||||
|
||||
# http://docs.python.org/2/library/unittest.html#unittest.TestCase.assertRaises
|
||||
with self.assertRaises(tuf.NoWorkingMirrorError) as context_manager:
|
||||
self.do_update()
|
||||
|
||||
mirror_errors = context_manager.exception.mirror_errors
|
||||
bad_hash_error = False
|
||||
|
||||
for mirror_url, mirror_error in mirror_errors.iteritems():
|
||||
if isinstance(mirror_error, tuf.BadHashError):
|
||||
bad_hash_error = True
|
||||
break
|
||||
|
||||
self.assertEqual(bad_hash_error, True)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TestConservationOfTargetDelegation(TestDelegationFunctions):
|
||||
"""We show that delegated targets roles have to neither sign for targets
|
||||
delegated to them nor further delegate them."""
|
||||
|
||||
|
||||
def make_targets_metadata(self):
|
||||
global version
|
||||
expiration = tuf.formats.format_time(time.time()+86400)
|
||||
|
||||
make_metadata = signerlib.generate_targets_metadata
|
||||
target1, target2 = self.target_filepaths
|
||||
|
||||
# Targets signed for by each of the targets roles.
|
||||
self.signed_targets[self.T0] = []
|
||||
self.signed_targets[self.T1] = [target1]
|
||||
self.signed_targets[self.T2] = [target2]
|
||||
self.signed_targets[self.T3] = []
|
||||
|
||||
# Targets delegated to each of the delegated targets roles.
|
||||
self.delegated_targets[self.T1] = [target1, target2]
|
||||
self.delegated_targets[self.T2] = [target1, target2]
|
||||
self.delegated_targets[self.T3] = []
|
||||
|
||||
self.T0_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T0],
|
||||
version, expiration)
|
||||
self.T1_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T1],
|
||||
version, expiration)
|
||||
self.T2_metadata =\
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T2],
|
||||
version, expiration)
|
||||
self.T3_metadata = \
|
||||
make_metadata(self.tuf_repo, self.signed_targets[self.T3],
|
||||
version, expiration)
|
||||
|
||||
|
||||
def test_that_initial_update_works_with_unconserved_targets(self):
|
||||
# Get relative target paths, because that is what TUF recognizes.
|
||||
relative_target_filepaths = self.relpath_from_targets(self.target_filepaths)
|
||||
# Get metadata about downloaded targets.
|
||||
targets_metadata = self.do_update()
|
||||
# Do we have metadata about all the expected targets?
|
||||
for target_filepath in relative_target_filepaths:
|
||||
self.assertIn(target_filepath, targets_metadata)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -22,6 +22,7 @@
|
|||
"""
|
||||
|
||||
import shutil
|
||||
import datetime
|
||||
|
||||
from tuf.repository_tool import *
|
||||
import tuf.util
|
||||
|
|
@ -105,11 +106,11 @@
|
|||
# Set the top-level expiration times far into the future so that
|
||||
# they do not expire anytime soon, or else the tests fail. Unit tests may
|
||||
# modify the expiration datetimes (of the copied files), if they wish.
|
||||
repository.root.expiration = "2088-01-01 00:00:00"
|
||||
repository.targets.expiration = "2088-01-01 00:00:00"
|
||||
repository.snapshot.expiration = "2088-01-01 00:00:00"
|
||||
repository.timestamp.expiration = "2088-01-01 00:00:00"
|
||||
repository.targets('role1').expiration = "2088-01-01 00:00:00"
|
||||
repository.root.expiration = datetime.datetime(2030, 01, 01, 00, 00)
|
||||
repository.targets.expiration = datetime.datetime(2030, 01, 01, 00, 00)
|
||||
repository.snapshot.expiration = datetime.datetime(2030, 01, 01, 00, 00)
|
||||
repository.timestamp.expiration = datetime.datetime(2030, 01, 01, 00, 00)
|
||||
repository.targets('role1').expiration = datetime.datetime(2030, 01, 01, 00, 00)
|
||||
|
||||
# Compress the 'targets.json' role so that the unit tests have a pre-generated
|
||||
# example of compressed metadata.
|
||||
|
|
|
|||
|
|
@ -1,30 +1,30 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,54482FB3B9B400FE
|
||||
DEK-Info: DES-EDE3-CBC,31815D9E16C988F5
|
||||
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoezivMqfuB87dx9HyAwa
|
||||
o/V269HKfCz292vwiuk+BPxjIlhYNpBBYfKbukqaudRpzDCjEeouvtWgzgZXIKKv
|
||||
9PtFwmVkNwYUdJ2mi0Vx5n9mso0/9W24Gma01QkXXUYY0RJRsG5/xWLtRs/CHAEH
|
||||
XHO0CcCzeQhyFd7QkkJscUqFhB3JEr71Tu9sG+BJwbayZCE4K1E7ydDQgeQqenv1
|
||||
vEHh/APs8+iTlRb/NeN4/t22GsjqFXi57fvllIhdKP/c94PZvK1tqcbWcpB8m+Cq
|
||||
DPajNeUfB3tnhvbdiFpU66cNokkVOkiAM6F1Rc4TUWKOk1+nnKYK5xm2PUIeBOrI
|
||||
qwIDAQAB
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsD++h8KXKhrJpzYxvZTE
|
||||
7GqTDKM3uAWL8qGcQnvh7CNbqR4WmZrCQj1zF9hO5OAV+lGVD+JxUXW+yOPw+RjN
|
||||
i7mPVa12Mq+vCS7WuosoCoooLpnYhRRVYMgpnhbvnjS6xA+7myJ1Bob+7WUEZZlC
|
||||
oWdsmjfYG82sA7TOTubPk0s9pqQllINMEsB4JTTt3P3DD9+uifCFhoAEKeAItcgA
|
||||
p4PJw2ImNwJiuet5wTP1ssTclPPWB6ofkm8zXoJUywTIW+hcQhN88jQv4Egx1llj
|
||||
pWZbEdkIpNxjm6BAEqfPfiuAt6MA8cmdRpDl+Jn030A1kI7NJossuvTcfHwvReZO
|
||||
WwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
|
@ -1,30 +1,30 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,3FF3C80523E9427F
|
||||
DEK-Info: DES-EDE3-CBC,820FC61841CA82E2
|
||||
|
||||
+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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtEYs4bpRKf6eVbpOvNvg
|
||||
aD7rVnFStWzYIdnWdCvzASga5pM3eI14nCalfS/Z4iGCpaCtArp1QURCf+8u09A2
|
||||
t9Rvx6eLEnR6jp4bE1wCzOdghaKqpdR8mc5Aw5IqRzcnJi44X3WhDBe3MCVEYya3
|
||||
UtTD7Y/FZtp0ZoH3nI8vYnaiYO/jPWmrz254GRGmbR+eu9YOmmtezJg3xQSX5/j1
|
||||
hBGl7cnEDIa4kZi1aqdL9UsM2uikhC0f7A/OyNdlgvXVRAZd6fnFFQb44HDix0VG
|
||||
VdAmRosI+U4J9JDVW7G4Bt+Z47CfQ5CCW1wCKPRwx9F681WpdkLFG2YQ0zYjfAvo
|
||||
UQIDAQAB
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA72PwhMhTpDZ/wuB5Bdst
|
||||
gYsfEI931GcIZ46Iq2dqMNWEg2Qt9w6W0xEQj8M5R99XFwbhXL6U7hKGDt958FzT
|
||||
OL6CnjrnnBgzjbFm1vT380Qi5DaUbJkPcNmjzV45gGZkJ6LnohnBtnWUM/IdbbwR
|
||||
PdWaqBxWRJHECPHjgbKt6Y9kDwaO6tJQdUIDGwt2V9hz9orPqwiX+c6uO6qJ0naU
|
||||
F31ZvI4AtHUDaesbyp2j2X2dfCKNiM2t2sgxz79/G6VQvKG30PXxVPXvOhCDowsk
|
||||
5NdM67bWIkFyf1yNArrhw0D/c0aSGZhYZs+FqvBzKjCy+9+uEfLZsRra6zvx8Jw9
|
||||
TwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
|
@ -1,30 +1,30 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,7349E671E697C1CC
|
||||
DEK-Info: DES-EDE3-CBC,0E7D0C9F6987D107
|
||||
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo7FuATglySRO9/s6ZEN7
|
||||
VYtwjcs7NBO7uMIPnk2+EnNlLrN5mcW4eFafrKNXXJYQXZP+/b2t0K1sin3J08eV
|
||||
lTQo33ROtWOVKNLITGYfFewesGN8Rz0nREAkQmD9w8kFTCphNruCiDE0P8m7jRrC
|
||||
AHYl7zqKuuhNqghfYqDiAa+f8GOhIhNxJPf6NreYCGHW2kaMURnOKoD1v+mV2QDs
|
||||
QpTEP+/gPvck7rLdfCNUB7iBZnnQw2fVSga44klDQ0tmhHnik0YakX0F7F0dra2e
|
||||
Kz0N385MnW1vqEH1/QnSZBsJuqSNwf8JdPQBjisX3Qvm1ddH10jpWFizPtwnkm1b
|
||||
vwIDAQAB
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs0uAxc1XwUIayVPNt9U/
|
||||
gLM5hjG/6AJ86XiHVIq6BuzUtiuKONZXq3SJwY5eAxdjylNt/A3FrJwylQbVMZkh
|
||||
wLj0eU1IMh23xV1wOGu63Q9ARkmBAaksM+6apo2CHjtQaNXorhJ3/WDti2hST/cc
|
||||
HjP81+JwJ+T6lXGKvGDbh3h6Car99MWlMAeYODdNqvRaVkkiQ20HgNB+RSiyGZPi
|
||||
bzqlMe+qCQU/vktmmy9Zw3bjY7b8GFBix+7PHzFCpX15xKwB4dITPmsiL2OOo/w/
|
||||
1Vqu3wP7Ct170oK+bH9eIk6wSAQX3IljKhgzkiYFRyCC33XHRpWmSjMgAGErCcl6
|
||||
cwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
|
@ -1,30 +1,30 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,25ACB134E522BFFF
|
||||
DEK-Info: DES-EDE3-CBC,D32B3B70C5CB2933
|
||||
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArto5S3epNKVy+k8BbqAx
|
||||
0/YDt968iu/crducSS1Ys4HxvWFZ+XuEqegZb8zVp8aem4WbNFw4XpUDConwOW4w
|
||||
wIaqmxJ4EgW0OzEmX+AeBlc6OQYW0wD6GEOWAMj5WjebJd54fE2zXn9p2dLdzm4q
|
||||
JA7iVGWPE5vNPkqOYfX7mmoj73/vpM8q0Ghbi9+2/7v0QYlRgeaR82C+InfeO1vi
|
||||
y7Wcu2M66iWxSmbF0whd7BAXaNHkyoH8AEl3dPVxHgtY8J7zdYoPrCN0/lx3mgUL
|
||||
r9fEcTqy+Q7K/0zKPOG97FT1CqRoY1svPNYP48HmbnTQT/vESwo6dTmTU1PwL+2K
|
||||
vQIDAQAB
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTXKgkuaAyfvjkInfVic
|
||||
lJnwLvG9mCXOcxR3HPwHK/8k/E/DBx8YGIGk7NWCXQFYnAeMZZdx8v3dBmH7oGAn
|
||||
1pW+LnaAI7Csark8sbgmwYqwTd2oLHHmp/fOZ1vNDWjqvMLwi1YUllR6wPWKAvP2
|
||||
8i7q7GCT/MBHDyZ899FCR4f7HvlCW5EYNt+wjxdm79T++Ix7iqvs4iUhvllsfdty
|
||||
cVPWc+wh60qqCCbnr1Fow8d2j42a8mHoIHWgDvEF9ch+ChDOzQ+53jVmXS3CC+a2
|
||||
H6EWNvKMc/wXvIAwA/y6cIjCG+Kep9AvVgz1blHf4ReTlNJWu2OkanszuboAR6nt
|
||||
+wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
|
@ -1,30 +1,30 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,FE4027E2AF1DF4E3
|
||||
DEK-Info: DES-EDE3-CBC,D5B52C0993E278D0
|
||||
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmyfY/TyvGDt/N/L+x8+
|
||||
hVpku3JNOvPrFG0QUEQYWjlNjS+DSqigQvo4hluKz++qGeSYFl+LJBw4YLa0RFAg
|
||||
b5jz9NAVBZJgTseT762jYC7HnZgmBE8vHcmAbfnUzcU7tLVn44xk3akzWGBTIEr6
|
||||
VBL6x8nMgKNqLylIMDIVBHUI/FkAMMnfccYhLQSm9y/VAF/uW+/vu7WTjQynlEAY
|
||||
vvQZqLxLC9mmY1i/kYeLbsJxZowzFw5KfVXQLjeVj420r8L0d9Yrl7T9ZH6AxCoi
|
||||
jC6qAV/T9EP/FSEmyTf0MbCZDVDXlRwia+0Eb+5UkWRLGkjJgvghC/zCcODLexXv
|
||||
+QIDAQAB
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAueyWz2lDPzyywmWegFTP
|
||||
l0DDXVNr9XIYLNffLRC24Y9ZKJCqb6eIz3XlF/3On5dCCqKFOfneHm55SxyCzoQb
|
||||
RAtr5+SmoXfsds7ZAnxv48iGLtk7aZEvHchhEJ+1HsKy5hMeqpXtOAMPJXqBfqgT
|
||||
ZzXagdCHNnbLEvhyJmRAaK88I/93s57KRNvPp6NIUbQ8EHaX1jaWt+LhGfsA3C34
|
||||
qcxlk16LXF45Wm2AgMFCtZ2BecUvSQds24b/ShxfeVRtXSSUMDd+dM+MbwclPsoP
|
||||
eTeegQATmA4pu4dDaBeYUnS/hstUZS5QPUuvVw6K0Q2JHUWv6CS2kziUjPXGI44H
|
||||
LwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -53,7 +53,7 @@ def do_GET(self):
|
|||
|
||||
if self.server.test_mode == 'mode_1':
|
||||
# Before sending any data, the server does nothing for a long time.
|
||||
DELAY = 60
|
||||
DELAY = 40
|
||||
time.sleep(DELAY)
|
||||
self.wfile.write(data)
|
||||
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
import tuf.util
|
||||
import tuf.log
|
||||
import tuf.client.updater as updater
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
logger = logging.getLogger('tuf.test_arbitrary_package_attack')
|
||||
|
||||
|
|
@ -110,8 +110,7 @@ def setUp(self):
|
|||
# Copy the original repository files provided in the test folder so that
|
||||
# any modifications made to repository files are restricted to the copies.
|
||||
# The 'repository_data' directory is expected to exist in 'tuf/tests/'.
|
||||
original_repository_files = os.path.join(os.getcwd(), os.pardir,
|
||||
'repository_data')
|
||||
original_repository_files = os.path.join(os.getcwd(), 'repository_data')
|
||||
temporary_repository_root = \
|
||||
self.make_temp_directory(directory=self.temporary_directory)
|
||||
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
test_download.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
Konstantin Andrianov.
|
||||
|
||||
<Started>
|
||||
March 26, 2012.
|
||||
|
|
@ -14,12 +14,10 @@
|
|||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
Test download.py module.
|
||||
|
||||
|
||||
NOTE: Make sure test_download.py is ran in 'tuf/tests/' directory.
|
||||
Otherwise, module that launches simple server would not be found.
|
||||
Unit test for 'download.py'.
|
||||
|
||||
NOTE: Make sure test_download.py is ran in 'tuf/tests/' directory.
|
||||
Otherwise, module that launches simple server would not be found.
|
||||
"""
|
||||
|
||||
|
||||
|
|
@ -37,7 +35,7 @@
|
|||
import tuf.conf as conf
|
||||
import tuf.download as download
|
||||
import tuf.log
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
logger = logging.getLogger('tuf.test_download')
|
||||
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
import tuf.util
|
||||
import tuf.log
|
||||
import tuf.client.updater as updater
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
logger = logging.getLogger('tuf.test_endless_data_attack')
|
||||
|
||||
|
|
@ -113,8 +113,7 @@ def setUp(self):
|
|||
# Copy the original repository files provided in the test folder so that
|
||||
# any modifications made to repository files are restricted to the copies.
|
||||
# The 'repository_data' directory is expected to exist in 'tuf/tests/'.
|
||||
original_repository_files = os.path.join(os.getcwd(), os.pardir,
|
||||
'repository_data')
|
||||
original_repository_files = os.path.join(os.getcwd(), 'repository_data')
|
||||
temporary_repository_root = \
|
||||
self.make_temp_directory(directory=self.temporary_directory)
|
||||
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
import tuf.util
|
||||
import tuf.log
|
||||
import tuf.client.updater as updater
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
|
||||
logger = logging.getLogger('tuf.test_extraneous_dependencies_attack')
|
||||
|
|
@ -116,8 +116,7 @@ def setUp(self):
|
|||
# Copy the original repository files provided in the test folder so that
|
||||
# any modifications made to repository files are restricted to the copies.
|
||||
# The 'repository_data' directory is expected to exist in 'tuf/tests/'.
|
||||
original_repository_files = os.path.join(os.getcwd(), os.pardir,
|
||||
'repository_data')
|
||||
original_repository_files = os.path.join(os.getcwd(), 'repository_data')
|
||||
temporary_repository_root = \
|
||||
self.make_temp_directory(directory=self.temporary_directory)
|
||||
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
"""
|
||||
|
||||
import unittest
|
||||
import datetime
|
||||
|
||||
import tuf
|
||||
import tuf.formats
|
||||
|
|
@ -39,7 +40,10 @@ def tearDown(self):
|
|||
def test_schemas(self):
|
||||
# Test conditions for valid schemas.
|
||||
valid_schemas = {
|
||||
'TIME_SCHEMA': (tuf.formats.TIME_SCHEMA, '2012-10-14 06:42:12 UTC'),
|
||||
'ISO8601_DATETIME_SCHEMA': (tuf.formats.ISO8601_DATETIME_SCHEMA,
|
||||
'1985-10-21T13:20:00Z'),
|
||||
|
||||
'UNIX_TIMESTAMP_SCHEMA': (tuf.formats.UNIX_TIMESTAMP_SCHEMA, 499137720),
|
||||
|
||||
'HASH_SCHEMA': (tuf.formats.HASH_SCHEMA, 'A4582BCF323BCEF'),
|
||||
|
||||
|
|
@ -53,7 +57,7 @@ def test_schemas(self):
|
|||
'KEYIDS_SCHEMA': (tuf.formats.KEYIDS_SCHEMA,
|
||||
['123456789abcdef', '123456789abcdef']),
|
||||
|
||||
'SIG_METHOD_SCHEMA': (tuf.formats.SIG_METHOD_SCHEMA, 'evp'),
|
||||
'SIG_METHOD_SCHEMA': (tuf.formats.SIG_METHOD_SCHEMA, 'ed25519'),
|
||||
|
||||
'RELPATH_SCHEMA': (tuf.formats.RELPATH_SCHEMA, 'metadata/root/'),
|
||||
|
||||
|
|
@ -184,7 +188,7 @@ def test_schemas(self):
|
|||
{'_type': 'Root',
|
||||
'version': 8,
|
||||
'consistent_snapshot': False,
|
||||
'expires': '2012-10-16 06:42:12 UTC',
|
||||
'expires': '1985-10-21T13:20:00Z',
|
||||
'keys': {'123abc': {'keytype': 'rsa',
|
||||
'keyval': {'public': 'pubkey',
|
||||
'private': 'privkey'}}},
|
||||
|
|
@ -195,7 +199,7 @@ def test_schemas(self):
|
|||
'TARGETS_SCHEMA': (tuf.formats.TARGETS_SCHEMA,
|
||||
{'_type': 'Targets',
|
||||
'version': 8,
|
||||
'expires': '2012-10-16 06:42:12 UTC',
|
||||
'expires': '1985-10-21T13:20:00Z',
|
||||
'targets': {'metadata/targets.json': {'length': 1024,
|
||||
'hashes': {'sha256': 'ABCD123'},
|
||||
'custom': {'type': 'metadata'}}},
|
||||
|
|
@ -209,7 +213,7 @@ def test_schemas(self):
|
|||
'SNAPSHOT_SCHEMA': (tuf.formats.SNAPSHOT_SCHEMA,
|
||||
{'_type': 'Snapshot',
|
||||
'version': 8,
|
||||
'expires': '2012-10-16 06:42:12 UTC',
|
||||
'expires': '1985-10-21T13:20:00Z',
|
||||
'meta': {'metadata/snapshot.json': {'length': 1024,
|
||||
'hashes': {'sha256': 'ABCD123'},
|
||||
'custom': {'type': 'metadata'}}}}),
|
||||
|
|
@ -217,7 +221,7 @@ def test_schemas(self):
|
|||
'TIMESTAMP_SCHEMA': (tuf.formats.TIMESTAMP_SCHEMA,
|
||||
{'_type': 'Timestamp',
|
||||
'version': 8,
|
||||
'expires': '2012-10-16 06:42:12 UTC',
|
||||
'expires': '1985-10-21T13:20:00Z',
|
||||
'meta': {'metadata/timestamp.json': {'length': 1024,
|
||||
'hashes': {'sha256': 'ABCD123'},
|
||||
'custom': {'type': 'metadata'}}}}),
|
||||
|
|
@ -239,7 +243,7 @@ def test_schemas(self):
|
|||
'MIRRORLIST_SCHEMA': (tuf.formats.MIRRORLIST_SCHEMA,
|
||||
{'_type': 'Mirrors',
|
||||
'version': 8,
|
||||
'expires': '2012-10-16 06:42:12 UTC',
|
||||
'expires': '1985-10-21T13:20:00Z',
|
||||
'mirrors': [{'url_prefix': 'http://localhost:8001',
|
||||
'metadata_path': 'metadata/',
|
||||
'targets_path': 'targets/',
|
||||
|
|
@ -289,7 +293,7 @@ def __init__(self, version, expires):
|
|||
def test_TimestampFile(self):
|
||||
# Test conditions for valid instances of 'tuf.formats.TimestampFile'.
|
||||
version = 8
|
||||
expires = '2012-10-16 06:42:12 UTC'
|
||||
expires = '1985-10-21T13:20:00Z'
|
||||
filedict = {'metadata/timestamp.json': {'length': 1024,
|
||||
'hashes': {'sha256': 'ABCD123'},
|
||||
'custom': {'type': 'metadata'}}}
|
||||
|
|
@ -323,7 +327,8 @@ def test_RootFile(self):
|
|||
# Test conditions for valid instances of 'tuf.formats.RootFile'.
|
||||
version = 8
|
||||
consistent_snapshot = False
|
||||
expires = '2018-10-16 06:42:12 UTC'
|
||||
expires = '1985-10-21T13:20:00Z'
|
||||
|
||||
keydict = {'123abc': {'keytype': 'rsa',
|
||||
'keyval': {'public': 'pubkey',
|
||||
'private': 'privkey'}}}
|
||||
|
|
@ -373,7 +378,8 @@ def test_RootFile(self):
|
|||
def test_SnapshotFile(self):
|
||||
# Test conditions for valid instances of 'tuf.formats.SnapshotFile'.
|
||||
version = 8
|
||||
expires = '2012-10-16 06:42:12 UTC'
|
||||
expires = '1985-10-21T13:20:00Z'
|
||||
|
||||
filedict = {'metadata/snapshot.json': {'length': 1024,
|
||||
'hashes': {'sha256': 'ABCD123'},
|
||||
'custom': {'type': 'metadata'}}}
|
||||
|
|
@ -405,7 +411,8 @@ def test_SnapshotFile(self):
|
|||
def test_TargetsFile(self):
|
||||
# Test conditions for valid instances of 'tuf.formats.TargetsFile'.
|
||||
version = 8
|
||||
expires = '2012-10-16 06:42:12 UTC'
|
||||
expires = '1985-10-21T13:20:00Z'
|
||||
|
||||
filedict = {'metadata/targets.json': {'length': 1024,
|
||||
'hashes': {'sha256': 'ABCD123'},
|
||||
'custom': {'type': 'metadata'}}}
|
||||
|
|
@ -444,27 +451,30 @@ def test_TargetsFile(self):
|
|||
|
||||
|
||||
|
||||
def test_format_time(self):
|
||||
def test_unix_timestamp_to_datetime(self):
|
||||
# Test conditions for valid arguments.
|
||||
TIME_SCHEMA = tuf.formats.TIME_SCHEMA
|
||||
self.assertTrue(TIME_SCHEMA.matches(tuf.formats.format_time(499137720)))
|
||||
self.assertEqual('1985-10-26 01:22:00 UTC', tuf.formats.format_time(499137720))
|
||||
UNIX_TIMESTAMP_SCHEMA = tuf.formats.UNIX_TIMESTAMP_SCHEMA
|
||||
self.assertTrue(datetime.datetime, tuf.formats.unix_timestamp_to_datetime(499137720))
|
||||
datetime_object = datetime.datetime(1985, 10, 26, 01, 22)
|
||||
self.assertEqual(datetime_object, tuf.formats.unix_timestamp_to_datetime(499137720))
|
||||
|
||||
# Test conditions for invalid arguments.
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.format_time, 'bad')
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.format_time, 1000000000000000000000)
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.format_time, ['5'])
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.unix_timestamp_to_datetime, 'bad')
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.unix_timestamp_to_datetime, 1000000000000000000000)
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.unix_timestamp_to_datetime, -1)
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.unix_timestamp_to_datetime, ['5'])
|
||||
|
||||
|
||||
|
||||
def test_parse_time(self):
|
||||
def test_datetime_to_unix_timestamp(self):
|
||||
# Test conditions for valid arguments.
|
||||
self.assertEqual(499137600, tuf.formats.parse_time('1985-10-26 01:20:00 UTC'))
|
||||
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(tuf.FormatError, tuf.formats.parse_time, 'bad')
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.parse_time, 1000000000000000000000)
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.parse_time, ['1'])
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.datetime_to_unix_timestamp, 'bad')
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.datetime_to_unix_timestamp, 1000000000000000000000)
|
||||
self.assertRaises(tuf.FormatError, tuf.formats.datetime_to_unix_timestamp, ['1'])
|
||||
|
||||
|
||||
|
||||
|
|
@ -498,7 +508,7 @@ def test_make_signable(self):
|
|||
root = {'_type': 'Root',
|
||||
'version': 8,
|
||||
'consistent_snapshot': False,
|
||||
'expires': '2012-10-16 06:42:12 UTC',
|
||||
'expires': '1985-10-21T13:20:00Z',
|
||||
'keys': {'123abc': {'keytype': 'rsa',
|
||||
'keyval': {'public': 'pubkey',
|
||||
'private': 'privkey'}}},
|
||||
|
|
@ -625,7 +635,7 @@ def test_check_signable_object_format(self):
|
|||
root = {'_type': 'Root',
|
||||
'version': 8,
|
||||
'consistent_snapshot': False,
|
||||
'expires': '2012-10-16 06:42:12 UTC',
|
||||
'expires': '1985-10-21T13:20:00Z',
|
||||
'keys': {'123abc': {'keytype': 'rsa',
|
||||
'keyval': {'public': 'pubkey',
|
||||
'private': 'privkey'}}},
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
import tuf.log
|
||||
import tuf.client.updater as updater
|
||||
import tuf.repository_tool as repo_tool
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
# The repository tool is imported and logs console messages by default. Disable
|
||||
# console log messages generated by this unit test.
|
||||
|
|
@ -111,8 +111,7 @@ def setUp(self):
|
|||
# Copy the original repository files provided in the test folder so that
|
||||
# any modifications made to repository files are restricted to the copies.
|
||||
# The 'repository_data' directory is expected to exist in 'tuf/tests/'.
|
||||
original_repository_files = os.path.join(os.getcwd(), os.pardir,
|
||||
'repository_data')
|
||||
original_repository_files = os.path.join(os.getcwd(), 'repository_data')
|
||||
temporary_repository_root = \
|
||||
self.make_temp_directory(directory=self.temporary_directory)
|
||||
|
||||
|
|
@ -177,9 +176,9 @@ def test_without_tuf(self):
|
|||
'timestamp.json')
|
||||
|
||||
timestamp_metadata = tuf.util.load_json_file(timestamp_path)
|
||||
timestamp_metadata['signed']['expires'] = \
|
||||
tuf.formats.format_time(time.time() - 10)
|
||||
|
||||
expires = tuf.formats.unix_timestamp_to_datetime(int(time.time() - 10))
|
||||
expires = expires.isoformat() + 'Z'
|
||||
timestamp_metadata['signed']['expires'] = expires
|
||||
tuf.formats.check_signable_object_format(timestamp_metadata)
|
||||
|
||||
with open(timestamp_path, 'wb') as file_object:
|
||||
|
|
@ -226,9 +225,8 @@ def test_with_tuf(self):
|
|||
repository.timestamp.load_signing_key(timestamp_private)
|
||||
|
||||
# expire in 1 second.
|
||||
utc_timestamp = tuf.formats.format_time(time.time() + 1)
|
||||
repository.timestamp.expiration = \
|
||||
utc_timestamp[0:utc_timestamp.rfind(' UTC')]
|
||||
datetime_object = tuf.formats.unix_timestamp_to_datetime(int(time.time() + 1))
|
||||
repository.timestamp.expiration = datetime_object
|
||||
repository.write()
|
||||
|
||||
# Move the staged metadata to the "live" metadata.
|
||||
|
|
@ -237,8 +235,9 @@ def test_with_tuf(self):
|
|||
os.path.join(self.repository_directory, 'metadata'))
|
||||
|
||||
# Verify that the TUF client detects outdated metadata and refuses to
|
||||
# continue the update process.
|
||||
time.sleep(1)
|
||||
# continue the update process. Sleep for at least 2 seconds to ensure
|
||||
# 'repository.timestamp.expiration' is reached.
|
||||
time.sleep(2)
|
||||
self.assertRaises(tuf.ExpiredMetadataError,
|
||||
self.repository_updater.refresh)
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ def test_create_keydb_from_root_metadata(self):
|
|||
'Targets': {'keyids': [keyid2], 'threshold': 1}}
|
||||
version = 8
|
||||
consistent_snapshot = False
|
||||
expires = '2012-10-16 06:42:12 UTC'
|
||||
expires = '1985-10-21T01:21:00Z'
|
||||
|
||||
root_metadata = tuf.formats.RootFile.make_metadata(version,
|
||||
expires,
|
||||
|
|
@ -208,7 +208,7 @@ def test_create_keydb_from_root_metadata(self):
|
|||
rsakey3['keytype'] = 'bad_keytype'
|
||||
keydict[keyid3] = rsakey3
|
||||
version = 8
|
||||
expires = '2012-10-16 06:42:12 UTC'
|
||||
expires = '1985-10-21T01:21:00Z'
|
||||
|
||||
root_metadata = tuf.formats.RootFile.make_metadata(version,
|
||||
expires,
|
||||
|
|
@ -12,8 +12,7 @@
|
|||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
Test mirrors.py module.
|
||||
|
||||
Unit test for 'mirrors.py'.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
|
@ -21,7 +20,7 @@
|
|||
import tuf
|
||||
import tuf.formats as formats
|
||||
import tuf.mirrors as mirrors
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
|
||||
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
import tuf.log
|
||||
import tuf.client.updater as updater
|
||||
import tuf.repository_tool as repo_tool
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
# The repository tool is imported and logs console messages by default. Disable
|
||||
# console log messages generated by this unit test.
|
||||
|
|
@ -117,8 +117,7 @@ def setUp(self):
|
|||
# Copy the original repository files provided in the test folder so that
|
||||
# any modifications made to repository files are restricted to the copies.
|
||||
# The 'repository_data' directory is expected to exist in 'tuf/tests/'.
|
||||
original_repository_files = os.path.join(os.getcwd(), os.pardir,
|
||||
'repository_data')
|
||||
original_repository_files = os.path.join(os.getcwd(), 'repository_data')
|
||||
temporary_repository_root = \
|
||||
self.make_temp_directory(directory=self.temporary_directory)
|
||||
|
||||
|
|
@ -39,6 +39,7 @@
|
|||
import tempfile
|
||||
import random
|
||||
import time
|
||||
import datetime
|
||||
import shutil
|
||||
import json
|
||||
import subprocess
|
||||
|
|
@ -50,7 +51,7 @@
|
|||
import tuf.log
|
||||
import tuf.client.updater as updater
|
||||
import tuf.repository_tool as repo_tool
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
# The repository tool is imported and logs console messages by default. Disable
|
||||
# console log messages generated by this unit test.
|
||||
|
|
@ -117,8 +118,7 @@ def setUp(self):
|
|||
# Copy the original repository files provided in the test folder so that
|
||||
# any modifications made to repository files are restricted to the copies.
|
||||
# The 'repository_data' directory is expected to exist in 'tuf/tests/'.
|
||||
original_repository_files = os.path.join(os.getcwd(), os.pardir,
|
||||
'repository_data')
|
||||
original_repository_files = os.path.join(os.getcwd(), 'repository_data')
|
||||
temporary_repository_root = \
|
||||
self.make_temp_directory(directory=self.temporary_directory)
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ def test_without_tuf(self):
|
|||
|
||||
# Set an arbitrary expiration so that the repository tool generates a new
|
||||
# version.
|
||||
repository.timestamp.expiration = '2088-01-01 12:12:00'
|
||||
repository.timestamp.expiration = datetime.datetime(2030, 01, 01, 12, 12)
|
||||
repository.write()
|
||||
|
||||
# Move the staged metadata to the "live" metadata.
|
||||
|
|
@ -280,7 +280,7 @@ def test_with_tuf(self):
|
|||
|
||||
# Set an arbitrary expiration so that the repository tool generates a new
|
||||
# version.
|
||||
repository.timestamp.expiration = '2088-01-01 12:12:00'
|
||||
repository.timestamp.expiration = datetime.datetime(2030, 01, 01, 12, 12)
|
||||
repository.write()
|
||||
|
||||
# Move the staged metadata to the "live" metadata.
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
import unittest
|
||||
import logging
|
||||
import tempfile
|
||||
|
|
@ -106,7 +107,7 @@ def test_write_and_write_partial(self):
|
|||
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
|
||||
targets_directory = os.path.join(temporary_directory, 'repository',
|
||||
repo_tool.TARGETS_DIRECTORY_NAME)
|
||||
original_targets_directory = os.path.join(os.pardir, 'repository_data',
|
||||
original_targets_directory = os.path.join('repository_data',
|
||||
'repository', 'targets')
|
||||
shutil.copytree(original_targets_directory, targets_directory)
|
||||
|
||||
|
|
@ -120,7 +121,7 @@ def test_write_and_write_partial(self):
|
|||
|
||||
# (1) Load the public and private keys of the top-level roles, and one
|
||||
# delegated role.
|
||||
keystore_directory = os.path.join(os.pardir, 'repository_data', 'keystore')
|
||||
keystore_directory = os.path.join('repository_data', 'keystore')
|
||||
|
||||
# Load the public keys.
|
||||
root_pubkey_path = os.path.join(keystore_directory, 'root_key.pub')
|
||||
|
|
@ -225,7 +226,7 @@ def test_write_and_write_partial(self):
|
|||
# is made to a role.
|
||||
repo_tool.load_repository(repository_directory)
|
||||
|
||||
repository.timestamp.expiration = '2084-01-01 12:00:00'
|
||||
repository.timestamp.expiration = datetime.datetime(2030, 01, 01, 12, 00)
|
||||
self.assertRaises(tuf.UnsignedMetadataError, repository.write)
|
||||
|
||||
# Verify that a write_partial() is allowed.
|
||||
|
|
@ -261,8 +262,8 @@ def test_write_and_write_partial(self):
|
|||
def test_get_filepaths_in_directory(self):
|
||||
# Test normal case.
|
||||
# Use the pre-generated metadata directory for testing.
|
||||
metadata_directory = os.path.join(os.pardir, 'repository_data',
|
||||
'repository', 'metadata')
|
||||
metadata_directory = os.path.join('repository_data',
|
||||
'repository', 'metadata')
|
||||
|
||||
|
||||
# Test improperly formatted arguments.
|
||||
|
|
@ -300,8 +301,9 @@ def __init__(self):
|
|||
self._rolename = 'metadata_role'
|
||||
|
||||
# Expire in 86400 seconds (1 day).
|
||||
expiration = tuf.formats.format_time(time.time() + 86400)
|
||||
|
||||
expiration = \
|
||||
tuf.formats.unix_timestamp_to_datetime(int(time.time() + 86400))
|
||||
expiration = expiration.isoformat() + 'Z'
|
||||
roleinfo = {'keyids': [], 'signing_keyids': [], 'threshold': 1,
|
||||
'signatures': [], 'version': 0,
|
||||
'consistent_snapshot': False,
|
||||
|
|
@ -354,31 +356,35 @@ def test_threshold(self):
|
|||
def test_expiration(self):
|
||||
# Test expiration getter.
|
||||
expiration = self.metadata.expiration
|
||||
self.assertTrue(tuf.formats.TIME_SCHEMA.matches(expiration))
|
||||
self.assertTrue(isinstance(expiration, datetime.datetime))
|
||||
|
||||
# Test expiration setter.
|
||||
self.metadata.expiration = '2088-01-01 12:00:00'
|
||||
self.metadata.expiration = datetime.datetime(2030, 01, 01, 12, 00)
|
||||
expiration = self.metadata.expiration
|
||||
self.assertTrue(tuf.formats.TIME_SCHEMA.matches(expiration))
|
||||
self.assertTrue(isinstance(expiration, datetime.datetime))
|
||||
|
||||
|
||||
# Test improperly formatted datetime.
|
||||
try:
|
||||
self.metadata.expiration = '3'
|
||||
|
||||
except tuf.FormatError:
|
||||
pass
|
||||
|
||||
else:
|
||||
self.fail('Setter failed to detect improperly formatted datetime.')
|
||||
|
||||
|
||||
# Test invalid argument (i.e., expiration has already expired.)
|
||||
expired_datetime = tuf.formats.format_time(time.time() - 1)
|
||||
expired_datetime = tuf.formats.unix_timestamp_to_datetime(int(time.time() - 1))
|
||||
try:
|
||||
self.metadata.expiration = expired_datetime
|
||||
except tuf.FormatError:
|
||||
|
||||
except tuf.Error:
|
||||
pass
|
||||
|
||||
else:
|
||||
self.fail('Setter failted to detect an expired datetime.')
|
||||
self.fail('Setter failed to detect an expired datetime.')
|
||||
|
||||
|
||||
|
||||
|
|
@ -388,7 +394,7 @@ def test_keys(self):
|
|||
|
||||
|
||||
# Test keys() getter after a verification key has been loaded.
|
||||
key_path = os.path.join(os.pardir, 'repository_data',
|
||||
key_path = os.path.join('repository_data',
|
||||
'keystore', 'root_key.pub')
|
||||
key_object = repo_tool.import_rsa_publickey_from_file(key_path)
|
||||
self.metadata.add_verification_key(key_object)
|
||||
|
|
@ -404,7 +410,7 @@ def test_signing_keys(self):
|
|||
|
||||
|
||||
# Test signing_keys() getter after a signing key has been loaded.
|
||||
key_path = os.path.join(os.pardir, 'repository_data',
|
||||
key_path = os.path.join('repository_data',
|
||||
'keystore', 'root_key')
|
||||
key_object = repo_tool.import_rsa_privatekey_from_file(key_path, 'password')
|
||||
self.metadata.load_signing_key(key_object)
|
||||
|
|
@ -436,7 +442,7 @@ def test_compressions(self):
|
|||
|
||||
def test_add_verification_key(self):
|
||||
# Add verification key and verify with keys() that it was added.
|
||||
key_path = os.path.join(os.pardir, 'repository_data',
|
||||
key_path = os.path.join('repository_data',
|
||||
'keystore', 'root_key.pub')
|
||||
key_object = repo_tool.import_rsa_publickey_from_file(key_path)
|
||||
self.metadata.add_verification_key(key_object)
|
||||
|
|
@ -452,7 +458,7 @@ def test_add_verification_key(self):
|
|||
|
||||
def test_remove_verification_key(self):
|
||||
# Add verification key so that remove_verifiation_key() can be tested.
|
||||
key_path = os.path.join(os.pardir, 'repository_data',
|
||||
key_path = os.path.join('repository_data',
|
||||
'keystore', 'root_key.pub')
|
||||
key_object = repo_tool.import_rsa_publickey_from_file(key_path)
|
||||
self.metadata.add_verification_key(key_object)
|
||||
|
|
@ -471,7 +477,7 @@ def test_remove_verification_key(self):
|
|||
|
||||
|
||||
# Test non-existent public key argument.
|
||||
key_path = os.path.join(os.pardir, 'repository_data',
|
||||
key_path = os.path.join('repository_data',
|
||||
'keystore', 'targets_key.pub')
|
||||
unused_key_object = repo_tool.import_rsa_publickey_from_file(key_path)
|
||||
|
||||
|
|
@ -482,7 +488,7 @@ def test_remove_verification_key(self):
|
|||
|
||||
def test_load_signing_key(self):
|
||||
# Test normal case.
|
||||
key_path = os.path.join(os.pardir, 'repository_data',
|
||||
key_path = os.path.join('repository_data',
|
||||
'keystore', 'root_key')
|
||||
key_object = repo_tool.import_rsa_privatekey_from_file(key_path, 'password')
|
||||
self.metadata.load_signing_key(key_object)
|
||||
|
|
@ -496,7 +502,7 @@ def test_load_signing_key(self):
|
|||
|
||||
|
||||
# Test non-private key.
|
||||
key_path = os.path.join(os.pardir, 'repository_data',
|
||||
key_path = os.path.join('repository_data',
|
||||
'keystore', 'root_key.pub')
|
||||
key_object = repo_tool.import_rsa_publickey_from_file(key_path)
|
||||
self.assertRaises(tuf.Error, self.metadata.load_signing_key, key_object)
|
||||
|
|
@ -505,7 +511,7 @@ def test_load_signing_key(self):
|
|||
|
||||
def test_unload_signing_key(self):
|
||||
# Load a signing key so that unload_signing_key() can have a key to unload.
|
||||
key_path = os.path.join(os.pardir, 'repository_data',
|
||||
key_path = os.path.join('repository_data',
|
||||
'keystore', 'root_key')
|
||||
key_object = repo_tool.import_rsa_privatekey_from_file(key_path, 'password')
|
||||
self.metadata.load_signing_key(key_object)
|
||||
|
|
@ -523,7 +529,7 @@ def test_unload_signing_key(self):
|
|||
|
||||
|
||||
# Test non-existent key argument.
|
||||
key_path = os.path.join(os.pardir, 'repository_data',
|
||||
key_path = os.path.join('repository_data',
|
||||
'keystore', 'targets_key')
|
||||
unused_key_object = repo_tool.import_rsa_privatekey_from_file(key_path,
|
||||
'password')
|
||||
|
|
@ -537,7 +543,7 @@ def test_add_signature(self):
|
|||
# Test normal case.
|
||||
# Load signature list from any of pre-generated metadata; needed for
|
||||
# testing.
|
||||
metadata_directory = os.path.join(os.pardir, 'repository_data',
|
||||
metadata_directory = os.path.join('repository_data',
|
||||
'repository', 'metadata')
|
||||
root_filepath = os.path.join(metadata_directory, 'root.json')
|
||||
root_signable = tuf.util.load_json_file(root_filepath)
|
||||
|
|
@ -556,7 +562,7 @@ def test_add_signature(self):
|
|||
def test_remove_signature(self):
|
||||
# Test normal case.
|
||||
# Add a signature so remove_signature() has some signature to remove.
|
||||
metadata_directory = os.path.join(os.pardir, 'repository_data',
|
||||
metadata_directory = os.path.join('repository_data',
|
||||
'repository', 'metadata')
|
||||
root_filepath = os.path.join(metadata_directory, 'root.json')
|
||||
root_signable = tuf.util.load_json_file(root_filepath)
|
||||
|
|
@ -587,7 +593,7 @@ def test_signatures(self):
|
|||
|
||||
|
||||
# Test getter after adding an example signature.
|
||||
metadata_directory = os.path.join(os.pardir, 'repository_data',
|
||||
metadata_directory = os.path.join('repository_data',
|
||||
'repository', 'metadata')
|
||||
root_filepath = os.path.join(metadata_directory, 'root.json')
|
||||
root_signable = tuf.util.load_json_file(root_filepath)
|
||||
|
|
@ -700,7 +706,7 @@ def setUp(self):
|
|||
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
|
||||
self.targets_directory = os.path.join(temporary_directory, 'repository',
|
||||
'targets')
|
||||
original_targets_directory = os.path.join(os.pardir, 'repository_data',
|
||||
original_targets_directory = os.path.join('repository_data',
|
||||
'repository', 'targets')
|
||||
shutil.copytree(original_targets_directory, self.targets_directory)
|
||||
self.targets_object = repo_tool.Targets(self.targets_directory)
|
||||
|
|
@ -752,7 +758,7 @@ def test_get_delegated_rolenames(self):
|
|||
# Test normal case.
|
||||
# Perform two delegations so that get_delegated_rolenames() has roles to
|
||||
# return.
|
||||
keystore_directory = os.path.join(os.pardir, 'repository_data', 'keystore')
|
||||
keystore_directory = os.path.join('repository_data', 'keystore')
|
||||
public_keypath = os.path.join(keystore_directory, 'root_key.pub')
|
||||
public_key = repo_tool.import_rsa_publickey_from_file(public_keypath)
|
||||
target1_filepath = os.path.join(self.targets_directory, 'file1.txt')
|
||||
|
|
@ -793,7 +799,7 @@ def test_delegations(self):
|
|||
# Test normal case.
|
||||
# Perform a delegation so that delegations() has a Targets() object to
|
||||
# return.
|
||||
keystore_directory = os.path.join(os.pardir, 'repository_data', 'keystore')
|
||||
keystore_directory = os.path.join('repository_data', 'keystore')
|
||||
public_keypath = os.path.join(keystore_directory, 'root_key.pub')
|
||||
public_key = repo_tool.import_rsa_publickey_from_file(public_keypath)
|
||||
target1_filepath = os.path.join(self.targets_directory, 'file1.txt')
|
||||
|
|
@ -915,7 +921,7 @@ def test_delegate(self):
|
|||
# Test normal case.
|
||||
# Need at least one public key and valid target paths required by
|
||||
# delegate().
|
||||
keystore_directory = os.path.join(os.pardir, 'repository_data', 'keystore')
|
||||
keystore_directory = os.path.join('repository_data', 'keystore')
|
||||
public_keypath = os.path.join(keystore_directory, 'root_key.pub')
|
||||
public_key = repo_tool.import_rsa_publickey_from_file(public_keypath)
|
||||
target1_filepath = os.path.join(self.targets_directory, 'file1.txt')
|
||||
|
|
@ -976,7 +982,7 @@ def test_delegate(self):
|
|||
|
||||
def test_delegate_hashed_bins(self):
|
||||
# Test normal case.
|
||||
keystore_directory = os.path.join(os.pardir, 'repository_data', 'keystore')
|
||||
keystore_directory = os.path.join('repository_data', 'keystore')
|
||||
public_keypath = os.path.join(keystore_directory, 'root_key.pub')
|
||||
public_key = repo_tool.import_rsa_publickey_from_file(public_keypath)
|
||||
target1_filepath = os.path.join(self.targets_directory, 'file1.txt')
|
||||
|
|
@ -1033,7 +1039,7 @@ def test_add_restricted_paths(self):
|
|||
# Test normal case.
|
||||
# Perform a delegation so that add_restricted_paths() has a child role
|
||||
# to restrict.
|
||||
keystore_directory = os.path.join(os.pardir, 'repository_data', 'keystore')
|
||||
keystore_directory = os.path.join('repository_data', 'keystore')
|
||||
public_keypath = os.path.join(keystore_directory, 'root_key.pub')
|
||||
public_key = repo_tool.import_rsa_publickey_from_file(public_keypath)
|
||||
|
||||
|
|
@ -1082,7 +1088,7 @@ def test_add_restricted_paths(self):
|
|||
def test_revoke(self):
|
||||
# Test normal case.
|
||||
# Perform a delegation so that revoke() has a delegation to revoke.
|
||||
keystore_directory = os.path.join(os.pardir, 'repository_data', 'keystore')
|
||||
keystore_directory = os.path.join('repository_data', 'keystore')
|
||||
public_keypath = os.path.join(keystore_directory, 'root_key.pub')
|
||||
public_key = repo_tool.import_rsa_publickey_from_file(public_keypath)
|
||||
target1_filepath = os.path.join(self.targets_directory, 'file1.txt')
|
||||
|
|
@ -1188,7 +1194,7 @@ def test_create_new_repository(self):
|
|||
def test_load_repository(self):
|
||||
# Test normal case.
|
||||
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
|
||||
original_repository_directory = os.path.join(os.pardir, 'repository_data',
|
||||
original_repository_directory = os.path.join('repository_data',
|
||||
'repository')
|
||||
repository_directory = os.path.join(temporary_directory, 'repository')
|
||||
shutil.copytree(original_repository_directory, repository_directory)
|
||||
|
|
@ -1279,7 +1285,7 @@ def test_import_rsa_privatekey_from_file(self):
|
|||
|
||||
# Load one of the pre-generated key files from 'tuf/tests/repository_data'.
|
||||
# 'password' unlocks the pre-generated key files.
|
||||
key_filepath = os.path.join(os.pardir, 'repository_data', 'keystore',
|
||||
key_filepath = os.path.join('repository_data', 'keystore',
|
||||
'root_key')
|
||||
self.assertTrue(os.path.exists(key_filepath))
|
||||
|
||||
|
|
@ -1314,7 +1320,7 @@ def test_import_rsa_publickey_from_file(self):
|
|||
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
|
||||
|
||||
# Load one of the pre-generated key files from 'tuf/tests/repository_data'.
|
||||
key_filepath = os.path.join(os.pardir, 'repository_data', 'keystore',
|
||||
key_filepath = os.path.join('repository_data', 'keystore',
|
||||
'root_key.pub')
|
||||
self.assertTrue(os.path.exists(key_filepath))
|
||||
|
||||
|
|
@ -1516,7 +1522,7 @@ def test_get_target_hash(self):
|
|||
def test_generate_root_metadata(self):
|
||||
# Test normal case.
|
||||
# Load the root metadata provided in 'tuf/tests/repository_data/'.
|
||||
root_filepath = os.path.join(os.pardir, 'repository_data', 'repository',
|
||||
root_filepath = os.path.join('repository_data', 'repository',
|
||||
'metadata', 'root.json')
|
||||
root_signable = tuf.util.load_json_file(root_filepath)
|
||||
|
||||
|
|
@ -1524,25 +1530,26 @@ def test_generate_root_metadata(self):
|
|||
# available in 'tuf.keydb' and 'tuf.roledb'.
|
||||
tuf.roledb.create_roledb_from_root_metadata(root_signable['signed'])
|
||||
tuf.keydb.create_keydb_from_root_metadata(root_signable['signed'])
|
||||
expires = '1985-10-21T01:22:00Z'
|
||||
|
||||
root_metadata = repo_tool.generate_root_metadata(1, '2088-01-01 12:00:00 UTC',
|
||||
root_metadata = repo_tool.generate_root_metadata(1, expires,
|
||||
consistent_snapshot=False)
|
||||
self.assertTrue(tuf.formats.ROOT_SCHEMA.matches(root_metadata))
|
||||
|
||||
|
||||
# Test improperly formatted arguments.
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_root_metadata,
|
||||
'3', '2088-01-01 12:00:00 UTC', False)
|
||||
'3', expires, False)
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_root_metadata,
|
||||
1, 3, False)
|
||||
1, '3', False)
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_root_metadata,
|
||||
1, '2088-01-01 12:00:00 UTC', 3)
|
||||
1, expires, 3)
|
||||
|
||||
# Test for missing required roles and keys.
|
||||
tuf.roledb.clear_roledb()
|
||||
tuf.keydb.clear_keydb()
|
||||
self.assertRaises(tuf.Error, repo_tool.generate_root_metadata,
|
||||
1, '2088-01-01 12:00:00 UTC', False)
|
||||
1, expires, False)
|
||||
|
||||
|
||||
|
||||
|
|
@ -1558,7 +1565,8 @@ def test_generate_targets_metadata(self):
|
|||
|
||||
# Set valid generate_targets_metadata() arguments.
|
||||
version = 1
|
||||
expiration_date = '2088-01-01 12:00:00 UTC'
|
||||
datetime_object = datetime.datetime(2030, 01, 01, 12, 00)
|
||||
expiration_date = datetime_object.isoformat() + 'Z'
|
||||
target_files = ['file.txt']
|
||||
|
||||
delegations = {"keys": {
|
||||
|
|
@ -1611,7 +1619,7 @@ def test_generate_targets_metadata(self):
|
|||
self.assertRaises(tuf.FormatError, repo_tool.generate_targets_metadata,
|
||||
targets_directory, target_files, '3', expiration_date)
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_targets_metadata,
|
||||
targets_directory, target_files, version, 3)
|
||||
targets_directory, target_files, version, '3')
|
||||
|
||||
# Improperly formatted 'delegations' and 'write_consistent_targets'
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_targets_metadata,
|
||||
|
|
@ -1633,7 +1641,7 @@ def test_generate_targets_metadata(self):
|
|||
def test_generate_snapshot_metadata(self):
|
||||
# Test normal case.
|
||||
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
|
||||
original_repository_path = os.path.join(os.pardir, 'repository_data',
|
||||
original_repository_path = os.path.join('repository_data',
|
||||
'repository')
|
||||
repository_directory = os.path.join(temporary_directory, 'repository')
|
||||
shutil.copytree(original_repository_path, repository_directory)
|
||||
|
|
@ -1643,7 +1651,7 @@ def test_generate_snapshot_metadata(self):
|
|||
targets_filename = os.path.join(metadata_directory,
|
||||
repo_tool.TARGETS_FILENAME)
|
||||
version = 1
|
||||
expiration_date = '2088-01-01 12:00:00 UTC'
|
||||
expiration_date = '1985-10-21T13:20:00Z'
|
||||
|
||||
snapshot_metadata = \
|
||||
repo_tool.generate_snapshot_metadata(metadata_directory, version,
|
||||
|
|
@ -1661,7 +1669,7 @@ def test_generate_snapshot_metadata(self):
|
|||
metadata_directory, '3', expiration_date,
|
||||
root_filename, targets_filename, consistent_snapshot=False)
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_snapshot_metadata,
|
||||
metadata_directory, version, 3,
|
||||
metadata_directory, version, '3',
|
||||
root_filename, targets_filename, consistent_snapshot=False)
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_snapshot_metadata,
|
||||
metadata_directory, version, expiration_date,
|
||||
|
|
@ -1678,7 +1686,7 @@ def test_generate_snapshot_metadata(self):
|
|||
def test_generate_timestamp_metadata(self):
|
||||
# Test normal case.
|
||||
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
|
||||
original_repository_path = os.path.join(os.pardir, 'repository_data',
|
||||
original_repository_path = os.path.join('repository_data',
|
||||
'repository')
|
||||
repository_directory = os.path.join(temporary_directory, 'repository')
|
||||
shutil.copytree(original_repository_path, repository_directory)
|
||||
|
|
@ -1689,7 +1697,8 @@ def test_generate_timestamp_metadata(self):
|
|||
|
||||
# Set valid generate_timestamp_metadata() arguments.
|
||||
version = 1
|
||||
expiration_date = '2088-01-01 12:00:00 UTC'
|
||||
expiration_date = '1985-10-21T13:20:00Z'
|
||||
|
||||
compressions = ['gz']
|
||||
|
||||
snapshot_metadata = \
|
||||
|
|
@ -1704,7 +1713,7 @@ def test_generate_timestamp_metadata(self):
|
|||
self.assertRaises(tuf.FormatError, repo_tool.generate_timestamp_metadata,
|
||||
snapshot_filename, '3', expiration_date, compressions)
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_timestamp_metadata,
|
||||
snapshot_filename, version, 3, compressions)
|
||||
snapshot_filename, version, '3', compressions)
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_timestamp_metadata,
|
||||
snapshot_filename, version, expiration_date, 3)
|
||||
self.assertRaises(tuf.FormatError, repo_tool.generate_timestamp_metadata,
|
||||
|
|
@ -1716,9 +1725,9 @@ def test_generate_timestamp_metadata(self):
|
|||
def test_sign_metadata(self):
|
||||
# Test normal case.
|
||||
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
|
||||
metadata_path = os.path.join(os.pardir, 'repository_data',
|
||||
metadata_path = os.path.join('repository_data',
|
||||
'repository', 'metadata')
|
||||
keystore_path = os.path.join(os.pardir, 'repository_data',
|
||||
keystore_path = os.path.join('repository_data',
|
||||
'keystore')
|
||||
root_filename = os.path.join(metadata_path, 'root.json')
|
||||
root_metadata = tuf.util.load_json_file(root_filename)['signed']
|
||||
|
|
@ -1757,7 +1766,7 @@ def test_sign_metadata(self):
|
|||
def test_write_metadata_file(self):
|
||||
# Test normal case.
|
||||
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
|
||||
metadata_directory = os.path.join(os.pardir, 'repository_data',
|
||||
metadata_directory = os.path.join('repository_data',
|
||||
'repository', 'metadata')
|
||||
root_filename = os.path.join(metadata_directory, 'root.json')
|
||||
root_signable = tuf.util.load_json_file(root_filename)
|
||||
|
|
@ -1787,7 +1796,7 @@ def test_write_metadata_file(self):
|
|||
def test_create_tuf_client_directory(self):
|
||||
# Test normal case.
|
||||
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
|
||||
repository_directory = os.path.join(os.pardir, 'repository_data',
|
||||
repository_directory = os.path.join('repository_data',
|
||||
'repository')
|
||||
client_directory = os.path.join(temporary_directory, 'client')
|
||||
|
||||
|
|
@ -320,7 +320,7 @@ def test_create_roledb_from_root_metadata(self):
|
|||
'targets': {'keyids': [keyid2], 'threshold': 1}}
|
||||
version = 8
|
||||
consistent_snapshot = False
|
||||
expires = '2012-10-16 06:42:12 UTC'
|
||||
expires = '1985-10-21T01:21:00Z'
|
||||
|
||||
root_metadata = tuf.formats.RootFile.make_metadata(version,
|
||||
expires,
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
import tuf.util
|
||||
import tuf.log
|
||||
import tuf.client.updater as updater
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
logger = logging.getLogger('tuf.test_slow_retrieval_attack')
|
||||
|
||||
|
|
@ -124,8 +124,7 @@ def setUp(self):
|
|||
# Copy the original repository files provided in the test folder so that
|
||||
# any modifications made to repository files are restricted to the copies.
|
||||
# The 'repository_data' directory is expected to exist in 'tuf/tests/'.
|
||||
original_repository_files = os.path.join(os.getcwd(), os.pardir,
|
||||
'repository_data')
|
||||
original_repository_files = os.path.join(os.getcwd(), 'repository_data')
|
||||
temporary_repository_root = \
|
||||
self.make_temp_directory(directory=self.temporary_directory)
|
||||
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
import tuf.keydb
|
||||
import tuf.roledb
|
||||
import tuf.repository_tool as repo_tool
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
import tuf.client.updater as updater
|
||||
|
||||
logger = logging.getLogger('tuf.test_updater')
|
||||
|
|
@ -120,8 +120,7 @@ def setUp(self):
|
|||
# Copy the original repository files provided in the test folder so that
|
||||
# any modifications made to repository files are restricted to the copies.
|
||||
# The 'repository_data' directory is expected to exist in 'tuf.tests/'.
|
||||
original_repository_files = os.path.join(os.getcwd(), os.pardir,
|
||||
'repository_data')
|
||||
original_repository_files = os.path.join(os.getcwd(), 'repository_data')
|
||||
temporary_repository_root = \
|
||||
self.make_temp_directory(directory=self.temporary_directory)
|
||||
|
||||
|
|
@ -465,7 +464,8 @@ def test_2__ensure_not_expired(self):
|
|||
|
||||
# 'tuf.ExpiredMetadataError' should be raised in this next test condition,
|
||||
# because the expiration_date has expired by 10 seconds.
|
||||
expires = tuf.formats.format_time(time.time() - 10)
|
||||
expires = tuf.formats.unix_timestamp_to_datetime(int(time.time() - 10))
|
||||
expires = expires.isoformat() + 'Z'
|
||||
self.repository_updater.metadata['current']['root']['expires'] = expires
|
||||
|
||||
# Ensure the 'expires' value of the root file is valid by checking the
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
util.py unit tests.
|
||||
Unit test for 'util.py'
|
||||
"""
|
||||
|
||||
import os
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
import tuf.log
|
||||
import tuf.hash
|
||||
import tuf.util as util
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
import tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
logger = logging.getLogger('tuf.test_util')
|
||||
|
||||
|
|
@ -1,355 +0,0 @@
|
|||
"""
|
||||
<Program Name>
|
||||
test_keystore.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
|
||||
<Started>
|
||||
April 27, 2012.
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
Unit test for keystore.py.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import shutil
|
||||
import os
|
||||
import logging
|
||||
import Crypto.Random
|
||||
import Crypto.Protocol.KDF
|
||||
|
||||
import tuf
|
||||
import tuf.repo.keystore
|
||||
import tuf.keys
|
||||
import tuf.formats
|
||||
import tuf.util
|
||||
import tuf.log
|
||||
|
||||
logger = logging.getLogger('tuf.test_keystore')
|
||||
|
||||
# We'll need json module for testing '_encrypt()' and '_decrypt()'
|
||||
# internal function.
|
||||
json = tuf.util.import_json()
|
||||
|
||||
tuf.repo.keystore._PBKDF2_ITERATIONS = 1000
|
||||
|
||||
# Creating a directory string in current directory.
|
||||
_CURRENT_DIR = os.getcwd()
|
||||
_DIR = os.path.join(_CURRENT_DIR, 'test_keystore')
|
||||
|
||||
# Check if directory '_DIR' exists.
|
||||
if os.path.exists(_DIR):
|
||||
msg = ('\''+_DIR+'\' directory already exists,'+
|
||||
' please change '+'\'_DIR\''+' to something else.')
|
||||
raise tuf.Error(msg)
|
||||
|
||||
KEYSTORE = tuf.repo.keystore
|
||||
RSAKEYS = []
|
||||
PASSWDS = []
|
||||
temp_keys_info = []
|
||||
temp_keys_vals = []
|
||||
|
||||
for i in range(3):
|
||||
# Populating the original 'RSAKEYS' and 'PASSWDS' lists.
|
||||
RSAKEYS.append(tuf.keys.generate_rsa_key())
|
||||
PASSWDS.append('passwd_'+str(i))
|
||||
|
||||
# Saving original copies of 'RSAKEYS' and 'PASSWDS' to temp variables
|
||||
# in order to repopulate them at the start of every test.
|
||||
temp_keys_info.append(RSAKEYS[i].values())
|
||||
temp_keys_vals.append(RSAKEYS[i]['keyval'].values())
|
||||
|
||||
temp_passwds=list(PASSWDS)
|
||||
|
||||
|
||||
|
||||
class TestKeystore(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# Returning 'RSAKEY' and 'PASSWDS' to original state.
|
||||
for i in range(len(temp_keys_info)):
|
||||
RSAKEYS[i]['keytype'] = temp_keys_info[i][0]
|
||||
RSAKEYS[i]['keyid'] = temp_keys_info[i][1]
|
||||
RSAKEYS[i]['keyval'] = temp_keys_info[i][2]
|
||||
RSAKEYS[i]['keyval']['public'] = temp_keys_vals[i][0]
|
||||
RSAKEYS[i]['keyval']['private'] = temp_keys_vals[i][1]
|
||||
PASSWDS[i] = temp_passwds[i]
|
||||
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
# Empty keystore's databases.
|
||||
KEYSTORE.clear_keystore()
|
||||
|
||||
# Check if directory '_DIR' exists, remove it if it does.
|
||||
if os.path.exists(_DIR):
|
||||
shutil.rmtree(_DIR)
|
||||
|
||||
|
||||
|
||||
def test_clear_keystore(self):
|
||||
# Populate KEYSTORE's internal databases '_keystore' and '_derived_keys'.
|
||||
for i in range(3):
|
||||
KEYSTORE.add_rsakey(RSAKEYS[i], PASSWDS[i], RSAKEYS[i]['keyid'])
|
||||
|
||||
# Verify KEYSTORE's internal databases ARE NOT EMPTY.
|
||||
self.assertTrue(len(KEYSTORE._keystore) > 0)
|
||||
self.assertTrue(len(KEYSTORE._derived_keys) > 0)
|
||||
|
||||
# Clear KEYSTORE's internal databases.
|
||||
KEYSTORE.clear_keystore()
|
||||
|
||||
# Verify KEYSTORE's internal databases ARE EMPTY.
|
||||
self.assertFalse(len(KEYSTORE._keystore) > 0)
|
||||
self.assertFalse(len(KEYSTORE._derived_keys) > 0)
|
||||
|
||||
|
||||
|
||||
def test_add_rsakey(self):
|
||||
# Passing 2 arguments to the function and verifying that the internal
|
||||
# databases have been modified.
|
||||
KEYSTORE.add_rsakey(RSAKEYS[0], PASSWDS[0])
|
||||
|
||||
self.assertEqual(RSAKEYS[0], KEYSTORE._keystore[RSAKEYS[0]['keyid']],
|
||||
'Adding an rsa key dict was unsuccessful.')
|
||||
|
||||
self.assertTrue(len(KEYSTORE._derived_keys) == 1,
|
||||
'Adding a password pertaining to \'_keyid\' was unsuccessful.')
|
||||
|
||||
# Passing three arguments to the function, i.e. including the 'keyid'.
|
||||
KEYSTORE.add_rsakey(RSAKEYS[1], PASSWDS[1], RSAKEYS[1]['keyid'])
|
||||
|
||||
self.assertEqual(RSAKEYS[1],
|
||||
KEYSTORE._keystore[RSAKEYS[1]['keyid']],
|
||||
'Adding an rsa key dict was unsuccessful.')
|
||||
|
||||
self.assertTrue(len(KEYSTORE._derived_keys) == 2,
|
||||
'Adding a password pertaining to \'_keyid\' was unsuccessful.')
|
||||
|
||||
# Passing a keyid that does not match the keyid in 'rsakey_dict'.
|
||||
_keyid = 'somedifferentkey123456789'
|
||||
self.assertRaises(tuf.Error, KEYSTORE.add_rsakey, RSAKEYS[2],
|
||||
PASSWDS[2], _keyid)
|
||||
|
||||
# Passing an existing 'rsakey_dict' object.
|
||||
self.assertRaises(tuf.KeyAlreadyExistsError, KEYSTORE.add_rsakey,
|
||||
RSAKEYS[1], PASSWDS[1], RSAKEYS[1]['keyid'])
|
||||
|
||||
# Passing an 'rsakey_dict' that does not conform to the 'RSAKEY_SCHEMA'.
|
||||
del RSAKEYS[2]['keytype']
|
||||
|
||||
self.assertRaises(tuf.FormatError, KEYSTORE.add_rsakey,
|
||||
RSAKEYS[2], PASSWDS[2], RSAKEYS[2]['keyid'])
|
||||
|
||||
|
||||
|
||||
def test_save_keystore_to_keyfiles(self):
|
||||
# Extract and store keyids in '_keyids' list.
|
||||
keyids = []
|
||||
|
||||
# Populate KEYSTORE's internal databases '_keystore' and '_derived_keys'.
|
||||
for i in range(3):
|
||||
KEYSTORE.add_rsakey(RSAKEYS[i], PASSWDS[i], RSAKEYS[i]['keyid'])
|
||||
keyids.append(RSAKEYS[i]['keyid'])
|
||||
|
||||
# Check if directory '_DIR' exists, remove it if it does.
|
||||
if os.path.exists(_DIR):
|
||||
shutil.rmtree(_DIR)
|
||||
|
||||
KEYSTORE.save_keystore_to_keyfiles(_DIR)
|
||||
|
||||
# Check if directory '_DIR' has been created.
|
||||
self.assertTrue(os.path.exists(_DIR), 'Creating directory failed.')
|
||||
|
||||
# Check if all of the key files where created and that they are not empty.
|
||||
for keyid in keyids:
|
||||
key_file = os.path.join(_DIR, str(keyid)+'.key')
|
||||
# Checks if key file has been created.
|
||||
self.assertTrue(os.path.exists(key_file), 'Key file does not exist.')
|
||||
|
||||
file_stats = os.stat(key_file)
|
||||
# Checks if key file is not empty.
|
||||
self.assertTrue(file_stats.st_size > 0)
|
||||
|
||||
# Passing an invalid 'directory_name' argument - an integer value.
|
||||
self.assertRaises(tuf.FormatError, KEYSTORE.save_keystore_to_keyfiles, 222)
|
||||
|
||||
|
||||
|
||||
def test_load_keystore_from_keyfiles(self):
|
||||
keyids = []
|
||||
# Check if '_DIR' directory exists, if not - create it.
|
||||
if not os.path.exists(_DIR):
|
||||
# Populate KEYSTORE's internal databases.
|
||||
for i in range(3):
|
||||
KEYSTORE.add_rsakey(RSAKEYS[i], PASSWDS[i], RSAKEYS[i]['keyid'])
|
||||
keyids.append(RSAKEYS[i]['keyid'])
|
||||
|
||||
# Create the key files.
|
||||
KEYSTORE.save_keystore_to_keyfiles(_DIR)
|
||||
|
||||
# Clearing internal databases.
|
||||
KEYSTORE.clear_keystore()
|
||||
|
||||
# Test normal conditions where two valid arguments are passed.
|
||||
loaded_keys = KEYSTORE.load_keystore_from_keyfiles(_DIR, keyids, PASSWDS)
|
||||
|
||||
# Loaded keys should all be contained in 'keyids'.
|
||||
loaded_keys_set = set(loaded_keys)
|
||||
keyids_set = set(keyids)
|
||||
intersect = keyids_set.intersection(loaded_keys_set)
|
||||
self.assertEquals(len(intersect), len(keyids))
|
||||
|
||||
for i in range(3):
|
||||
self.assertEqual(RSAKEYS[i], KEYSTORE._keystore[RSAKEYS[i]['keyid']])
|
||||
|
||||
# Clearing internal databases.
|
||||
KEYSTORE.clear_keystore()
|
||||
|
||||
_invalid_dir = os.path.join(_CURRENT_DIR, 'invalid_directory')
|
||||
|
||||
# Passing an invalid 'directory_name' argument - a directory that
|
||||
# does not exist. AS EXPECTED, THIS CALL SHOULDN'T RAISE ANY ERRORS.
|
||||
KEYSTORE.load_keystore_from_keyfiles(_invalid_dir, keyids, PASSWDS)
|
||||
|
||||
# The keystore should not have loaded any keys.
|
||||
self.assertEqual(0, len(KEYSTORE._keystore))
|
||||
self.assertEqual(0, len(KEYSTORE._derived_keys))
|
||||
|
||||
# Passing nonexistent 'keyids'.
|
||||
# AS EXPECTED, THIS CALL SHOULDN'T RAISE ANY ERRORS.
|
||||
invalid_keyids = ['333', '333', '333']
|
||||
KEYSTORE.load_keystore_from_keyfiles(_DIR, invalid_keyids, PASSWDS)
|
||||
|
||||
# The keystore should not have loaded any keys.
|
||||
self.assertEqual(0, len(KEYSTORE._keystore))
|
||||
self.assertEqual(0, len(KEYSTORE._derived_keys))
|
||||
|
||||
# Passing an invalid 'directory_name' argument - an integer value.
|
||||
self.assertRaises(tuf.FormatError, KEYSTORE.load_keystore_from_keyfiles,
|
||||
333, keyids, PASSWDS)
|
||||
|
||||
# Passing an invalid 'passwords' argument - a string value.
|
||||
self.assertRaises(tuf.FormatError, KEYSTORE.load_keystore_from_keyfiles,
|
||||
_DIR, keyids, '333')
|
||||
|
||||
# Passing an invalid 'passwords' argument - an integer value.
|
||||
self.assertRaises(tuf.FormatError, KEYSTORE.load_keystore_from_keyfiles,
|
||||
_DIR, keyids, 333)
|
||||
|
||||
# Passing an invalid 'keyids' argument - a string value.
|
||||
self.assertRaises(tuf.FormatError, KEYSTORE.load_keystore_from_keyfiles,
|
||||
_DIR, '333', PASSWDS)
|
||||
|
||||
# Passing an invalid 'keyids' argument - an integer value.
|
||||
self.assertRaises(tuf.FormatError, KEYSTORE.load_keystore_from_keyfiles,
|
||||
_DIR, 333, PASSWDS)
|
||||
|
||||
|
||||
|
||||
def test_change_password(self):
|
||||
# Populate KEYSTORE's internal databases.
|
||||
for i in range(2):
|
||||
KEYSTORE.add_rsakey(RSAKEYS[i], PASSWDS[i], RSAKEYS[i]['keyid'])
|
||||
|
||||
derived_key_0 = KEYSTORE._derived_keys[RSAKEYS[0]['keyid']]
|
||||
# Create a new password.
|
||||
new_passwd = 'changed_password'
|
||||
|
||||
# Change a password - normal case.
|
||||
KEYSTORE.change_password(RSAKEYS[0]['keyid'], PASSWDS[0], new_passwd)
|
||||
|
||||
# Check if password was changed.
|
||||
new_derived_key = KEYSTORE._derived_keys[RSAKEYS[0]['keyid']]['derived_key']
|
||||
self.assertNotEqual(new_derived_key,
|
||||
derived_key_0['derived_key'])
|
||||
|
||||
# Passing an invalid keyid (i.e., RSAKEY[2] that was not loaded into
|
||||
# the '_keystore').
|
||||
self.assertRaises(tuf.UnknownKeyError, KEYSTORE.change_password,
|
||||
RSAKEYS[2]['keyid'], PASSWDS[1], new_passwd)
|
||||
|
||||
# Passing an incorrect old password.
|
||||
self.assertRaises(tuf.BadPasswordError, KEYSTORE.change_password,
|
||||
RSAKEYS[1]['keyid'], PASSWDS[2], new_passwd)
|
||||
|
||||
|
||||
|
||||
def test_get_key(self):
|
||||
# Populate KEYSTORE's internal databases.
|
||||
for i in range(2):
|
||||
KEYSTORE.add_rsakey(RSAKEYS[i], PASSWDS[i], RSAKEYS[i]['keyid'])
|
||||
|
||||
# Get a key - normal case.
|
||||
self.assertEqual(KEYSTORE.get_key(RSAKEYS[0]['keyid']), RSAKEYS[0])
|
||||
|
||||
# Passing an invalid keyid.
|
||||
self.assertRaises(tuf.UnknownKeyError,
|
||||
KEYSTORE.get_key, RSAKEYS[2]['keyid'])
|
||||
|
||||
# Passing an invalid keyid format.
|
||||
self.assertRaises(tuf.FormatError, KEYSTORE.get_key, 123)
|
||||
|
||||
|
||||
|
||||
def test_internal_encrypt(self):
|
||||
# Test for valid arguments to '_encrypt()' and a valid return type.
|
||||
salt = Crypto.Random.new().read(16)
|
||||
iterations = tuf.repo.keystore._PBKDF2_ITERATIONS
|
||||
derived_key = Crypto.Protocol.KDF.PBKDF2(PASSWDS[0], salt)
|
||||
derived_key_information = {'salt': salt, 'derived_key': derived_key,
|
||||
'iterations': iterations}
|
||||
encrypted_key = KEYSTORE._encrypt(json.dumps(RSAKEYS[0]),
|
||||
derived_key_information)
|
||||
self.assertEqual(type(encrypted_key), str)
|
||||
|
||||
|
||||
|
||||
def test_internal_decrypt(self):
|
||||
del RSAKEYS[0]['keyid']
|
||||
tuf.formats.KEY_SCHEMA.check_match(RSAKEYS[0])
|
||||
|
||||
salt = Crypto.Random.new().read(16)
|
||||
salt, iterations, derived_key = \
|
||||
tuf.repo.keystore._generate_derived_key(PASSWDS[0], salt)
|
||||
derived_key_information = {'salt': salt,
|
||||
'iterations': iterations,
|
||||
'derived_key': derived_key}
|
||||
|
||||
# Getting a valid encrypted key using '_encrypt()'.
|
||||
encrypted_key = KEYSTORE._encrypt(json.dumps(RSAKEYS[0]),
|
||||
derived_key_information)
|
||||
|
||||
# Decrypting and decoding (using json's loads()) an encrypted file.
|
||||
#tuf.util.load_json_string(KEYSTORE._decrypt(encrypted_key, PASSWDS[0]))
|
||||
json.dumps(KEYSTORE._decrypt(encrypted_key, PASSWDS[0]))
|
||||
|
||||
self.assertEqual(RSAKEYS[0], tuf.util.load_json_string(
|
||||
KEYSTORE._decrypt(encrypted_key, PASSWDS[0])))
|
||||
|
||||
# Passing an invalid password to try to decrypt the file.
|
||||
self.assertRaises(tuf.CryptoError, KEYSTORE._decrypt,
|
||||
encrypted_key, PASSWDS[1])
|
||||
|
||||
|
||||
|
||||
def setUpModule():
|
||||
# setUpModule() is called before any test cases run.
|
||||
# Ensure the keystore has not been modified by a previous test, which may
|
||||
# affect assumptions (i.e., empty keystore) made by the tests cases in this
|
||||
# unit test.
|
||||
tuf.repo.keystore.clear_keystore()
|
||||
|
||||
def tearDownModule():
|
||||
# tearDownModule() is called after all the tests have run.
|
||||
# Ensure we clean up the keystore. They say courtesy is contagious.
|
||||
tuf.repo.keystore.clear_keystore()
|
||||
|
||||
|
||||
|
||||
# Run the unit tests.
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
"""
|
||||
<Program Name>
|
||||
test_push.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
|
||||
<Started>
|
||||
April 2013.
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
Test push.py.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import getpass
|
||||
import logging
|
||||
import tempfile
|
||||
import unittest
|
||||
import ConfigParser
|
||||
|
||||
import tuf
|
||||
import tuf.log
|
||||
import tuf.pushtools.push as push
|
||||
import tuf.pushtools.transfer.scp as scp
|
||||
import tuf.pushtools.pushtoolslib as pushtoolslib
|
||||
import tuf.tests.util_test_tools as util_test_tools
|
||||
|
||||
logger = logging.getLogger('tuf.test_push')
|
||||
|
||||
|
||||
class TestPush(unittest.TestCase):
|
||||
src_push_dict = {}
|
||||
|
||||
ORIGINAL_PUSH_CONFIG = pushtoolslib.PUSH_CONFIG
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _mock_scp_transfer(config_dict):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def write_config_file(config_filename, config_dictionary):
|
||||
"""Create a configuration file by writing supplied configuration
|
||||
dictionary ('config_dictionary') into the file ('config_filename')."""
|
||||
|
||||
config = ConfigParser.RawConfigParser()
|
||||
|
||||
for section, values_dict in config_dictionary.iteritems():
|
||||
config.add_section(section)
|
||||
for key in values_dict:
|
||||
config.set(section, key, values_dict[key])
|
||||
|
||||
# Writing our configuration file to 'config_filename'.
|
||||
with open(config_filename, 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
|
||||
|
||||
def setUp(self):
|
||||
# Create push configuration file, general temporary dir 'root_repo'.
|
||||
cwd = os.getcwd()
|
||||
self.push_config = tempfile.mkstemp(prefix='tmp_push_conf_', dir=cwd)[1]
|
||||
self.root_repo = tempfile.mkdtemp(prefix='tmp_tuf_repo_', dir=cwd)
|
||||
|
||||
# Drop target files into the working project directory 'reg_repo'.
|
||||
# When targets metadata updates, the target files in the 'reg_repo'
|
||||
# will be copied into the tuf's targets directory.
|
||||
self.reg_repo = os.path.join(self.root_repo, 'reg_repo')
|
||||
os.mkdir(self.reg_repo)
|
||||
|
||||
# Add a file to the 'reg_repo'.
|
||||
util_test_tools.add_file_to_repository(self.reg_repo, data='Test String')
|
||||
|
||||
# Create TUF repository.
|
||||
util_test_tools.init_tuf(self.root_repo)
|
||||
|
||||
# Update the tuf targets metadata.
|
||||
util_test_tools.make_targets_meta(self.root_repo)
|
||||
|
||||
# Populate 'src_push_dict'.
|
||||
targets_dir = os.path.join(self.root_repo, 'tuf_repo', 'targets')
|
||||
metadate_path = os.path.join(self.root_repo, 'tuf_repo', 'metadata',
|
||||
'targets.txt')
|
||||
remote_dir = tempfile.mkdtemp(prefix='tmp_tuf_repo_', dir=self.root_repo)
|
||||
|
||||
self.src_push_dict = {'general':{'transfer_module':'scp',
|
||||
'metadata_path':metadate_path,
|
||||
'targets_directory':targets_dir},
|
||||
'scp':{'host':'localhost',
|
||||
'identity_file':None,
|
||||
'user':getpass.getuser(),
|
||||
'remote_directory':remote_dir}}
|
||||
|
||||
# Write the config dictionary into the push configuration file.
|
||||
self.write_config_file(self.push_config, self.src_push_dict)
|
||||
|
||||
# Patch 'pushtoolslib.PUSH_CONFIG'.
|
||||
pushtoolslib.PUSH_CONFIG = os.path.basename(self.push_config)
|
||||
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
# Remove tempfile.
|
||||
os.remove(self.push_config)
|
||||
|
||||
# Remove TUF repository.
|
||||
util_test_tools.cleanup(self.root_repo)
|
||||
|
||||
# Clear 'src_push_dict'.
|
||||
self.src_push_dict.clear()
|
||||
|
||||
# # Reassign 'pushtoolslib.PUSH_CONFIG'.
|
||||
pushtoolslib.PUSH_CONFIG = self.ORIGINAL_PUSH_CONFIG
|
||||
|
||||
|
||||
|
||||
def test_expected_behaviour_of_push_without_scp(self):
|
||||
# Patch 'scp.transfer' function.
|
||||
ORIGINAL_SCP_TRANSFER_MODULE = scp.transfer
|
||||
scp.transfer = self._mock_scp_transfer
|
||||
|
||||
push.push(self.push_config)
|
||||
|
||||
# Restore 'scp.transfer' function.
|
||||
scp.transfer = ORIGINAL_SCP_TRANSFER_MODULE
|
||||
|
||||
|
||||
|
||||
def test_exceptions_handeling_of_push_without_scp(self):
|
||||
# Patch 'scp.transfer' function.
|
||||
ORIGINAL_SCP_TRANSFER_MODULE = scp.transfer
|
||||
scp.transfer = self._mock_scp_transfer
|
||||
|
||||
self.assertRaises(tuf.Error, push.push, self.root_repo)
|
||||
self.assertRaises(tuf.FormatError, push.push, None)
|
||||
self.assertRaises(tuf.FormatError, push.push, 12345)
|
||||
self.assertRaises(tuf.FormatError, push.push, ['test'])
|
||||
self.assertRaises(tuf.FormatError, push.push, {'test':'test'})
|
||||
|
||||
# Restore 'scp.transfer' function.
|
||||
scp.transfer = ORIGINAL_SCP_TRANSFER_MODULE
|
||||
|
||||
|
||||
|
||||
# Unit test bellow executes secure copy 'scp' command. Hence user's
|
||||
# password is requered. Comment-out or remove the line bellow to
|
||||
# un-skip the unit test.
|
||||
@unittest.skip("Requires user's password!")
|
||||
def test_expected_behaviour_of_push_with_scp(self):
|
||||
push.push(self.push_config)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Run the unittests
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
"""
|
||||
<Program Name>
|
||||
test_pushtoolslib.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
|
||||
<Started>
|
||||
April 2013.
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
Test pushtoolslib.py.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
import ConfigParser
|
||||
import logging
|
||||
|
||||
import tuf
|
||||
import tuf.log
|
||||
import tuf.formats
|
||||
import tuf.pushtools.pushtoolslib as pushtoolslib
|
||||
|
||||
logger = logging.getLogger('tuf.test_pushtoolslib')
|
||||
|
||||
|
||||
class TestPushtoolslib(unittest.TestCase):
|
||||
src_push_dict = {}
|
||||
src_receive_dict = {}
|
||||
ORIGINAL_PUSH_CONFIG = pushtoolslib.PUSH_CONFIG
|
||||
ORIGINAL_RECEIVE_CONFIG = pushtoolslib.RECEIVE_CONFIG
|
||||
|
||||
|
||||
|
||||
def setUp(self):
|
||||
# Create config tempfiles.
|
||||
cwd = os.getcwd()
|
||||
self.push_config_file = tempfile.mkstemp(prefix='tmp_push_conf_', dir=cwd)[1]
|
||||
self.receive_config_file = tempfile.mkstemp(prefix='tmp_receive_conf_', dir=cwd)[1]
|
||||
|
||||
# Populate 'src_push_dict' and 'src_receive_dict'.
|
||||
self.src_push_dict = {'general':{'transfer_module':'scp',
|
||||
'metadata_path':'some/path',
|
||||
'targets_directory':'some/path'},
|
||||
'scp':{'host':'localhost',
|
||||
'user':'user',
|
||||
'identity_file':None,
|
||||
'remote_directory':'~/pushes'}}
|
||||
|
||||
self.src_receive_dict = {'general':{'pushroots':['some/path'],
|
||||
'repository_directory':'some/path',
|
||||
'metadata_directory':'some/path',
|
||||
'targets_directory':'some/path',
|
||||
'backup_directory':'some/path'}}
|
||||
|
||||
# Patch the 'pushtoolslib.PUSH_CONFIG' and 'pushtoolslib.RECEIVE_CONFIG'
|
||||
pushtoolslib.PUSH_CONFIG = os.path.basename(self.push_config_file)
|
||||
pushtoolslib.RECEIVE_CONFIG = os.path.basename(self.receive_config_file)
|
||||
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
# Remove tempfile.
|
||||
os.remove(self.push_config_file)
|
||||
os.remove(self.receive_config_file)
|
||||
|
||||
# Clear dictionaries.
|
||||
self.src_push_dict.clear()
|
||||
self.src_receive_dict.clear()
|
||||
|
||||
# Reassign 'pushtoolslib.PUSH_CONFIG' and 'pushtoolslib.RECEIVE_CONFIG'
|
||||
# to original values.
|
||||
pushtoolslib.PUSH_CONFIG = self.ORIGINAL_PUSH_CONFIG
|
||||
pushtoolslib.RECEIVE_CONFIG = self.ORIGINAL_RECEIVE_CONFIG
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def write_config_file(config_filename, config_dictionary):
|
||||
"""Create a configuration file by writing supplied configuration
|
||||
dictionary ('config_dictionary') into the file ('config_filename')."""
|
||||
|
||||
config = ConfigParser.RawConfigParser()
|
||||
|
||||
for section, values_dict in config_dictionary.iteritems():
|
||||
config.add_section(section)
|
||||
for key in values_dict:
|
||||
config.set(section, key, values_dict[key])
|
||||
|
||||
# Writing our configuration file to 'config_filename'.
|
||||
with open(config_filename, 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
|
||||
|
||||
def test_expected_behavior_of_read_config_file(self):
|
||||
# Test 'push' configuration type.
|
||||
self.write_config_file(self.push_config_file, self.src_push_dict)
|
||||
config_dict = pushtoolslib.read_config_file(self.push_config_file, 'push')
|
||||
tuf.formats.SCPCONFIG_SCHEMA.check_match(config_dict)
|
||||
|
||||
# Test 'receive' configuration type.
|
||||
self.write_config_file(self.receive_config_file, self.src_receive_dict)
|
||||
config_dict = pushtoolslib.read_config_file(self.receive_config_file, 'receive')
|
||||
tuf.formats.RECEIVECONFIG_SCHEMA.check_match(config_dict)
|
||||
|
||||
|
||||
|
||||
def test_exceptions_handeling_of_read_config_file(self):
|
||||
# Test an incorrect configuration file.
|
||||
with open(self.push_config_file, 'wb') as configfile:
|
||||
configfile.write('test')
|
||||
self.assertRaises(tuf.Error, pushtoolslib.read_config_file,
|
||||
self.push_config_file, 'push')
|
||||
|
||||
self.write_config_file(self.push_config_file, {})
|
||||
self.assertRaises(tuf.Error, pushtoolslib.read_config_file,
|
||||
self.push_config_file, 'push')
|
||||
|
||||
self.write_config_file(self.receive_config_file, self.src_receive_dict)
|
||||
self.assertRaises(tuf.Error, pushtoolslib.read_config_file,
|
||||
self.receive_config_file, 'push')
|
||||
|
||||
self.write_config_file(self.push_config_file, self.src_push_dict)
|
||||
self.assertRaises(tuf.Error, pushtoolslib.read_config_file,
|
||||
self.push_config_file, 'receive')
|
||||
|
||||
# Test incorrect configuration type.
|
||||
self.write_config_file(self.push_config_file, self.src_push_dict)
|
||||
self.assertRaises(tuf.Error, pushtoolslib.read_config_file,
|
||||
self.push_config_file, 'junk')
|
||||
|
||||
# Test 'push' type configuration with 'transfer_module' absent from
|
||||
# config_dict['general'].
|
||||
saved_transfer_module = self.src_push_dict['general']['transfer_module']
|
||||
del self.src_push_dict['general']['transfer_module']
|
||||
self.write_config_file(self.push_config_file, self.src_push_dict)
|
||||
self.assertRaises(tuf.Error, pushtoolslib.read_config_file,
|
||||
self.push_config_file, 'push')
|
||||
|
||||
# Test 'push' type configuration with
|
||||
# config_dict['general']['transfer_module'] != 'scp'.
|
||||
self.src_push_dict['general']['transfer_module'] = 'test'
|
||||
self.write_config_file(self.push_config_file, self.src_push_dict)
|
||||
self.assertRaises(tuf.Error, pushtoolslib.read_config_file,
|
||||
self.push_config_file, 'push')
|
||||
|
||||
# Test 'push' type configuration with one of the keys missing.
|
||||
self.src_push_dict['general']['transfer_module'] = 'scp'
|
||||
del self.src_push_dict['general']['metadata_path']
|
||||
self.write_config_file(self.push_config_file, self.src_push_dict)
|
||||
self.assertRaises(tuf.FormatError, pushtoolslib.read_config_file,
|
||||
self.push_config_file, 'push')
|
||||
|
||||
# Test 'receive' type configuration with one of the keys missing.
|
||||
del self.src_receive_dict['general']['repository_directory']
|
||||
self.write_config_file(self.receive_config_file, self.src_receive_dict)
|
||||
self.assertRaises(tuf.FormatError, pushtoolslib.read_config_file,
|
||||
self.receive_config_file, 'receive')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Run the unittests
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
"""
|
||||
<Program Name>
|
||||
test_quickstart.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
|
||||
<Started>
|
||||
September 6, 2012
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
To test quickstart.py for expected/unexpected input by the user, verifying
|
||||
that all unexpected input is caught and an exception is raised.
|
||||
|
||||
Given that all message prompts don't change - this will work pretty well
|
||||
for running quickstart without having to manually enter input to prompts
|
||||
every time you want to run quickstart.
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import unittest
|
||||
import logging
|
||||
|
||||
import tuf
|
||||
import tuf.log
|
||||
import tuf.repo.quickstart as quickstart
|
||||
import tuf.util
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
logger = logging.getLogger('tuf.test_quickstart')
|
||||
unit_tbox = unittest_toolbox.Modified_TestCase
|
||||
|
||||
|
||||
logger.info('from test_quickstart')
|
||||
|
||||
class TestQuickstart(unit_tbox):
|
||||
def test_1_get_password(self):
|
||||
|
||||
# SETUP
|
||||
original_getpass = quickstart.getpass.getpass
|
||||
|
||||
# A quick test of _get_password.
|
||||
password = self.random_string()
|
||||
def _mock_getpass(junk1, junk2, pw = password):
|
||||
return pw
|
||||
# Monkey patch getpass.getpass().
|
||||
quickstart.getpass.getpass = _mock_getpass
|
||||
# Run _get_password().
|
||||
self.assertEqual(quickstart._get_password(), password)
|
||||
|
||||
# RESTORE
|
||||
quickstart.getpass.getpass = original_getpass
|
||||
|
||||
|
||||
|
||||
def test_2_build_repository(self):
|
||||
|
||||
# SETUP
|
||||
original_prompt = quickstart._prompt
|
||||
original_get_password = quickstart._get_password
|
||||
|
||||
# Create the project directories.
|
||||
repo_dir = os.path.join(os.getcwd(), 'repository')
|
||||
keystore_dir = os.path.join(os.getcwd(), 'keystore')
|
||||
client_dir = os.path.join(os.getcwd(), 'client')
|
||||
|
||||
proj_files = self.make_temp_directory_with_data_files()
|
||||
proj_dir = os.path.join(proj_files[0], 'targets')
|
||||
|
||||
input_dict = {'expiration':'12/12/2020',
|
||||
'root':{'threshold':1, 'password':'pass'},
|
||||
'targets':{'threshold':1, 'password':'pass'},
|
||||
'release':{'threshold':1, 'password':'pass'},
|
||||
'timestamp':{'threshold':1, 'password':'pass'}}
|
||||
|
||||
|
||||
def _mock_prompt(message, confirm=False, input_parameters=input_dict):
|
||||
if message.startswith('\nWhen would you like your '+
|
||||
'"root.txt" metadata to expire?'):
|
||||
return input_parameters['expiration']
|
||||
for role in self.role_list: # role_list=['root', 'targets', ...]
|
||||
if message.startswith('\nEnter the desired threshold '+
|
||||
'for the role '+repr(role)):
|
||||
return input_parameters[role]['threshold']
|
||||
elif message.startswith('Enter a password for '+repr(role)):
|
||||
for threshold in range(input_parameters[role]['threshold']):
|
||||
if message.endswith(repr(role)+' ('+str(threshold+1)+'): '):
|
||||
return input_parameters[role]['password']
|
||||
print 'Cannot recognize message: '+message
|
||||
|
||||
# Monkey patching quickstart's _prompt() and _get_password.
|
||||
quickstart._prompt = _mock_prompt
|
||||
quickstart._get_password = _mock_prompt
|
||||
|
||||
|
||||
def _remove_repository_directories(repo_dir, keystore_dir, client_dir):
|
||||
"""
|
||||
quickstart.py creates the 'client', 'keystore', and 'repository'
|
||||
directories in the current working directory. Remove these
|
||||
directories after every quickstart.build_repository() call.
|
||||
"""
|
||||
|
||||
try:
|
||||
shutil.rmtree(repo_dir)
|
||||
shutil.rmtree(keystore_dir)
|
||||
shutil.rmtree(client_dir)
|
||||
except OSError, e:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
# TESTS
|
||||
|
||||
# TEST: various input parameters.
|
||||
# Supplying bogus expiration.
|
||||
input_dict['expiration'] = '5/8/2011'
|
||||
self.assertRaises(tuf.RepositoryError, quickstart.build_repository,
|
||||
proj_dir)
|
||||
# Random string.
|
||||
input_dict['expiration'] = self.random_string()
|
||||
self.assertRaises(tuf.RepositoryError, quickstart.build_repository,
|
||||
proj_dir)
|
||||
_remove_repository_directories(repo_dir, keystore_dir, client_dir)
|
||||
|
||||
# Restore expiration.
|
||||
input_dict['expiration'] = '10/10/2020'
|
||||
|
||||
# Supplying bogus 'root' threshold. Doing this for all roles slows
|
||||
# the test significantly.
|
||||
input_dict['root']['threshold'] = self.random_string()
|
||||
self.assertRaises(tuf.RepositoryError, quickstart.build_repository,
|
||||
proj_dir)
|
||||
_remove_repository_directories(repo_dir, keystore_dir, client_dir)
|
||||
|
||||
input_dict['root']['threshold'] = 0
|
||||
self.assertRaises(tuf.RepositoryError, quickstart.build_repository,
|
||||
proj_dir)
|
||||
_remove_repository_directories(repo_dir, keystore_dir, client_dir)
|
||||
|
||||
# Restore keystore directory.
|
||||
input_dict['root']['threshold'] = 1
|
||||
|
||||
|
||||
# TEST: normal case.
|
||||
try:
|
||||
quickstart.build_repository(proj_dir)
|
||||
except Exception, e:
|
||||
raise
|
||||
|
||||
# Verify the existence of metadata, target, and keystore files.
|
||||
meta_dir = os.path.join(repo_dir, 'metadata')
|
||||
targets_dir = os.path.join(repo_dir, 'targets')
|
||||
client_current_meta_dir = os.path.join(client_dir, 'metadata', 'current')
|
||||
client_previous_meta_dir = os.path.join(client_dir, 'metadata', 'previous')
|
||||
target_files = os.listdir(targets_dir)
|
||||
|
||||
# Verify repository, keystore, metadata, and targets directories.
|
||||
self.assertTrue(os.path.exists(repo_dir))
|
||||
self.assertTrue(os.path.exists(keystore_dir))
|
||||
self.assertTrue(os.path.exists(meta_dir))
|
||||
self.assertTrue(os.path.exists(targets_dir))
|
||||
self.assertTrue(os.path.exists(client_current_meta_dir))
|
||||
self.assertTrue(os.path.exists(client_previous_meta_dir))
|
||||
|
||||
# Verify that target_files exist.
|
||||
self.assertTrue(target_files)
|
||||
|
||||
for role in self.role_list:
|
||||
meta_file = role+'.txt'
|
||||
# Verify metadata file for a 'role'.
|
||||
self.assertTrue(os.path.isfile(os.path.join(meta_dir, meta_file)))
|
||||
# Get the metadata.
|
||||
signable = tuf.util.load_json_file(os.path.join(meta_dir, meta_file))
|
||||
for signature in range(len(signable['signatures'])):
|
||||
# Extract a keyid.
|
||||
keyid = signable['signatures'][signature]['keyid']
|
||||
key_file = os.path.join(keystore_dir, keyid+'.key')
|
||||
# Verify existence of a key for the keyid that belong to the 'role'.
|
||||
self.assertTrue(os.path.isfile(key_file))
|
||||
|
||||
_remove_repository_directories(repo_dir, keystore_dir, client_dir)
|
||||
|
||||
# RESTORE
|
||||
quickstart._prompt = original_prompt
|
||||
quickstart._get_password = original_get_password
|
||||
|
||||
|
||||
|
||||
# Run the unit tests.
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,986 +0,0 @@
|
|||
"""
|
||||
<Program Name>
|
||||
test_signerlib.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
|
||||
<Started>
|
||||
September 6, 2012
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
Test_signerlib.py provides collection of methods that tries to test all the
|
||||
units (methods) of the module under test.
|
||||
|
||||
This unittest module requires setting of rsa keys, keyids and such.
|
||||
There is a method in unittest_toolbox.Modified_TestCase class
|
||||
'bind_keys_to_roles()'. This method will set dictionaries
|
||||
'top_level_role_info' and 'rsa_keystore'.
|
||||
|
||||
'top_level_role_info' corresponds to ROLEDICT_SCHEMA and it looks like this:
|
||||
{'rolename': {'keyids': ['34345df32093bd12...'], 'threshold': 1}, ...}
|
||||
|
||||
'rsa_keystore' looks like this: {keyid : { -- RSAKEY_SCHEMA --}, ... } or
|
||||
{keyid : {'keytype': 'rsa', 'keyid': keyid,
|
||||
'keyval': {'public': 'PUBLIC KEY',
|
||||
'private ': 'PRIVATE KEY'}}, ... }
|
||||
|
||||
unittest_toolbox module was created to provide additional testing tools for
|
||||
tuf's modules. For more info see unittest_toolbox.py.
|
||||
|
||||
|
||||
<Methodology>
|
||||
Unittests must follow a specific structure i.e. independent methods should
|
||||
be tested prior to dependent methods. More accurately: least dependent methods
|
||||
are tested before most dependent methods. There is no reason to rewrite or
|
||||
construct other methods that replicate already-tested methods solely for
|
||||
testing purposes. This is possible because 'unittest.TestCase' class guarantees
|
||||
the order of unit tests. So that, 'test_something_A' method would be tested
|
||||
before 'test_something_B'. To ensure the structure a number will be placed
|
||||
after 'test' and before methods name like so 'test_1_check_directory'. The
|
||||
number is sort of a measure of dependence, where 1 is less dependent than 2.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import filecmp
|
||||
import shutil
|
||||
import ConfigParser
|
||||
import gzip
|
||||
import logging
|
||||
import unittest
|
||||
|
||||
import tuf
|
||||
import tuf.log
|
||||
import tuf.util
|
||||
import tuf.formats as formats
|
||||
import tuf.repo.signerlib as signerlib
|
||||
import tuf.repo.keystore
|
||||
import tuf.tests.unittest_toolbox as unittest_toolbox
|
||||
|
||||
|
||||
logger = logging.getLogger('tuf.test_signerlib')
|
||||
|
||||
# 'unittest_toolbox.Modified_TestCase' is too long, I'll set it to 'unit_tbox'.
|
||||
unit_tbox = unittest_toolbox.Modified_TestCase
|
||||
|
||||
|
||||
|
||||
class TestSignerlib(unit_tbox):
|
||||
|
||||
def setUp(self):
|
||||
unit_tbox.setUp(self)
|
||||
|
||||
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
unit_tbox.tearDown(self)
|
||||
|
||||
|
||||
|
||||
|
||||
# Test methods.
|
||||
def test_1_get_metadata_filenames(self):
|
||||
|
||||
# SETUP
|
||||
metadata_dir = self.make_temp_directory()
|
||||
empty_dir = ''
|
||||
|
||||
def _get_metadata_filenames(test_metadata_dir):
|
||||
filenames = signerlib.get_metadata_filenames(test_metadata_dir)
|
||||
if test_metadata_dir is None:
|
||||
test_metadata_dir = '.'
|
||||
|
||||
# Check if a dictionary instance with 4 mappings is returned.
|
||||
self.assertTrue(isinstance(filenames, dict))
|
||||
self.assertFalse(not filenames, 'Empty dictionary returned.')
|
||||
self.assertEqual(len(filenames), 4)
|
||||
|
||||
# Check if all the keys in 'filenames' dictionary
|
||||
# correspond to 'role_list' items i.e. all top level
|
||||
# roles are include in the 'filenames' with their
|
||||
# appropriate paths as values.
|
||||
for role in unit_tbox.role_list:
|
||||
value_at_role = os.path.join(test_metadata_dir, role+'.txt')
|
||||
self.assertTrue(role in filenames)
|
||||
self.assertEqual(filenames[role], value_at_role)
|
||||
|
||||
# Run _get_metadata_filenames(arg) trying different arguments.
|
||||
self.assertRaises(tuf.FormatError, signerlib.get_metadata_filenames, 123)
|
||||
_get_metadata_filenames(metadata_dir)
|
||||
_get_metadata_filenames(empty_dir)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_1_get_metadata_file_info(self):
|
||||
|
||||
# SETUP
|
||||
temp_file_path = self.make_temp_data_file()
|
||||
rand_str = self.random_string()
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: improper arguments that should raise exceptions.
|
||||
self.assertRaises(tuf.Error, signerlib.get_metadata_file_info, '')
|
||||
self.assertRaises(tuf.FormatError, signerlib.get_metadata_file_info,
|
||||
123)
|
||||
self.assertRaises(tuf.FormatError, signerlib.get_metadata_file_info,
|
||||
{rand_str: rand_str})
|
||||
self.assertRaises(tuf.FormatError, signerlib.get_metadata_file_info,
|
||||
[rand_str, rand_str])
|
||||
|
||||
# Make sure the format return by 'get_metadata_file_info'
|
||||
# matches tuf.formats.FILEINFO_SCHEMA.
|
||||
file_info = signerlib.get_metadata_file_info(temp_file_path)
|
||||
self.assertTrue(formats.FILEINFO_SCHEMA.matches(file_info))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_1_generate_and_save_rsa_key(self):
|
||||
"""
|
||||
generate_and_save_rsa_key() is independent from all the other methods in
|
||||
signerlib. In order to test this method all we need is to create a temp
|
||||
directory and a sample password.
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
keystore_dir = self.make_temp_directory()
|
||||
password = self.random_string()
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: Run generate_and_save_rsa_key().
|
||||
rsakey = signerlib.generate_and_save_rsa_key(keystore_dir, password)
|
||||
self.assertTrue(formats.RSAKEY_SCHEMA.matches(rsakey))
|
||||
|
||||
# Test: Check if rsa key file was created.
|
||||
key_path = os.path.join(keystore_dir, rsakey['keyid']+'.key')
|
||||
self.assertTrue(os.path.exists(key_path))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_1_read_config_file(self):
|
||||
"""
|
||||
A short test of 'read_config_file' method. Using a tuple
|
||||
that contains config dictionary and a config file containing
|
||||
the same dictionary, test if 'read_config_file' returns a
|
||||
dictionary corresponding to the supplied config dictionary when
|
||||
config file is passes.
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
# 'base_config' is a tuple containing a config file path and
|
||||
# a corresponding config dictionary. Note, make sure appropriate
|
||||
# suffix is set. In our case it will be 'signerlib.CONFIG_FILENAME'.
|
||||
base_config = self.make_temp_config_file(suffix=signerlib.CONFIG_FILENAME)
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
self.assertTrue(signerlib.read_config_file(base_config[0]),
|
||||
base_config[1])
|
||||
|
||||
# Test: Incorrect arguments.
|
||||
self.assertRaises(tuf.FormatError, signerlib.read_config_file, 123)
|
||||
self.assertRaises((tuf.Error, tuf.FormatError), signerlib.read_config_file,
|
||||
'')
|
||||
self.assertRaises((tuf.Error, tuf.FormatError), signerlib.read_config_file,
|
||||
'junk/dir/'+self.random_string())
|
||||
self.assertRaises(tuf.FormatError, signerlib.read_config_file,
|
||||
[self.random_string()])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_1_generate_targets_metadata(self):
|
||||
|
||||
# SETUP
|
||||
generate_targets_meta = signerlib.generate_targets_metadata
|
||||
version = 8
|
||||
expiration_date = '1985-10-26 01:20:00 UTC'
|
||||
|
||||
# Generate target files.
|
||||
# 'repo_dir' represents repository base.
|
||||
# 'target_files' represents a list of relative target paths.
|
||||
repo_dir, target_files = self.make_temp_directory_with_data_files()
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: Run the generate_targets_metadata(). Test its return value.
|
||||
# Its return value should correspond to tuf.formats.SIGNABLE_SCHEMA
|
||||
target_signable_obj = generate_targets_meta(repo_dir, target_files,
|
||||
version, expiration_date)
|
||||
|
||||
# Test: Validate input.
|
||||
self.assertTrue(formats.SIGNABLE_SCHEMA.matches(target_signable_obj))
|
||||
|
||||
# Test: Incorrect arguments.
|
||||
self.assertRaises(tuf.FormatError, generate_targets_meta,
|
||||
self.random_string(), expiration_date,
|
||||
repo_dir, target_files)
|
||||
self.assertRaises(tuf.FormatError, generate_targets_meta,
|
||||
repo_dir, self.random_string(),
|
||||
repo_dir, target_files)
|
||||
self.assertRaises(tuf.FormatError, generate_targets_meta,
|
||||
version, expiration_date,
|
||||
self.random_string(), target_files)
|
||||
self.assertRaises(tuf.FormatError, generate_targets_meta,
|
||||
version, expiration_date,
|
||||
repo_dir, self.random_string())
|
||||
self.assertRaises(tuf.FormatError, generate_targets_meta,
|
||||
version, expiration_date,
|
||||
repo_dir, [self.random_string(), 1234])
|
||||
self.assertRaises(tuf.Error, generate_targets_meta,
|
||||
version, expiration_date,
|
||||
self.random_path(), target_files)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_1_check_directory(self):
|
||||
"""
|
||||
Quick test to ensure that the method returns valid output.
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
temp_dir, _junk = self.make_temp_directory_with_data_files()
|
||||
rand_str = self.random_string()
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: normal case, check proper output.
|
||||
self.assertEqual(signerlib.check_directory(temp_dir), temp_dir)
|
||||
|
||||
# Test: Incorrect arguments.
|
||||
self.assertRaises(tuf.FormatError, signerlib.check_directory, 1234)
|
||||
self.assertRaises(tuf.FormatError, signerlib.check_directory, [rand_str])
|
||||
self.assertRaises(tuf.FormatError, signerlib.check_directory,
|
||||
{rand_str: rand_str})
|
||||
self.assertRaises(tuf.Error, signerlib.check_directory, self.random_path())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_1_write_metadata_file(self):
|
||||
|
||||
# SETUP
|
||||
# Create temp directory to be prevent any relative path discrepancies.
|
||||
meta_dir = self.make_temp_directory()
|
||||
|
||||
# Create a temp file to store 'metadata' info in.
|
||||
meta_file = self.make_temp_file(directory=meta_dir)
|
||||
|
||||
# Use valid input for json obj.
|
||||
signable_dict = {'signatures':[], 'signed':{'role':'info'}}
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
signerlib.write_metadata_file(signable_dict, meta_file)
|
||||
|
||||
# Extract the content of the temp file.
|
||||
stored_signable_dict = tuf.util.load_json_file(meta_file)
|
||||
|
||||
# Check if object stored in the file corresponds to SIGNABLE_SCHEMA.
|
||||
self.assertTrue(formats.SIGNABLE_SCHEMA.matches(stored_signable_dict))
|
||||
|
||||
# Does original dictionary 'signable_dict' matches dictionary retrieved
|
||||
# from the file - 'stored_signable_dict'?
|
||||
self.assertEqual(signable_dict, stored_signable_dict)
|
||||
|
||||
# Test: Incorrect arguments.
|
||||
self.assertRaises(tuf.FormatError, signerlib.write_metadata_file,'','')
|
||||
self.assertRaises(tuf.FormatError, signerlib.write_metadata_file,
|
||||
[self.random_string()], meta_file)
|
||||
self.assertRaises(tuf.FormatError, signerlib.write_metadata_file,
|
||||
signable_dict, [self.random_string()])
|
||||
self.assertRaises(tuf.Error, signerlib.write_metadata_file, signable_dict,
|
||||
self.random_path())
|
||||
self.assertRaises(tuf.FormatError, signerlib.write_metadata_file,
|
||||
{self.random_string(): self.random_string()},
|
||||
self.random_path())
|
||||
|
||||
|
||||
|
||||
def test_2_build_config_file(self):
|
||||
"""
|
||||
This method tests build_config_file().
|
||||
Previously tested signerlib's read_config_file() is used here.
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
# Declare timeout.
|
||||
days = 365 # number of days
|
||||
|
||||
# Make a temp directory for config file.
|
||||
config_dir = self.make_temp_directory()
|
||||
|
||||
# For 'role_info' argument we going to use 'self.top_level_role_info'
|
||||
# dictionary. There is more info in the beginning of this test
|
||||
# module, also in the test.unittest_toolbox module.
|
||||
roledict_info = self.top_level_role_info
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
# Run build_config_file(). The method is expected to return file
|
||||
# path of the config file. We'll compare it to 'roledict_info'.
|
||||
build_config = signerlib.build_config_file
|
||||
config_path = build_config(config_file_directory=config_dir,
|
||||
timeout=days, role_info=roledict_info)
|
||||
|
||||
# Check if 'config_path' directory exists.
|
||||
self.assertTrue(os.path.exists(config_path))
|
||||
|
||||
# Using 'signerlib.read_config_file' method extract config dictionary
|
||||
# that was stored.
|
||||
config_dict = signerlib.read_config_file(config_path)
|
||||
|
||||
# Remove 'expiration' key from the extracted config dictionary, since
|
||||
# initial role dictionary does not have this field.
|
||||
del config_dict['expiration']
|
||||
|
||||
# Compare the initial dictionary 'roledict_info' with extracted
|
||||
# dictionary 'config_dict'. They have to match.
|
||||
self.assertTrue(config_dict, roledict_info)
|
||||
|
||||
# Test: exceptions on bogus arguments.
|
||||
self.assertRaises(tuf.Error, signerlib.build_config_file,
|
||||
self.random_path(), 365, roledict_info)
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_config_file,
|
||||
config_dir, -1, roledict_info)
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_config_file,
|
||||
config_dir, 365, self.directory_dictionary)
|
||||
|
||||
|
||||
|
||||
def test_3_generate_root_metadata(self):
|
||||
"""
|
||||
test_3_build_root_metadata() is based on two other signerlib methods
|
||||
i.e. build_config_file() and read_config_file(). Hence, 3rd level.
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
original_get_key = tuf.repo.keystore.get_key
|
||||
build_config = signerlib.build_config_file
|
||||
version = 8
|
||||
|
||||
# Create a temp directory to hold a config file.
|
||||
config_dir = self.make_temp_directory()
|
||||
|
||||
# Create config file using previously tested build_config_file().
|
||||
config_path = build_config(config_dir, 365, self.top_level_role_info)
|
||||
|
||||
# Create a config file without a 'targets' role section.
|
||||
notargets_conf_dir = self.make_temp_directory()
|
||||
saved_targets_role = self.top_level_role_info['targets']
|
||||
del self.top_level_role_info['targets']
|
||||
notargets_conf_path = build_config(notargets_conf_dir, 365,
|
||||
self.top_level_role_info)
|
||||
|
||||
# Restore top_level_role_info to initial state.
|
||||
self.top_level_role_info['targets'] = saved_targets_role
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: What if keystore is not set up?
|
||||
self.assertRaises(tuf.UnknownKeyError, signerlib.generate_root_metadata,
|
||||
config_path, version)
|
||||
|
||||
# Patch keystore's get_key method. No harm is done here since correct
|
||||
# arguments are passed and keystore methods are tested separately.
|
||||
tuf.repo.keystore.get_key = self.get_keystore_key
|
||||
|
||||
# Test: normal case. Pass a correct config path.
|
||||
root_meta = signerlib.generate_root_metadata(config_path, version)
|
||||
|
||||
# Check if the returned dictionary corresponds to SIGNABLE_SCHEMA.
|
||||
self.assertTrue(formats.SIGNABLE_SCHEMA.matches(root_meta))
|
||||
|
||||
# Test: bogus arguments.
|
||||
self.assertRaises(tuf.Error, signerlib.generate_root_metadata,
|
||||
notargets_conf_path, version)
|
||||
self.assertRaises(tuf.Error, signerlib.generate_root_metadata, '', version)
|
||||
self.assertRaises(tuf.Error, signerlib.generate_root_metadata,
|
||||
self.random_string(), version)
|
||||
self.assertRaises(tuf.Error, signerlib.generate_root_metadata,
|
||||
{self.random_string(): self.random_string()}, version)
|
||||
self.assertRaises(tuf.FormatError, signerlib.generate_root_metadata,
|
||||
config_path, self.random_string())
|
||||
|
||||
|
||||
# RESTORE
|
||||
tuf.repo.keystore.get_key = original_get_key
|
||||
|
||||
|
||||
|
||||
|
||||
def test_4_sign_metadata(self):
|
||||
"""
|
||||
test_4_sign_metadata() will require us to create metadata using one of
|
||||
the generate_role_metadata() and use monkey patched keystore's get_key().
|
||||
"""
|
||||
|
||||
# SETUP.
|
||||
original_get_key = tuf.repo.keystore.get_key
|
||||
|
||||
for role in ['root', 'targets']:
|
||||
|
||||
role_info = self._get_role_info(role)
|
||||
filename = role+'.txt'
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
signable = signerlib.sign_metadata(role_info[0], role_info[1],
|
||||
filename)
|
||||
|
||||
# Check if signable is returned.
|
||||
self.assertTrue(formats.SIGNABLE_SCHEMA.matches(signable))
|
||||
|
||||
# Test: Incorrect arguments.
|
||||
self.assertRaises(tuf.FormatError, signerlib.sign_metadata,
|
||||
self.random_string(), role_info[1], filename)
|
||||
self.assertRaises(tuf.FormatError, signerlib.sign_metadata,
|
||||
role_info[0], 12345, filename)
|
||||
|
||||
# Test: Verifying 'keytype' value, once is sufficient.
|
||||
if role == 'root':
|
||||
# Alter 'keytype' value of the rsa key. Restore it after.
|
||||
for keyid in role_info[1]:
|
||||
key = self.get_keystore_key(keyid)
|
||||
key['keytype'] = 'unknown_type'
|
||||
self.assertRaises(tuf.Error, signerlib.sign_metadata, role_info[0],
|
||||
role_info[1], filename)
|
||||
|
||||
# Restoring the initial state of rsa_keystore.
|
||||
for keyid in role_info[1]:
|
||||
key = self.get_keystore_key(keyid)
|
||||
key['keytype'] = 'rsa'
|
||||
|
||||
# RESTORE
|
||||
tuf.repo.keystore.get_key = original_get_key
|
||||
|
||||
|
||||
|
||||
def test_5_build_root_file(self):
|
||||
"""
|
||||
test_5_build_root_file() relies on previously tested signerlib's
|
||||
generate_root_metadata(), sign_metadata() and write_metadata_file().
|
||||
build_root_file() basically joins these methods together to create
|
||||
root.txt.
|
||||
|
||||
Test Outline: Get signed metadata and other info of a root role.
|
||||
'root_meta' is a tuple - see _get_role_meta() and _get_signed_role_info().
|
||||
Run build_root_file() with created parameters 'config_path', 'root_keyids'
|
||||
and 'meta_dir'. Verify existence of the created directory. Extract
|
||||
content of the file and verify that it matches original 'signed_root_meta'
|
||||
dictionary. Test various bogus parameters.
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
original_get_key = tuf.repo.keystore.get_key
|
||||
version = 8
|
||||
|
||||
signed_root_meta, root_info = self._get_signed_role_info('root')
|
||||
root_keyids = root_info[1]
|
||||
config_path = root_info[3]
|
||||
meta_dir = root_info[2] # Reuse config's directory.
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
root_filepath = signerlib.build_root_file(config_path, root_keyids,
|
||||
meta_dir, version)
|
||||
|
||||
# Check existence of the file and validity of it's content.
|
||||
self.assertTrue(os.path.exists(root_filepath))
|
||||
file_content = tuf.util.load_json_file(root_filepath)
|
||||
self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(file_content))
|
||||
root_metadata = file_content['signed']
|
||||
self.assertTrue(tuf.formats.ROOT_SCHEMA.matches(root_metadata))
|
||||
|
||||
# Test: various exceptions.
|
||||
self.assertRaises(tuf.Error, signerlib.build_root_file,
|
||||
self.random_path(), root_keyids, meta_dir, version)
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_root_file,
|
||||
config_path, self.random_string(), meta_dir, version)
|
||||
self.assertRaises(tuf.Error, signerlib.build_root_file,
|
||||
config_path, root_keyids, self.random_path(), version)
|
||||
self.assertRaises(tuf.Error, signerlib.build_root_file,
|
||||
config_path, root_keyids, meta_dir, self.random_string())
|
||||
|
||||
# RESTORE
|
||||
tuf.repo.keystore.get_key = original_get_key
|
||||
|
||||
|
||||
|
||||
|
||||
def test_5_build_targets_file(self):
|
||||
"""
|
||||
test_5_build_targets_file() relies on previously tested signerlib's
|
||||
generate_targets_metadata(), sign_metadata() and write_metadata_file().
|
||||
build_targets_file() basically joins these methods together to create
|
||||
targets.txt.
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
original_get_key = tuf.repo.keystore.get_key
|
||||
version = 8
|
||||
expiration_date = '1985-10-26 01:20:00 UTC'
|
||||
|
||||
signed_targets_meta, targets_info = self._get_signed_role_info('targets')
|
||||
|
||||
# 'targets_info' is a tuple that includes targets meta, repository dir,
|
||||
# list of target files.
|
||||
targets_keyids = targets_info[1]
|
||||
repo_dir = targets_info[2]
|
||||
meta_dir = os.path.join(repo_dir, 'metadata')
|
||||
os.mkdir(meta_dir)
|
||||
targets_dir = os.path.join(repo_dir, 'targets')
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
targets_filepath = signerlib.build_targets_file([targets_dir],
|
||||
targets_keyids, meta_dir,
|
||||
version, expiration_date)
|
||||
|
||||
# Check existence of the file and validity of it's content.
|
||||
self.assertTrue(os.path.exists(targets_filepath))
|
||||
file_content = tuf.util.load_json_file(targets_filepath)
|
||||
self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(file_content))
|
||||
targets_metadata = file_content['signed']
|
||||
self.assertTrue(tuf.formats.TARGETS_SCHEMA.matches(targets_metadata))
|
||||
|
||||
# Test: various exceptions.
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_targets_file,
|
||||
[targets_dir], self.random_string(), meta_dir, version, expiration_date)
|
||||
self.assertRaises((tuf.FormatError, tuf.Error), signerlib.build_targets_file,
|
||||
[targets_dir], targets_keyids, self.random_path(), version, expiration_date)
|
||||
self.assertRaises((tuf.FormatError, tuf.Error), signerlib.build_targets_file,
|
||||
[targets_dir], targets_keyids, meta_dir, self.random_string(), expiration_date)
|
||||
self.assertRaises((tuf.FormatError, tuf.Error), signerlib.build_targets_file,
|
||||
[targets_dir], targets_keyids, meta_dir, version, self.random_string())
|
||||
|
||||
# RESTORE
|
||||
tuf.repo.keystore.get_key = original_get_key
|
||||
|
||||
|
||||
|
||||
|
||||
def test_6_generate_release_metadata(self):
|
||||
"""
|
||||
test_6_generate_release_metadata() uses previously tested
|
||||
singnerlib's build_root_file(), build_targets_file()
|
||||
and get_metadata_file_info. In order to use generate_release_metadata()
|
||||
we need to have root.txt and targets.txt in the metadata directory,
|
||||
plus we need to have targets directory (with target files/directories).
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
original_get_key = tuf.repo.keystore.get_key
|
||||
version = 8
|
||||
expiration_date = '1985-10-26 01:20:00 UTC'
|
||||
|
||||
# Create root.txt and targets.txt as described above.
|
||||
meta_dir = self._create_root_and_targets_meta_files()
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: Run generate_release_metadata().
|
||||
release_meta = signerlib.generate_release_metadata(meta_dir,
|
||||
version, expiration_date)
|
||||
|
||||
# Verify that created metadata dictionary corresponds to
|
||||
# SIGNABLE_SCHEMA and its 'signed' value to RELEASE_SCHEMA.
|
||||
self.assertTrue(formats.SIGNABLE_SCHEMA.matches(release_meta))
|
||||
self.assertTrue(formats.RELEASE_SCHEMA.matches(release_meta['signed']))
|
||||
|
||||
# Test: exceptions.
|
||||
self.assertRaises(tuf.Error, signerlib.generate_release_metadata,
|
||||
self.random_path(), version, expiration_date)
|
||||
self.assertRaises(tuf.FormatError, signerlib.generate_release_metadata,
|
||||
['junk'], version, expiration_date)
|
||||
self.assertRaises(tuf.Error, signerlib.generate_release_metadata,
|
||||
meta_dir, self.random_string(), expiration_date)
|
||||
self.assertRaises(tuf.Error, signerlib.generate_release_metadata,
|
||||
meta_dir, version, self.random_string())
|
||||
|
||||
|
||||
# RESTORE
|
||||
tuf.repo.keystore.get_key = original_get_key
|
||||
|
||||
|
||||
|
||||
|
||||
def test_7_build_release_file(self):
|
||||
"""
|
||||
test_7_build_release_file() uses previously tested
|
||||
generate_release_metadata().
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
original_get_key = tuf.repo.keystore.get_key
|
||||
version = 8
|
||||
expiration_date = '1985-10-26 01:20:00 UTC'
|
||||
|
||||
# Create root.txt and targets.txt as described above. Also, get signed
|
||||
# release metadata to compare it with the content of the file
|
||||
signed_release_meta, release_info = self._get_signed_role_info('release')
|
||||
meta_dir = release_info[2]
|
||||
release_keyids = release_info[1]
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
release_filepath = signerlib.build_release_file(release_keyids, meta_dir,
|
||||
version, expiration_date)
|
||||
|
||||
# Check if 'release.txt' file was created in metadata directory.
|
||||
self.assertTrue(os.path.exists(release_filepath))
|
||||
file_content = tuf.util.load_json_file(release_filepath)
|
||||
self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(file_content))
|
||||
release_metadata = file_content['signed']
|
||||
self.assertTrue(tuf.formats.RELEASE_SCHEMA.matches(release_metadata))
|
||||
|
||||
# Test: exceptions.
|
||||
self.assertRaises(tuf.Error, signerlib.build_release_file, release_keyids,
|
||||
self.random_path(), version, expiration_date)
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_release_file,
|
||||
self.random_string(), meta_dir, version, expiration_date)
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_release_file,
|
||||
release_keyids, meta_dir, self.random_string(),
|
||||
expiration_date)
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_release_file,
|
||||
release_keyids, meta_dir, version, self.random_string())
|
||||
|
||||
# RESTORE
|
||||
tuf.repo.keystore.get_key = original_get_key
|
||||
|
||||
|
||||
|
||||
|
||||
def test_8_generate_timestamp_metadata(self):
|
||||
"""
|
||||
test_8_generate_timestamp_metadata() uses previously tested
|
||||
build_release_file()
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
original_get_key = tuf.repo.keystore.get_key
|
||||
version = 8
|
||||
expiration_date = '1985-10-26 01:20:00 UTC'
|
||||
|
||||
generate_timestamp_meta = signerlib.generate_timestamp_metadata
|
||||
|
||||
# Create release metadata and create 'release.txt' file.
|
||||
junk, release_keyids, meta_dir = self._get_role_info('release')
|
||||
signerlib.build_release_file(release_keyids, meta_dir, version,
|
||||
expiration_date)
|
||||
release_filepath = os.path.join(meta_dir, 'release.txt')
|
||||
|
||||
# To test compression we need to create compressed 'release.txt'.
|
||||
# The 'release.txt' should exist at this point, compress it.
|
||||
release_file = open(release_filepath, 'rb')
|
||||
gzipped_release = open(release_filepath+'.gz', 'wb')
|
||||
gzipped_release.writelines(release_file)
|
||||
gzipped_release.close()
|
||||
release_file.close()
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
timestamp_meta = generate_timestamp_meta(release_filepath, version,
|
||||
expiration_date)
|
||||
|
||||
# Verify metadata formats.
|
||||
self.assertTrue(formats.SIGNABLE_SCHEMA.matches(timestamp_meta))
|
||||
self.assertTrue(formats.TIMESTAMP_SCHEMA.matches(timestamp_meta['signed']))
|
||||
|
||||
# Test: normal case (with compression).
|
||||
timestamp_meta = generate_timestamp_meta(release_filepath+'.gz', version,
|
||||
expiration_date)
|
||||
|
||||
# Verify metadata formats.
|
||||
self.assertTrue(formats.SIGNABLE_SCHEMA.matches(timestamp_meta))
|
||||
self.assertTrue(formats.TIMESTAMP_SCHEMA.matches(timestamp_meta['signed']))
|
||||
|
||||
# Test: invalid path.
|
||||
self.assertRaises(tuf.Error, generate_timestamp_meta, self.random_path(),
|
||||
version, expiration_date)
|
||||
self.assertRaises(tuf.FormatError, generate_timestamp_meta, release_filepath,
|
||||
self.random_string(), expiration_date)
|
||||
self.assertRaises(tuf.FormatError, generate_timestamp_meta, release_filepath,
|
||||
version, self.random_string())
|
||||
|
||||
# RESTORE
|
||||
tuf.repo.keystore.get_key = original_get_key
|
||||
|
||||
|
||||
|
||||
|
||||
def test_9_build_timestamp_file(self):
|
||||
"""
|
||||
test_9_build_timestamp_file() uses previously tested
|
||||
generate_timestamp_metadata().
|
||||
"""
|
||||
|
||||
# SETUP
|
||||
original_get_key = tuf.repo.keystore.get_key
|
||||
version = 8
|
||||
expiration_date = '1985-10-26 01:20:00 UTC'
|
||||
|
||||
# Create all necessary files and metadata i.e. signed timestamp
|
||||
# metadata, timestamp keyids, 'release.txt', 'root.txt', 'targets.txt',
|
||||
# target files, etc.
|
||||
signed_timestamp_meta, timestamp_info = \
|
||||
self._get_signed_role_info('timestamp')
|
||||
|
||||
timestamp_keyids = timestamp_info[1]
|
||||
meta_dir = timestamp_info[2]
|
||||
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
timestamp_filepath = signerlib.build_timestamp_file(timestamp_keyids,
|
||||
meta_dir, version,
|
||||
expiration_date)
|
||||
|
||||
# Check if 'timestamp.txt' file was created in metadata directory.
|
||||
self.assertTrue(os.path.exists(timestamp_filepath))
|
||||
file_content = tuf.util.load_json_file(timestamp_filepath)
|
||||
self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(file_content))
|
||||
timestamp_metadata = file_content['signed']
|
||||
self.assertTrue(tuf.formats.TIMESTAMP_SCHEMA.matches(timestamp_metadata))
|
||||
|
||||
# Test: try bogus parameters.
|
||||
self.assertRaises(tuf.Error, signerlib.build_timestamp_file,
|
||||
timestamp_keyids, self.random_path(), version,
|
||||
expiration_date)
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_timestamp_file,
|
||||
self.random_string(), meta_dir, version, expiration_date)
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_timestamp_file,
|
||||
timestamp_keyids, meta_dir, self.random_string(),
|
||||
expiration_date)
|
||||
self.assertRaises(tuf.FormatError, signerlib.build_timestamp_file,
|
||||
timestamp_keyids, meta_dir, version, self.random_string())
|
||||
|
||||
# RESTORE
|
||||
tuf.repo.keystore.get_key = original_get_key
|
||||
|
||||
|
||||
|
||||
|
||||
def test_9_get_target_keyids(self):
|
||||
|
||||
# SETUP
|
||||
original_get_key = tuf.repo.keystore.get_key
|
||||
version = 8
|
||||
expiration_date = '1985-10-26 01:20:00 UTC'
|
||||
|
||||
# Create metadata directory and targets metadata file.
|
||||
meta_dir = self._create_root_and_targets_meta_files()
|
||||
|
||||
signed_targets_meta, targets_info = self._get_signed_role_info('targets')
|
||||
|
||||
# 'targets_info' is a tuple that includes targets meta, repository dir,
|
||||
# list of target files.
|
||||
targets_keyids = targets_info[1]
|
||||
repo_dir = targets_info[2]
|
||||
meta_dir = os.path.join(repo_dir, 'metadata')
|
||||
os.mkdir(meta_dir)
|
||||
targets_dir = os.path.join(repo_dir, 'targets')
|
||||
|
||||
# TESTS
|
||||
# Test: normal case.
|
||||
targets_filepath = signerlib.build_targets_file([targets_dir],
|
||||
targets_keyids, meta_dir,
|
||||
version, expiration_date)
|
||||
|
||||
# Check existence of the file and validity of it's content.
|
||||
self.assertTrue(os.path.exists(targets_filepath))
|
||||
file_content = tuf.util.load_json_file(targets_filepath)
|
||||
self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(file_content))
|
||||
targets_metadata = file_content['signed']
|
||||
self.assertTrue(tuf.formats.TARGETS_SCHEMA.matches(targets_metadata))
|
||||
# TODO: Generate some delegation metadata files.
|
||||
|
||||
# Test: normal case.
|
||||
_target_keyids = signerlib.get_target_keyids(meta_dir)
|
||||
for keyid in targets_keyids:
|
||||
self.assertTrue(keyid in _target_keyids['targets'])
|
||||
|
||||
# RESTORE
|
||||
tuf.repo.keystore.get_key = original_get_key
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# HELPER METHODS
|
||||
# Call these non-test methods ONLY in methods that begin with 'test'.
|
||||
def _create_root_and_targets_meta_files(self, repo_dir=None):
|
||||
"""
|
||||
This method generates temp root.txt and target.txt, it uses following
|
||||
previously tested signerlib's methods:
|
||||
build_root_file()
|
||||
build_targets_file()
|
||||
"""
|
||||
|
||||
# The version number and expiration date for the root and target
|
||||
# metadata created.
|
||||
version = 8
|
||||
expiration_date = '1985-10-26 01:20:00 UTC'
|
||||
|
||||
if not repo_dir:
|
||||
# Create repository directory.
|
||||
repo_dir = self.make_temp_directory()
|
||||
|
||||
# Create metadata directory.
|
||||
meta_dir = os.path.join(repo_dir, 'metadata')
|
||||
os.mkdir(meta_dir)
|
||||
|
||||
# Create root.txt.
|
||||
junk, root_keyids, repo_dir, config_path = \
|
||||
self._get_role_info('root', directory=repo_dir)
|
||||
signerlib.build_root_file(config_path, root_keyids, meta_dir, version)
|
||||
self.assertTrue(os.path.exists(os.path.join(meta_dir, 'root.txt')))
|
||||
|
||||
# Create targets.txt.
|
||||
junk, targets_keyids, repo_dir, target_files = \
|
||||
self._get_role_info('targets', directory=repo_dir)
|
||||
path_to_targets = os.path.join(repo_dir, 'targets')
|
||||
signerlib.build_targets_file([path_to_targets], targets_keyids, meta_dir,
|
||||
version, expiration_date)
|
||||
self.assertTrue(os.path.exists(os.path.join(meta_dir, 'root.txt')))
|
||||
|
||||
return meta_dir
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def _get_role_info(self, role, directory=None):
|
||||
"""
|
||||
This method generates role's metadata dictionary, it uses previously
|
||||
tested signerlib's methods. Note that at everything maintains the order.
|
||||
Nothing that has not been tested previously is used in any of the
|
||||
following conditions.
|
||||
|
||||
<Arguments>
|
||||
directory:
|
||||
Directory of a config file.
|
||||
|
||||
<Returns>
|
||||
Tuple (role's metadata(not signed), role's keyids, directory, optional)
|
||||
|
||||
"""
|
||||
|
||||
# The version number and expiration date for metadata files created.
|
||||
version = 8
|
||||
expiration_date = '1985-10-26 01:20:00 UTC'
|
||||
|
||||
|
||||
if not directory:
|
||||
# Create a temp directory to hold a config file.
|
||||
directory = self.make_temp_directory()
|
||||
|
||||
# Get role's keyids.
|
||||
role_keyids = self.top_level_role_info[role]['keyids']
|
||||
|
||||
|
||||
if role == 'root':
|
||||
# Create config file using previously tested build_config_file().
|
||||
config_path = signerlib.build_config_file(directory, 365,
|
||||
self.top_level_role_info)
|
||||
|
||||
# Patch keystore's get_key method.
|
||||
tuf.repo.keystore.get_key = self.get_keystore_key
|
||||
|
||||
# Create root metadata.
|
||||
root_meta = signerlib.generate_root_metadata(config_path, version)
|
||||
return root_meta, role_keyids, directory, config_path
|
||||
|
||||
elif role == 'targets':
|
||||
# Generate target files.
|
||||
# 'repo_dir' represents repository base.
|
||||
# 'target_files' represents a list of relative target paths.
|
||||
repo_dir, target_files = \
|
||||
self.make_temp_directory_with_data_files(directory=directory)
|
||||
|
||||
# Patch keystore's get_key method.
|
||||
tuf.repo.keystore.get_key = self.get_keystore_key
|
||||
|
||||
# Run the 'signerlib.generate_targets_metadata'. Test its return value.
|
||||
# Its return value should correspond to tuf.formats.SIGNABLE_SCHEMA
|
||||
targets_meta = signerlib.generate_targets_metadata(repo_dir, target_files,
|
||||
version,
|
||||
expiration_date)
|
||||
return targets_meta, role_keyids, repo_dir, target_files
|
||||
|
||||
elif role == 'release':
|
||||
# Generate 'root.txt' and 'targets.txt' with targets directory in
|
||||
# the repository containing files and directories.
|
||||
meta_dir = self._create_root_and_targets_meta_files()
|
||||
release_meta = signerlib.generate_release_metadata(meta_dir, version,
|
||||
expiration_date)
|
||||
return release_meta, role_keyids, meta_dir
|
||||
|
||||
elif role == 'timestamp':
|
||||
# Generate 'release.txt' which includes creation of 'root.txt',
|
||||
# 'targets.txt' and target files.
|
||||
junk, release_keyids, meta_dir = self._get_role_info('release')
|
||||
signerlib.build_release_file(release_keyids, meta_dir, version,
|
||||
expiration_date)
|
||||
release_filepath = os.path.join(meta_dir, 'release.txt')
|
||||
|
||||
# Generate timestamp metadata.
|
||||
timestamp_meta = signerlib.generate_timestamp_metadata(release_filepath,
|
||||
version,
|
||||
expiration_date)
|
||||
return timestamp_meta, role_keyids, meta_dir
|
||||
|
||||
else:
|
||||
logger.warning('\nUnrecognized top-level role.')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def _get_signed_role_info(self, role, directory=None):
|
||||
role_info = self._get_role_info(role, directory=directory)
|
||||
filename = repr(role+'.txt')
|
||||
|
||||
# Try sign_metadata(), see if signable is returned.
|
||||
signed_meta = signerlib.sign_metadata(role_info[0], role_info[1],
|
||||
filename)
|
||||
return signed_meta, role_info
|
||||
|
||||
|
||||
def setUpModule():
|
||||
# setUpModule() is called before any test cases run.
|
||||
# Generate rsa keys and roles dictionary dictionaries.
|
||||
unit_tbox.bind_keys_to_roles()
|
||||
|
||||
def tearDownModule():
|
||||
# tearDownModule() is called after all the test cases have run.
|
||||
unit_tbox.clear_toolbox()
|
||||
tuf.repo.keystore.clear_keystore()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
"""
|
||||
<Program>
|
||||
simple_server.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
|
||||
<Started>
|
||||
February 15, 2012
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
This is a basic server that was designed to be used in conjunction with
|
||||
test_download.py to test download.py module.
|
||||
|
||||
<Referencesi>
|
||||
SimpleHTTPServer:
|
||||
http://docs.python.org/library/simplehttpserver.html#module-SimpleHTTPServer
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import random
|
||||
import SimpleHTTPServer
|
||||
import SocketServer
|
||||
|
||||
PORT = 0
|
||||
|
||||
def _port_gen():
|
||||
return random.randint(30000, 45000)
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
try:
|
||||
PORT = int(sys.argv[1])
|
||||
if PORT < 30000 or PORT > 45000:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
PORT = _port_gen()
|
||||
else:
|
||||
PORT = _port_gen()
|
||||
|
||||
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
|
||||
httpd = SocketServer.TCPServer(("", PORT), Handler)
|
||||
|
||||
#print "PORT: ", PORT
|
||||
httpd.serve_forever()
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
"""
|
||||
<Program Name>
|
||||
statement_coverage.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
|
||||
<Started>
|
||||
March 20, 2013.
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
Measure test coverage.
|
||||
|
||||
NOTE: This script is based on third party software. In order to use this
|
||||
script install Ned Batchelder's coverage.py:
|
||||
http://nedbatchelder.com/code/coverage/
|
||||
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Try to import coverage.py. Coverage.py is a third party software.
|
||||
try:
|
||||
coverage = __import__('coverage')
|
||||
except ImportError, error:
|
||||
error_msg = ("\nIt appears that coverage.py is not installed. Install "+
|
||||
"Ned Batchelder's coverage.py "+
|
||||
"('http://nedbatchelder.com/code/coverage/') and try again.\n")
|
||||
print error_msg
|
||||
raise
|
||||
|
||||
|
||||
cov = coverage.coverage()
|
||||
cov.start()
|
||||
|
||||
try:
|
||||
current_directory = os.getcwd()
|
||||
current_directory_content = os.listdir(current_directory)
|
||||
|
||||
# Find test scripts and import them.
|
||||
test_modules = [] # Test modules.
|
||||
tested_modules = [] # Modules that are tested by the 'test_modules'.
|
||||
|
||||
for _file in current_directory_content:
|
||||
if _file.startswith('test') and _file.endswith('.py'):
|
||||
|
||||
_file = os.path.splitext(_file)[0]
|
||||
test_modules.append(_file)
|
||||
|
||||
# Import the module.
|
||||
try:
|
||||
module = __import__(_file)
|
||||
except ImportError, error:
|
||||
print 'Unable to load the module: '+_file
|
||||
raise
|
||||
|
||||
_file = '.'+_file[5:]
|
||||
tested_modules.append(_file)
|
||||
|
||||
finally:
|
||||
cov.stop()
|
||||
|
||||
|
||||
# Include quickstart.
|
||||
tested_modules.remove('.quickstart')
|
||||
tested_modules.append('quickstart')
|
||||
|
||||
# Extracting tuf modules.
|
||||
tuf_modules = {} # list of all loaded tuf modules.
|
||||
for module_name in sys.modules:
|
||||
if module_name.startswith('tuf') or module_name.startswith('quickstart'):
|
||||
tuf_modules[module_name] = sys.modules[module_name]
|
||||
|
||||
# Tested module paths.
|
||||
tested_module_paths = []
|
||||
for module_name in tuf_modules:
|
||||
for tested_module in tested_modules:
|
||||
if module_name.endswith(tested_module):
|
||||
tested_module_paths.append(tuf_modules[module_name].__file__)
|
||||
|
||||
cov.report(tested_module_paths)
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
<Program Name>
|
||||
test_util_test_tools.py
|
||||
|
||||
<Author>
|
||||
Konstantin Andrianov
|
||||
|
||||
<Started>
|
||||
February 26, 2012
|
||||
|
||||
<Copyright>
|
||||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
Test util_test_tools.
|
||||
|
||||
"""
|
||||
import os
|
||||
import urllib
|
||||
import unittest
|
||||
|
||||
import tuf.tests.util_test_tools as util_test_tools
|
||||
import tuf.repo.keystore
|
||||
|
||||
|
||||
class test_UtilTestTools(unittest.TestCase):
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
|
||||
# Ensure the keystore is empty prior to initializing the repository
|
||||
# generated by 'util_test_tools'.
|
||||
tuf.repo.keystore.clear_keystore()
|
||||
|
||||
# Unpacking necessary parameters returned from init_repo()
|
||||
essential_params = util_test_tools.init_repo(using_tuf=True)
|
||||
self.root_repo = essential_params[0]
|
||||
self.url = essential_params[1]
|
||||
self.server_proc = essential_params[2]
|
||||
self.keyids = essential_params[3]
|
||||
# TODO: In the line below, 'util_test_tools.init_repo' does
|
||||
# not return the interposition config and this unit test
|
||||
# does not directly use it. WIP?
|
||||
#self.interpose_json = essential_params[4]
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
|
||||
# 'util_test_tools.cleanup()' should clear the keystore...
|
||||
util_test_tools.cleanup(self.root_repo, self.server_proc)
|
||||
|
||||
# Clear the keystore here just in case.
|
||||
tuf.repo.keystore.clear_keystore()
|
||||
|
||||
|
||||
#================================================#
|
||||
# Below are a few quick tests that make sure #
|
||||
# everything works smoothly in util_test_tools. #
|
||||
#================================================#
|
||||
|
||||
# A few quick internal tests to see if everything runs smoothly.
|
||||
def test_direct_download(self):
|
||||
# Setup.
|
||||
reg_repo = os.path.join(self.root_repo, 'reg_repo')
|
||||
downloads = os.path.join(self.root_repo, 'downloads')
|
||||
filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test')
|
||||
file_basename = os.path.basename(filepath)
|
||||
url_to_reg_repo = self.url+'reg_repo/'+file_basename
|
||||
downloaded_file = os.path.join(downloads, file_basename)
|
||||
|
||||
# Test direct download using 'urllib.urlretrieve'.
|
||||
urllib.urlretrieve(url_to_reg_repo, downloaded_file)
|
||||
self.assertTrue(os.path.isfile(downloaded_file))
|
||||
|
||||
# Verify the content of the downloaded file.
|
||||
downloaded_content = util_test_tools.read_file_content(downloaded_file)
|
||||
self.assertEquals('Test', downloaded_content)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_correct_directory_structure(self):
|
||||
# Verify following directories exists: '{root_repo}/reg_repo/',
|
||||
# '{root_repo}/downloads/.
|
||||
self.assertTrue(os.path.isdir(os.path.join(self.root_repo, 'reg_repo')))
|
||||
self.assertTrue(os.path.isdir(os.path.join(self.root_repo, 'downloads')))
|
||||
|
||||
# Verify that all necessary TUF-paths exist.
|
||||
tuf_repo = os.path.join(self.root_repo, 'tuf_repo')
|
||||
tuf_client = os.path.join(self.root_repo, 'tuf_client')
|
||||
metadata_dir = os.path.join(tuf_repo, 'metadata')
|
||||
current_dir = os.path.join(tuf_client, 'metadata', 'current')
|
||||
|
||||
# Verify '{root_repo}/tuf_repo/metadata/role.json' paths exists.
|
||||
for role in ['root', 'targets', 'snapshot', 'timestamp']:
|
||||
# Repository side.
|
||||
role_file = os.path.join(metadata_dir, role+'.json')
|
||||
self.assertTrue(os.path.isfile(role_file))
|
||||
|
||||
# Client side.
|
||||
role_file = os.path.join(current_dir, role+'.json')
|
||||
self.assertTrue(os.path.isfile(role_file))
|
||||
|
||||
# Verify '{root_repo}/tuf_repo/keystore/keyid.key' exists.
|
||||
keys_list = os.listdir(os.path.join(tuf_repo, 'keystore'))
|
||||
self.assertEquals(len(keys_list), 1)
|
||||
|
||||
# Verify '{root_repo}/tuf_repo/targets/' directory exists.
|
||||
self.assertTrue(os.path.isdir(os.path.join(tuf_repo, 'targets')))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_methods(self):
|
||||
"""
|
||||
Making sure following methods work as intended:
|
||||
- add_file_to_repository(data)
|
||||
- modify_file_at_repository(filepath, data)
|
||||
- delete_file_at_repository(filepath)
|
||||
- read_file_content(filepath)
|
||||
- tuf_refresh_repo()
|
||||
- tuf_refresh_and_download()
|
||||
|
||||
Note: here file at the 'filepath' and the 'target' file at tuf-targets
|
||||
directory are identical files.
|
||||
Ex: filepath = '{root_repo}/reg_repo/file.json'
|
||||
target = '{root_repo}/tuf_repo/targets/file.json'
|
||||
"""
|
||||
|
||||
reg_repo = os.path.join(self.root_repo, 'reg_repo')
|
||||
tuf_repo = os.path.join(self.root_repo, 'tuf_repo')
|
||||
downloads = os.path.join(self.root_repo, 'downloads')
|
||||
|
||||
# Test 'add_file_to_repository(directory, data)' and
|
||||
# read_file_content(filepath) methods.
|
||||
filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test')
|
||||
self.assertTrue(os.path.isfile(filepath))
|
||||
self.assertEquals(os.path.dirname(filepath), reg_repo)
|
||||
filepath_content = util_test_tools.read_file_content(filepath)
|
||||
self.assertEquals('Test', filepath_content)
|
||||
|
||||
# Test 'modify_file_at_repository(filepath, data)' method.
|
||||
filepath = util_test_tools.modify_file_at_repository(filepath, 'Modify')
|
||||
self.assertTrue(os.path.exists(filepath))
|
||||
filepath_content = util_test_tools.read_file_content(filepath)
|
||||
self.assertEquals('Modify', filepath_content)
|
||||
|
||||
# Test 'tuf_refresh_repo' method.
|
||||
util_test_tools.tuf_refresh_repo(self.root_repo, self.keyids)
|
||||
file_basename = os.path.basename(filepath)
|
||||
target = os.path.join(tuf_repo, 'targets', file_basename)
|
||||
self.assertTrue(os.path.isfile(target))
|
||||
|
||||
# Test 'delete_file_at_repository(filepath)' method.
|
||||
util_test_tools.delete_file_at_repository(filepath)
|
||||
self.assertFalse(os.path.exists(filepath))
|
||||
|
||||
# Test 'tuf_refresh_repo' method once more.
|
||||
util_test_tools.tuf_refresh_repo(self.root_repo, self.keyids)
|
||||
file_basename = os.path.basename(filepath)
|
||||
target = os.path.join(tuf_repo, 'targets', file_basename)
|
||||
self.assertFalse(os.path.isfile(target))
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue