#! /usr/bin/env python

###
### Generate trust anchor tables from a text file
### like, for example, TLS-Trust-Anchors-base.crt
## and TLS-Trust-Anchors-extended.crt located under Extras/Data
###

### imports
import sys
import base64

### generate a C file with bult-in TLS trust anchors
FILE_HEADER = """/*****************************************************************
|
|   Neptune - Trust Anchors
|
|   This file is automatically generated by a script, do not edit!
|
| Copyright (c) 2002-2010, Axiomatic Systems, LLC.
| All rights reserved.
|
| Redistribution and use in source and binary forms, with or without
| modification, are permitted provided that the following conditions are met:
|     * Redistributions of source code must retain the above copyright
|       notice, this list of conditions and the following disclaimer.
|     * Redistributions in binary form must reproduce the above copyright
|       notice, this list of conditions and the following disclaimer in the
|       documentation and/or other materials provided with the distribution.
|     * Neither the name of Axiomatic Systems nor the
|       names of its contributors may be used to endorse or promote products
|       derived from this software without specific prior written permission.
|
| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
 ****************************************************************/

 """

if len(sys.argv) != 3:
    print "usage: GenTrustAnchosTable.py <input-file> <category>"
    print " where category may be 'Base', 'Extended', or other"
    sys.exit(1)
    
INPUT_FILE = sys.argv[1]
CERT_CATEGORY = sys.argv[2]

digest_oid_pattern = "\x2a\x86\x48\x86\xf7\x0d\x01\x01"

in_cert = False
prev = ''
prev_prev = ''
index = 0
Certs = []
CertNames = []
CertComments = []
for line in open(sys.argv[1]).readlines():
    if line.startswith('-----BEGIN CERTIFICATE-----'):
        in_cert = True
        b64 = ''
        continue;
    if line.startswith('-----END CERTIFICATE-----'):
        cert = base64.decodestring(b64);
        if not digest_oid_pattern in cert:
            sys.stderr.write("-------- skipping cert (digest not supported) -------\n")
            continue
        Certs.append(cert)
        cert_name = 'NptTlsTrustAnchor_%s_%04d' % (CERT_CATEGORY, index)
        #cert_comment = eval('"'+prev_prev.rstrip('\r\n')+'"')
        cert_comment = prev_prev.rstrip('\r\n')
        CertNames.append(cert_name)
        CertComments.append(cert_comment)
        out = open(CERT_CATEGORY+'/'+cert_name+'.cpp', 'w+b')
        out.write(FILE_HEADER)
        out.write('/* %s */\n' % (cert_comment))
        out.write('const unsigned char %s_Data[%d] = {\n' % (cert_name, len(cert)))
        counter = 0
        sep = ''
        for byte in cert:
            out.write('%s0x%02x' % (sep, ord(byte)))
            counter += 1
            sep = ','
            if counter == 8:
                out.write('\n')
                counter = 0
        in_cert = False
        out.write('};\n')
        out.write('const unsigned int  %s_Size = %d;\n' % (cert_name, len(cert)))
        index += 1
        out.close()
        continue
    if in_cert:
        b64 += line.rstrip('\r\n')
    else:
        prev_prev = prev
        prev = line
        
out = open('NptTlsDefaultTrustAnchors'+CERT_CATEGORY+'.cpp', 'w+b')
out.write(FILE_HEADER)
out.write("/* This file is automatically generated by GenTrustAnchorsTables.py, do not edit */\n\n")
out.write('#include "NptTls.h"\n')

total_size = 0
for i in xrange(0, len(CertNames)):
    out.write('#include "'+CERT_CATEGORY+'/'+CertNames[i]+'.cpp" /* '+CertComments[i]+' */\n')
    total_size += len(Certs[i])
out.write("/* total anchors size ="+ str(total_size)+" */\n\n")

out.write('const NPT_TlsTrustAnchorData NptTlsDefaultTrustAnchors%s[%s] = {\r\n' % (CERT_CATEGORY, 1+len(Certs)))
sep = '    '
for i in xrange(0, len(Certs)):
    out.write('%s{ %s_Data, %s_Size} /* %s */' % (sep, CertNames[i], CertNames[i], CertComments[i]))
    sep = ',\r\n    '
out.write(sep+'{0, 0} /* sentinel */\n')
out.write('};\n')
out.close()
    
out = open('NptTlsDefaultTrustAnchors'+CERT_CATEGORY+'.h', 'w+b')
out.write(FILE_HEADER)
out.write("/* This file is automatically generated by GenTrustAnchorsTables.py, do not edit */\n\n")
out.write('#include "NptTls.h"\n\n')
out.write('extern const NPT_TlsTrustAnchorData NptTlsDefaultTrustAnchors%s[%d];\n\n' % (CERT_CATEGORY, 1+len(Certs)))
for i in xrange(0, len(CertNames)):
    out.write('/* '+CertComments[i]+' */\n')
    out.write('extern const unsigned int %s_Size;\n' % (CertNames[i]))
    out.write('extern const unsigned char %s_Data[];\n\n' % (CertNames[i]))
    
out.close()
    