Reputation: 95
I am extracting SSL/TLS certificate fields from serverhello packet using scapy-ssl_tls library which I installed using pip.
The problem is, I'm not able to figure out a way to extract values from ASN1 encoded fields:
sign_algo2: <ASN1_OID['.1.2.840.113549.1.1.11']>
sa2_value: <ASN1_NULL[0L]>
not_before: <ASN1_UTC_TIME['170321131500Z']>
not_after: <ASN1_UTC_TIME['200321131500Z']>
pubkey_algo: <ASN1_OID['.1.2.840.113549.1.1.1']>
version: <ASN1_INTEGER[2L]>
sn: <ASN1_INTEGER[6348220899422160075L]>
sign_algo: <ASN1_OID['.1.2.840.113549.1.1.11']>
pubkey: <ASN1_BIT_STRING['\x000\x']>
I've dug out scapy.layers.ssl_tls, ssl_tls_crypto, scapy.layers.x509 modules but couldn't get any hint to decode it. I also tried using Asn1Value.load() from asn1crypto.core package but it fails with following error:
TypeError: encoded_data must be a byte string, not scapy.asn1.asn1.ASN1_UTC_TIME
It'd be great if anyone could help me getting this resolved using scapy's native decoding preferably or any other way possible.
Note: Please note that I've to extract these values from SSL/TLS serverhello packets which I'm reading from a pcap file as I need other fields from packet headers as well. I know many solutions exist on stackoverflow or wireshark/tshark for extracting/reading certificates from .pem files or possibly from .der files (after having it exported from wireshark explicitly), they don't work in my case as I need a solution which works around extracting certificates or certificate fields from packets.
Upvotes: 1
Views: 2089
Reputation: 3356
This has been discussed in scapy-ssl_tls issue #116 which describes basic handling of scapy ASN.1 fields:
...
# resp holds the raw socket response to a client_hello
tls_response = TLS(resp)
tls_response.show() # show the structure
# iterate all certificates
for cert in tls_response[TLSCertificateList].payload.certificates:
# .payload as the structure is [...][TLSCertificateList][TLS10Certificate].certificates = [x509Cert,x509Cert,...]
# we'll have a TLSCertificateList object at this point; get the scapy X509Cert Object
tlscert = cert[X509Cert]
print repr(str(tlscert.sign_algo)) # raw bytes -> '\x06\t*\x86H\x86\xf7\r\x01\x01\x0b'
print repr(tlscert.sign_algo) # <ASN1_OID['.1.2.840.113549.1.1.11']>
print tlscert.sign_algo.val # 1.2.840.113549.1.1.11
print repr(tlscert.version) # <ASN1_INTEGER[2L]>
print tlscert.version.val # 2
Upvotes: 0
Reputation: 613
If you have a DER-encoded byte string of the X.509 certificate, the correct way to use asn1crypto would be:
from asn1crypto import x509
cert = x509.Certificate.load(der_byte_string)
print(cert.native)
It would seem from the error message, you have tried to pass some of Python object that represents an ASN.1 value.
Upvotes: 1
Reputation: 5555
Make sure you are passing asn1crypto the byte string, not some internal scapy object. May be you need to cast the latter into a byte string.
Alternatively, this tool is designed to decode X.509 certs into a tree of Python objects. You also need to feed it either a string (Python2) or bytes (Python 3).
Upvotes: 1