#!/usr/bin/env ruby

tmpcert = "/tmp/tmpcert.der"

incert=false
intrust=false

if ARGV.length != 1
  abort "\nPass path to the certdata.txt you want to add as first input argument to this script\n\n"+
    "certdata.txt can be retrieved from the newest NSS release."
end

url = 'http://mxr.mozilla.org/mozilla-central/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1'
io = open(ARGV[0]);

puts "# Don't edit!  This file is automatically generated."
puts "# Generated at: #{Time.now}"
puts "# Generated from: #{url}"
puts "#"
puts "# The original source file comes with this licensing statement:"
puts "#"
puts "#   This Source Code Form is subject to the terms of the Mozilla Public"
puts "#   License, v. 2.0. If a copy of the MPL was not distributed with this"
puts "#   file, You can obtain one at http://mozilla.org/MPL/2.0/."
puts ""

puts "@load base/protocols/ssl"
puts "module SSL;";
puts "redef root_certs += {";

all_certs = []
all_subjects = []

cert_name = ""
cert = ""
io.each do |line|
  line.chomp!
  if intrust
    if line =~ /^CKA_TRUST_SERVER_AUTH/
      if line =~ /CKT_NSS_TRUSTED_DELEGATOR/
        File.open(tmpcert, "wb") do |f|
            byteArray = cert.split("\\x")
            max = byteArray.length() - 1
            byteArray[1..max].each do | byte |
                f.print byte.hex.chr
            end
        end

        cert_subj = `openssl x509 -in #{tmpcert} -inform DER -noout -subject -nameopt RFC2253`
        cert_subj["subject= "]= ""
        cert_subj.chomp!
        File.delete(tmpcert)

        if not all_subjects.include?(cert_subj)
            puts "	[\"#{cert_subj}\"] = \"#{cert}\","
            all_subjects << cert_subj
        end
      end
      intrust=false
    end
  else
    if line =~ /^CKA_LABEL/
      cert_name = line.sub(/.*\"(.*)\".*/, "\\1")
      i = 0
      while all_certs.include?(cert_name)
        i+=1
        cert_name += " #{i}"
      end
      all_certs << cert_name
    elsif line =~ /^CKA_VALUE MULTILINE_OCTAL/
      incert=true
      cert=""
    elsif line =~ /^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/
      intrust=true
    elsif line =~ /^END/
      incert=false
    elsif incert
      cert += line.split(/\\/).collect { |x| x.oct.chr.unpack("H2")[0].upcase if x!="" }.join("\\x")
    end
  end
end
puts "};"
