# -*- coding: utf-8 -*-
""" tests.test_signing
Unit tests for conda-content-trust/conda_content_trust/signing.py
NOTE that much of the signing module is currently tested in
test_authentication.py instead. Some unit tests are missing.
Run the tests this way:
pytest tests/test_signing.py
"""
# Python2 Compatibility
from __future__ import absolute_import, division, print_function, unicode_literals
import os, os.path
import shutil
import copy
from conda_content_trust.common import *
from conda_content_trust.authentication import *
from conda_content_trust.signing import *
import pytest
# Some REGRESSION test data.
REG__KEYPAIR_NAME = 'keytest_old'
REG__PRIVATE_BYTES = b'\xc9\xc2\x06\r~\r\x93al&T\x84\x0bI\x83\xd0\x02!\xd8\xb6\xb6\x9c\x85\x01\x07\xdat\xb4!h\xf97'
REG__PRIVATE_HEX = 'c9c2060d7e0d93616c2654840b4983d00221d8b6b69c850107da74b42168f937'
REG__PUBLIC_BYTES = b"\x01=\xddqIb\x86m\x12\xba[\xae'?\x14\xd4\x8c\x89\xcf\x07s\xde\xe2\xdb\xf6\xd4V\x1eR\x1c\x83\xf7"
REG__PUBLIC_HEX = '013ddd714962866d12ba5bae273f14d48c89cf0773dee2dbf6d4561e521c83f7'
# Signature is over b'123456\x067890' using key REG__PRIVATE_BYTES.
REG__SIGNATURE = b'\xb6\xda\x14\xa1\xedU\x9e\xbf\x01\xb3\xa9\x18\xc9\xb8\xbd\xccFM@\x87\x99\xe8\x98\x84C\xe4}9;\xa4\xe5\xfd\xcf\xdaau\x04\xf5\xcc\xc0\xe7O\x0f\xf0F\x91\xd3\xb8"\x7fD\x1dO)*\x1f?\xd7&\xd6\xd3\x1f\r\x0e'
REG__HASHED_VAL = b'string to hash\n'
REG__HASH_HEX = '73aec9a93f4beb41a9bad14b9d1398f60e78ccefd97e4eb7d3cf26ba71dbe0ce'
#REG__HASH_BYTES = b's\xae\xc9\xa9?K\xebA\xa9\xba\xd1K\x9d\x13\x98\xf6\x0ex\xcc\xef\xd9~N\xb7\xd3\xcf&\xbaq\xdb\xe0\xce'
REG__REPODATA_HASHMAP = {
"noarch/current_repodata.json": "908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe",
"noarch/repodata.json": "908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe",
"noarch/repodata_from_packages.json": "908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe",
"osx-64/current_repodata.json": "8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2",
"osx-64/repodata.json": "8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2",
"osx-64/repodata_from_packages.json": "8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2"
}
REG__TEST_TIMESTAMP = '2019-10-01T00:00:00Z'
REG__TEST_EXPIRY_DATE = '2025-01-01T10:30:00Z'
REG__EXPECTED_UNSIGNED_REPODATA_VERIFY = {
'type': 'repodata_verify', 'timestamp': REG__TEST_TIMESTAMP,
'metadata_spec_version': '0.1.0', 'expiration': REG__TEST_EXPIRY_DATE,
'secured_files': {
'noarch/current_repodata.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
'noarch/repodata.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
'noarch/repodata_from_packages.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
'osx-64/current_repodata.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2',
'osx-64/repodata.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2',
'osx-64/repodata_from_packages.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2'}
}
REG__EXPECTED_REGSIGNED_REPODATA_VERIFY = {
# Re-sign this if its data changes: it's signed!
'type': 'repodata_verify', 'timestamp': '2019-10-01T00:00:00Z',
'metadata_spec_version': '0.1.0', 'expiration': '2025-01-01T10:30:00Z',
'secured_files': {
'noarch/current_repodata.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
'noarch/repodata.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
'noarch/repodata_from_packages.json': '908724926552827ab58dfc0bccba92426cec9f1f483883da3ff0d8664e18c0fe',
'osx-64/current_repodata.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2',
'osx-64/repodata.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2',
'osx-64/repodata_from_packages.json': '8120fb07a6a8a280ffa2b89fb2fbb89484823d0b0357ff0cfa7c333352b2faa2'}
}
REG__REPODATA_SAMPLE_FNAME = 'tests/repodata_sample.json'
REG__REPODATA_SAMPLE_TEMP_FNAME = 'tests/repodata_sample_temp.json'
# def test_serialize_and_sign():
# raise(NotImplementedError()
# '⚠️ These tests are currently implemented in '
# 'test_authentication.py instead.'))
# def test_sign_signable():
# raise(NotImplementedError(
# '⚠️ These tests are currently implemented in '
# 'test_authentication.py instead.'))
# def test_wrap_as_signable():
# raise(NotImplementedError(
# '⚠️ This function is tested in multiple modules, but '
# 'a unit test should be constructed from those tests.'))
def test_sign_all_in_repodata():
public = PublicKey.from_hex(REG__PUBLIC_HEX)
# Make a test copy of the repodata sample, since we're going to
# update it.
if os.path.exists(REG__REPODATA_SAMPLE_TEMP_FNAME):
os.remove(REG__REPODATA_SAMPLE_TEMP_FNAME)
shutil.copy(
REG__REPODATA_SAMPLE_FNAME,
REG__REPODATA_SAMPLE_TEMP_FNAME)
# grab data and use it to compare to what we produce in a bit
repodata = load_metadata_from_file(REG__REPODATA_SAMPLE_FNAME)
sign_all_in_repodata(REG__REPODATA_SAMPLE_TEMP_FNAME, REG__PRIVATE_HEX)
repodata_signed = load_metadata_from_file(REG__REPODATA_SAMPLE_TEMP_FNAME)
# Ensure that the rest of repodata is unchanged.
repodata_signed_stripped = copy.deepcopy(repodata_signed)
del repodata_signed_stripped['signatures']
assert repodata_signed_stripped == repodata
del repodata_signed_stripped
# Make sure there is one signature entry for every artifact entry, and no
# mystery entries.
assert repodata['packages'].keys() == repodata_signed['signatures'].keys()
for artifact_name in repodata['packages']:
# There's a signature "by" this key listed for every artifact.
assert REG__PUBLIC_HEX in repodata_signed['signatures'][artifact_name]
# The signature is valid.
verify_signature(
# signature, (supposed) key, data that was (supposedly) signed
repodata_signed['signatures'][artifact_name][REG__PUBLIC_HEX]['signature'],
public,
canonserialize(repodata['packages'][artifact_name]))
# if os.path.exists(REG__REPODATA_SAMPLE_TEMP_FNAME):
# os.remove(REG__REPODATA_SAMPLE_TEMP_FNAME)