blob: db9857c19f21eef0b9a54de26f23493a816e9e21 [file] [log] [blame]
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
import unittest
import sys
import os
from asn1crypto import pem, util
from .unittest_data import data_decorator, data
from ._unittest_compat import patch
patch()
if sys.version_info < (3,):
byte_cls = str
num_cls = long # noqa
else:
byte_cls = bytes
num_cls = int
tests_root = os.path.dirname(__file__)
fixtures_dir = os.path.join(tests_root, 'fixtures')
@data_decorator
class PEMTests(unittest.TestCase):
@staticmethod
def detect_files():
return (
(
'keys/test-der.crt',
False
),
(
'keys/test-inter-der.crt',
False
),
(
'keys/test-third-der.crt',
False
),
(
'keys/test.crt',
True
),
(
'keys/test-inter.crt',
True
),
(
'keys/test-third.crt',
True
),
)
@data('detect_files')
def detect(self, relative_path, is_pem):
with open(os.path.join(fixtures_dir, relative_path), 'rb') as f:
byte_string = f.read()
self.assertEqual(is_pem, pem.detect(byte_string))
@staticmethod
def unarmor_armor_files():
return (
(
'keys/test.crt',
'keys/test-der.crt',
'CERTIFICATE',
{}
),
(
'keys/test-inter.crt',
'keys/test-inter-der.crt',
'CERTIFICATE',
{}
),
(
'keys/test-third.crt',
'keys/test-third-der.crt',
'CERTIFICATE',
{}
),
(
'keys/test-pkcs8.key',
'keys/test-pkcs8-der.key',
'PRIVATE KEY',
{}
),
(
'test-third.csr',
'test-third-der.csr',
'CERTIFICATE REQUEST',
{}
),
(
'keys/test-aes128.key',
'keys/test-aes128-der.key',
'RSA PRIVATE KEY',
util.OrderedDict([
('Proc-Type', '4,ENCRYPTED'),
('DEK-Info', 'AES-128-CBC,01F6EE04516C912788B11BD7377626C2')
])
),
)
@data('unarmor_armor_files')
def unarmor(self, relative_path, expected_bytes_filename, expected_type_name, expected_headers):
with open(os.path.join(fixtures_dir, relative_path), 'rb') as f:
byte_string = f.read()
type_name, headers, decoded_bytes = pem.unarmor(byte_string)
self.assertEqual(expected_type_name, type_name)
self.assertEqual(expected_headers, headers)
with open(os.path.join(fixtures_dir, expected_bytes_filename), 'rb') as f:
expected_bytes = f.read()
self.assertEqual(expected_bytes, decoded_bytes)
def test_unarmor_multiple(self):
data = self.unarmor_armor_files()
input_data = b''
der_data = []
for pem_file, der_file in ((data[0][0], data[0][1]), (data[1][0], data[1][1])):
with open(os.path.join(fixtures_dir, pem_file), 'rb') as f:
input_data += f.read() + b'\n'
with open(os.path.join(fixtures_dir, der_file), 'rb') as f:
der_data.append(f.read())
i = 0
for name, headers, der_bytes in pem.unarmor(input_data, True):
self.assertEqual('CERTIFICATE', name)
self.assertEqual({}, headers)
self.assertEqual(der_data[i], der_bytes)
i += 1
self.assertEqual(2, i)
@data('unarmor_armor_files')
def armor(self, expected_bytes_filename, relative_path, type_name, headers):
with open(os.path.join(fixtures_dir, relative_path), 'rb') as f:
byte_string = f.read()
encoded_bytes = pem.armor(type_name, byte_string, headers=headers)
with open(os.path.join(fixtures_dir, expected_bytes_filename), 'rb') as f:
expected_bytes = f.read()
# In case a user on Windows has CRLF translation on in Git.
# Ran into this with the GitHub Actions Windows environments.
expected_bytes = expected_bytes.replace(b'\r\n', b'\n')
self.assertEqual(expected_bytes, encoded_bytes)
def test_armor_wrong_type(self):
with self.assertRaisesRegex(TypeError, 'type_name must be a unicode string'):
pem.armor(b'CERTIFICATE', b'')
def test_armor_wrong_type2(self):
with self.assertRaisesRegex(TypeError, 'der_bytes must be a byte string'):
pem.armor('CERTIFICATE', '')
def test_detect_wrong_type(self):
with self.assertRaisesRegex(TypeError, 'byte_string must be a byte string'):
pem.detect('CERTIFICATE')