diff options
author | Michael Tänzer <neo@nhng.de> | 2011-06-17 18:34:11 +0200 |
---|---|---|
committer | Michael Tänzer <neo@nhng.de> | 2011-06-17 18:34:11 +0200 |
commit | 9516e1d117d1dcf88db7ead53f950c66850c6fcb (patch) | |
tree | 12c677e0038b8f169831f84228c6e1a8f367c491 /scripts/DumpWeakCerts.pl | |
parent | 7c2327209cb81339d7e9a55d175c59786a2853b9 (diff) | |
download | cacert-devel-9516e1d117d1dcf88db7ead53f950c66850c6fcb.tar.gz cacert-devel-9516e1d117d1dcf88db7ead53f950c66850c6fcb.tar.xz cacert-devel-9516e1d117d1dcf88db7ead53f950c66850c6fcb.zip |
Source code taken from cacert-20110616.tar.bz2
Diffstat (limited to 'scripts/DumpWeakCerts.pl')
-rw-r--r-- | scripts/DumpWeakCerts.pl | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl new file mode 100644 index 0000000..85648fe --- /dev/null +++ b/scripts/DumpWeakCerts.pl @@ -0,0 +1,179 @@ +#!/usr/bin/perl +# Script to dump weak RSA certs (Exponent 3 or Modulus size < 1024) according to https://bugs.cacert.org/view.php?id=918 +# and https://wiki.cacert.org/Arbitrations/a20110312.1 + +use strict; +use warnings; + +use DBI; + +my $cacert_db_config; +my $cacert_db_user; +my $cacert_db_password; + +# Read database access data from the config file +eval `cat perl_mysql`; + +my $dbh = DBI->connect($cacert_db_config, $cacert_db_user, $cacert_db_password, { RaiseError => 1, AutoCommit => 0 } ) || die "Cannot connect database: $DBI::errstr"; + +my $sth_certs; +my $sth_userdata; + +my $cert_domid; +my $cert_userid; +my $cert_orgid; +my $cert_CN; +my $cert_expire; +my $cert_filename; +my $cert_serial; + +my $user_email; +my $user_firstname; + +my $reason; + +my @row; + +sub IsWeak($) { + my ($CertFileName) = @_; + + my $ModulusSize = 0; + my $Exponent = 0; + my $result = 0; + + # Do key size and exponent checking for RSA keys + open(CERTTEXT, '-|', "openssl x509 -in $CertFileName -noout -text") || die "Cannot start openssl"; + while (<CERTTEXT>) { + if (/^ +([^ ]+) Public Key:/) { + last if ($1 ne "RSA"); + } + if (/^ +Modulus \((\d+) bit\)/) { + $ModulusSize = $1; + } + if (/^ +Exponent: (\d+)/) { + $Exponent = $1; + last; + } + } + close(CERTTEXT); + if ($ModulusSize > 0 && $Exponent > 0) { + if ($ModulusSize < 1024 || $Exponent==3) { + $result = "SmallKey"; + } + } + + if (!$result) { + # Check with openssl-vulnkey + # This is currently not tested, if you don't know what you are doing leave it commented! + if (system("openssl-vulnkey -q $CertFileName") != 0) { + $result = "openssl-vulnkey"; + } + } + + return $result; +} + +# Select only certificates expiring in more than two weeks, since two weeks will probably be needed as turnaround time +# Get all domain certificates +$sth_certs = $dbh->prepare( + "SELECT `dc`.`domid`, `dc`.`CN`, `dc`.`expire`, `dc`.`crt_name`, `dc`.`serial` ". + " FROM `domaincerts` AS `dc` ". + " WHERE `dc`.`revoked`=0 AND `dc`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); +$sth_certs->execute(); + +$sth_userdata = $dbh->prepare( + "SELECT `u`.`email`, `u`.`fname` ". + " FROM `domains` AS `d`, `users` AS `u` ". + " WHERE `d`.`memid`=`u`.`id` AND `d`.`id`=?"); + +while(($cert_domid, $cert_CN, $cert_expire, $cert_filename, $cert_serial) = $sth_certs->fetchrow_array) { + if (-f $cert_filename) { + $reason = IsWeak($cert_filename); + if ($reason) { + $sth_userdata->execute($cert_domid); + ($user_email, $user_firstname) = $sth_userdata->fetchrow_array(); + print join("\t", ('DomainCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason, $cert_serial)). "\n"; + $sth_userdata->finish(); + } + } +} +$sth_certs->finish(); + +# Get all email certificates +$sth_certs = $dbh->prepare( + "SELECT `ec`.`memid`, `ec`.`CN`, `ec`.`expire`, `ec`.`crt_name`, `ec`.`serial` ". + " FROM `emailcerts` AS `ec` ". + " WHERE `ec`.`revoked`=0 AND `ec`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); +$sth_certs->execute(); + +$sth_userdata = $dbh->prepare( + "SELECT `u`.`email`, `u`.`fname` ". + " FROM `users` AS `u` ". + " WHERE `u`.`id`=?"); + +while(($cert_userid, $cert_CN, $cert_expire, $cert_filename, $cert_serial) = $sth_certs->fetchrow_array) { + if (-f $cert_filename) { + $reason = IsWeak($cert_filename); + if ($reason) { + $sth_userdata->execute($cert_userid); + ($user_email, $user_firstname) = $sth_userdata->fetchrow_array(); + print join("\t", ('EmailCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason, $cert_serial)). "\n"; + $sth_userdata->finish(); + } + } +} +$sth_certs->finish(); + +# Get all Org Server certificates, notify all admins of the Org! +$sth_certs = $dbh->prepare( + "SELECT `dc`.`orgid`, `dc`.`CN`, `dc`.`expire`, `dc`.`crt_name`, `dc`.`serial` ". + " FROM `orgdomaincerts` AS `dc` ". + " WHERE `dc`.`revoked`=0 AND `dc`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); +$sth_certs->execute(); + +$sth_userdata = $dbh->prepare( + "SELECT `u`.`email`, `u`.`fname` ". + " FROM `users` AS `u`, `org` ". + " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?"); + +while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename, $cert_serial) = $sth_certs->fetchrow_array) { + if (-f $cert_filename) { + $reason = IsWeak($cert_filename); + if ($reason) { + $sth_userdata->execute($cert_orgid); + while(($user_email, $user_firstname) = $sth_userdata->fetchrow_array()) { + print join("\t", ('OrgServerCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason, $cert_serial)). "\n"; + } + $sth_userdata->finish(); + } + } +} +$sth_certs->finish(); + +# Get all Org Email certificates, notify all admins of the Org! +$sth_certs = $dbh->prepare( + "SELECT `ec`.`orgid`, `ec`.`CN`, `ec`.`expire`, `ec`.`crt_name`, `ec`.`serial` ". + " FROM `orgemailcerts` AS `ec` ". + " WHERE `ec`.`revoked`=0 AND `ec`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); +$sth_certs->execute(); + +$sth_userdata = $dbh->prepare( + "SELECT `u`.`email`, `u`.`fname` ". + " FROM `users` AS `u`, `org` ". + " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?"); + +while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename, $cert_serial) = $sth_certs->fetchrow_array) { + if (-f $cert_filename) { + $reason = IsWeak($cert_filename); + if ($reason) { + $sth_userdata->execute($cert_orgid); + while(($user_email, $user_firstname) = $sth_userdata->fetchrow_array()) { + print join("\t", ('OrgEmailCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason, $cert_serial)). "\n"; + } + $sth_userdata->finish(); + } + } +} +$sth_certs->finish(); + +$dbh->disconnect(); |