Adding SHA-2 to tinyca

Google has announced a sunset for SHA-1 certificate signatures in Chrome. SHA-2 (aka SHA-256, SHA-384, and SHA-512) is the remaining option for certificate signatures. I decided to upgrade my certificates to SHA-2 (256 bits). However, when I tried to use tinyca2 to generate a SHA-2 certificate, I found it was not supported.

As tinyca2 is a Perl package, I looked at the code to see how difficult it would be to update. The code is easy to read and well modularized. Adding the SHA-2 involves changes to the GUI, REQ, CERT, and OpenSSL components. I updated six files, although support can be added with fewer.

Patches are attached at the end of this post.  An additional patch to apply the selected digest when creating sub-CAs (thanks to Cédric Dufour) has been included.

Included in the patches I generated were removing or flagging insecure signature algorithms. I removed all algorithms not supported by my openssl installation, and modified the labels for insecure algorithms to flag them. These algorithms should still be usable.  Line numbers in the following discussion refer to the code distributed in Ubuntu Trusty Tahr as tinyca 0.7.5-5.

REQ.pm

When generating a request, the signature digest is added.  This module sets the default algorithm. I changed the default from sha-1 to sha-256 at line 62.

The code trims the digest algorithm option starting at line 419. I added 2 lines at line 429 to trim the option sha256. This change may not be required. Additional algorithms may be added here.

      } elsif ($opts->{'digest'} =~ /^sha256/) {
          $opts->{'digest'} = "sha256";

OpenSSL.pm

This module captures fingerprints starting at line 642. It loads fingerprints for the MD5 and SHA1 algorithms. I duplicated the code for SHA1 code starting at line 660 and changed the algorithm to SHA256. This code enables changes to the displayed fingerprints described below. You may choose to omit checking the value in $ret if you want the display to work if the SHA-256 fingerprint cannot be retrieved.

   $cmd = "$self->{'bin'} x509 -noout -fingerprint -sha256 -in $file";
   $ext = "$cmdnn";
   $pid = open3($wtfh, $rdfh, $rdfh, $cmd);
   while(<$rdfh>){
      $ext .= $_;
      ($k, $v) = split(/=/);
      $tmp->{'FINGERPRINTSHA256'} = $v if($k =~ /SHA256 Fingerprint/i);
      chomp($tmp->{'FINGERPRINTSHA256'});
   }
   waitpid($pid, 0);
   $ret = $? >> 8;

   if($ret) {
      $t = _("Error reading fingerprint from Certificate");
      GUI::HELPERS::print_warning($t, $ext);
   }

MD5 signature display may be removed by deleting or commenting the two blocks at line 642. It is like the above block and begins:

        $cmd = "$self->{'bin'} x509 -noout -fingerprint -md5 -in $file";

GUI.pm

Labels for the signature algorithms are at line 31. I commented the labels for md2, mcd2, and sha which did not work with my openssl version. I also commented a duplicated sha1 definition. I added the new algorithm to the end of the list at line 40.

                     'sha256' => 'SHA-256',

NOTE: The line containing the signature labels and radio buttons controls the width of the request entry screen. If you trim the list excessively, the window will be quite narrow. You can increase the width by using longer label text.

Further down at line 1066 there is code to display the fingerprints for requests. I added the FINGERPRINT256 signature to the list. To remove the MD5 fingerprint remove FINGERPRINTMD5 from the list.  OpenSSL.pm ass the fingerprints as described above.

       for my $l (qw(FINGERPRINTMD5 FINGERPRINTSHA1 FINGERPRINTSHA256)) {

GUI/WORDS.pm

This module has the display labels for various text segments (words). It defines labels for the fingerprints. Add the SHA-256 description at line 73 after the SHA-1 description.

    'FINGERPRINTSHA256'     => _("Fingerprint (SHA256)"),

GUI/X509_infobox.pm

The module displays the infobox for X509 certificates. Fingerprints for SHA-384 and SHA-512 are too long to display cleanly.

      if(defined($self->{'certfingerprintsha256'})) {
         $self->{'certfingerprintsha256'}->destroy();
      }
      $self->{'certfingerprintsha256'} = GUI::HELPERS::create_label(
            _("Fingerprint (SHA256)").": ".$parsed->{'FINGERPRINTSHA256'},
            'center', 0, 0);
      $self->{'x509textbox'}->pack_start($self->{'certfingerprintsha256'},
            0, 0, 0);

CERT.pm

This GUI module displays certificate requests. This change shows the SHA-256 fingerprint, but is not required to add support for SHA-2. The display of the MD5 signature can be removed by commenting or removing line 281. SHA2 support is added at line 283, but requires the fingerprint must be captured as documented above.

          $out .= "Fingerprint (SHA256): $opts->{'parsed'}->{'FINGERPRINTSHA256'}nn";

Patches

I have created two patch files. The first support for SHA-2 with a 256 bit signature (SHA-256).

This second patch adds support for SHA-2 with 384 and 512 bit signatures (SHA-384, and SHA-512). The CA display screen was not updated to show these signatures for the CA certificate.

git. generated the patches. Apply the patches with patch from within the tinyca directory using the -p1 option, or use git.

7 thoughts on “Adding SHA-2 to tinyca

  1. Alexander

    Dear, I have tinyca 0.7.5-4 on a Debian server….does this patch work for me ??? I have my own CA with several server certificates, do I have to do anything before patching ???

    Thanks a lot,

    Alexander

  2. Bill Thorsteinson Post author

    The Debian and Ubuntu versions should be identical. The patch should work fine. If there are any failures, the patch utility will create a reject file which will help you adjust the patch if necessary.

    Once you are done you will want to create a new CA using SHA-2. If you have installed your new CA certificate anywhere, install the new CA certificate as well. When your certificates need renewing, issue new certificates with SHA-2 signatures using the new CA.

  3. Cédric Dufour

    Hello,

    Thanks for your patches!

    To allow subCA to be created with user-configured digest, please consider:

    diff -urN tinyca.orig/CA.pm tinyca/CA.pm
    — tinyca.orig/CA.pm2006-07-25 22:12:00.000000000 +0200
    +++ tinyca/CA.pm2014-11-25 19:23:39.480333876 +0100
    @@ -1062,6 +1062,7 @@
    ‘outdir’ => $self->{$ca}->{‘dir’}.”/newcerts/”,
    ‘keyfile’ => $self->{$ca}->{‘dir’}.”/cacert.key”,
    ‘cacertfile’ => $self->{$ca}->{‘dir’}.”/cacert.pem”,
    + ‘digest’ => $opts->{‘digest’},
    ‘pass’ => $opts->{‘passwd’},
    ‘days’ => $opts->{‘days’},
    ‘parentpw’ => $opts->{‘parentpw’},

Comments are closed.