Sadia Bashir
Sadia Bashir

Reputation: 95

Decoding Scapy ASN1 encoded SSL/TLS certificate fields

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

Answers (3)

tintin
tintin

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

wbond
wbond

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

Ilya Etingof
Ilya Etingof

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

Related Questions