michael@3: #!/usr/bin/perl michael@3: michael@3: # Copyright (C) 2007, 2008 Red Hat, Inc. michael@3: # michael@3: # This program is free software; you can redistribute it and/or modify michael@3: # it under the terms of the GNU General Public License as published by michael@3: # the Free Software Foundation; either version 2 of the License, or michael@3: # (at your option) any later version. michael@3: # michael@3: # This program is distributed in the hope that it will be useful, michael@3: # but WITHOUT ANY WARRANTY; without even the implied warranty of michael@3: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the michael@3: # GNU General Public License for more details. michael@3: michael@3: # generate-cacerts.pl generates a JKS keystore named 'cacerts' from michael@3: # OpenSSL's certificate bundle using OpenJDK's keytool. michael@3: michael@3: # First extract each of OpenSSL's bundled certificates into its own michael@3: # aliased filename. michael@3: $file = $ARGV[1]; michael@3: open(CERTS, $file); michael@3: @certs = ; michael@3: close(CERTS); michael@3: michael@3: $pem_file_count = 0; michael@3: $in_cert_block = 0; michael@3: $write_current_cert = 1; michael@3: foreach $cert (@certs) michael@3: { michael@3: if ($cert =~ /Issuer: /) michael@3: { michael@3: $_ = $cert; michael@3: if ($cert =~ /personal-freemail/) michael@3: { michael@3: $cert_alias = "thawtepersonalfreemailca"; michael@3: } michael@3: elsif ($cert =~ /personal-basic/) michael@3: { michael@3: $cert_alias = "thawtepersonalbasicca"; michael@3: } michael@3: elsif ($cert =~ /personal-premium/) michael@3: { michael@3: $cert_alias = "thawtepersonalpremiumca"; michael@3: } michael@3: elsif ($cert =~ /server-certs/) michael@3: { michael@3: $cert_alias = "thawteserverca"; michael@3: } michael@3: elsif ($cert =~ /premium-server/) michael@3: { michael@3: $cert_alias = "thawtepremiumserverca"; michael@3: } michael@3: elsif ($cert =~ /Class 1 Public Primary Certification Authority$/) michael@3: { michael@3: $cert_alias = "verisignclass1ca"; michael@3: } michael@3: elsif ($cert =~ /Class 1 Public Primary Certification Authority - G2/) michael@3: { michael@3: $cert_alias = "verisignclass1g2ca"; michael@3: } michael@3: elsif ($cert =~ michael@3: /VeriSign Class 1 Public Primary Certification Authority - G3/) michael@3: { michael@3: $cert_alias = "verisignclass1g3ca"; michael@3: } michael@3: elsif ($cert =~ /Class 2 Public Primary Certification Authority$/) michael@3: { michael@3: $cert_alias = "verisignclass2ca"; michael@3: } michael@3: elsif ($cert =~ /Class 2 Public Primary Certification Authority - G2/) michael@3: { michael@3: $cert_alias = "verisignclass2g2ca"; michael@3: } michael@3: elsif ($cert =~ michael@3: /VeriSign Class 2 Public Primary Certification Authority - G3/) michael@3: { michael@3: $cert_alias = "verisignclass2g3ca"; michael@3: } michael@3: elsif ($cert =~ /Class 3 Public Primary Certification Authority$/) michael@3: { michael@3: $cert_alias = "verisignclass3ca"; michael@3: } michael@3: # Version 1 of Class 3 Public Primary Certification Authority michael@3: # - G2 is added. Version 3 is excluded. See below. michael@3: elsif ($cert =~ /Class 3 Public Primary Certification Authority - G2/) michael@3: { michael@3: $cert_alias = "verisignclass3g2ca"; michael@3: } michael@3: elsif ($cert =~ michael@3: /VeriSign Class 3 Public Primary Certification Authority - G3/) michael@3: { michael@3: $cert_alias = "verisignclass3g3ca"; michael@3: } michael@3: elsif ($cert =~ michael@3: /RSA Data Security.*Secure Server Certification Authority/) michael@3: { michael@3: $cert_alias = "verisignserverca"; michael@3: } michael@3: elsif ($cert =~ /GTE CyberTrust Global Root/) michael@3: { michael@3: $cert_alias = "gtecybertrustglobalca"; michael@3: } michael@3: elsif ($cert =~ /Baltimore CyberTrust Root/) michael@3: { michael@3: $cert_alias = "baltimorecybertrustca"; michael@3: } michael@3: elsif ($cert =~ /www.entrust.net\/Client_CA_Info\/CPS/) michael@3: { michael@3: $cert_alias = "entrustclientca"; michael@3: } michael@3: elsif ($cert =~ /www.entrust.net\/GCCA_CPS/) michael@3: { michael@3: $cert_alias = "entrustglobalclientca"; michael@3: } michael@3: elsif ($cert =~ /www.entrust.net\/CPS_2048/) michael@3: { michael@3: $cert_alias = "entrust2048ca"; michael@3: } michael@3: elsif ($cert =~ /www.entrust.net\/CPS /) michael@3: { michael@3: $cert_alias = "entrustsslca"; michael@3: } michael@3: elsif ($cert =~ /www.entrust.net\/SSL_CPS/) michael@3: { michael@3: $cert_alias = "entrustgsslca"; michael@3: } michael@3: elsif ($cert =~ /The Go Daddy Group/) michael@3: { michael@3: $cert_alias = "godaddyclass2ca"; michael@3: } michael@3: elsif ($cert =~ /Starfield Class 2 Certification Authority/) michael@3: { michael@3: $cert_alias = "starfieldclass2ca"; michael@3: } michael@3: elsif ($cert =~ /ValiCert Class 2 Policy Validation Authority/) michael@3: { michael@3: $cert_alias = "valicertclass2ca"; michael@3: } michael@3: elsif ($cert =~ /GeoTrust Global CA$/) michael@3: { michael@3: $cert_alias = "geotrustglobalca"; michael@3: } michael@3: elsif ($cert =~ /Equifax Secure Certificate Authority/) michael@3: { michael@3: $cert_alias = "equifaxsecureca"; michael@3: } michael@3: elsif ($cert =~ /Equifax Secure eBusiness CA-1/) michael@3: { michael@3: $cert_alias = "equifaxsecureebusinessca1"; michael@3: } michael@3: elsif ($cert =~ /Equifax Secure eBusiness CA-2/) michael@3: { michael@3: $cert_alias = "equifaxsecureebusinessca2"; michael@3: } michael@3: elsif ($cert =~ /Equifax Secure Global eBusiness CA-1/) michael@3: { michael@3: $cert_alias = "equifaxsecureglobalebusinessca1"; michael@3: } michael@3: elsif ($cert =~ /Sonera Class1 CA/) michael@3: { michael@3: $cert_alias = "soneraclass1ca"; michael@3: } michael@3: elsif ($cert =~ /Sonera Class2 CA/) michael@3: { michael@3: $cert_alias = "soneraclass2ca"; michael@3: } michael@3: elsif ($cert =~ /AAA Certificate Services/) michael@3: { michael@3: $cert_alias = "comodoaaaca"; michael@3: } michael@3: elsif ($cert =~ /AddTrust Class 1 CA Root/) michael@3: { michael@3: $cert_alias = "addtrustclass1ca"; michael@3: } michael@3: elsif ($cert =~ /AddTrust External CA Root/) michael@3: { michael@3: $cert_alias = "addtrustexternalca"; michael@3: } michael@3: elsif ($cert =~ /AddTrust Qualified CA Root/) michael@3: { michael@3: $cert_alias = "addtrustqualifiedca"; michael@3: } michael@3: elsif ($cert =~ /UTN-USERFirst-Hardware/) michael@3: { michael@3: $cert_alias = "utnuserfirsthardwareca"; michael@3: } michael@3: elsif ($cert =~ /UTN-USERFirst-Client Authentication and Email/) michael@3: { michael@3: $cert_alias = "utnuserfirstclientauthemailca"; michael@3: } michael@3: elsif ($cert =~ /UTN - DATACorp SGC/) michael@3: { michael@3: $cert_alias = "utndatacorpsgcca"; michael@3: } michael@3: elsif ($cert =~ /UTN-USERFirst-Object/) michael@3: { michael@3: $cert_alias = "utnuserfirstobjectca"; michael@3: } michael@3: elsif ($cert =~ /America Online Root Certification Authority 1/) michael@3: { michael@3: $cert_alias = "aolrootca1"; michael@3: } michael@3: elsif ($cert =~ /DigiCert Assured ID Root CA/) michael@3: { michael@3: $cert_alias = "digicertassuredidrootca"; michael@3: } michael@3: elsif ($cert =~ /DigiCert Global Root CA/) michael@3: { michael@3: $cert_alias = "digicertglobalrootca"; michael@3: } michael@3: elsif ($cert =~ /DigiCert High Assurance EV Root CA/) michael@3: { michael@3: $cert_alias = "digicerthighassuranceevrootca"; michael@3: } michael@3: elsif ($cert =~ /GlobalSign Root CA$/) michael@3: { michael@3: $cert_alias = "globalsignca"; michael@3: } michael@3: elsif ($cert =~ /GlobalSign Root CA - R2/) michael@3: { michael@3: $cert_alias = "globalsignr2ca"; michael@3: } michael@3: elsif ($cert =~ /Elektronik.*Kas.*2005/) michael@3: { michael@3: $cert_alias = "extra-elektronikkas2005"; michael@3: } michael@3: elsif ($cert =~ /Elektronik/) michael@3: { michael@3: $cert_alias = "extra-elektronik2005"; michael@3: } michael@3: # Mozilla does not provide these certificates: michael@3: # baltimorecodesigningca michael@3: # gtecybertrust5ca michael@3: # trustcenterclass2caii michael@3: # trustcenterclass4caii michael@3: # trustcenteruniversalcai michael@3: else michael@3: { michael@3: # Generate an alias using the OU and CN attributes of the michael@3: # Issuer field if both are present, otherwise use only the michael@3: # CN attribute. The Issuer field must have either the OU michael@3: # or the CN attribute. michael@3: $_ = $cert; michael@3: if ($cert =~ /OU=/) michael@3: { michael@3: s/Issuer:.*?OU=//; michael@3: # Remove other occurrences of OU=. michael@3: s/OU=.*CN=//; michael@3: # Remove CN= if there were not other occurrences of OU=. michael@3: s/CN=//; michael@3: s/\/emailAddress.*//; michael@3: s/Certificate Authority/ca/g; michael@3: s/Certification Authority/ca/g; michael@3: } michael@3: elsif ($cert =~ /CN=/) michael@3: { michael@3: s/Issuer:.*CN=//; michael@3: s/\/emailAddress.*//; michael@3: s/Certificate Authority/ca/g; michael@3: s/Certification Authority/ca/g; michael@3: } michael@3: s/\W//g; michael@3: tr/A-Z/a-z/; michael@3: $cert_alias = "extra-$_"; michael@3: } michael@3: } michael@3: # When it attempts to parse: michael@3: # michael@3: # Class 3 Public Primary Certification Authority - G2, Version 3 michael@3: # michael@3: # keytool says: michael@3: # michael@3: # #2: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false michael@3: # Unparseable AuthorityInfoAccess extension due to michael@3: # java.io.IOException: Invalid encoding of URI michael@3: # michael@3: # If we do not exclude this file michael@3: # openjdk/jdk/test/lib/security/cacerts/VerifyCACerts.java fails michael@3: # on this cert, printing: michael@3: # michael@3: # Couldn't verify: java.security.SignatureException: Signature michael@3: # does not match. michael@3: # michael@3: elsif ($cert =~ michael@3: /A6:0F:34:C8:62:6C:81:F6:8B:F7:7D:A9:F6:67:58:8A:90:3F:7D:36/) michael@3: { michael@3: $write_current_cert = 0; michael@3: $pem_file_count--; michael@3: } michael@3: elsif ($cert eq "-----BEGIN CERTIFICATE-----\n") michael@3: { michael@3: if ($in_cert_block != 0) michael@3: { michael@3: die "$file is malformed."; michael@3: } michael@3: $in_cert_block = 1; michael@3: if ($write_current_cert == 1) michael@3: { michael@3: $pem_file_count++; michael@3: open(PEM, ">$cert_alias.pem"); michael@3: print PEM $cert; michael@3: } michael@3: } michael@3: elsif ($cert eq "-----END CERTIFICATE-----\n") michael@3: { michael@3: $in_cert_block = 0; michael@3: if ($write_current_cert == 1) michael@3: { michael@3: print PEM $cert; michael@3: close(PEM); michael@3: } michael@3: $write_current_cert = 1 michael@3: } michael@3: else michael@3: { michael@3: if ($in_cert_block == 1 && $write_current_cert == 1) michael@3: { michael@3: print PEM $cert; michael@3: } michael@3: } michael@3: } michael@3: michael@3: # Check that the correct number of .pem files were produced. michael@3: @pem_files = <*.pem>; michael@3: if (@pem_files != $pem_file_count) michael@3: { michael@3: print "$pem_file_count"; michael@3: die "Number of .pem files produced does not match". michael@3: " number of certs read from $file."; michael@3: } michael@3: michael@3: # Now store each cert in the 'cacerts' file using keytool. michael@3: $certs_written_count = 0; michael@3: foreach $pem_file (@pem_files) michael@3: { michael@3: system "/bin/echo yes | $ARGV[0] -import". michael@3: " -alias `basename $pem_file .pem`". michael@3: " -keystore cacerts -storepass 'changeit' -file $pem_file"; michael@3: unlink($pem_file); michael@3: $certs_written_count++; michael@3: } michael@3: michael@3: # Check that the correct number of certs were added to the keystore. michael@3: if ($certs_written_count != $pem_file_count) michael@3: { michael@3: die "Number of certs added to keystore does not match". michael@3: " number of certs read from $file."; michael@3: }