def test_DictOf(self): # Test conditions for valid arguments. dictof_schema = SCHEMA.DictOf( SCHEMA.RegularExpression(r'[aeiou]+'), SCHEMA.Struct([SCHEMA.AnyString(), SCHEMA.AnyString()])) self.assertTrue(dictof_schema.matches({})) self.assertTrue(dictof_schema.matches({ 'a': ['x', 'y'], 'e': ['', ''] })) # Test conditions for invalid arguments. self.assertFalse(dictof_schema.matches('')) self.assertFalse(dictof_schema.matches({'a': ['x', 3], 'e': ['', '']})) self.assertFalse( dictof_schema.matches({ 'a': ['x', 'y'], 'e': ['', ''], 'd': ['a', 'b'] })) # Test conditions for invalid arguments in a schema definition. self.assertRaises(securesystemslib.exceptions.FormatError, SCHEMA.DictOf, 1, 1) self.assertRaises(securesystemslib.exceptions.FormatError, SCHEMA.DictOf, [1], [1]) self.assertRaises(securesystemslib.exceptions.FormatError, SCHEMA.DictOf, {'a': 1}, 1) self.assertRaises(securesystemslib.exceptions.FormatError, SCHEMA.DictOf, SCHEMA.AnyString(), 1)
def _create_gpg_pubkey_with_subkey_schema(pubkey_schema): """Helper method to extend the passed public key schema with an optional dictionary of sub public keys "subkeys" with the same schema.""" schema = pubkey_schema subkey_schema_tuple = ("subkeys", SCHEMA.Optional( SCHEMA.DictOf(key_schema=KEYID_SCHEMA, value_schema=pubkey_schema))) # Any subclass of `securesystemslib.schema.Object` stores the schemas that # define the attributes of the object in its `_required` property, even if # such a schema is of type `Optional`. # TODO: Find a way that does not require to access a protected member schema._required.append(subkey_schema_tuple) # pylint: disable=protected-access return schema
ISO8601_DATETIME_SCHEMA = SCHEMA.RegularExpression( r'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z') # A Unix/POSIX time format. An integer representing the number of seconds # since the epoch (January 1, 1970.) Metadata uses this format for the # 'expires' field. Set 'hi' to the upper timestamp limit (year 2038), the max # value of an int. UNIX_TIMESTAMP_SCHEMA = SCHEMA.Integer(lo=0, hi=2147483647) # A hexadecimal value in '23432df87ab..' format. HEX_SCHEMA = SCHEMA.RegularExpression(r'[a-fA-F0-9]+') HASH_SCHEMA = HEX_SCHEMA # A dict in {'sha256': '23432df87ab..', 'sha512': '34324abc34df..', ...} format. HASHDICT_SCHEMA = SCHEMA.DictOf(key_schema=SCHEMA.AnyString(), value_schema=HASH_SCHEMA) # Uniform Resource Locator identifier (e.g., 'https://www.updateframework.com/'). # TODO: Some level of restriction here would be good.... Note that I pulled # this from securesystemslib, since it's neither sophisticated nor used # by anyone else. URL_SCHEMA = SCHEMA.AnyString() # A key identifier (e.g., a hexadecimal value identifying an RSA key). KEYID_SCHEMA = HASH_SCHEMA # A list of KEYID_SCHEMA. KEYIDS_SCHEMA = SCHEMA.ListOf(KEYID_SCHEMA) # The signing scheme used by a key to generate a signature (e.g., # 'rsassa-pss-sha256' is one of the signing schemes for key type 'rsa').
<Author> Lukas Puehringer <*****@*****.**> Santiago Torres-Arias <*****@*****.**> <Started> November 28, 2017. <Copyright> See LICENSE for licensing information. <Purpose> Format schemas for in-toto metadata, based on securesystemslib.schema. The schemas can be verified using the following methods inherited from securesystemslib.schema: in_toto.formats.<SCHEMA>.check_match(<object to verify>) in_toto.formats.<SCHEMA>.matches(<object to verify>) `check_match` raises a securesystemslib.exceptions.FormatError and `matches` returns False if the verified object does not match the schema (True otherwise). """ import securesystemslib.schema as ssl_schema # pylint: disable=bad-whitespace PARAMETER_DICTIONARY_KEY = ssl_schema.RegularExpression(r'[a-zA-Z0-9_-]+') PARAMETER_DICTIONARY_SCHEMA = ssl_schema.DictOf( key_schema=PARAMETER_DICTIONARY_KEY, value_schema=ssl_schema.AnyString())
# Role object in {'keyids': [keydids..], 'name': 'ABC', 'threshold': 1, # 'paths':[filepaths..]} format. # TODO: This is not a role. In further #660-related PRs, fix it, similar to # the way I did in Uptane's TUF fork. ROLE_SCHEMA = SCHEMA.Object( object_name='ROLE_SCHEMA', name=SCHEMA.Optional(ROLENAME_SCHEMA), keyids=sslib_formats.KEYIDS_SCHEMA, threshold=THRESHOLD_SCHEMA, terminating=SCHEMA.Optional(sslib_formats.BOOLEAN_SCHEMA), paths=SCHEMA.Optional(RELPATHS_SCHEMA), path_hash_prefixes=SCHEMA.Optional(PATH_HASH_PREFIXES_SCHEMA)) # A dict of roles where the dict keys are role names and the dict values holding # the role data/information. ROLEDICT_SCHEMA = SCHEMA.DictOf(key_schema=ROLENAME_SCHEMA, value_schema=ROLE_SCHEMA) # A dictionary of ROLEDICT, where dictionary keys can be repository names, and # dictionary values containing information for each role available on the # repository (corresponding to the repository belonging to named repository in # the dictionary key) ROLEDICTDB_SCHEMA = SCHEMA.DictOf(key_schema=sslib_formats.NAME_SCHEMA, value_schema=ROLEDICT_SCHEMA) # Command argument list, as used by the CLI tool. # Example: {'keytype': ed25519, 'expires': 365,} COMMAND_SCHEMA = SCHEMA.DictOf(key_schema=sslib_formats.NAME_SCHEMA, value_schema=SCHEMA.Any()) # A dictionary holding version information. VERSION_SCHEMA = SCHEMA.Object(object_name='VERSION_SCHEMA',
# Role object in {'keyids': [keydids..], 'name': 'ABC', 'threshold': 1, # 'paths':[filepaths..]} format. # TODO: This is not a role. In further #660-related PRs, fix it, similar to # the way I did in Uptane's TUF fork. ROLE_SCHEMA = SCHEMA.Object( object_name='ROLE_SCHEMA', name=SCHEMA.Optional(ROLENAME_SCHEMA), keyids=securesystemslib.formats.KEYIDS_SCHEMA, threshold=THRESHOLD_SCHEMA, terminating=SCHEMA.Optional(securesystemslib.formats.BOOLEAN_SCHEMA), paths=SCHEMA.Optional(RELPATHS_SCHEMA), path_hash_prefixes=SCHEMA.Optional(PATH_HASH_PREFIXES_SCHEMA)) # A dict of roles where the dict keys are role names and the dict values holding # the role data/information. ROLEDICT_SCHEMA = SCHEMA.DictOf(key_schema=ROLENAME_SCHEMA, value_schema=ROLE_SCHEMA) # A dictionary of ROLEDICT, where dictionary keys can be repository names, and # dictionary values containing information for each role available on the # repository (corresponding to the repository belonging to named repository in # the dictionary key) ROLEDICTDB_SCHEMA = SCHEMA.DictOf( key_schema=securesystemslib.formats.NAME_SCHEMA, value_schema=ROLEDICT_SCHEMA) # Command argument list, as used by the CLI tool. # Example: {'keytype': ed25519, 'expires': 365,} COMMAND_SCHEMA = SCHEMA.DictOf(key_schema=securesystemslib.formats.NAME_SCHEMA, value_schema=SCHEMA.Any()) # A dictionary holding version information.
`check_match` raises a securesystemslib.exceptions.FormatError and `matches` returns False if the verified object does not match the schema (True otherwise). """ import in_toto.gpg.formats as gpg_formats import securesystemslib.schema as ssl_schema import securesystemslib.formats as ssl_formats # Note: Verification keys can have private portions but in case of GPG we # only have a PUBKEY_SCHEMA (because we never export private gpg keys from # the gpg keyring) ANY_VERIFICATION_KEY_SCHEMA = ssl_schema.OneOf( [ssl_formats.ANYKEY_SCHEMA, gpg_formats.PUBKEY_SCHEMA]) ANY_VERIFICATION_KEY_DICT_SCHEMA = ssl_schema.DictOf( key_schema=ssl_formats.KEYID_SCHEMA, value_schema=ANY_VERIFICATION_KEY_SCHEMA) ANY_PUBKEY_SCHEMA = ssl_schema.OneOf( [ssl_formats.PUBLIC_KEY_SCHEMA, gpg_formats.PUBKEY_SCHEMA]) ANY_PUBKEY_DICT_SCHEMA = ssl_schema.DictOf(key_schema=ssl_formats.KEYID_SCHEMA, value_schema=ANY_PUBKEY_SCHEMA) ANY_SIGNATURE_SCHEMA = ssl_schema.OneOf( [ssl_formats.SIGNATURE_SCHEMA, gpg_formats.SIGNATURE_SCHEMA]) ANY_STRING_SCHEMA = ssl_schema.AnyString() LIST_OF_ANY_STRING_SCHEMA = ssl_schema.ListOf(ANY_STRING_SCHEMA)
returns False if the verified object does not match the schema (True otherwise). """ import in_toto.gpg.formats as gpg_formats import securesystemslib.schema as ssl_schema import securesystemslib.formats as ssl_formats # Note: Verification keys can have private portions but in case of GPG we # only have a PUBKEY_SCHEMA (because we never export private gpg keys from # the gpg keyring) ANY_VERIFICATION_KEY_SCHEMA = ssl_schema.OneOf( [ssl_formats.ANYKEY_SCHEMA, gpg_formats.PUBKEY_SCHEMA]) ANY_VERIFICATION_KEY_DICT_SCHEMA = ssl_schema.DictOf( key_schema=ssl_formats.KEYID_SCHEMA, value_schema=ANY_VERIFICATION_KEY_SCHEMA) ANY_PUBKEY_SCHEMA = ssl_schema.OneOf( [ssl_formats.PUBLIC_KEY_SCHEMA, gpg_formats.PUBKEY_SCHEMA]) ANY_PUBKEY_DICT_SCHEMA = ssl_schema.DictOf(key_schema=ssl_formats.KEYID_SCHEMA, value_schema=ANY_PUBKEY_SCHEMA) ANY_SIGNATURE_SCHEMA = ssl_schema.OneOf( [ssl_formats.SIGNATURE_SCHEMA, gpg_formats.SIGNATURE_SCHEMA]) ANY_STRING_SCHEMA = ssl_schema.AnyString() LIST_OF_ANY_STRING_SCHEMA = ssl_schema.ListOf(ANY_STRING_SCHEMA) PARAMETER_DICTIONARY_KEY = ssl_schema.RegularExpression(r'[a-zA-Z0-9_-]+')
# supported.) Example: '2015-10-21T13:20:00Z'. Note: This is a simple format # check, and an ISO8601 string should be fully verified when it is parsed. ISO8601_DATETIME_SCHEMA = SCHEMA.RegularExpression( r'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z') # A Unix/POSIX time format. An integer representing the number of seconds # since the epoch (January 1, 1970.) Metadata uses this format for the # 'expires' field. Set 'hi' to the upper timestamp limit (year 2038), the max # value of an int. UNIX_TIMESTAMP_SCHEMA = SCHEMA.Integer(lo=0, hi=2147483647) # A hexadecimal value in '23432df87ab..' format. HASH_SCHEMA = SCHEMA.RegularExpression(r'[a-fA-F0-9]+') # A dict in {'sha256': '23432df87ab..', 'sha512': '34324abc34df..', ...} format. HASHDICT_SCHEMA = SCHEMA.DictOf(key_schema=SCHEMA.AnyString(), value_schema=HASH_SCHEMA) # A hexadecimal value in '23432df87ab..' format. HEX_SCHEMA = SCHEMA.RegularExpression(r'[a-fA-F0-9]+') # A key identifier (e.g., a hexadecimal value identifying an RSA key). KEYID_SCHEMA = HASH_SCHEMA # A list of KEYID_SCHEMA. KEYIDS_SCHEMA = SCHEMA.ListOf(KEYID_SCHEMA) # The signing scheme used by a key to generate a signature (e.g., # 'rsassa-pss-sha256' is one of the signing schemes for key type 'rsa'). SCHEME_SCHEMA = SCHEMA.AnyString() # A relative file path (e.g., 'metadata/root/').