diff --git a/tuf/rsa_key.py b/tuf/rsa_key.py index 634abf71..1b825640 100755 --- a/tuf/rsa_key.py +++ b/tuf/rsa_key.py @@ -502,17 +502,16 @@ def create_encrypted_pem(rsakey_dict, passphrase): passphrase: The passphrase, or password, to encrypt the private part of the RSA - key. 'passphrase' is not used directly as the encryption key, but used - to derive a stronger encryption key. + key. 'passphrase' is not used directly as the encryption key, a stronger + encryption key is derived from it. TypeError, if a private key is not defined for 'rsakey_dict'. - tuf.FormatError, if an incorrect format is found for the - 'rsakey_dict' object. + tuf.FormatError, if an incorrect format is found for 'rsakey_dict'. - PyCrypto's 'Crypto.PublicKey.RSA.exportKey()' called to perform the actual + PyCrypto's Crypto.PublicKey.RSA.exportKey() called to perform the actual generation of the PEM-formatted output. @@ -608,7 +607,7 @@ def create_from_encrypted_pem(encrypted_pem, passphrase): try: rsa_key_object = Crypto.PublicKey.RSA.importKey(encrypted_pem, passphrase) except (ValueError, IndexError, TypeError), e: - message = 'An RSA key object could not be generated from the encrypted'+\ + message = 'An RSA key object could not be generated from the encrypted '+\ 'PEM string.' raise tuf.CryptoError(message) diff --git a/tuf/tests/test_rsa_key.py b/tuf/tests/test_rsa_key.py index 09a38663..881ee1d7 100755 --- a/tuf/tests/test_rsa_key.py +++ b/tuf/tests/test_rsa_key.py @@ -183,6 +183,75 @@ def test_verify_signature(self): self.assertRaises(TypeError,RSA_KEY.verify_signature) + def test_create_encrypted_pem(self): + passphrase = 'pw' + + # Check format of 'rsakey_dict'. + self.assertEqual(None, tuf.formats.RSAKEY_SCHEMA.check_match(rsakey_dict), + FORMAT_ERROR_MSG) + + # Check format of 'passphrase'. + self.assertEqual(None, tuf.formats.PASSWORD_SCHEMA.check_match(passphrase), + FORMAT_ERROR_MSG) + + # Generate the encrypted PEM string of 'rsakey_dict'. + pem_rsakey = tuf.rsa_key.create_encrypted_pem(rsakey_dict, passphrase) + + # Check for invalid arguments. + self.assertRaises(tuf.FormatError, + tuf.rsa_key.create_encrypted_pem, 'Biff', passphrase) + self.assertRaises(tuf.FormatError, + tuf.rsa_key.create_encrypted_pem, rsakey_dict, ['pw']) + + + + def test_create_from_encrypted_pem(self): + passphrase = 'pw' + + # Check format of 'rsakey_dict'. + self.assertEqual(None, tuf.formats.RSAKEY_SCHEMA.check_match(rsakey_dict), + FORMAT_ERROR_MSG) + + # Check format of 'passphrase'. + self.assertEqual(None, tuf.formats.PASSWORD_SCHEMA.check_match(passphrase), + FORMAT_ERROR_MSG) + + # Generate the encrypted PEM string of 'rsakey_dict'. + pem_rsakey = tuf.rsa_key.create_encrypted_pem(rsakey_dict, passphrase) + + # Decrypt 'pem_rsakey' and verify the decrypted object is properly + # formatted. + decrypted_rsakey = tuf.rsa_key.create_from_encrypted_pem(pem_rsakey, + passphrase) + self.assertEqual(None, tuf.formats.RSAKEY_SCHEMA.check_match(decrypted_rsakey), + FORMAT_ERROR_MSG) + + # Does 'decrypted_rsakey' match the original 'rsakey_dict'. + self.assertEqual(rsakey_dict, decrypted_rsakey) + + # Attempt decryption of 'pem_rsakey' using an incorrect passphrase. + self.assertRaises(tuf.CryptoError, + tuf.rsa_key.create_from_encrypted_pem, pem_rsakey, + 'bad_pw') + # Check for non-encrypted PEM string. create_from_encrypted_pem()/PyCrypto + # returns a tuf.formats.RSAKEY_SCHEMA object if PEM formatted string is + # not actually encrypted but still a valid PEM string. + non_encrypted_private_key = rsakey_dict['keyval']['private'] + decrypted_non_encrypted = tuf.rsa_key.create_from_encrypted_pem( + non_encrypted_private_key, passphrase) + self.assertEqual(None, tuf.formats.RSAKEY_SCHEMA.check_match( + decrypted_non_encrypted), FORMAT_ERROR_MSG) + + # Check for invalid arguments. + self.assertRaises(tuf.FormatError, + tuf.rsa_key.create_from_encrypted_pem, 123, passphrase) + self.assertRaises(tuf.FormatError, + tuf.rsa_key.create_from_encrypted_pem, pem_rsakey, ['pw']) + self.assertRaises(tuf.CryptoError, + tuf.rsa_key.create_from_encrypted_pem, 'invalid_pem', + passphrase) + + # Run the unit tests. if __name__ == '__main__':