Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions tests/test_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,31 @@ def test_format_keyval_to_metadata(self):
self.assertRaises(tuf.FormatError, KEYS.format_keyval_to_metadata,
keytype, keyvalue)
keyvalue['public'] = public



def test_format_rsakey_from_pem(self):
pem = self.rsakey_dict['keyval']['public']
rsa_key = KEYS.format_rsakey_from_pem(pem)

# Check if the format of the object returned by this function corresponds
# to 'tuf.formats.RSAKEY_SCHEMA' format.
self.assertTrue(tuf.formats.RSAKEY_SCHEMA.matches(rsa_key))

# Verify whitespace is stripped.
self.assertEqual(rsa_key, KEYS.format_rsakey_from_pem(pem + '\n'))

# Supplying a 'bad_pem' argument.
self.assertRaises(tuf.FormatError, KEYS.format_rsakey_from_pem, 'bad_pem')

# Supplying an improperly formatted PEM.
# Strip the PEM header and footer.
pem_header = '-----BEGIN PUBLIC KEY-----'
pem_footer= '-----END PUBLIC KEY-----'
self.assertRaises(tuf.FormatError, KEYS.format_rsakey_from_pem,
pem[:len(pem_footer)])
self.assertRaises(tuf.FormatError, KEYS.format_rsakey_from_pem,
pem[len(pem_header):])



Expand Down
45 changes: 37 additions & 8 deletions tuf/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ def format_rsakey_from_pem(pem):

{'keytype': 'rsa',
'keyid': keyid,
'keyval': {'public': '-----BEGIN RSA PUBLIC KEY----- ...',
'keyval': {'public': '-----BEGIN PUBLIC KEY----- ...',
'private': ''}}

The public portion of the RSA key is a string in PEM format.
Expand All @@ -997,7 +997,9 @@ def format_rsakey_from_pem(pem):
tuf.FormatError, if 'pem' is improperly formatted.

<Side Effects>
None.
Only the public portion of the PEM is extracted. Leading or trailing
whitespace is not included in the PEM string stored in the rsakey object
returned.

<Returns>
A dictionary containing the RSA keys and other identifying information.
Expand All @@ -1010,16 +1012,43 @@ def format_rsakey_from_pem(pem):
# Raise 'tuf.FormatError' if the check fails.
tuf.formats.PEMRSA_SCHEMA.check_match(pem)

# Ensure the PEM string starts with the required number of dashes. Although
# a simple validation of 'pem' is performed here, a fully valid PEM string is
# needed to successfully verify signatures.
if not pem.startswith('-----'):
raise tuf.FormatError('The PEM string argument is improperly formatted.')
# Ensure the PEM string has a valid header and footer. Although a simple
# validation of 'pem' is performed here, a fully valid PEM string is
# needed to later successfully verify signatures.
pem_header = '-----BEGIN PUBLIC KEY-----'
pem_footer = '-----END PUBLIC KEY-----'
header_start = 0
footer_start = 0

# Raise error message if the expected header or footer is not found in 'pem'.
try:
header_start = pem.index(pem_header)

except ValueError:
message = \
'Required PEM header ' + repr(pem_header) + '\n not found in PEM' + \
' string: ' + repr(pem)
raise tuf.FormatError(message)

try:
# Search for 'pem_footer' after the PEM header.
footer_start = pem.index(pem_footer, header_start + len(pem_header))

except ValueError:
message = \
'Required PEM footer ' + repr(pem_footer) + '\n not found in PEM' + \
' string ' + repr(pem)
raise tuf.FormatError(message)

# Extract only the public portion of 'pem'. Leading or trailing whitespace
# is not included.
public_pem = pem[header_start:footer_start + len(pem_footer)]


# Begin building the RSA key dictionary.
rsakey_dict = {}
keytype = 'rsa'
public = pem
public = public_pem

# Generate the keyid of the RSA key. 'key_value' corresponds to the
# 'keyval' entry of the 'RSAKEY_SCHEMA' dictionary. The private key
Expand Down