Files
compliance-scan/tests/iana/test_iana_parser.py
Heiko f60de7c2da Add SSH scan support with BSI TR-02102-4 compliance
- SSH scanning via ssh-audit (KEX, encryption, MAC, host keys)
- BSI TR-02102-4 and IANA compliance validation for SSH
- CSV/Markdown/reST reports for SSH results
- Unified compliance schema and database views
- Code optimization: modular query/writer architecture
2026-01-23 11:05:01 +01:00

203 lines
7.1 KiB
Python

"""Tests for IANA XML parsing functionality."""
import xml.etree.ElementTree as ET
import pytest
from sslysze_scan.iana_parser import (
extract_field_value,
find_registry,
get_element_text,
is_unassigned,
parse_xml_with_namespace_support,
process_xref_elements,
)
class TestParseXmlWithNamespace:
"""Tests for XML parsing with namespace detection."""
def test_parse_tls_parameters_with_namespace(self) -> None:
"""Test parsing TLS parameters XML with IANA namespace."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
root, ns = parse_xml_with_namespace_support(xml_path)
assert root is not None
assert ns is not None
assert "iana" in ns
assert ns["iana"] == "http://www.iana.org/assignments"
def test_parse_nonexistent_file(self) -> None:
"""Test that parsing nonexistent file raises FileNotFoundError."""
with pytest.raises(FileNotFoundError):
parse_xml_with_namespace_support("nonexistent.xml")
class TestFindRegistry:
"""Tests for finding registry by ID."""
def test_find_cipher_suites_registry(self) -> None:
"""Test finding TLS cipher suites registry."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
root, ns = parse_xml_with_namespace_support(xml_path)
registry = find_registry(root, "tls-parameters-4", ns)
assert registry is not None
assert registry.get("id") == "tls-parameters-4"
def test_find_nonexistent_registry(self) -> None:
"""Test that finding nonexistent registry raises ValueError."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
root, ns = parse_xml_with_namespace_support(xml_path)
with pytest.raises(ValueError, match="Registry with ID '.*' not found"):
find_registry(root, "nonexistent-registry", ns)
class TestGetElementText:
"""Tests for element text extraction."""
def test_get_element_text_with_namespace(self) -> None:
"""Test extracting text from element with namespace."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
root, ns = parse_xml_with_namespace_support(xml_path)
registry = find_registry(root, "tls-parameters-4", ns)
records = registry.findall("iana:record", ns)
first_record = records[0]
value = get_element_text(first_record, "value", ns)
assert value == "0x13,0x01"
description = get_element_text(first_record, "description", ns)
assert description == "TLS_AES_128_GCM_SHA256"
def test_get_element_text_nonexistent(self) -> None:
"""Test that nonexistent element returns empty string."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
root, ns = parse_xml_with_namespace_support(xml_path)
registry = find_registry(root, "tls-parameters-4", ns)
records = registry.findall("iana:record", ns)
first_record = records[0]
result = get_element_text(first_record, "nonexistent", ns)
assert result == ""
class TestProcessXrefElements:
"""Tests for xref element processing."""
def test_process_single_xref(self) -> None:
"""Test processing single xref element."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
root, ns = parse_xml_with_namespace_support(xml_path)
registry = find_registry(root, "tls-parameters-4", ns)
records = registry.findall("iana:record", ns)
first_record = records[0]
xref_str = process_xref_elements(first_record, ns)
assert "rfc:rfc8446" in xref_str
def test_process_no_xref(self) -> None:
"""Test processing record without xref elements."""
xml_str = """
<record xmlns="http://www.iana.org/assignments">
<value>0x13,0x01</value>
<description>Test</description>
</record>
"""
record = ET.fromstring(xml_str)
ns = {"iana": "http://www.iana.org/assignments"}
xref_str = process_xref_elements(record, ns)
assert xref_str == ""
class TestExtractFieldValue:
"""Tests for field value extraction."""
def test_extract_recommended_field(self) -> None:
"""Test extracting Recommended field."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
root, ns = parse_xml_with_namespace_support(xml_path)
registry = find_registry(root, "tls-parameters-4", ns)
records = registry.findall("iana:record", ns)
first_record = records[0]
rec = extract_field_value(first_record, "Recommended", ns)
assert rec == "Y"
def test_extract_rfc_draft_field(self) -> None:
"""Test extracting RFC/Draft field via xref processing."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
root, ns = parse_xml_with_namespace_support(xml_path)
registry = find_registry(root, "tls-parameters-4", ns)
records = registry.findall("iana:record", ns)
first_record = records[0]
rfc_draft = extract_field_value(first_record, "RFC/Draft", ns)
assert "rfc:rfc8446" in rfc_draft
class TestExtractUpdatedDate:
"""Tests for extracting updated date from XML."""
def test_extract_updated_from_tls_xml(self) -> None:
"""Test extracting updated date from TLS parameters XML."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
with open(xml_path, encoding="utf-8") as f:
xml_content = f.read()
lines = xml_content.split("\n")[:10]
updated_line = [line for line in lines if "<updated>" in line]
assert len(updated_line) == 1
assert "2025-12-03" in updated_line[0]
class TestIsUnassigned:
"""Tests for unassigned entry detection."""
def test_is_unassigned_numeric_range(self) -> None:
"""Test detection of numeric range values."""
xml_str = """
<record xmlns="http://www.iana.org/assignments">
<value>42-255</value>
<description>Unassigned</description>
</record>
"""
record = ET.fromstring(xml_str)
ns = {"iana": "http://www.iana.org/assignments"}
assert is_unassigned(record, ns) is True
def test_is_unassigned_hex_range(self) -> None:
"""Test detection of hex range values."""
xml_str = """
<record xmlns="http://www.iana.org/assignments">
<value>0x0000-0x0200</value>
<description>Reserved for backward compatibility</description>
</record>
"""
record = ET.fromstring(xml_str)
ns = {"iana": "http://www.iana.org/assignments"}
assert is_unassigned(record, ns) is True
def test_is_unassigned_false(self) -> None:
"""Test that assigned entries return False."""
xml_path = "tests/fixtures/iana_xml/tls-parameters-minimal.xml"
root, ns = parse_xml_with_namespace_support(xml_path)
registry = find_registry(root, "tls-parameters-4", ns)
records = registry.findall("iana:record", ns)
first_record = records[0]
assert is_unassigned(first_record, ns) is False