5f392b3
#!/usr/bin/python
5f392b3
# vim:set et sw=4:
5f392b3
#
5f392b3
# certdata2pem.py - splits certdata.txt into multiple files
5f392b3
#
5f392b3
# Copyright (C) 2009 Philipp Kern <pkern@debian.org>
Kai Engert b2e71a9
# Copyright (C) 2013 Kai Engert <kaie@redhat.com>
5f392b3
#
5f392b3
# This program is free software; you can redistribute it and/or modify
5f392b3
# it under the terms of the GNU General Public License as published by
5f392b3
# the Free Software Foundation; either version 2 of the License, or
5f392b3
# (at your option) any later version.
5f392b3
#
5f392b3
# This program is distributed in the hope that it will be useful,
5f392b3
# but WITHOUT ANY WARRANTY; without even the implied warranty of
5f392b3
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5f392b3
# GNU General Public License for more details.
5f392b3
#
5f392b3
# You should have received a copy of the GNU General Public License
5f392b3
# along with this program; if not, write to the Free Software
5f392b3
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
5f392b3
# USA.
5f392b3
5f392b3
import base64
5f392b3
import os.path
5f392b3
import re
5f392b3
import sys
5f392b3
import textwrap
Kai Engert 1a2c011
import urllib.request, urllib.parse, urllib.error
Kai Engert f0b0be2
import subprocess
5f392b3
5f392b3
objects = []
5f392b3
Kai Engert b2e71a9
def printable_serial(obj):
Kai Engert 1a2c011
  return ".".join([str(x) for x in obj['CKA_SERIAL_NUMBER']])
Kai Engert b2e71a9
5f392b3
# Dirty file parser.
5f392b3
in_data, in_multiline, in_obj = False, False, False
Kai Engert 1a2c011
field, ftype, value, binval, obj = None, None, None, bytearray(), dict()
5f392b3
for line in open('certdata.txt', 'r'):
5f392b3
    # Ignore the file header.
5f392b3
    if not in_data:
5f392b3
        if line.startswith('BEGINDATA'):
5f392b3
            in_data = True
5f392b3
        continue
5f392b3
    # Ignore comment lines.
5f392b3
    if line.startswith('#'):
5f392b3
        continue
5f392b3
    # Empty lines are significant if we are inside an object.
5f392b3
    if in_obj and len(line.strip()) == 0:
5f392b3
        objects.append(obj)
5f392b3
        obj = dict()
5f392b3
        in_obj = False
5f392b3
        continue
5f392b3
    if len(line.strip()) == 0:
5f392b3
        continue
5f392b3
    if in_multiline:
5f392b3
        if not line.startswith('END'):
Kai Engert 1a2c011
            if ftype == 'MULTILINE_OCTAL':
5f392b3
                line = line.strip()
5f392b3
                for i in re.finditer(r'\\([0-3][0-7][0-7])', line):
Kai Engert 1a2c011
                    integ = int(i.group(1), 8)
Kai Engert 1a2c011
                    binval.extend((integ).to_bytes(1, sys.byteorder))
Kai Engert 1a2c011
                obj[field] = binval
5f392b3
            else:
5f392b3
                value += line
Kai Engert 1a2c011
                obj[field] = value
5f392b3
            continue
5f392b3
        in_multiline = False
5f392b3
        continue
5f392b3
    if line.startswith('CKA_CLASS'):
5f392b3
        in_obj = True
5f392b3
    line_parts = line.strip().split(' ', 2)
5f392b3
    if len(line_parts) > 2:
Kai Engert 1a2c011
        field, ftype = line_parts[0:2]
5f392b3
        value = ' '.join(line_parts[2:])
5f392b3
    elif len(line_parts) == 2:
Kai Engert 1a2c011
        field, ftype = line_parts
5f392b3
        value = None
5f392b3
    else:
Kai Engert 1a2c011
        raise NotImplementedError('line_parts < 2 not supported.\n' + line)
Kai Engert 1a2c011
    if ftype == 'MULTILINE_OCTAL':
5f392b3
        in_multiline = True
5f392b3
        value = ""
Kai Engert 1a2c011
        binval = bytearray()
5f392b3
        continue
5f392b3
    obj[field] = value
Kai Engert 1a2c011
if len(list(obj.items())) > 0:
5f392b3
    objects.append(obj)
5f392b3
5f392b3
# Build up trust database.
708646c
trustmap = dict()
5f392b3
for obj in objects:
37d25f7
    if obj['CKA_CLASS'] != 'CKO_NSS_TRUST':
5f392b3
        continue
Kai Engert b2e71a9
    key = obj['CKA_LABEL'] + printable_serial(obj)
Kai Engert b2e71a9
    trustmap[key] = obj
Kai Engert 1a2c011
    print(" added trust", key)
Kai Engert 34f352d
Kai Engert 34f352d
# Build up cert database.
Kai Engert 34f352d
certmap = dict()
Kai Engert 34f352d
for obj in objects:
Kai Engert 34f352d
    if obj['CKA_CLASS'] != 'CKO_CERTIFICATE':
Kai Engert 34f352d
        continue
Kai Engert b2e71a9
    key = obj['CKA_LABEL'] + printable_serial(obj)
Kai Engert b2e71a9
    certmap[key] = obj
Kai Engert 1a2c011
    print(" added cert", key)
5f392b3
Joe Orton 5968244
def obj_to_filename(obj):
Joe Orton 5968244
    label = obj['CKA_LABEL'][1:-1]
5f392b3
    label = label.replace('/', '_')\
5f392b3
        .replace(' ', '_')\
5f392b3
        .replace('(', '=')\
5f392b3
        .replace(')', '=')\
Joe Orton 5968244
        .replace(',', '_')
Kai Engert 1a2c011
    labelbytes = bytearray()
Kai Engert 1a2c011
    i = 0
Kai Engert 1a2c011
    imax = len(label)
Kai Engert 1a2c011
    while i < imax:
Kai Engert 1a2c011
        if i < imax-3 and label[i] == '\\' and label[i+1] == 'x':
Kai Engert 1a2c011
            labelbytes.extend(bytes.fromhex(label[i+2:i+4]))
Kai Engert 1a2c011
            i += 4
Kai Engert 1a2c011
            continue
Kai Engert 1a2c011
        labelbytes.extend(str.encode(label[i]))
Kai Engert 1a2c011
        i = i+1
Kai Engert 1a2c011
        continue
Kai Engert 1a2c011
    label = labelbytes.decode('utf-8')
Kai Engert b2e71a9
    serial = printable_serial(obj)
Kai Engert 34f352d
    return label + ":" + serial
5f392b3
Kai Engert f0b0be2
def write_cert_ext_to_file(f, oid, value, public_key):
Kai Engert f0b0be2
    f.write("[p11-kit-object-v1]\n")
Kai Engert f0b0be2
    f.write("label: ");
Kai Engert f0b0be2
    f.write(tobj['CKA_LABEL'])
Kai Engert f0b0be2
    f.write("\n")
Kai Engert f0b0be2
    f.write("class: x-certificate-extension\n");
Kai Engert f0b0be2
    f.write("object-id: " + oid + "\n")
Kai Engert f0b0be2
    f.write("value: \"" + value + "\"\n")
Kai Engert c1c2757
    f.write("modifiable: false\n");
Kai Engert f0b0be2
    f.write(public_key)
Kai Engert f0b0be2
708646c
trust_types = {
708646c
  "CKA_TRUST_DIGITAL_SIGNATURE": "digital-signature",
708646c
  "CKA_TRUST_NON_REPUDIATION": "non-repudiation",
708646c
  "CKA_TRUST_KEY_ENCIPHERMENT": "key-encipherment",
708646c
  "CKA_TRUST_DATA_ENCIPHERMENT": "data-encipherment",
708646c
  "CKA_TRUST_KEY_AGREEMENT": "key-agreement",
708646c
  "CKA_TRUST_KEY_CERT_SIGN": "cert-sign",
708646c
  "CKA_TRUST_CRL_SIGN": "crl-sign",
708646c
  "CKA_TRUST_SERVER_AUTH": "server-auth",
708646c
  "CKA_TRUST_CLIENT_AUTH": "client-auth",
708646c
  "CKA_TRUST_CODE_SIGNING": "code-signing",
708646c
  "CKA_TRUST_EMAIL_PROTECTION": "email-protection",
708646c
  "CKA_TRUST_IPSEC_END_SYSTEM": "ipsec-end-system",
708646c
  "CKA_TRUST_IPSEC_TUNNEL": "ipsec-tunnel",
708646c
  "CKA_TRUST_IPSEC_USER": "ipsec-user",
708646c
  "CKA_TRUST_TIME_STAMPING": "time-stamping",
708646c
  "CKA_TRUST_STEP_UP_APPROVED": "step-up-approved",
708646c
}
708646c
Kai Engert e24bfeb
legacy_trust_types = {
Kai Engert e24bfeb
  "LEGACY_CKA_TRUST_SERVER_AUTH": "server-auth",
Kai Engert e24bfeb
  "LEGACY_CKA_TRUST_CODE_SIGNING": "code-signing",
Kai Engert e24bfeb
  "LEGACY_CKA_TRUST_EMAIL_PROTECTION": "email-protection",
Kai Engert e24bfeb
}
Kai Engert e24bfeb
Kai Engert e24bfeb
legacy_to_real_trust_types = {
Kai Engert e24bfeb
  "LEGACY_CKA_TRUST_SERVER_AUTH": "CKA_TRUST_SERVER_AUTH",
Kai Engert e24bfeb
  "LEGACY_CKA_TRUST_CODE_SIGNING": "CKA_TRUST_CODE_SIGNING",
Kai Engert e24bfeb
  "LEGACY_CKA_TRUST_EMAIL_PROTECTION": "CKA_TRUST_EMAIL_PROTECTION",
Kai Engert e24bfeb
}
Kai Engert e24bfeb
708646c
openssl_trust = {
708646c
  "CKA_TRUST_SERVER_AUTH": "serverAuth",
708646c
  "CKA_TRUST_CLIENT_AUTH": "clientAuth",
708646c
  "CKA_TRUST_CODE_SIGNING": "codeSigning",
708646c
  "CKA_TRUST_EMAIL_PROTECTION": "emailProtection",
708646c
}
708646c
6aec97d
cert_distrust_types = {
6aec97d
  "CKA_NSS_SERVER_DISTRUST_AFTER": "nss-server-distrust-after",
6aec97d
  "CKA_NSS_EMAIL_DISTRUST_AFTER": "nss-email-distrust-after",
6aec97d
}
6aec97d
Kai Engert 34f352d
for tobj in objects:
Kai Engert 34f352d
    if tobj['CKA_CLASS'] == 'CKO_NSS_TRUST':
Kai Engert b2e71a9
        key = tobj['CKA_LABEL'] + printable_serial(tobj)
Kai Engert 1a2c011
        print("producing trust for " + key)
708646c
        trustbits = []
Kai Engert d538ada
        distrustbits = []
708646c
        openssl_trustflags = []
Kai Engert d538ada
        openssl_distrustflags = []
Kai Engert e24bfeb
        legacy_trustbits = []
Kai Engert e24bfeb
        legacy_openssl_trustflags = []
Kai Engert 1a2c011
        for t in list(trust_types.keys()):
Kai Engert 1a2c011
            if t in tobj and tobj[t] == 'CKT_NSS_TRUSTED_DELEGATOR':
708646c
                trustbits.append(t)
708646c
                if t in openssl_trust:
708646c
                    openssl_trustflags.append(openssl_trust[t])
Kai Engert 1a2c011
            if t in tobj and tobj[t] == 'CKT_NSS_NOT_TRUSTED':
Kai Engert d538ada
                distrustbits.append(t)
Kai Engert d538ada
                if t in openssl_trust:
Kai Engert d538ada
                    openssl_distrustflags.append(openssl_trust[t])
f098063
Kai Engert 1a2c011
        for t in list(legacy_trust_types.keys()):
Kai Engert 1a2c011
            if t in tobj and tobj[t] == 'CKT_NSS_TRUSTED_DELEGATOR':
Kai Engert e24bfeb
                real_t = legacy_to_real_trust_types[t]
Kai Engert e24bfeb
                legacy_trustbits.append(real_t)
Kai Engert e24bfeb
                if real_t in openssl_trust:
Kai Engert e24bfeb
                    legacy_openssl_trustflags.append(openssl_trust[real_t])
Kai Engert 1a2c011
            if t in tobj and tobj[t] == 'CKT_NSS_NOT_TRUSTED':
Kai Engert 1a2c011
                raise NotImplementedError('legacy distrust not supported.\n' + line)
Kai Engert e24bfeb
Kai Engert 34f352d
        fname = obj_to_filename(tobj)
Kai Engert 34f352d
        try:
Kai Engert b2e71a9
            obj = certmap[key]
Kai Engert 34f352d
        except:
Kai Engert 34f352d
            obj = None
f098063
Kai Engert f0b0be2
        # optional debug code, that dumps the parsed input to files
Kai Engert f0b0be2
        #fulldump = "dump-" + fname
Kai Engert f0b0be2
        #dumpf = open(fulldump, 'w')
Kai Engert f0b0be2
        #dumpf.write(str(obj));
Kai Engert f0b0be2
        #dumpf.write(str(tobj));
Kai Engert f0b0be2
        #dumpf.close();
5f392b3
Kai Engert e24bfeb
        is_legacy = 0
Kai Engert 1a2c011
        if 'LEGACY_CKA_TRUST_SERVER_AUTH' in tobj or 'LEGACY_CKA_TRUST_EMAIL_PROTECTION' in tobj or 'LEGACY_CKA_TRUST_CODE_SIGNING' in tobj:
Kai Engert e24bfeb
            is_legacy = 1
Kai Engert e24bfeb
            if obj == None:
Kai Engert 1a2c011
                raise NotImplementedError('found legacy trust without certificate.\n' + line)
Kai Engert f0b0be2
Kai Engert f0b0be2
            legacy_fname = "legacy-default/" + fname + ".crt"
Kai Engert e24bfeb
            f = open(legacy_fname, 'w')
Kai Engert e24bfeb
            f.write("# alias=%s\n"%tobj['CKA_LABEL'])
Kai Engert e24bfeb
            f.write("# trust=" + " ".join(legacy_trustbits) + "\n")
Kai Engert e24bfeb
            if legacy_openssl_trustflags:
Kai Engert e24bfeb
                f.write("# openssl-trust=" + " ".join(legacy_openssl_trustflags) + "\n")
Kai Engert e24bfeb
            f.write("-----BEGIN CERTIFICATE-----\n")
Kai Engert 1a2c011
            temp_encoded_b64 = base64.b64encode(obj['CKA_VALUE'])
Kai Engert 1a2c011
            temp_wrapped = textwrap.wrap(temp_encoded_b64.decode(), 64)
Kai Engert 1a2c011
            f.write("\n".join(temp_wrapped))
Kai Engert e24bfeb
            f.write("\n-----END CERTIFICATE-----\n")
Kai Engert e24bfeb
            f.close()
Kai Engert f0b0be2
Kai Engert 1a2c011
            if 'CKA_TRUST_SERVER_AUTH' in tobj or 'CKA_TRUST_EMAIL_PROTECTION' in tobj or 'CKA_TRUST_CODE_SIGNING' in tobj:
Kai Engert f0b0be2
                legacy_fname = "legacy-disable/" + fname + ".crt"
Kai Engert f0b0be2
                f = open(legacy_fname, 'w')
Kai Engert f0b0be2
                f.write("# alias=%s\n"%tobj['CKA_LABEL'])
Kai Engert f0b0be2
                f.write("# trust=" + " ".join(trustbits) + "\n")
Kai Engert f0b0be2
                if openssl_trustflags:
Kai Engert f0b0be2
                    f.write("# openssl-trust=" + " ".join(openssl_trustflags) + "\n")
Kai Engert f0b0be2
                f.write("-----BEGIN CERTIFICATE-----\n")
Kai Engert f0b0be2
                f.write("\n".join(textwrap.wrap(base64.b64encode(obj['CKA_VALUE']), 64)))
Kai Engert f0b0be2
                f.write("\n-----END CERTIFICATE-----\n")
Kai Engert f0b0be2
                f.close()
Kai Engert f0b0be2
Kai Engert f0b0be2
            # don't produce p11-kit output for legacy certificates
Kai Engert f0b0be2
            continue
Kai Engert e24bfeb
Kai Engert f0b0be2
        pk = ''
Kai Engert f0b0be2
        cert_comment = ''
Kai Engert f0b0be2
        if obj != None:
Kai Engert f0b0be2
            # must extract the public key from the cert, let's use openssl
Kai Engert f0b0be2
            cert_fname = "cert-" + fname
Kai Engert f0b0be2
            fc = open(cert_fname, 'w')
Kai Engert f0b0be2
            fc.write("-----BEGIN CERTIFICATE-----\n")
Kai Engert 1a2c011
            temp_encoded_b64 = base64.b64encode(obj['CKA_VALUE'])
Kai Engert 1a2c011
            temp_wrapped = textwrap.wrap(temp_encoded_b64.decode(), 64)
Kai Engert 1a2c011
            fc.write("\n".join(temp_wrapped))
Kai Engert f0b0be2
            fc.write("\n-----END CERTIFICATE-----\n")
Kai Engert f0b0be2
            fc.close();
Kai Engert f0b0be2
            pk_fname = "pubkey-" + fname
Kai Engert f0b0be2
            fpkout = open(pk_fname, "w")
Kai Engert f0b0be2
            dump_pk_command = ["openssl", "x509", "-in", cert_fname, "-noout", "-pubkey"]
Kai Engert f0b0be2
            subprocess.call(dump_pk_command, stdout=fpkout)
Kai Engert f0b0be2
            fpkout.close()
Kai Engert f0b0be2
            with open (pk_fname, "r") as myfile:
Kai Engert f0b0be2
                pk=myfile.read()
Kai Engert f0b0be2
            # obtain certificate information suitable as a comment
Kai Engert f0b0be2
            comment_fname = "comment-" + fname
Kai Engert f0b0be2
            fcout = open(comment_fname, "w")
Kai Engert f0b0be2
            comment_command = ["openssl", "x509", "-in", cert_fname, "-noout", "-text"]
Kai Engert f0b0be2
            subprocess.call(comment_command, stdout=fcout)
Kai Engert f0b0be2
            fcout.close()
Kai Engert f0b0be2
            sed_command = ["sed", "--in-place", "s/^/#/", comment_fname]
Kai Engert f0b0be2
            subprocess.call(sed_command)
Kai Engert 1a2c011
            with open (comment_fname, "r", errors = 'replace') as myfile:
Kai Engert f0b0be2
                cert_comment=myfile.read()
Kai Engert f0b0be2
Kai Engert f0b0be2
        fname += ".tmp-p11-kit"
Kai Engert 34f352d
        f = open(fname, 'w')
Kai Engert f0b0be2
Kai Engert 34f352d
        if obj != None:
Kai Engert f0b0be2
            is_distrusted = False
Kai Engert f0b0be2
            has_server_trust = False
Kai Engert f0b0be2
            has_email_trust = False
Kai Engert f0b0be2
            has_code_trust = False
Kai Engert f0b0be2
Kai Engert 1a2c011
            if 'CKA_TRUST_SERVER_AUTH' in tobj:
Kai Engert f0b0be2
                if tobj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_NOT_TRUSTED':
Kai Engert f0b0be2
                    is_distrusted = True
Kai Engert f0b0be2
                elif tobj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_TRUSTED_DELEGATOR':
Kai Engert f0b0be2
                    has_server_trust = True
Kai Engert f0b0be2
Kai Engert 1a2c011
            if 'CKA_TRUST_EMAIL_PROTECTION' in tobj:
Kai Engert f0b0be2
                if tobj['CKA_TRUST_EMAIL_PROTECTION'] == 'CKT_NSS_NOT_TRUSTED':
Kai Engert f0b0be2
                    is_distrusted = True
Kai Engert f0b0be2
                elif tobj['CKA_TRUST_EMAIL_PROTECTION'] == 'CKT_NSS_TRUSTED_DELEGATOR':
Kai Engert f0b0be2
                    has_email_trust = True
Kai Engert f0b0be2
Kai Engert 1a2c011
            if 'CKA_TRUST_CODE_SIGNING' in tobj:
Kai Engert f0b0be2
                if tobj['CKA_TRUST_CODE_SIGNING'] == 'CKT_NSS_NOT_TRUSTED':
Kai Engert f0b0be2
                    is_distrusted = True
Kai Engert f0b0be2
                elif tobj['CKA_TRUST_CODE_SIGNING'] == 'CKT_NSS_TRUSTED_DELEGATOR':
Kai Engert f0b0be2
                    has_code_trust = True
Kai Engert f0b0be2
Kai Engert f0b0be2
            if is_distrusted:
Kai Engert f0b0be2
                trust_ext_oid = "1.3.6.1.4.1.3319.6.10.1"
Kai Engert f0b0be2
                trust_ext_value = "0.%06%0a%2b%06%01%04%01%99w%06%0a%01%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
Kai Engert f0b0be2
                write_cert_ext_to_file(f, trust_ext_oid, trust_ext_value, pk)
Kai Engert f0b0be2
Kai Engert f0b0be2
            trust_ext_oid = "2.5.29.37"
Kai Engert f0b0be2
            if has_server_trust:
Kai Engert f0b0be2
                if has_email_trust:
Kai Engert f0b0be2
                    if has_code_trust:
Kai Engert f0b0be2
                        # server + email + code
Kai Engert f0b0be2
                        trust_ext_value = "0%2a%06%03U%1d%25%01%01%ff%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
Kai Engert f0b0be2
                    else:
Kai Engert f0b0be2
                        # server + email
Kai Engert f0b0be2
                        trust_ext_value = "0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01"
Kai Engert f0b0be2
                else:
Kai Engert f0b0be2
                    if has_code_trust:
Kai Engert f0b0be2
                        # server + code
Kai Engert f0b0be2
                        trust_ext_value = "0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
Kai Engert f0b0be2
                    else:
Kai Engert f0b0be2
                        # server
Kai Engert f0b0be2
                        trust_ext_value = "0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%01"
Kai Engert f0b0be2
            else:
Kai Engert f0b0be2
                if has_email_trust:
Kai Engert f0b0be2
                    if has_code_trust:
Kai Engert f0b0be2
                        # email + code
Kai Engert f0b0be2
                        trust_ext_value = "0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%03"
Kai Engert f0b0be2
                    else:
Kai Engert f0b0be2
                        # email
Kai Engert f0b0be2
                        trust_ext_value = "0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%04"
Kai Engert f0b0be2
                else:
Kai Engert f0b0be2
                    if has_code_trust:
Kai Engert f0b0be2
                        # code
Kai Engert f0b0be2
                        trust_ext_value = "0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%03"
Kai Engert f0b0be2
                    else:
Kai Engert f0b0be2
                        # none
Kai Engert f0b0be2
                        trust_ext_value = "0%18%06%03U%1d%25%01%01%ff%04%0e0%0c%06%0a%2b%06%01%04%01%99w%06%0a%10"
Kai Engert f0b0be2
Kai Engert f0b0be2
            # no 2.5.29.37 for neutral certificates
Kai Engert f0b0be2
            if (is_distrusted or has_server_trust or has_email_trust or has_code_trust):
Kai Engert f0b0be2
                write_cert_ext_to_file(f, trust_ext_oid, trust_ext_value, pk)
Kai Engert f0b0be2
Kai Engert f0b0be2
            pk = ''
Kai Engert f0b0be2
            f.write("\n")
Kai Engert f0b0be2
Kai Engert f0b0be2
            f.write("[p11-kit-object-v1]\n")
Kai Engert f0b0be2
            f.write("label: ");
Kai Engert f0b0be2
            f.write(tobj['CKA_LABEL'])
Kai Engert f0b0be2
            f.write("\n")
Kai Engert f0b0be2
            if is_distrusted:
Kai Engert f0b0be2
                f.write("x-distrusted: true\n")
Kai Engert f0b0be2
            elif has_server_trust or has_email_trust or has_code_trust:
Kai Engert f0b0be2
                f.write("trusted: true\n")
Kai Engert f0b0be2
            else:
Kai Engert f0b0be2
                f.write("trusted: false\n")
Kai Engert f0b0be2
Kai Engert c1c2757
            # requires p11-kit >= 0.23.4
Kai Engert c1c2757
            f.write("nss-mozilla-ca-policy: true\n")
Kai Engert c1c2757
            f.write("modifiable: false\n");
Kai Engert f0b0be2
6aec97d
            # requires p11-kit >= 0.23.19
6aec97d
            for t in list(cert_distrust_types.keys()):
6aec97d
                if t in obj:
6aec97d
                    value = obj[t]
6aec97d
                    if value == 'CK_FALSE':
6aec97d
                        value = bytearray(1)
6aec97d
                    f.write(cert_distrust_types[t] + ": \"")
6aec97d
                    f.write(urllib.parse.quote(value));
6aec97d
                    f.write("\"\n")
6aec97d
Kai Engert 34f352d
            f.write("-----BEGIN CERTIFICATE-----\n")
Kai Engert 1a2c011
            temp_encoded_b64 = base64.b64encode(obj['CKA_VALUE'])
Kai Engert 1a2c011
            temp_wrapped = textwrap.wrap(temp_encoded_b64.decode(), 64)
Kai Engert 1a2c011
            f.write("\n".join(temp_wrapped))
Kai Engert 34f352d
            f.write("\n-----END CERTIFICATE-----\n")
Kai Engert f0b0be2
            f.write(cert_comment)
Kai Engert f0b0be2
            f.write("\n")
Kai Engert f0b0be2
Kai Engert 34f352d
        else:
Kai Engert 34f352d
            f.write("[p11-kit-object-v1]\n")
Kai Engert 34f352d
            f.write("label: ");
Kai Engert 34f352d
            f.write(tobj['CKA_LABEL']);
Kai Engert 34f352d
            f.write("\n")
Kai Engert 34f352d
            f.write("class: certificate\n")
Kai Engert 34f352d
            f.write("certificate-type: x-509\n")
Kai Engert c1c2757
            f.write("modifiable: false\n");
Kai Engert 34f352d
            f.write("issuer: \"");
Kai Engert 1a2c011
            f.write(urllib.parse.quote(tobj['CKA_ISSUER']));
Kai Engert 34f352d
            f.write("\"\n")
Kai Engert 34f352d
            f.write("serial-number: \"");
Kai Engert 1a2c011
            f.write(urllib.parse.quote(tobj['CKA_SERIAL_NUMBER']));
Kai Engert 34f352d
            f.write("\"\n")
Kai Engert 34f352d
            if (tobj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_NOT_TRUSTED') or (tobj['CKA_TRUST_EMAIL_PROTECTION'] == 'CKT_NSS_NOT_TRUSTED') or (tobj['CKA_TRUST_CODE_SIGNING'] == 'CKT_NSS_NOT_TRUSTED'):
Kai Engert 34f352d
              f.write("x-distrusted: true\n")
Kai Engert 34f352d
            f.write("\n\n")
Kai Engert e24bfeb
        f.close()
Kai Engert 1a2c011
        print(" -> written as '%s', trust = %s, openssl-trust = %s, distrust = %s, openssl-distrust = %s" % (fname, trustbits, openssl_trustflags, distrustbits, openssl_distrustflags))