Graphing Terena CRL stats

Heartbleed

heartbleed

The OpenSSL heartbleed vulnerability CVE-2014-0160 has been all over the news this month. I posted an overview on what to do and how to detect exploit attempts.

Certificate revocations

Generating new certificates is one of the advices to cope with this vulnerability. A new certificate means that you have to revoke the old one. Revoked certificates are ‘announced’ in a CRL, or a certificate revocation list.

Graphing CRL content

SANS ISC has a graph on certificates revoked per day. This graph is based on different sources. I am only interested in the CRL revocation data of Terena. Below are the graphs for the Terena CRL list. It is generated with a Python script (see below).

You can see a spike shortly after the announcement of the Heartbleed bug but I would have expected to see a higher number of requested revoked certificates.

Script to generate stats

The Python script generates a JSON file that is used to feed a Google Chart. It uses a file TERENASSLCA.crl.parsed that is the output of parsing the CRL file through OpenSSL.

wget --output-document TERENASSLCA.crl http://crl.tcs.terena.org/TERENASSLCA.crl
openssl crl -in TERENASSLCA.crl -inform DER -text > TERENASSLCA.crl.parsed
#!/usr/bin/python
# 
# Koen Van Impe - Google Chart graphs based on Terena CRL
#
# In cron:
#    wget http://crl.tcs.terena.org/TERENASSLCA.crl
#    openssl crl -in TERENASSLCA.crl -inform DER -text > TERENASSLCA.crl.parsed
#

crl = open('TERENASSLCA.crl.parsed', 'r')
crl_json = open('terena-crl.json', 'w')
revoc_match = 'Revocation Date:'
revoc_date = 'Last Update:'
crl_data = {}
update_date = 'Unknown'

# Init dictionary
for x in range(1, 31):
    crl_data[ x ] = 0

# Walk through CRL file
for line in crl:
    pos = line.find( revoc_match )
    pos_update = line.find( revoc_date )
    if pos > 0 :        # A line indicating a revoked certificate?       
        date = line[(pos + len( revoc_match )):].strip().split(' ')
        # Only grab the Apr2014 (could also add an extra 'match' above)
        if date[0] == 'Apr' and date[3] == '2014':
            day = int(date[1])
            crl_data[ day ] = crl_data[ day ] + 1
    elif pos_update > 0:
        update_date = line[(pos_update + len( revoc_date )):].strip()

# Build JSON        
crl_json.write( '{"update_date": "' + update_date + '", \n "googlechart": ')
crl_json.write( '{"cols":[{"type":"string"},{"type":"number","label":"hits"}] \n')
crl_json.write( ', "rows":[ \n')

row = 1
for item in crl_data:
    json_line = '{"c":[{"v":"' + str(item) + '/Apr"},{"v":"' + str(crl_data[ item ]) + '"}]} '
    if row != len(crl_data):
        json_line = json_line + " , "
    crl_json.write ( json_line + "\n")
    row = row + 1
    
crl_json.write( ']} }\n')

# Cleanup
crl.close()
crl_json.close()

2 thoughts on “Graphing Terena CRL stats

  1. Koen on said:

    I fetch the CRL; parse it with OpenSSL and then the python script parses it to create a JSON file. The graph (+table) itself is made with Google Chart.

Leave a Reply

Your email address will not be published. Required fields are marked *