def test_parse_corrupted_certificate(): chain_bytes = read_bytes('corrupted') key_bytes = read_bytes('2-key.pem') with pytest.raises(ParseCertificateError) as exception: X509Svid.parse(chain_bytes, key_bytes) assert str(exception.value) == 'Unable to parse PEM X.509 certificate.'
def test_parse_raw_missing_certificate(): chain_bytes = read_bytes('1-key.der') key_bytes = read_bytes('1-key.der') with pytest.raises(ParseCertificateError) as exception: X509Svid.parse_raw(chain_bytes, key_bytes) assert str(exception.value) == 'Unable to parse DER X.509 certificate.'
def test_parse_corrupted_private_key(): chain_bytes = read_bytes('2-chain.pem') key_bytes = read_bytes('corrupted') with pytest.raises(ParsePrivateKeyError) as exception: X509Svid.parse(chain_bytes, key_bytes) assert str(exception.value) == ( 'Error parsing private key: Could not deserialize key data. The data may be in an incorrect format ' 'or it may be encrypted with an unsupported algorithm.')
def test_parse_raw_corrupted_certificate(): chain_bytes = read_bytes('corrupted') key_bytes = read_bytes('1-key.der') with pytest.raises(ParseCertificateError) as exception: X509Svid.parse_raw(chain_bytes, key_bytes) assert (str( exception.value ) == 'Error parsing certificate: Unable to parse DER X.509 certificate.')
def test_load_non_supported_encoding(): chain_path = _TEST_CERTS_PATH.format('2-chain.pem') key_path = _TEST_CERTS_PATH.format('2-key.pem') with pytest.raises(ArgumentError) as err: X509Svid.load(chain_path, key_path, serialization.Encoding.OpenSSH) assert ( str(err.value) == 'Encoding not supported: Encoding.OpenSSH. Expected \'PEM\' or \'DER\'.' )
def test_parse_missing_certificate(): chain_bytes = read_bytes('2-key.pem') key_bytes = read_bytes('2-key.pem') with pytest.raises(ParseCertificateError) as exception: X509Svid.parse(chain_bytes, key_bytes) assert (str( exception.value ) == 'Error parsing certificate: Unable to parse PEM X.509 certificate.')
def test_parse_intermediate_no_ca(): chain_bytes = read_bytes('wrong-intermediate-no-ca.pem') key_bytes = read_bytes('2-key.pem') with pytest.raises(InvalidIntermediateCertificateError) as exception: X509Svid.parse(chain_bytes, key_bytes) assert ( str(exception.value) == 'Invalid intermediate certificate: Signing certificate must have CA flag set to true.' )
def test_parse_intermediate_no_key_cert_sign(): chain_bytes = read_bytes('wrong-intermediate-no-key-cert-sign.pem') key_bytes = read_bytes('2-key.pem') with pytest.raises(InvalidIntermediateCertificateError) as exception: X509Svid.parse(chain_bytes, key_bytes) assert ( str(exception.value) == 'Invalid intermediate certificate: Signing certificate must have \'keyCertSign\' as key usage.' )
def test_load_non_existent_key_bytes(): chain_path = _TEST_CERTS_PATH.format('2-chain.pem') key_path = 'no-exists' with pytest.raises(LoadPrivateKeyError) as exception: X509Svid.load(chain_path, key_path, serialization.Encoding.PEM) assert ( str(exception.value) == 'Error loading private key from file: Private key file not found: no-exists.' )
def test_parse_crl_sign(): chain_bytes = read_bytes('wrong-leaf-crl-sign.pem') key_bytes = read_bytes('2-key.pem') with pytest.raises(InvalidLeafCertificateError) as exception: X509Svid.parse(chain_bytes, key_bytes) assert ( str(exception.value) == 'Invalid leaf certificate: Leaf certificate must not have \'cRLSign\' as key usage.' )
def test_parse_no_digital_signature(): chain_bytes = read_bytes('wrong-leaf-no-digital-signature.pem') key_bytes = read_bytes('2-key.pem') with pytest.raises(InvalidLeafCertificateError) as exception: X509Svid.parse(chain_bytes, key_bytes) assert ( str(exception.value) == 'Invalid leaf certificate: Leaf certificate must have \'digitalSignature\' as key usage.' )
def test_parse_leaf_ca_true(): chain_bytes = read_bytes('wrong-leaf-ca-true.pem') key_bytes = read_bytes('2-key.pem') with pytest.raises(InvalidLeafCertificateError) as exception: X509Svid.parse(chain_bytes, key_bytes) assert ( str(exception.value) == 'Invalid leaf certificate: Leaf certificate must not have CA flag set to true.' )
def test_parse_invalid_spiffe_id(): chain_bytes = read_bytes('wrong-empty-spiffe-id.pem') key_bytes = read_bytes('2-key.pem') with pytest.raises(InvalidLeafCertificateError) as exception: X509Svid.parse(chain_bytes, key_bytes) assert ( str(exception.value) == 'Invalid leaf certificate: Certificate does not contain a SPIFFE ID in the URI SAN.' )
def test_load_non_existent_cert_file(): chain_path = 'no-exists' key_path = '2-key.pem' with pytest.raises(LoadCertificateError) as exception: X509Svid.load(chain_path, key_path, serialization.Encoding.PEM) assert ( str(exception.value) == 'Error loading certificate from file: Certificates file not found: no-exists.' )
def test_save_error_writing_x509_svid_to_file(mocker): mocker.patch('builtins.open', side_effect=Exception('Error msg'), autospect=True) mock_x509_svid = mocker.Mock(X509Svid) with pytest.raises(StoreCertificateError) as exception: X509Svid.save(mock_x509_svid, 'chain_file', 'key_file', serialization.Encoding.PEM) assert ( str(exception.value) == 'Error saving certificate to file: Error writing X.509 SVID to file: Error msg.' )
def test_save_non_supported_encoding(): chain_bytes = read_bytes('3-good-leaf-only.pem') key_bytes = read_bytes('3-key-pkcs8-rsa.pem') # create the X509Svid to be saved mock_x509_svid = X509Svid.parse(chain_bytes, key_bytes) with pytest.raises(ArgumentError) as err: X509Svid.save(mock_x509_svid, 'chain_file', 'key_file', serialization.Encoding.Raw) assert (str( err.value ) == 'Encoding not supported: Encoding.Raw. Expected \'PEM\' or \'DER\'.')
def test_save_error_writing_private_key_to_file(mocker): mocker.patch('pyspiffe.svid.x509_svid._write_x509_svid_to_file', autospect=True) mock_x509_svid = mocker.Mock(X509Svid) mock_private_key = mocker.Mock() mock_private_key.private_bytes.side_effect = Exception('Error msg') mock_x509_svid.private_key.return_value = mock_private_key with pytest.raises(X509SvidError) as exception: X509Svid.save(mock_x509_svid, 'chain_file', 'key_file', serialization.Encoding.PEM) assert (str(exception.value) == 'Could not extract private key bytes from object: Error msg.')
def test_save_error_extracting_private_key(mocker): mocker.patch('pyspiffe.svid.x509_svid._write_x509_svid_to_file', autospect=True) mocker.patch('builtins.open', side_effect=Exception('Error msg'), autospect=True) x509_svid = mocker.Mock(X509Svid) with pytest.raises(StorePrivateKeyError) as exception: X509Svid.save(x509_svid, 'chain_file', 'key_file', serialization.Encoding.PEM) assert ( str(exception.value) == 'Error saving private key to file: Could not write private key bytes to file: Error msg.' )
def _create_x509_svid(svid: workload_pb2.X509SVID) -> X509Svid: cert = svid.x509_svid key = svid.x509_svid_key try: return X509Svid.parse_raw(cert, key) except Exception as e: raise FetchX509SvidError(str(e))
def test_create_x509_svid_no_cert_chain(mocker): with pytest.raises(ArgumentError) as exc_info: X509Svid(spiffe_id=mocker.Mock(), cert_chain=[], private_key=mocker.Mock()) assert str(exc_info.value) == 'cert_chain cannot be empty.'
def test_create_x509_svid_no_private_key(mocker): with pytest.raises(ArgumentError) as exc_info: X509Svid(spiffe_id=mocker.Mock(), cert_chain=[mocker.Mock()], private_key=None) assert str(exc_info.value) == 'private_key cannot be None.'
def test_get_chain_returns_a_copy(): chain_bytes = read_bytes('1-chain.der') key_bytes = read_bytes('1-key.der') x509_svid = X509Svid.parse_raw(chain_bytes, key_bytes) assert x509_svid.cert_chain() is not x509_svid._cert_chain
def test_load_cannot_read_key_bytes(mocker): mocker.patch( 'pyspiffe.svid.x509_svid.load_certificates_bytes_from_file', return_value=b'bytes', autospect=True, ) mocker.patch('builtins.open', side_effect=Exception('Error msg'), autospect=True) with pytest.raises(LoadPrivateKeyError) as exception: X509Svid.load('chain_path', 'key-no-exists', serialization.Encoding.PEM) assert ( str(exception.value) == 'Error loading private key from file: Private key file could not be read: Error msg.' )
def test_parse_leaf_only_and_rsa_key(): chain_bytes = read_bytes('3-good-leaf-only.pem') key_bytes = read_bytes('3-key-pkcs8-rsa.pem') x509_svid = X509Svid.parse(chain_bytes, key_bytes) expected_spiffe_id = SpiffeId.parse('spiffe://example.org/workload-1') assert x509_svid.spiffe_id() == expected_spiffe_id assert len(x509_svid.cert_chain()) == 1 assert isinstance(x509_svid.leaf(), Certificate) assert isinstance(x509_svid.private_key(), rsa.RSAPrivateKey) assert _extract_spiffe_id(x509_svid.leaf()) == expected_spiffe_id
def test_parse_raw_chain_and_ec_key(): chain_bytes = read_bytes('1-chain.der') key_bytes = read_bytes('1-key.der') x509_svid = X509Svid.parse_raw(chain_bytes, key_bytes) expected_spiffe_id = SpiffeId.parse('spiffe://example.org/service') assert x509_svid.spiffe_id() == expected_spiffe_id assert len(x509_svid.cert_chain()) == 2 assert isinstance(x509_svid.leaf(), Certificate) assert isinstance(x509_svid.private_key(), ec.EllipticCurvePrivateKey) assert _extract_spiffe_id(x509_svid.leaf()) == expected_spiffe_id
def test_save_chain_and_rsa_key_as_der(tmpdir): chain_bytes = read_bytes('3-good-leaf-only.pem') key_bytes = read_bytes('3-key-pkcs8-rsa.pem') # create the X509Svid to be saved x509_svid = X509Svid.parse(chain_bytes, key_bytes) # temp files to store the certs and private_key chain_der_file = tmpdir.join('chain.der') key_der_file = tmpdir.join('key.der') x509_svid.save(chain_der_file, key_der_file, serialization.Encoding.DER) # now load the saved svid, and check that everything was stored correctly saved_svid = X509Svid.load(chain_der_file, key_der_file, serialization.Encoding.DER) expected_spiffe_id = SpiffeId.parse('spiffe://example.org/workload-1') assert saved_svid.spiffe_id() == expected_spiffe_id assert len(saved_svid.cert_chain()) == 1 assert isinstance(saved_svid.leaf(), Certificate) assert isinstance(saved_svid.private_key(), rsa.RSAPrivateKey) assert _extract_spiffe_id(saved_svid.leaf()) == expected_spiffe_id
def test_load_from_der_files(): chain_path = _TEST_CERTS_PATH.format('1-chain.der') key_path = _TEST_CERTS_PATH.format('1-key.der') x509_svid = X509Svid.load(chain_path, key_path, serialization.Encoding.DER) expected_spiffe_id = SpiffeId.parse('spiffe://example.org/service') assert x509_svid.spiffe_id() == expected_spiffe_id assert len(x509_svid.cert_chain()) == 2 assert isinstance(x509_svid.leaf(), Certificate) assert isinstance(x509_svid.cert_chain()[1], Certificate) assert isinstance(x509_svid.private_key(), ec.EllipticCurvePrivateKey) assert _extract_spiffe_id(x509_svid.leaf()) == expected_spiffe_id
def test_create_x509_svid(mocker): fake_spiffe_id = mocker.Mock() fake_cert_chain = [mocker.Mock()] fake_private_key = mocker.Mock() res = X509Svid( spiffe_id=fake_spiffe_id, cert_chain=fake_cert_chain, private_key=fake_private_key, ) assert res.spiffe_id() == fake_spiffe_id assert len(res.cert_chain()) == len(fake_cert_chain) assert res.private_key() == fake_private_key
def test_save_chain_and_ec_key_as_pem(tmpdir): chain_bytes = read_bytes('2-chain.pem') key_bytes = read_bytes('2-key.pem') # create the X509Svid to be saved x509_svid = X509Svid.parse(chain_bytes, key_bytes) # temp files to store the certs and private_key chain_pem_file = tmpdir.join('chain.pem') key_pem_file = tmpdir.join('key.pem') x509_svid.save(chain_pem_file, key_pem_file, serialization.Encoding.PEM) # now load the saved svid, and check that everything was stored correctly saved_svid = X509Svid.load(chain_pem_file, key_pem_file, serialization.Encoding.PEM) expected_spiffe_id = SpiffeId.parse('spiffe://example.org/service') assert saved_svid.spiffe_id() == expected_spiffe_id assert len(saved_svid.cert_chain()) == 2 assert isinstance(saved_svid.leaf(), Certificate) assert isinstance(x509_svid.cert_chain()[1], Certificate) assert isinstance(saved_svid.private_key(), ec.EllipticCurvePrivateKey) assert _extract_spiffe_id(saved_svid.leaf()) == expected_spiffe_id
def test_save_error_writing_x509_svid_to_file(mocker): chain_bytes = read_bytes('3-good-leaf-only.pem') key_bytes = read_bytes('3-key-pkcs8-rsa.pem') # create the X509Svid to be saved x509_svid = X509Svid.parse(chain_bytes, key_bytes) mocker.patch('builtins.open', side_effect=Exception('Error msg'), autospect=True) with pytest.raises(StoreCertificateError) as exception: x509_svid.save('chain_file', 'key_file', serialization.Encoding.PEM) assert ( str(exception.value) == 'Error saving certificate to file: Error writing X.509 SVID to file: Error msg.' )