cacert.pem / include fingerprints/serial in the output of mk-ca-bundle.pl #937

Closed
rmoriz opened this Issue Jul 28, 2016 · 5 comments

Projects

None yet

2 participants

@rmoriz
rmoriz commented Jul 28, 2016 edited

Hi,

Mozilla's trust store contains serveral metadata for each root certificate like serial and fingerprints as comments, for example:

# Certificate "GlobalSign Root CA - R2"
#
# Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R2
# Serial Number:04:00:00:00:00:01:0f:86:26:e6:0d
# Subject: CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R2
# Not Valid Before: Fri Dec 15 08:00:00 2006
# Not Valid After : Wed Dec 15 08:00:00 2021
# Fingerprint (MD5): 94:14:77:7E:3E:5E:FD:8F:30:BD:41:B0:CF:E7:D0:30
# Fingerprint (SHA1): 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE

However mk-ca-bundle.pl currently ignores this while generating cacert.pem.

I understand adding serial and fingerprints would slightly increase the file size, however it would provide a better debug/verify-ability for humans. Currently one has to copy the extracted certificate to a file, run openssl to get fingerprints, fire up google (or use another way) to lookup fingerprints.

@bagder
Member
bagder commented Jul 28, 2016

It was made like that I think mostly because nobody has expressed any desire to use that metadata. It should be fairly easy to just keep that in the output file as well. You feel like writing a pull-request to make this happen?

@bagder
Member
bagder commented Aug 2, 2016

I'm adding a -m option to the script (m for meta data) that will pass on those comments to the output file.

@bagder bagder self-assigned this Aug 2, 2016
@rmoriz
rmoriz commented Aug 2, 2016

Parsing comments is probably ugly, running openssl to get the values is probably taking a lot of time…

by the way: Is there anything that speaks against using https here? https://github.com/curl/curl/blob/a0c2ab93700069a03fad0115442bad9a3ca996fe/lib/mk-ca-bundle.pl#L47-L58

@bagder
Member
bagder commented Aug 2, 2016

Well, parsing the comments is left for someone else. I'm just suggesting the new option would pass the comments that hold the meta-data through to the output file. What to do with them and how to parse them is left for the user of this.

And for HTTPS, we already use that if you have curl installed to download with. See https://github.com/curl/curl/blob/a0c2ab93700069a03fad0115442bad9a3ca996fe/lib/mk-ca-bundle.pl#L293

@bagder
Member
bagder commented Aug 2, 2016

Here's my proposed patch

From a0df737e3007cb207c829394bfd80f085bad3fad Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 2 Aug 2016 12:17:10 +0200
Subject: [PATCH] mk-ca-bundle.pl: -m keeps ca cert meta data in output

Makes the script pass on comments holding meta data to the output
file. Like fingerprinters, issuer, date ranges etc.

Closes #937
---
 lib/mk-ca-bundle.pl | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/lib/mk-ca-bundle.pl b/lib/mk-ca-bundle.pl
index 5a1435c..01a552e 100755
--- a/lib/mk-ca-bundle.pl
+++ b/lib/mk-ca-bundle.pl
@@ -4,11 +4,11 @@
 # *  Project                     ___| | | |  _ \| |
 # *                             / __| | | | |_) | |
 # *                            | (__| |_| |  _ <| |___
 # *                             \___|\___/|_| \_\_____|
 # *
-# * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+# * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
 # *
 # * This software is licensed as described in the file COPYING, which
 # * you should have received as part of this distribution. The terms
 # * are also available at https://curl.haxx.se/docs/copyright.html.
 # *
@@ -32,11 +32,11 @@
 #
 use Getopt::Std;
 use MIME::Base64;
 use LWP::UserAgent;
 use strict;
-use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_l $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
+use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
 use List::Util;
 use Text::Wrap;
 my $MOD_SHA = "Digest::SHA";
 eval "require $MOD_SHA";
 if ($@) {
@@ -60,11 +60,11 @@ my %urls = (
 $opt_d = 'release';

 # If the OpenSSL commandline is not in search path you can configure it here!
 my $openssl = 'openssl';

-my $version = '1.25';
+my $version = '1.26';

 $opt_w = 76; # default base64 encoded lines length

 # default cert types to include in the output (default is to include CAs which may issue SSL server certs)
 my $default_mozilla_trust_purposes = "SERVER_AUTH";
@@ -107,11 +107,11 @@ my @valid_signature_algorithms = (
   "SHA512"
 );

 $0 =~ s@.*(/|\\)@@;
 $Getopt::Std::STANDARD_HELP_VERSION = 1;
-getopts('bd:fhilnp:qs:tuvw:');
+getopts('bd:fhilmnp:qs:tuvw:');

 if(!defined($opt_d)) {
     # to make plain "-d" use not cause warnings, and actually still work
     $opt_d = 'release';
 }
@@ -159,10 +159,11 @@ sub HELP_MESSAGE() {
   print "\t\t  Valid names are:\n";
   print "\t\t    ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n";
   print "\t-f\tforce rebuild even if certdata.txt is current\n";
   print "\t-i\tprint version info about used modules\n";
   print "\t-l\tprint license info about certdata.txt\n";
+  print "\t-m\tinclude meta data in output\n";
   print "\t-n\tno download of certdata.txt (to use existing)\n";
   print wrap("\t","\t\t", "-p\tlist of Mozilla trust purposes and levels for certificates to include in output. Takes the form of a comma separated list of purposes, a colon, and a comma separated list of levels. (default: $default_mozilla_trust_purposes:$default_mozilla_trust_levels)"), "\n";
   print "\t\t  Valid purposes are:\n";
   print wrap("\t\t    ","\t\t    ", join( ", ", "ALL", @valid_mozilla_trust_purposes ) ), "\n";
   print "\t\t  Valid levels are:\n";
@@ -369,10 +370,11 @@ EOT
 report "Processing  '$txt' ...";
 my $caname;
 my $certnum = 0;
 my $skipnum = 0;
 my $start_of_cert = 0;
+my @precert;

 open(TXT,"$txt") or die "Couldn't open $txt: $!\n";
 while (<TXT>) {
   if (/\*\*\*\*\* BEGIN LICENSE BLOCK \*\*\*\*\*/) {
     print CRT;
@@ -381,15 +383,19 @@ while (<TXT>) {
       print CRT;
       print if ($opt_l);
       last if (/\*\*\*\*\* END LICENSE BLOCK \*\*\*\*\*/);
     }
   }
-  next if /^#|^\s*$/;
-  chomp;
-  if (/^CVS_ID\s+\"(.*)\"/) {
-    print CRT "# $1\n";
+  elsif(/^# (Issuer|Serial Number|Subject|Not Valid Before|Not Valid After |Fingerprint \(MD5\)|Fingerprint \(SHA1\)):/) {
+      push @precert, $_;
+      next;
+  }
+  elsif(/^#|^\s*$/) {
+      undef @precert;
+      next;
   }
+  chomp;

   # this is a match for the start of a certificate
   if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) {
     $start_of_cert = 1
   }
@@ -434,11 +440,11 @@ while (<TXT>) {
       $encoded =~ s/(.{1,${opt_w}})/$1\n/g;
       my $pem = "-----BEGIN CERTIFICATE-----\n"
               . $encoded
               . "-----END CERTIFICATE-----\n";
       print CRT "\n$caname\n";
-
+      print CRT @precert if($opt_m);
       my $maxStringLength = length($caname);
       if ($opt_t) {
         foreach my $key (keys %trust_purposes_by_level) {
            my $string = $key . ": " . join(", ", @{$trust_purposes_by_level{$key}});
            $maxStringLength = List::Util::max( length($string), $maxStringLength );
@@ -477,11 +483,13 @@ while (<TXT>) {
       }
       report "Parsing: $caname" if ($opt_v);
       $certnum ++;
       $start_of_cert = 0;
     }
+    undef @precert;
   }
+
 }
 close(TXT) or die "Couldn't close $txt: $!\n";
 close(CRT) or die "Couldn't close $crt.~: $!\n";
 unless( $stdout ) {
     if ($opt_b && -e $crt) {
-- 
2.8.1
@bagder bagder added a commit that closed this issue Aug 3, 2016
@bagder bagder mk-ca-bundle.pl: -m keeps ca cert meta data in output
Makes the script pass on comments holding meta data to the output
file. Like fingerprinters, issuer, date ranges etc.

Closes #937
600bb4e
@bagder bagder closed this in 600bb4e Aug 3, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment