- 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
180 lines
7.5 KiB
Python
180 lines
7.5 KiB
Python
"""Targeted test for specific compliance checking issues."""
|
|
|
|
import os
|
|
import tempfile
|
|
from datetime import UTC, datetime
|
|
from pathlib import Path
|
|
|
|
from sslysze_scan.db.compliance import check_compliance
|
|
from sslysze_scan.db.writer import write_scan_results
|
|
|
|
|
|
def test_specific_known_compliant_elements():
|
|
"""Test that specifically known compliant elements are correctly identified as compliant.
|
|
|
|
This test verifies that specific, known compliant SSH and TLS elements
|
|
are correctly matched against BSI/IANA compliance rules.
|
|
"""
|
|
# Use the template database for this test
|
|
import shutil
|
|
|
|
template_db = (
|
|
Path(__file__).parent.parent.parent
|
|
/ "src"
|
|
/ "sslysze_scan"
|
|
/ "data"
|
|
/ "crypto_standards.db"
|
|
)
|
|
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as temp_db:
|
|
db_path = temp_db.name
|
|
# Copy the template database to use as our test database
|
|
shutil.copy2(template_db, db_path)
|
|
|
|
try:
|
|
# Create scan results with specifically known compliant elements that exist in the databases
|
|
scan_results = {
|
|
22: {
|
|
# These are known to be compliant with BSI standards (from bsi_tr_02102_4_ssh_kex table)
|
|
"kex_algorithms": ["ecdh-sha2-nistp256", "diffie-hellman-group16-sha512"],
|
|
"encryption_algorithms_client_to_server": [
|
|
"chacha20-poly1305@openssh.com", # From IANA list
|
|
"aes256-ctr", # From IANA list
|
|
],
|
|
"encryption_algorithms_server_to_client": [
|
|
"chacha20-poly1305@openssh.com",
|
|
"aes256-ctr",
|
|
],
|
|
"mac_algorithms_client_to_server": [
|
|
"hmac-sha2-256",
|
|
"hmac-sha2-512",
|
|
], # From IANA list
|
|
"mac_algorithms_server_to_client": ["hmac-sha2-256", "hmac-sha2-512"],
|
|
"host_keys": [
|
|
{
|
|
"algorithm": "rsa-sha2-512", # From BSI list
|
|
"type": "rsa",
|
|
"bits": 4096,
|
|
"fingerprint": "aa:bb:cc:dd:ee:ff:gg:hh:ii:jj:kk:ll:mm:nn:oo:pp",
|
|
},
|
|
{
|
|
"algorithm": "ecdsa-sha2-nistp256", # From BSI list
|
|
"type": "ecdsa",
|
|
"bits": 256,
|
|
"fingerprint": "qq:rr:ss:tt:uu:vv:ww:xx:yy:zz:aa:bb:cc:dd:ee:ff",
|
|
},
|
|
],
|
|
},
|
|
443: {
|
|
"tls_versions": ["TLS_1_2", "TLS_1_3"],
|
|
"cipher_suites": {
|
|
"TLS_1_3": [
|
|
"TLS_AES_256_GCM_SHA384",
|
|
"TLS_CHACHA20_POLY1305_SHA256",
|
|
], # From IANA list
|
|
"TLS_1_2": [
|
|
"ECDHE-RSA-AES256-GCM-SHA384", # From IANA list
|
|
"ECDHE-RSA-AES128-GCM-SHA256",
|
|
],
|
|
},
|
|
"supported_groups": [
|
|
"X25519",
|
|
"secp256r1",
|
|
"secp384r1",
|
|
], # From IANA list
|
|
"certificates": [
|
|
{
|
|
"subject": "CN=test.example.com",
|
|
"issuer": "CN=Test CA",
|
|
"key_type": "RSA",
|
|
"key_bits": 4096,
|
|
"signature_algorithm": "sha256WithRSAEncryption",
|
|
}
|
|
],
|
|
},
|
|
}
|
|
|
|
# Save scan results to database using the regular save function
|
|
scan_start_time = datetime.now(UTC)
|
|
scan_id = write_scan_results(
|
|
db_path,
|
|
"test.example.com",
|
|
[22, 443],
|
|
scan_results,
|
|
scan_start_time,
|
|
1.0, # duration
|
|
)
|
|
|
|
assert scan_id is not None
|
|
assert scan_id > 0
|
|
|
|
# Check compliance
|
|
compliance_results = check_compliance(db_path, scan_id)
|
|
|
|
# The test should fail if known compliant elements are not recognized as compliant
|
|
# This will highlight the specific issue with the compliance checking logic
|
|
|
|
print(
|
|
f"SSH KEX checked: {compliance_results['ssh_kex_checked']}, passed: {compliance_results['ssh_kex_passed']}"
|
|
)
|
|
print(
|
|
f"SSH Encryption checked: {compliance_results['ssh_encryption_checked']}, passed: {compliance_results['ssh_encryption_passed']}"
|
|
)
|
|
print(
|
|
f"SSH MAC checked: {compliance_results['ssh_mac_checked']}, passed: {compliance_results['ssh_mac_passed']}"
|
|
)
|
|
print(
|
|
f"SSH Host Keys checked: {compliance_results['ssh_host_keys_checked']}, passed: {compliance_results['ssh_host_keys_passed']}"
|
|
)
|
|
print(
|
|
f"Cipher suites checked: {compliance_results['cipher_suites_checked']}, passed: {compliance_results['cipher_suites_passed']}"
|
|
)
|
|
print(
|
|
f"Supported groups checked: {compliance_results['supported_groups_checked']}, passed: {compliance_results['supported_groups_passed']}"
|
|
)
|
|
|
|
# These assertions will fail if the compliance checking logic is not working correctly
|
|
# This is the targeted test for the specific issue
|
|
assert (
|
|
compliance_results["ssh_kex_checked"] == 0
|
|
or compliance_results["ssh_kex_passed"] > 0
|
|
), (
|
|
f"Known compliant SSH KEX methods should be recognized as compliant, but got {compliance_results['ssh_kex_passed']}/{compliance_results['ssh_kex_checked']} passed"
|
|
)
|
|
|
|
assert (
|
|
compliance_results["ssh_encryption_checked"] == 0
|
|
or compliance_results["ssh_encryption_passed"] > 0
|
|
), (
|
|
f"Known compliant SSH encryption algorithms should be recognized as compliant, but got {compliance_results['ssh_encryption_passed']}/{compliance_results['ssh_encryption_checked']} passed"
|
|
)
|
|
|
|
assert (
|
|
compliance_results["ssh_mac_checked"] == 0
|
|
or compliance_results["ssh_mac_passed"] > 0
|
|
), (
|
|
f"Known compliant SSH MAC algorithms should be recognized as compliant, but got {compliance_results['ssh_mac_passed']}/{compliance_results['ssh_mac_checked']} passed"
|
|
)
|
|
|
|
assert (
|
|
compliance_results["ssh_host_keys_checked"] == 0
|
|
or compliance_results["ssh_host_keys_passed"] > 0
|
|
), (
|
|
f"Known compliant SSH host keys should be recognized as compliant, but got {compliance_results['ssh_host_keys_passed']}/{compliance_results['ssh_host_keys_checked']} passed"
|
|
)
|
|
|
|
# For TLS elements, if they were checked, they should have some compliant ones
|
|
if compliance_results["cipher_suites_checked"] > 0:
|
|
assert compliance_results["cipher_suites_passed"] > 0, (
|
|
f"Known compliant cipher suites should be recognized as compliant, but got {compliance_results['cipher_suites_passed']}/{compliance_results['cipher_suites_checked']} passed"
|
|
)
|
|
|
|
if compliance_results["supported_groups_checked"] > 0:
|
|
assert compliance_results["supported_groups_passed"] > 0, (
|
|
f"Known compliant supported groups should be recognized as compliant, but got {compliance_results['supported_groups_passed']}/{compliance_results['supported_groups_checked']} passed"
|
|
)
|
|
|
|
finally:
|
|
# Clean up temporary database
|
|
if os.path.exists(db_path):
|
|
os.unlink(db_path)
|