Skip to content

Commit

Permalink
Add RFC7093 SKID calculation support
Browse files Browse the repository at this point in the history
  • Loading branch information
CBonnell committed Dec 15, 2023
1 parent 9639b42 commit e3af04b
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 17 deletions.
64 changes: 50 additions & 14 deletions pkilint/pkix/certificate/certificate_key.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import binascii

from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding, rsa, ec
from pyasn1.codec.der.encoder import encode
from pyasn1.type import univ
Expand Down Expand Up @@ -102,57 +103,92 @@ def __init__(self, *, decode_func, **kwargs):
)


def _calculate_method2_hash(sha1_hash):
last_8_octets = bytearray(sha1_hash[12:])
last_8_octets[0] = 0x40 | (last_8_octets[0] & 0xF)

return bytes(last_8_octets)


class SubjectKeyIdentifierValidator(validation.Validator):
VALIDATION_UNKNOWN_METHOD = validation.ValidationFinding(
validation.ValidationFindingSeverity.NOTICE,
'pkix.unknown_subject_key_identifier_calculation_method'
)

# TODO: consider renaming the finding code after weighing risk of user breakage
VALIDATION_METHOD_1 = validation.ValidationFinding(
validation.ValidationFindingSeverity.INFO,
'pkix.subject_key_identifier_method_1_identified'
)

# TODO: consider renaming the finding code after weighing risk of user breakage
VALIDATION_METHOD_2 = validation.ValidationFinding(
validation.ValidationFindingSeverity.INFO,
'pkix.subject_key_identifier_method_2_identified'
)

VALIDATION_RFC7093_METHOD_1 = validation.ValidationFinding(
validation.ValidationFindingSeverity.INFO,
'pkix_subject_key_identifier_rfc7093_method_1_identified'
)

VALIDATION_RFC7093_METHOD_2 = validation.ValidationFinding(
validation.ValidationFindingSeverity.INFO,
'pkix_subject_key_identifier_rfc7093_method_2_identified'
)

VALIDATION_RFC7093_METHOD_3 = validation.ValidationFinding(
validation.ValidationFindingSeverity.INFO,
'pkix_subject_key_identifier_rfc7093_method_3_identified'
)

def __init__(self):
super().__init__(
validations=[
self.VALIDATION_UNKNOWN_METHOD,
self.VALIDATION_METHOD_1,
self.VALIDATION_METHOD_2,
self.VALIDATION_RFC7093_METHOD_1,
self.VALIDATION_RFC7093_METHOD_2,
self.VALIDATION_RFC7093_METHOD_3,
],
pdu_class=rfc5280.SubjectKeyIdentifier
)

@staticmethod
def _calculate_rfc5280_method2_id(sha1_hash):
last_8_octets = bytearray(sha1_hash[12:])
last_8_octets[0] = 0x40 | (last_8_octets[0] & 0xF)

return bytes(last_8_octets)

_RFC7093_HASH_CLS_TO_FINDINGS = {
hashes.SHA256: VALIDATION_RFC7093_METHOD_1,
hashes.SHA384: VALIDATION_RFC7093_METHOD_2,
hashes.SHA512: VALIDATION_RFC7093_METHOD_3,
}

# TODO: support RFC 7093 method 4
@staticmethod
def _calculate_rfc7093_method_hash(public_key_octets, hash_cls):
h = util.calculate_hash(public_key_octets, hash_cls())

# leftmost 160 bits (i.e., 20 octets)
return h[:20]

def validate(self, node):
public_key_node = node.document.root.navigate(
'tbsCertificate.subjectPublicKeyInfo.subjectPublicKey'
)

public_key_bytes = public_key_node.pdu.asOctets()
public_key_sha1 = util.calculate_sha1_hash(public_key_bytes)

method2_hash = _calculate_method2_hash(public_key_sha1)
public_key_octets = public_key_node.pdu.asOctets()

identifier_octets = bytes(node.pdu)

if public_key_sha1 == identifier_octets:
public_key_sha1 = util.calculate_sha1_hash(public_key_octets)

if identifier_octets == public_key_sha1:
finding = self.VALIDATION_METHOD_1
elif method2_hash == identifier_octets:
elif identifier_octets == SubjectKeyIdentifierValidator._calculate_rfc5280_method2_id(public_key_sha1):
finding = self.VALIDATION_METHOD_2
else:
finding = self.VALIDATION_UNKNOWN_METHOD
finding = next((f for h, f in SubjectKeyIdentifierValidator._RFC7093_HASH_CLS_TO_FINDINGS.items() if
SubjectKeyIdentifierValidator._calculate_rfc7093_method_hash(
public_key_octets, h) == identifier_octets), self.VALIDATION_UNKNOWN_METHOD)

raise validation.ValidationFindingEncountered(finding)

Expand Down
6 changes: 3 additions & 3 deletions pkilint/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
from pkilint.report import report_wrapper, REPORT_FORMATS


def _calculate_hash(octets, hash_algo):
def calculate_hash(octets: bytes, hash_algo: hashes.HashAlgorithm) -> bytes:
h = hashes.Hash(hash_algo)
h.update(octets)

return h.finalize()


def calculate_sha1_hash(octets):
return _calculate_hash(octets, hashes.SHA1())
def calculate_sha1_hash(octets: bytes) -> bytes:
return calculate_hash(octets, hashes.SHA1())


def argparse_enum_type_parser(enum_type):
Expand Down
20 changes: 20 additions & 0 deletions tests/integration_certificate/pkix/rfc7093_method_1.crttest
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIICyjCCAlCgAwIBAgIQY1zINBzZ6YS8yyP57Ql/HjAKBggqhkjOPQQDAzBWMQsw
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
R3JvdXAxHDAaBgNVBAMTEyhGQUtFKSBJU1JHIFJvb3QgWDIwHhcNMjMwOTI1MDAw
MDAwWhcNMjYwOTI0MjM1OTU5WjBAMQswCQYDVQQGEwJVUzEdMBsGA1UEChMUKEZB
S0UpIExldCdzIEVuY3J5cHQxEjAQBgNVBAMTCShGQUtFKSBFNzB2MBAGByqGSM49
AgEGBSuBBAAiA2IABOn6Rxf8w7JMveol0MqmodXTPkxfQDCCuZIWo7NsL9nFSVrp
FNOajWXg1uxujC25VK62gNRP5OSoiAAnlZ6CUI6/cWWHF78QWyLk3SS6mrPrlBUl
TZr3DrFi67X4+R93GaOB+DCB9TAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYI
KwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYE
FLmhijFtd+cJnmo9dqY7HHRulw77MB8GA1UdIwQYMBaAFDnxnbEOFolx9/jcKlXc
CcyDWni7MDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3gyLmku
bGVuY3Iub3JnLzATBgNVHSAEDDAKMAgGBmeBDAECATAnBgNVHR8EIDAeMBygGqAY
hhZodHRwOi8veDIuYy5sZW5jci5vcmcvMAoGCCqGSM49BAMDA2gAMGUCMAO7SkY9
m1jgu8HC/+WQEPKzhU1Eze+AZF3yCjbxc08xIThaxIL3m3syDXAMyfbtfQIxAMLy
AZvTbDmzq9nfzN4wz4KGkMuy0Ab7nuguoYht4LNEZG/M+uz3eh6rCEzoxIoy8w==
-----END CERTIFICATE-----

node_path,validator,severity,code,message
certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix_subject_key_identifier_rfc7093_method_1_identified
36 changes: 36 additions & 0 deletions tests/integration_certificate/pkix/rfc7093_method_2.crttest
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIFwjCCA6qgAwIBAgIUH/nOhctN2lspZ2LasyeIMEixJzEwDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCVVMxHzAdBgNVBAoMFkZvbyBJbmR1c3RyaWVzIExpbWl0
ZWQxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0yMzA0MTkwMDAwMDBaFw0y
MzA3MTgyMzU5NTlaME4xIjAgBgNVBAMMGWhhbmFrby55YW1hZGFAZXhhbXBsZS5j
b20xKDAmBgkqhkiG9w0BCQEWGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb20wggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCw+egZQ6eumJKq3hfKfED4dE/t
L4FI5sjqont9ABVI+1GSqyi1bFBgsRjM0THllIdMbKmJtWwnKW8J+5OgNN8y6Xxv
8JmM/Y5vQt2lis0fqXmG8UTz0VTWdlAXXmhUs6lSADvAaIe4RVrCsZ97L3ZQTryY
7JRVcbB4khUN3Gp0yg+801SXzoFTTa+UGIRLE66jH51aa5VXu99hnv1OiH8tQrjd
i8mH6uG/icq4XuIeNWMF32wHqIOOPvQcWV3M5D2vxJEj702Ku6k9OQXkAo17qRSE
onWW4HtLbtmS8He1JNPc/n3dVUm+fM6NoDXPoLP7j55G9zKyqGtGAWXAj1MTAgMB
AAGjggGcMIIBmDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDAfBgNVHSME
GDAWgBTWRAAyfKgN/6xPa2buta6bLMU4VDAdBgNVHQ4EFgQU3omPCXKXVhKhLmjb
NT6C2kVHzt8wFAYDVR0gBA0wCzAJBgdngQwBBQECMD0GA1UdHwQ2MDQwMqAwoC6G
LGh0dHA6Ly9jcmwuY2EuZXhhbXBsZS5jb20vaXNzdWluZ19jYV9jcmwuY3JsMEsG
CCsGAQUFBwEBBD8wPTA7BggrBgEFBQcwAoYvaHR0cDovL3JlcG9zaXRvcnkuY2Eu
ZXhhbXBsZS5jb20vaXNzdWluZ19jYS5kZXIwHQYDVR0lBBYwFAYIKwYBBQUHAwQG
CCsGAQUFBwMCMHcGA1UdEQRwMG6BGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb22g
KQYKKwYBBAGCNxQCA6AbDBloYW5ha28ueWFtYWRhQGV4YW1wbGUuY29toCYGCCsG
AQUFBwgJoBoMGOWxseeUsOiKseWtkEBleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsF
AAOCAgEAg4rIcKGMfLh347FX/Y12lx7b9/iVrjsX7lsliirpITuPmfCli76JVrO0
Fqypfdd2P4ZVvH9WTpQUhRBv06kwHkJRkgpqNPO0WOpNVnsK8vcP1/RylDiJGryz
u6AzOSDqsxomFD6hm71XRYcsgBXXNPUzSGhbqUeuBuZwZe1WmP/yuvNpghMvlWFc
jAHktC9FuNpHhQ/3zZ20GUc6AQwwtn8rviFSwQihVJDJkGiGaJUc7lVVoswx87bS
oGpVluEIY/RK2HsXU0kmek4qq2t9v1OgRL98ZqUgOS26ooOXxqnR3QMx1S5KSLy9
+hK6y2gPhyiHoaPVTk4s54Es/YDtbCz7piyyyp3DEIzmgrwB/mG2IbOv6dT8Za5B
R7A+ggB7uwo3zYxKd2SFIDmXb+n9ML/s6/3aeyKJms4FmRq+fX8icb+lvVeLMhlC
Re5MFL2tkb72BFku0eeUde4iUnw93fzG6+Wl8VPCzYOwV0j+UTiyygcXaEZW+TpT
EmyY/fQ/7TCbGp+8Ur3rLlY5Okt5T83MmZdMFIHLQxaZUXkT2dBaSnh3VfNKFi0a
re9xdiBQZGkMkvWiKTjrUOwLXSNBnP6TXO9zn51tTK4KPZnQvNvULtn4H7z3FhfW
kie/jPNYkFvMzOaawwPAhG9R6G2ZB7cTOuG0Uu863Hkh5XX2oAo=
-----END CERTIFICATE-----

node_path,validator,severity,code,message
certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix_subject_key_identifier_rfc7093_method_2_identified,
36 changes: 36 additions & 0 deletions tests/integration_certificate/pkix/rfc7093_method_3.crttest
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIFwjCCA6qgAwIBAgIUH/nOhctN2lspZ2LasyeIMEixJzEwDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCVVMxHzAdBgNVBAoMFkZvbyBJbmR1c3RyaWVzIExpbWl0
ZWQxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0yMzA0MTkwMDAwMDBaFw0y
MzA3MTgyMzU5NTlaME4xIjAgBgNVBAMMGWhhbmFrby55YW1hZGFAZXhhbXBsZS5j
b20xKDAmBgkqhkiG9w0BCQEWGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb20wggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCw+egZQ6eumJKq3hfKfED4dE/t
L4FI5sjqont9ABVI+1GSqyi1bFBgsRjM0THllIdMbKmJtWwnKW8J+5OgNN8y6Xxv
8JmM/Y5vQt2lis0fqXmG8UTz0VTWdlAXXmhUs6lSADvAaIe4RVrCsZ97L3ZQTryY
7JRVcbB4khUN3Gp0yg+801SXzoFTTa+UGIRLE66jH51aa5VXu99hnv1OiH8tQrjd
i8mH6uG/icq4XuIeNWMF32wHqIOOPvQcWV3M5D2vxJEj702Ku6k9OQXkAo17qRSE
onWW4HtLbtmS8He1JNPc/n3dVUm+fM6NoDXPoLP7j55G9zKyqGtGAWXAj1MTAgMB
AAGjggGcMIIBmDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDAfBgNVHSME
GDAWgBTWRAAyfKgN/6xPa2buta6bLMU4VDAdBgNVHQ4EFgQUY8emM7B5J41rU5mX
UlMU8cq/Rg8wFAYDVR0gBA0wCzAJBgdngQwBBQECMD0GA1UdHwQ2MDQwMqAwoC6G
LGh0dHA6Ly9jcmwuY2EuZXhhbXBsZS5jb20vaXNzdWluZ19jYV9jcmwuY3JsMEsG
CCsGAQUFBwEBBD8wPTA7BggrBgEFBQcwAoYvaHR0cDovL3JlcG9zaXRvcnkuY2Eu
ZXhhbXBsZS5jb20vaXNzdWluZ19jYS5kZXIwHQYDVR0lBBYwFAYIKwYBBQUHAwQG
CCsGAQUFBwMCMHcGA1UdEQRwMG6BGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb22g
KQYKKwYBBAGCNxQCA6AbDBloYW5ha28ueWFtYWRhQGV4YW1wbGUuY29toCYGCCsG
AQUFBwgJoBoMGOWxseeUsOiKseWtkEBleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsF
AAOCAgEAg4rIcKGMfLh347FX/Y12lx7b9/iVrjsX7lsliirpITuPmfCli76JVrO0
Fqypfdd2P4ZVvH9WTpQUhRBv06kwHkJRkgpqNPO0WOpNVnsK8vcP1/RylDiJGryz
u6AzOSDqsxomFD6hm71XRYcsgBXXNPUzSGhbqUeuBuZwZe1WmP/yuvNpghMvlWFc
jAHktC9FuNpHhQ/3zZ20GUc6AQwwtn8rviFSwQihVJDJkGiGaJUc7lVVoswx87bS
oGpVluEIY/RK2HsXU0kmek4qq2t9v1OgRL98ZqUgOS26ooOXxqnR3QMx1S5KSLy9
+hK6y2gPhyiHoaPVTk4s54Es/YDtbCz7piyyyp3DEIzmgrwB/mG2IbOv6dT8Za5B
R7A+ggB7uwo3zYxKd2SFIDmXb+n9ML/s6/3aeyKJms4FmRq+fX8icb+lvVeLMhlC
Re5MFL2tkb72BFku0eeUde4iUnw93fzG6+Wl8VPCzYOwV0j+UTiyygcXaEZW+TpT
EmyY/fQ/7TCbGp+8Ur3rLlY5Okt5T83MmZdMFIHLQxaZUXkT2dBaSnh3VfNKFi0a
re9xdiBQZGkMkvWiKTjrUOwLXSNBnP6TXO9zn51tTK4KPZnQvNvULtn4H7z3FhfW
kie/jPNYkFvMzOaawwPAhG9R6G2ZB7cTOuG0Uu863Hkh5XX2oAo=
-----END CERTIFICATE-----

node_path,validator,severity,code,message
certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix_subject_key_identifier_rfc7093_method_3_identified,
36 changes: 36 additions & 0 deletions tests/integration_certificate/pkix/unknown_skid_method.crttest
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIFwjCCA6qgAwIBAgIUH/nOhctN2lspZ2LasyeIMEixJzEwDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCVVMxHzAdBgNVBAoMFkZvbyBJbmR1c3RyaWVzIExpbWl0
ZWQxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0yMzA0MTkwMDAwMDBaFw0y
MzA3MTgyMzU5NTlaME4xIjAgBgNVBAMMGWhhbmFrby55YW1hZGFAZXhhbXBsZS5j
b20xKDAmBgkqhkiG9w0BCQEWGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb20wggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCw+egZQ6eumJKq3hfKfED4dE/t
L4FI5sjqont9ABVI+1GSqyi1bFBgsRjM0THllIdMbKmJtWwnKW8J+5OgNN8y6Xxv
8JmM/Y5vQt2lis0fqXmG8UTz0VTWdlAXXmhUs6lSADvAaIe4RVrCsZ97L3ZQTryY
7JRVcbB4khUN3Gp0yg+801SXzoFTTa+UGIRLE66jH51aa5VXu99hnv1OiH8tQrjd
i8mH6uG/icq4XuIeNWMF32wHqIOOPvQcWV3M5D2vxJEj702Ku6k9OQXkAo17qRSE
onWW4HtLbtmS8He1JNPc/n3dVUm+fM6NoDXPoLP7j55G9zKyqGtGAWXAj1MTAgMB
AAGjggGcMIIBmDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDAfBgNVHSME
GDAWgBTWRAAyfKgN/6xPa2buta6bLMU4VDAdBgNVHQ4EFgQUY8emM7B5J41rU5mX
UlMU8cq/Rg4wFAYDVR0gBA0wCzAJBgdngQwBBQECMD0GA1UdHwQ2MDQwMqAwoC6G
LGh0dHA6Ly9jcmwuY2EuZXhhbXBsZS5jb20vaXNzdWluZ19jYV9jcmwuY3JsMEsG
CCsGAQUFBwEBBD8wPTA7BggrBgEFBQcwAoYvaHR0cDovL3JlcG9zaXRvcnkuY2Eu
ZXhhbXBsZS5jb20vaXNzdWluZ19jYS5kZXIwHQYDVR0lBBYwFAYIKwYBBQUHAwQG
CCsGAQUFBwMCMHcGA1UdEQRwMG6BGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb22g
KQYKKwYBBAGCNxQCA6AbDBloYW5ha28ueWFtYWRhQGV4YW1wbGUuY29toCYGCCsG
AQUFBwgJoBoMGOWxseeUsOiKseWtkEBleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsF
AAOCAgEAg4rIcKGMfLh347FX/Y12lx7b9/iVrjsX7lsliirpITuPmfCli76JVrO0
Fqypfdd2P4ZVvH9WTpQUhRBv06kwHkJRkgpqNPO0WOpNVnsK8vcP1/RylDiJGryz
u6AzOSDqsxomFD6hm71XRYcsgBXXNPUzSGhbqUeuBuZwZe1WmP/yuvNpghMvlWFc
jAHktC9FuNpHhQ/3zZ20GUc6AQwwtn8rviFSwQihVJDJkGiGaJUc7lVVoswx87bS
oGpVluEIY/RK2HsXU0kmek4qq2t9v1OgRL98ZqUgOS26ooOXxqnR3QMx1S5KSLy9
+hK6y2gPhyiHoaPVTk4s54Es/YDtbCz7piyyyp3DEIzmgrwB/mG2IbOv6dT8Za5B
R7A+ggB7uwo3zYxKd2SFIDmXb+n9ML/s6/3aeyKJms4FmRq+fX8icb+lvVeLMhlC
Re5MFL2tkb72BFku0eeUde4iUnw93fzG6+Wl8VPCzYOwV0j+UTiyygcXaEZW+TpT
EmyY/fQ/7TCbGp+8Ur3rLlY5Okt5T83MmZdMFIHLQxaZUXkT2dBaSnh3VfNKFi0a
re9xdiBQZGkMkvWiKTjrUOwLXSNBnP6TXO9zn51tTK4KPZnQvNvULtn4H7z3FhfW
kie/jPNYkFvMzOaawwPAhG9R6G2ZB7cTOuG0Uu863Hkh5XX2oAo=
-----END CERTIFICATE-----

node_path,validator,severity,code,message
certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,NOTICE,pkix.unknown_subject_key_identifier_calculation_method,

0 comments on commit e3af04b

Please sign in to comment.