From 00bf1965735bd5a5bc41ed3db42ac935b5a5e387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Fr=C3=B6hlich?= Date: Sat, 26 Mar 2011 23:44:20 +0100 Subject: First running version. Call to openssl-vulnkey still missing. --- scripts/DumpWeakCerts.pl | 153 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100755 scripts/DumpWeakCerts.pl diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl new file mode 100755 index 0000000..b00988c --- /dev/null +++ b/scripts/DumpWeakCerts.pl @@ -0,0 +1,153 @@ +#!/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 $dbh = DBI->connect('DBI:mysql:database=cacert;host=127.0.0.1', 'cacert', 'FKj54eZQsZIW', { RaiseError => 1 } ) || die "Cannot connect database: $DBI::errstr"; + +my $sth_certs; +my $sth_userdata; + +my $cert_domid; +my $cert_userid; +my $cert_CN; +my $cert_expire; +my $cert_filename; + +my $user_email; +my $user_firstname; + +my @row; + +sub IsWeak($) { + my ($CertFileName) = @_; + + my $ModulusSize = 0; + my $Exponent = 0; + my $result = 0; + + open(CERTTEXT, '-|', "openssl x509 -in $CertFileName -noout -text") || die "Cannot start openssl"; + while () { + 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 = 1; + } + } +} + +# 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 ". + " FROM domaincerts AS dc ". + " WHERE 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) = $sth_certs->fetchrow_array) { + if (-f $cert_filename) { + if (IsWeak($cert_filename)) { + $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)). "\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 ". + " FROM emailcerts AS ec ". + " WHERE 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) = $sth_certs->fetchrow_array) { + if (-f $cert_filename) { + if (IsWeak($cert_filename)) { + $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)). "\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 ". + " FROM orgdomaincerts AS dc ". + " WHERE 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_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { + if (-f $cert_filename) { + if (IsWeak($cert_filename)) { + $sth_userdata->execute($cert_userid); + while(($user_email, $user_firstname) = $sth_userdata->fetchrow_array()) { + print join("\t", ('OrgServerCert', $user_email, $user_firstname, $cert_expire, $cert_CN)). "\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 ". + " FROM orgemailcerts AS ec ". + " WHERE 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_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { + if (-f $cert_filename) { + if (IsWeak($cert_filename)) { + $sth_userdata->execute($cert_userid); + while(($user_email, $user_firstname) = $sth_userdata->fetchrow_array()) { + print join("\t", ('OrgEmailCert', $user_email, $user_firstname, $cert_expire, $cert_CN)). "\n"; + } + $sth_userdata->finish(); + } + } +} +$sth_certs->finish(); + +$dbh->disconnect(); -- cgit v1.2.1 From 3cdf9f382b70f4fb44f70e9e7acfb3775a24f906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Sun, 27 Mar 2011 22:25:05 +0200 Subject: #918: Weak keys in certificates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detection script: Put database username and password into a separate file Signed-off-by: Michael Tänzer --- scripts/DumpWeakCerts.pl | 9 ++++++++- scripts/perl_mysql.sample | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 scripts/perl_mysql.sample diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl index b00988c..54bd11a 100755 --- a/scripts/DumpWeakCerts.pl +++ b/scripts/DumpWeakCerts.pl @@ -7,7 +7,14 @@ use warnings; use DBI; -my $dbh = DBI->connect('DBI:mysql:database=cacert;host=127.0.0.1', 'cacert', 'FKj54eZQsZIW', { RaiseError => 1 } ) || die "Cannot connect database: $DBI::errstr"; +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 } ) || die "Cannot connect database: $DBI::errstr"; my $sth_certs; my $sth_userdata; diff --git a/scripts/perl_mysql.sample b/scripts/perl_mysql.sample new file mode 100644 index 0000000..4800289 --- /dev/null +++ b/scripts/perl_mysql.sample @@ -0,0 +1,6 @@ +# This file contains the data needed to connect to the database to be +# used in perl scripts + +$cacert_db_config = 'DBI:mysql:database=cacert;host=127.0.0.1'; +$cacert_db_user = 'cacert'; +$cacert_db_password = ''; \ No newline at end of file -- cgit v1.2.1 From 94391e3f41777169f9064dbf2d1a4fa8fa53784d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Sun, 27 Mar 2011 23:02:03 +0200 Subject: #918: Weak keys in certificates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't rely on AutoCommit being on by default as stated in the perl docu Signed-off-by: Michael Tänzer --- scripts/DumpWeakCerts.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl index 54bd11a..e31d0be 100755 --- a/scripts/DumpWeakCerts.pl +++ b/scripts/DumpWeakCerts.pl @@ -14,7 +14,7 @@ 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 } ) || die "Cannot connect database: $DBI::errstr"; +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; -- cgit v1.2.1 From 7a296469f7d4aa0a5e6d646780357979db04dfdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Sun, 27 Mar 2011 23:58:25 +0200 Subject: #918: Weak keys in certificates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detection script: Always escape all SQL non-keywords Signed-off-by: Michael Tänzer --- scripts/DumpWeakCerts.pl | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl index e31d0be..cecdad5 100755 --- a/scripts/DumpWeakCerts.pl +++ b/scripts/DumpWeakCerts.pl @@ -61,15 +61,15 @@ sub IsWeak($) { # 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 ". - " FROM domaincerts AS dc ". - " WHERE dc.expire > DATE_ADD(NOW(), INTERVAL 14 DAY)"); + "SELECT `dc`.`domid`, `dc`.`CN`, `dc`.`expire`, `dc`.`crt_name` ". + " FROM `domaincerts` AS `dc` ". + " WHERE `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=?"); + "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) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { @@ -85,15 +85,15 @@ $sth_certs->finish(); # Get all email certificates $sth_certs = $dbh->prepare( - "SELECT ec.memid, ec.CN, ec.expire, ec.crt_name ". - " FROM emailcerts AS ec ". - " WHERE ec.expire > DATE_ADD(NOW(), INTERVAL 14 DAY)"); + "SELECT `ec`.`memid`, `ec`.`CN`, `ec`.`expire`, `ec`.`crt_name` ". + " FROM `emailcerts` AS `ec` ". + " WHERE `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=?"); + "SELECT `u`.`email`, `u`.`fname` ". + " FROM `users` AS `u` ". + " WHERE `u`.`id`=?"); while(($cert_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { @@ -109,15 +109,15 @@ $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 ". - " FROM orgdomaincerts AS dc ". - " WHERE dc.expire > DATE_ADD(NOW(), INTERVAL 14 DAY)"); + "SELECT `dc`.`orgid`, `dc`.`CN`, `dc`.`expire`, `dc`.`crt_name` ". + " FROM `orgdomaincerts` AS `dc` ". + " WHERE `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=?"); + "SELECT `u`.`email`, `u`.`fname` ". + " FROM `users` AS `u`, `org` ". + " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?"); while(($cert_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { @@ -134,15 +134,15 @@ $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 ". - " FROM orgemailcerts AS ec ". - " WHERE ec.expire > DATE_ADD(NOW(), INTERVAL 14 DAY)"); + "SELECT `ec`.`orgid`, `ec`.`CN`, `ec`.`expire`, `ec`.`crt_name` ". + " FROM `orgemailcerts` AS `ec` ". + " WHERE `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=?"); + "SELECT `u`.`email`, `u`.`fname` ". + " FROM `users` AS `u`, `org` ". + " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?"); while(($cert_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { -- cgit v1.2.1 From a706b59b4c033466916a923264ac12e1c164a432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Mon, 28 Mar 2011 00:11:25 +0200 Subject: #918: Weak keys in certificates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detection script: Name variables in a consistant way Signed-off-by: Michael Tänzer --- scripts/DumpWeakCerts.pl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl index cecdad5..dc6030c 100755 --- a/scripts/DumpWeakCerts.pl +++ b/scripts/DumpWeakCerts.pl @@ -21,6 +21,7 @@ my $sth_userdata; my $cert_domid; my $cert_userid; +my $cert_orgid; my $cert_CN; my $cert_expire; my $cert_filename; @@ -119,10 +120,10 @@ $sth_userdata = $dbh->prepare( " FROM `users` AS `u`, `org` ". " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?"); -while(($cert_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { +while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { if (IsWeak($cert_filename)) { - $sth_userdata->execute($cert_userid); + $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)). "\n"; } @@ -144,10 +145,10 @@ $sth_userdata = $dbh->prepare( " FROM `users` AS `u`, `org` ". " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?"); -while(($cert_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { +while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { if (IsWeak($cert_filename)) { - $sth_userdata->execute($cert_userid); + $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)). "\n"; } -- cgit v1.2.1 From ab74a1333cb130bdb19f4fddd6f96c55d1473234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Fr=C3=B6hlich?= Date: Tue, 29 Mar 2011 21:32:34 +0200 Subject: Added restriction "revoked=0" to cert queries --- scripts/DumpWeakCerts.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl index dc6030c..7b648b9 100755 --- a/scripts/DumpWeakCerts.pl +++ b/scripts/DumpWeakCerts.pl @@ -64,7 +64,7 @@ sub IsWeak($) { $sth_certs = $dbh->prepare( "SELECT `dc`.`domid`, `dc`.`CN`, `dc`.`expire`, `dc`.`crt_name` ". " FROM `domaincerts` AS `dc` ". - " WHERE `dc`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); + " WHERE `dc`.`revoked`=0 AND `dc`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); $sth_certs->execute(); $sth_userdata = $dbh->prepare( @@ -88,7 +88,7 @@ $sth_certs->finish(); $sth_certs = $dbh->prepare( "SELECT `ec`.`memid`, `ec`.`CN`, `ec`.`expire`, `ec`.`crt_name` ". " FROM `emailcerts` AS `ec` ". - " WHERE `ec`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); + " WHERE `ec`.`revoked`=0 AND `ec`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); $sth_certs->execute(); $sth_userdata = $dbh->prepare( @@ -112,7 +112,7 @@ $sth_certs->finish(); $sth_certs = $dbh->prepare( "SELECT `dc`.`orgid`, `dc`.`CN`, `dc`.`expire`, `dc`.`crt_name` ". " FROM `orgdomaincerts` AS `dc` ". - " WHERE `dc`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); + " WHERE `dc`.`revoked`=0 AND `dc`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); $sth_certs->execute(); $sth_userdata = $dbh->prepare( @@ -137,7 +137,7 @@ $sth_certs->finish(); $sth_certs = $dbh->prepare( "SELECT `ec`.`orgid`, `ec`.`CN`, `ec`.`expire`, `ec`.`crt_name` ". " FROM `orgemailcerts` AS `ec` ". - " WHERE `ec`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); + " WHERE `ec`.`revoked`=0 AND `ec`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)"); $sth_certs->execute(); $sth_userdata = $dbh->prepare( -- cgit v1.2.1 From cac190c8d1f78f9ae8fcf2019f96ec9d16ab1284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Fr=C3=B6hlich?= Date: Tue, 29 Mar 2011 21:47:29 +0200 Subject: Added reason column to output. Call to openssl-vulnkey as comment --- scripts/DumpWeakCerts.pl | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl index 7b648b9..9f6a3df 100755 --- a/scripts/DumpWeakCerts.pl +++ b/scripts/DumpWeakCerts.pl @@ -29,6 +29,8 @@ my $cert_filename; my $user_email; my $user_firstname; +my $reason; + my @row; sub IsWeak($) { @@ -37,7 +39,8 @@ sub IsWeak($) { 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 () { if (/^ +([^ ]+) Public Key:/) { @@ -54,9 +57,19 @@ sub IsWeak($) { close(CERTTEXT); if ($ModulusSize > 0 && $Exponent > 0) { if ($ModulusSize < 1024 || $Exponent==3) { - $result = 1; + $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 @@ -74,10 +87,11 @@ $sth_userdata = $dbh->prepare( while(($cert_domid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { - if (IsWeak($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)). "\n"; + print join("\t", ('DomainCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason)). "\n"; $sth_userdata->finish(); } } @@ -98,10 +112,11 @@ $sth_userdata = $dbh->prepare( while(($cert_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { - if (IsWeak($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)). "\n"; + print join("\t", ('EmailCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason)). "\n"; $sth_userdata->finish(); } } @@ -122,10 +137,11 @@ $sth_userdata = $dbh->prepare( while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { - if (IsWeak($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)). "\n"; + print join("\t", ('OrgServerCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason)). "\n"; } $sth_userdata->finish(); } @@ -147,10 +163,11 @@ $sth_userdata = $dbh->prepare( while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { if (-f $cert_filename) { - if (IsWeak($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)). "\n"; + print join("\t", ('OrgEmailCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason)). "\n"; } $sth_userdata->finish(); } -- cgit v1.2.1 From b1ec4f45e452f7d99eeced93682e06488b63ac48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Fr=C3=B6hlich?= Date: Tue, 29 Mar 2011 22:09:33 +0200 Subject: Typo in openssl-vulnkey call --- scripts/DumpWeakCerts.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl index 9f6a3df..f5e2f55 100755 --- a/scripts/DumpWeakCerts.pl +++ b/scripts/DumpWeakCerts.pl @@ -64,7 +64,7 @@ sub IsWeak($) { 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) { + #if (system("openssl-vulnkey -q $CertFileName") != 0) { # $result = "openssl-vulnkey"; #} } -- cgit v1.2.1 From f6ba93d49740847c50158598ae10335e03ba1f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Tue, 5 Apr 2011 00:19:22 +0200 Subject: #918 - add functions to test for weak keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #918: "Weak keys in certificates" Mostly untested, will have to do that when actually called anywhere Signed-off-by: Michael Tänzer --- README | 1 + includes/account_stuff.php | 233 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+) diff --git a/README b/README index 6e07b04..7f2ca78 100644 --- a/README +++ b/README @@ -9,6 +9,7 @@ PHP GetText UFPDF - PDF generation library from http://acko.net/node/56 OpenSSL - X.509 toolkit from http://www.openssl.org/ +openssl-vulnkey including blacklists for all common key sizes GnuPG - OpenPGP toolkit from http://www.gnupg.org/ whois - whois client from http://www.linux.it/~md/software/ XEnroll - Enrollment Active-X control for IE5/6 from Microsoft (search for xenroll.cab) diff --git a/includes/account_stuff.php b/includes/account_stuff.php index fa6757b..e9d26cc 100644 --- a/includes/account_stuff.php +++ b/includes/account_stuff.php @@ -284,4 +284,237 @@ function hideall() { array("pipe", "r"), // STDIN for child + 1 => array("pipe", "w"), // STDOUT for child + 2 => array("file", "/dev/null", "w") // ignore STDERR + ); + $encoding = escapeshellarg($encoding); + $proc = proc_open("openssl req -inform $encoding -outform PEM", + $descriptorspec, $pipes); + + if (is_resource($proc)) + { + fwrite($pipes[0], $csr); + fclose($pipes[0]); + + $csr = stream_get_contents($pipes[1]); + fclose($pipes[1]); + + proc_close($proc); + } else { + trigger_error("checkWeakKeyCSR(): Failed to start OpenSSL", + E_USER_ERROR); + return _("Something went wrong when parsing the certificate ". + "signing request!"); + } + } + + + /* Check for the debian OpenSSL vulnerability */ + + $csr = escapeshellarg($csr); + exec("echo $csr | openssl-vulnkey -q -", NULL, $debianVuln); + if ($debianVuln === -1) + { + return sprintf(_("The keys you use have very likely been ". + "generated with a vulnerable version of OpenSSL which was ". + "distributed by debian. Please generate new keys. More ". + "information about this issue can be found in %sthe ". + "wiki%s"), + "", + ""); + } elseif ($debianVuln !== 0) { + trigger_error("checkWeakKeyCSR(): Something went wrong in the ". + "openssl-vulnkey call", E_USER_ERROR); + } + + // $csr already escaped + $csrText = `echo $csr | openssl req -text -noout`; + return checkWeakKeyText($csrText); + } + + /** + * Checks whether the given SPKAC contains a vulnerable key + * + * @param $spkac string + * The SPKAC to be checked + * @param $spkacname string [optional] + * The name of the variable that contains the SPKAC. The default is + * "SPKAC" + * @return string containing the reason if the key is considered weak, + * empty string otherwise + */ + function checkWeakKeySPKAC($spkac, $spkacname = "SPKAC") + { + /* Check for the debian OpenSSL vulnerability */ + + $spkac = escapeshellarg($spkac); + $spkacname = escapeshellarg($spkacname); + + $spkacText = `echo $spkac | openssl spkac -spkac $spkacname`; + + /* Which public key algorithm? */ + if (!preg_match('/^\s*Public Key Algorithm: ([^\s])$/m', $spkacText, + $algorithm)) + { + trigger_error("checkWeakKeySPKAC(): Couldn't extract the public ". + "key algorithm used", E_USER_WARNING); + return ""; + } else { + $algorithm = $algorithm[1]; + } + + if ($algorithm === "rsaEncryption") + { + if (!preg_match('/^\s*RSA Public Key: \((\d+) bit\)$/m', $spkacText, + $keysize)) + { + trigger_error("checkWeakKeySPKAC(): Couldn't parse the RSA ". + "key size", E_USER_WARNING); + } else { + $keysize = $keysize[1]; + + // $spkac and $spkacname already escaped + $modulus = `echo $spkac | openssl spkac -spkac $spkacname \ + -pubkey -noout | openssl rsa -pubin -modulus -noout`; + + if (!preg_match('/^Modulus=([0-9A-F]+)$/', $modulus, $modulus)) + { + trigger_error("checkWeakKeySPKAC(): Couldn't parse the ". + "RSA modulus", E_USER_WARNING); + } else { + $modulus = $modulus[1]; + + $keysize = escapeshellarg($keysize); + $modulus = escapeshellarg($modulus); + exec("openssl-vulnkey -q -b $keysize -m $modulus", NULL, + $debianVuln); + if ($debianVuln === -1) + { + return sprintf(_("The keys you use have very likely been ". + "generated with a vulnerable version of OpenSSL which was ". + "distributed by debian. Please generate new keys. More ". + "information about this issue can be found in %sthe ". + "wiki%s"), + "", + ""); + } elseif ($debianVuln !== 0) { + trigger_error("checkWeakKeySPKAC(): Something went ". + "wrong in the openssl-vulnkey call", E_USER_ERROR); + } + } + } + } + + return checkWeakKeyText($spkacText); + } + + /** + * Checks whether the given text representation of a CSR or a SPKAC contains + * a weak key. + * ONLY TO BE USED BY THE MORE SPECIAL METHODS checkWeakKeyCSR() AND + * checkWeakKeySPKAC() + * + * @param $text string + * The text representation of a key as output by the + * "openssl -text -noout" commands + * @return string containing the reason if the key is considered weak, + * empty string otherwise + */ + function checkWeakKeyText($text) + { + /* Which public key algorithm? */ + if (!preg_match('/^\s*Public Key Algorithm: ([^\s])$/m', $text, + $algorithm)) + { + trigger_error("checkWeakKeyText(): Couldn't extract the public ". + "key algorithm used", E_USER_WARNING); + return ""; + } else { + $algorithm = $algorithm[1]; + } + + + if ($algorithm === "rsaEncryption") + { + if (!preg_match('/^\s*RSA Public Key: \((\d+) bit\)$/m', $text, + $keysize)) + { + trigger_error("checkWeakKeyText(): Couldn't parse the RSA key ". + "size", E_USER_WARNING); + } else { + $keysize = intval($keysize[1]); + + if ($keysize < 1024) + { + return sprintf(_("The keys that you use are very small ". + "and therefore insecure. Please generate stronger ". + "keys. More information about this issue can be ". + "found in %sthe wiki%s"), + "", + ""); + } elseif ($keysize < 2048) { + // not critical but log so we have some statistics about + // affected users + trigger_error("checkWeakKeyText(): Certificate for small ". + "key (< 2048 bit) requested", E_USER_NOTICE); + } + } + + if (!preg_match('/^\s*Exponent: (\d+) \(0x[0-9a-fA-F]+\)$/m', $text, + $exponent)) + { + trigger_error("checkWeakKeyText(): Couldn't parse the RSA ". + "exponent", E_USER_WARNING); + } else { + $exponent = $exponent[1]; // exponent might be very big => + //handle as string using bc*() + + if (bccomp($exponent, "3") === 0) + { + return sprintf(_("The keys you use might be insecure. ". + "Although there is currently no known attack for ". + "reasonable encryption schemes, we're being ". + "cautious and don't allow certificates for such ". + "keys. Please generate stronger keys. More ". + "information about this issue can be found in ". + "%sthe wiki%s"), + "", + ""); + } elseif (!(bccomp($exponent, "65537") >= 0 && + (bccomp($exponent, "100000") === -1 || + // speed things up if way smaller than 2^256 + bccomp($exponent, bcpow("2", "256")) === -1) )) { + // 65537 <= exponent < 2^256 recommended by NIST + // not critical but log so we have some statistics about + // affected users + trigger_error("checkWeakKeyText(): Certificate for ". + "unsuitable exponent '$exponent' requested", + E_USER_NOTICE); + } + } + } + + /* No weakness found */ + return ""; + } ?> -- cgit v1.2.1 From e2cad28b9dd071297b047b726c5d197f4af7c144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Tue, 5 Apr 2011 23:29:41 +0200 Subject: #918: PHP needs a variable, can't pass NULL by reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #918: "Weak keys in certificates" Signed-off-by: Michael Tänzer --- includes/account_stuff.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/account_stuff.php b/includes/account_stuff.php index e9d26cc..fd480b3 100644 --- a/includes/account_stuff.php +++ b/includes/account_stuff.php @@ -332,7 +332,7 @@ function hideall() { /* Check for the debian OpenSSL vulnerability */ $csr = escapeshellarg($csr); - exec("echo $csr | openssl-vulnkey -q -", NULL, $debianVuln); + exec("echo $csr | openssl-vulnkey -q -", $dummy, $debianVuln); if ($debianVuln === -1) { return sprintf(_("The keys you use have very likely been ". @@ -406,7 +406,7 @@ function hideall() { $keysize = escapeshellarg($keysize); $modulus = escapeshellarg($modulus); - exec("openssl-vulnkey -q -b $keysize -m $modulus", NULL, + exec("openssl-vulnkey -q -b $keysize -m $modulus", $dummy, $debianVuln); if ($debianVuln === -1) { -- cgit v1.2.1 From b23ac549d4db4891e0d694ac6b69a5834905f42f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Wed, 6 Apr 2011 12:11:03 +0200 Subject: #918: Link to new wiki page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #918: "Weak keys in certificates" Signed-off-by: Michael Tänzer --- includes/account_stuff.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/account_stuff.php b/includes/account_stuff.php index fd480b3..a38890e 100644 --- a/includes/account_stuff.php +++ b/includes/account_stuff.php @@ -340,7 +340,7 @@ function hideall() { "distributed by debian. Please generate new keys. More ". "information about this issue can be found in %sthe ". "wiki%s"), - "", + "", ""); } elseif ($debianVuln !== 0) { trigger_error("checkWeakKeyCSR(): Something went wrong in the ". @@ -415,7 +415,7 @@ function hideall() { "distributed by debian. Please generate new keys. More ". "information about this issue can be found in %sthe ". "wiki%s"), - "", + "", ""); } elseif ($debianVuln !== 0) { trigger_error("checkWeakKeySPKAC(): Something went ". @@ -470,7 +470,7 @@ function hideall() { "and therefore insecure. Please generate stronger ". "keys. More information about this issue can be ". "found in %sthe wiki%s"), - "", + "", ""); } elseif ($keysize < 2048) { // not critical but log so we have some statistics about @@ -498,7 +498,7 @@ function hideall() { "keys. Please generate stronger keys. More ". "information about this issue can be found in ". "%sthe wiki%s"), - "", + "", ""); } elseif (!(bccomp($exponent, "65537") >= 0 && (bccomp($exponent, "100000") === -1 || -- cgit v1.2.1 From 949ae23c8343c139ef3a27790c7f5e9bd1ee6206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Fr=C3=B6hlich?= Date: Wed, 6 Apr 2011 23:06:28 +0200 Subject: Added serial nuber of the weak cert as output column --- scripts/DumpWeakCerts.pl | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl index f5e2f55..894d06d 100755 --- a/scripts/DumpWeakCerts.pl +++ b/scripts/DumpWeakCerts.pl @@ -25,6 +25,7 @@ my $cert_orgid; my $cert_CN; my $cert_expire; my $cert_filename; +my $cert_serial; my $user_email; my $user_firstname; @@ -75,7 +76,7 @@ sub IsWeak($) { # 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` ". + "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(); @@ -85,13 +86,13 @@ $sth_userdata = $dbh->prepare( " FROM `domains` AS `d`, `users` AS `u` ". " WHERE `d`.`memid`=`u`.`id` AND `d`.`id`=?"); -while(($cert_domid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { +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)). "\n"; + print join("\t", ('DomainCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason, $cert_serial)). "\n"; $sth_userdata->finish(); } } @@ -100,7 +101,7 @@ $sth_certs->finish(); # Get all email certificates $sth_certs = $dbh->prepare( - "SELECT `ec`.`memid`, `ec`.`CN`, `ec`.`expire`, `ec`.`crt_name` ". + "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(); @@ -110,13 +111,13 @@ $sth_userdata = $dbh->prepare( " FROM `users` AS `u` ". " WHERE `u`.`id`=?"); -while(($cert_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { +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)). "\n"; + print join("\t", ('EmailCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason, $cert_serial)). "\n"; $sth_userdata->finish(); } } @@ -125,7 +126,7 @@ $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` ". + "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(); @@ -135,13 +136,13 @@ $sth_userdata = $dbh->prepare( " FROM `users` AS `u`, `org` ". " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?"); -while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { +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)). "\n"; + print join("\t", ('OrgServerCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason, $cert_serial)). "\n"; } $sth_userdata->finish(); } @@ -151,7 +152,7 @@ $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` ". + "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(); @@ -161,13 +162,13 @@ $sth_userdata = $dbh->prepare( " FROM `users` AS `u`, `org` ". " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?"); -while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) { +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)). "\n"; + print join("\t", ('OrgEmailCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason, $cert_serial)). "\n"; } $sth_userdata->finish(); } -- cgit v1.2.1 From 2faeb0030546e42418a24d8343f42e4888bd3dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Thu, 7 Apr 2011 05:37:02 +0200 Subject: #918: Fix regex for extracting the public key algorithm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #918: "Weak keys in certificates" Signed-off-by: Michael Tänzer --- includes/account_stuff.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/account_stuff.php b/includes/account_stuff.php index a38890e..e19879c 100644 --- a/includes/account_stuff.php +++ b/includes/account_stuff.php @@ -373,7 +373,7 @@ function hideall() { $spkacText = `echo $spkac | openssl spkac -spkac $spkacname`; /* Which public key algorithm? */ - if (!preg_match('/^\s*Public Key Algorithm: ([^\s])$/m', $spkacText, + if (!preg_match('/^\s*Public Key Algorithm: ([^\s]+)$/m', $spkacText, $algorithm)) { trigger_error("checkWeakKeySPKAC(): Couldn't extract the public ". @@ -443,7 +443,7 @@ function hideall() { function checkWeakKeyText($text) { /* Which public key algorithm? */ - if (!preg_match('/^\s*Public Key Algorithm: ([^\s])$/m', $text, + if (!preg_match('/^\s*Public Key Algorithm: ([^\s]+)$/m', $text, $algorithm)) { trigger_error("checkWeakKeyText(): Couldn't extract the public ". -- cgit v1.2.1 From 384b57dc57b90c01b6c376be8c2b564470d042cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Thu, 7 Apr 2011 05:44:35 +0200 Subject: #918: More sophisticated error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #918: "Weak keys in certificates" Signed-off-by: Michael Tänzer --- includes/account_stuff.php | 65 ++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/includes/account_stuff.php b/includes/account_stuff.php index e19879c..0299ead 100644 --- a/includes/account_stuff.php +++ b/includes/account_stuff.php @@ -285,6 +285,27 @@ function hideall() { support@cacert.org", + $errorId); + } + /** * Checks whether the given CSR contains a vulnerable key * @@ -446,9 +467,8 @@ function hideall() { if (!preg_match('/^\s*Public Key Algorithm: ([^\s]+)$/m', $text, $algorithm)) { - trigger_error("checkWeakKeyText(): Couldn't extract the public ". - "key algorithm used", E_USER_WARNING); - return ""; + return failWithId("checkWeakKeyText(): Couldn't extract the ". + "public key algorithm used"); } else { $algorithm = $algorithm[1]; } @@ -459,32 +479,33 @@ function hideall() { if (!preg_match('/^\s*RSA Public Key: \((\d+) bit\)$/m', $text, $keysize)) { - trigger_error("checkWeakKeyText(): Couldn't parse the RSA key ". - "size", E_USER_WARNING); + return failWithId("checkWeakKeyText(): Couldn't parse the RSA ". + "key size"); } else { $keysize = intval($keysize[1]); - - if ($keysize < 1024) - { - return sprintf(_("The keys that you use are very small ". - "and therefore insecure. Please generate stronger ". - "keys. More information about this issue can be ". - "found in %sthe wiki%s"), - "", - ""); - } elseif ($keysize < 2048) { - // not critical but log so we have some statistics about - // affected users - trigger_error("checkWeakKeyText(): Certificate for small ". - "key (< 2048 bit) requested", E_USER_NOTICE); - } } + if ($keysize < 1024) + { + return sprintf(_("The keys that you use are very small ". + "and therefore insecure. Please generate stronger ". + "keys. More information about this issue can be ". + "found in %sthe wiki%s"), + "", + ""); + } elseif ($keysize < 2048) { + // not critical but log so we have some statistics about + // affected users + trigger_error("checkWeakKeyText(): Certificate for small ". + "key (< 2048 bit) requested", E_USER_NOTICE); + } + + if (!preg_match('/^\s*Exponent: (\d+) \(0x[0-9a-fA-F]+\)$/m', $text, $exponent)) { - trigger_error("checkWeakKeyText(): Couldn't parse the RSA ". - "exponent", E_USER_WARNING); + return failWithId("checkWeakKeyText(): Couldn't parse the RSA ". + "exponent"); } else { $exponent = $exponent[1]; // exponent might be very big => //handle as string using bc*() -- cgit v1.2.1 From 6dd75856f30923879eb01bc94ae7a735dc413063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Fr=C3=B6hlich?= Date: Fri, 8 Apr 2011 22:54:31 +0200 Subject: First version of mailing script added --- scripts/mail-weak-keys.php | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100755 scripts/mail-weak-keys.php diff --git a/scripts/mail-weak-keys.php b/scripts/mail-weak-keys.php new file mode 100755 index 0000000..f8909c9 --- /dev/null +++ b/scripts/mail-weak-keys.php @@ -0,0 +1,33 @@ +#!/usr/bin/php -q + -- cgit v1.2.1 From 8b8426f275e842492af6a729c97da35424415ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Fr=C3=B6hlich?= Date: Fri, 8 Apr 2011 22:56:32 +0200 Subject: First running version of mailing script added --- scripts/mail-weak-keys.php | 150 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 139 insertions(+), 11 deletions(-) diff --git a/scripts/mail-weak-keys.php b/scripts/mail-weak-keys.php index f8909c9..018bd64 100755 --- a/scripts/mail-weak-keys.php +++ b/scripts/mail-weak-keys.php @@ -1,15 +1,109 @@ #!/usr/bin/php -q \nReply-To: returns@cacert.org"); + } + + function SendClientMail($cert_type, $cert_email, $owner_name, $cert_expire, $cert_CN, $reason, $cert_serial, $action_date) { + $mail_text = +"Dear $owner_name, + +CAcert recently became aware that some of the certificates signed by CAcert pose a security +risk because they are backed by private keys that are vulnerable to attack. + +The security issues identified are: +Private keys with a small key size. These keys are vulnerable to brute force attack. +Private keys with an unsafe exponent. These keys are vulnerable to some specialised attacks. +Private keys generated by a compromised version of OpenSSL distributed by Debian. + +You received this email because a certificate issued to you is vulnerable: +Client Certificate, Serial $cert_serial, expiring $cert_expire, CN $cert_CN + +To rectify the problem CAcert will revoke all vulnerable certificates (including yours) on $action_date. +CAcert will no longer accept vulnerable certificate requests for signing. In future all +client certficates must be backed by private keys with a key length at least 1024 bits +and no other known vulnerabilities. + +This means that you should replace your current certificate with a new one of acceptable strength. +If you use Firefox or Chrome, select 'Keysize: High Grade' before 'Create Certificate Request'. +If you use Internet Explorer, select 'Microsoft Strong Cryptographic Provider'. If you select an +option that generates a weak key (eg 'Microsoft Base Cryptographic Provider v1.0') your certficate +request will be rejected. + +Kind regards +CAcert Suport Team +"; + mail($cert_email, "[CAcert.org]CAcert Client Certificate - Urgent Action Required", $mail_text, "From: CAcert Support \nReply-To: returns@cacert.org"); + } + + function SendOrgServerCertMail($cert_type, $cert_email, $owner_name, $cert_expire, $cert_CN, $reason, $cert_serial, $action_date) { + $mail_text = +"Dear $owner_name, + +CAcert recently became aware that some of the certificates signed by CAcert pose a security +risk because they are backed by private keys that are vulnerable to attack. + +The security issues identified are: +Private keys with a small key size. These keys are vulnerable to brute force attack. +Private keys with an unsafe exponent. These keys are vulnerable to some specialised attacks. +Private keys generated by a compromised version of OpenSSL distributed by Debian. + +You received this email because a certificate issued to you is vulnerable: + +Organisation Server Certificate, Serial $cert_serial, expiring $cert_expire, CN $cert_CN + +To rectify the problem CAcert will revoke all vulnerable certificates (including yours) on $action_date. +CAcert will no longer accept vulnerable certificate requests for signing. In future all Certficate +Signing Requests must be backed by private keys with a key length at least 2048 bits and no other known vulnerabilities. + +You should submit a new Certificate Signing Request of acceptable strength as soon as possible +and replace your existing certificate. + +If you are interested in background information on this change please refer to this document: +http://csrc.nist.gov/publications/nistpubs/800-78-3/sp800-78-3.pdf + +Kind regards +CAcert Suport Team +"; + mail($cert_email, "[CAcert.org]CAcert Organisation Server Certificate - Urgent Action Required", $mail_text, "From: CAcert Support \nReply-To: returns@cacert.org"); + } + + function SendOrgClientMail($cert_type, $cert_email, $owner_name, $cert_expire, $cert_CN, $reason, $cert_serial, $action_date) { $mail_text = "Dear $owner_name, -CAcert recently became aware that some of the server certficates signed by CAcert =pose a security risk because they are backed by private keys that are vulnerable to attack. +CAcert recently became aware that some of the certificates signed by CAcert pose a security +risk because they are backed by private keys that are vulnerable to attack. The security issues identified are: Private keys with a small key size. These keys are vulnerable to brute force attack. @@ -18,16 +112,50 @@ Private keys generated by a compromised version of OpenSSL distributed by Debian You received this email because a certificate issued to you is vulnerable: -Serial $cert_serial, expiring $cert_expire, CN $cert_CN +Organisation Client Certificate, Serial $cert_serial, expiring $cert_expire, CN $cert_CN -To rectify the problem CAcert will revoke all vulnerable certificates (including yours) on $action_date. CAcert will no longer accept vulnerable certificate requests for signing. In future all Certficate Signing Requests must be backed by private keys with a key length at least 2048 bits and no other known vulnerabilities. +To rectify the problem CAcert will revoke all vulnerable certificates (including yours) on $action_date. +CAcert will no longer accept vulnerable certificate requests for signing. In future all +client certficates must be backed by private keys with a key length at least 1024 bits +and no other known vulnerabilities. -You should submit a new Certificate Signing Request of acceptable strength as soon as possible and replace your existing certificate. +This means that you should replace your current certificate with a new one of acceptable strength. +If you use Firefox or Chrome, select 'Keysize: High Grade' before 'Create Certificate Request'. +If you use Internet Explorer, select 'Microsoft Strong Cryptographic Provider'. If you select an +option that generates a weak key (eg 'Microsoft Base Cryptographic Provider v1.0') your certficate +request will be rejected. -If you are interested in background information on this change please refer to this document http://csrc.nist.gov/publications/nistpubs/800-78-3/sp800-78-3.pdf --------------------- +Kind regards +CAcert Suport Team "; - echo $mail_text; + mail($cert_email, "[CAcert.org]CAcert Organisation Client Certificate - Urgent Action Required", $mail_text, "From: CAcert Support \nReply-To: returns@cacert.org"); + } + + # Main + + $num_domain = 0; + $num_client = 0; + $num_orgdomain = 0; + $num_orgclient = 0; + $action_date = '2011-04-??'; + $in = fopen("php://stdin", "r"); + while($in_string = rtrim(fgets($in, 255))) { + list($cert_type, $cert_email, $owner_name, $cert_expire, $cert_CN, $reason, $cert_serial) = explode("\t", $in_string); + + if ($cert_type == "DomainCert") { + SendServerCertMail($cert_type, $cert_email, $owner_name, $cert_expire, $cert_CN, $reason, $cert_serial, $action_date); + $num_domain++; + } else if ($cert_type == "EmailCert") { + SendClientMail($cert_type, $cert_email, $owner_name, $cert_expire, $cert_CN, $reason, $cert_serial, $action_date); + $num_client++; + } else if ($cert_type == "OrgServerCert") { + SendOrgServerCertMail($cert_type, $cert_email, $owner_name, $cert_expire, $cert_CN, $reason, $cert_serial, $action_date); + $num_orgdomain++; + } else if ($cert_type == "OrgEmailCert") { + SendOrgClientMail($cert_type, $cert_email, $owner_name, $cert_expire, $cert_CN, $reason, $cert_serial, $action_date); + $num_orgclient++; + } } fclose($in); + echo "Mails sent: $num_domain server certs, $num_client client certs, $num_orgdomain Org server certs, $num_orgclient Org client certs.\n"; ?> -- cgit v1.2.1 From 803eaaf70962b3beedc5cb8ce0f82aa8e7fe589f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Mon, 11 Apr 2011 00:43:33 +0200 Subject: #918: Reimplement openssl-vulnkey in PHP so we don't have to include python in the chroot of the web server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #918: "Weak keys in certificates" Signed-off-by: Michael Tänzer --- includes/account_stuff.php | 256 +++++++++++++++++++++++++++------------------ 1 file changed, 156 insertions(+), 100 deletions(-) diff --git a/includes/account_stuff.php b/includes/account_stuff.php index 0299ead..e8beb7f 100644 --- a/includes/account_stuff.php +++ b/includes/account_stuff.php @@ -319,57 +319,37 @@ function hideall() { */ function checkWeakKeyCSR($csr, $encoding = "PEM") { - /* If another encoding is used: convert to PEM */ - if ($encoding !== "PEM") + // non-PEM-encodings may be binary so don't use echo + $descriptorspec = array( + 0 => array("pipe", "r"), // STDIN for child + 1 => array("pipe", "w"), // STDOUT for child + ); + $encoding = escapeshellarg($encoding); + $proc = proc_open("openssl req -inform $encoding -text -noout", + $descriptorspec, $pipes); + + if (is_resource($proc)) { - // other encodings may be binary so don't use echo - $descriptorspec = array( - 0 => array("pipe", "r"), // STDIN for child - 1 => array("pipe", "w"), // STDOUT for child - 2 => array("file", "/dev/null", "w") // ignore STDERR - ); - $encoding = escapeshellarg($encoding); - $proc = proc_open("openssl req -inform $encoding -outform PEM", - $descriptorspec, $pipes); + fwrite($pipes[0], $csr); + fclose($pipes[0]); - if (is_resource($proc)) + $csrText = ""; + while (!feof($pipes[1])) { - fwrite($pipes[0], $csr); - fclose($pipes[0]); - - $csr = stream_get_contents($pipes[1]); - fclose($pipes[1]); - - proc_close($proc); - } else { - trigger_error("checkWeakKeyCSR(): Failed to start OpenSSL", - E_USER_ERROR); - return _("Something went wrong when parsing the certificate ". - "signing request!"); + $csrText .= fread($pipes[1], 8192); } + fclose($pipes[1]); + + if (($status = proc_close($proc)) !== 0 || $csrText === "") + { + return _("I didn't receive a valid Certificate Request, hit ". + "the back button and try again."); + } + } else { + return failWithId("checkWeakKeyCSR(): Failed to start OpenSSL"); } - /* Check for the debian OpenSSL vulnerability */ - - $csr = escapeshellarg($csr); - exec("echo $csr | openssl-vulnkey -q -", $dummy, $debianVuln); - if ($debianVuln === -1) - { - return sprintf(_("The keys you use have very likely been ". - "generated with a vulnerable version of OpenSSL which was ". - "distributed by debian. Please generate new keys. More ". - "information about this issue can be found in %sthe ". - "wiki%s"), - "", - ""); - } elseif ($debianVuln !== 0) { - trigger_error("checkWeakKeyCSR(): Something went wrong in the ". - "openssl-vulnkey call", E_USER_ERROR); - } - - // $csr already escaped - $csrText = `echo $csr | openssl req -text -noout`; return checkWeakKeyText($csrText); } @@ -390,60 +370,10 @@ function hideall() { $spkac = escapeshellarg($spkac); $spkacname = escapeshellarg($spkacname); - $spkacText = `echo $spkac | openssl spkac -spkac $spkacname`; - - /* Which public key algorithm? */ - if (!preg_match('/^\s*Public Key Algorithm: ([^\s]+)$/m', $spkacText, - $algorithm)) - { - trigger_error("checkWeakKeySPKAC(): Couldn't extract the public ". - "key algorithm used", E_USER_WARNING); - return ""; - } else { - $algorithm = $algorithm[1]; - } - - if ($algorithm === "rsaEncryption") - { - if (!preg_match('/^\s*RSA Public Key: \((\d+) bit\)$/m', $spkacText, - $keysize)) - { - trigger_error("checkWeakKeySPKAC(): Couldn't parse the RSA ". - "key size", E_USER_WARNING); - } else { - $keysize = $keysize[1]; - - // $spkac and $spkacname already escaped - $modulus = `echo $spkac | openssl spkac -spkac $spkacname \ - -pubkey -noout | openssl rsa -pubin -modulus -noout`; - - if (!preg_match('/^Modulus=([0-9A-F]+)$/', $modulus, $modulus)) - { - trigger_error("checkWeakKeySPKAC(): Couldn't parse the ". - "RSA modulus", E_USER_WARNING); - } else { - $modulus = $modulus[1]; - - $keysize = escapeshellarg($keysize); - $modulus = escapeshellarg($modulus); - exec("openssl-vulnkey -q -b $keysize -m $modulus", $dummy, - $debianVuln); - if ($debianVuln === -1) - { - return sprintf(_("The keys you use have very likely been ". - "generated with a vulnerable version of OpenSSL which was ". - "distributed by debian. Please generate new keys. More ". - "information about this issue can be found in %sthe ". - "wiki%s"), - "", - ""); - } elseif ($debianVuln !== 0) { - trigger_error("checkWeakKeySPKAC(): Something went ". - "wrong in the openssl-vulnkey call", E_USER_ERROR); - } - } - } + if ($spkacText === null) { + return _("I didn't receive a valid Certificate Request, hit the ". + "back button and try again."); } return checkWeakKeyText($spkacText); @@ -451,9 +381,7 @@ function hideall() { /** * Checks whether the given text representation of a CSR or a SPKAC contains - * a weak key. - * ONLY TO BE USED BY THE MORE SPECIAL METHODS checkWeakKeyCSR() AND - * checkWeakKeySPKAC() + * a weak key * * @param $text string * The text representation of a key as output by the @@ -501,6 +429,23 @@ function hideall() { } + $debianVuln = checkDebianVulnerability($text, $keysize); + if ($debianVuln === true) + { + return sprintf(_("The keys you use have very likely been ". + "generated with a vulnerable version of OpenSSL which ". + "was distributed by debian. Please generate new keys. ". + "More information about this issue can be found in ". + "%sthe wiki%s"), + "", + ""); + } elseif ($debianVuln === false) { + // not vulnerable => do nothing + } else { + return failWithId("checkWeakKeyText(): Something went wrong in". + "checkDebianVulnerability()"); + } + if (!preg_match('/^\s*Exponent: (\d+) \(0x[0-9a-fA-F]+\)$/m', $text, $exponent)) { @@ -538,4 +483,115 @@ function hideall() { /* No weakness found */ return ""; } + + /** + * Reimplement the functionality of the openssl-vulnkey tool + * + * @param $text string + * The text representation of a key as output by the + * "openssl -text -noout" commands + * @param $keysize int [optional] + * If the key size is already known it can be provided so it doesn't + * have to be parsed again. This also skips the check whether the key + * is an RSA key => use wisely + * @return TRUE if key is vulnerable, FALSE otherwise, NULL in case of error + */ + function checkDebianVulnerability($text, $keysize = 0) + { + $keysize = intval($keysize); + + if ($keysize === 0) + { + /* Which public key algorithm? */ + if (!preg_match('/^\s*Public Key Algorithm: ([^\s]+)$/m', $text, + $algorithm)) + { + trigger_error("checkDebianVulnerability(): Couldn't extract ". + "the public key algorithm used", E_USER_WARNING); + return null; + } else { + $algorithm = $algorithm[1]; + } + + if ($algorithm !== "rsaEncryption") return false; + + /* Extract public key size */ + if (!preg_match('/^\s*RSA Public Key: \((\d+) bit\)$/m', $text, + $keysize)) + { + trigger_error("checkDebianVulnerability(): Couldn't parse the ". + "RSA key size", E_USER_WARNING); + return null; + } else { + $keysize = intval($keysize[1]); + } + } + + // $keysize has been made sure to contain an int + $blacklist = "/usr/share/openssl-blacklist/blacklist.RSA-$keysize"; + if (!(is_file($blacklist) && is_readable($blacklist))) + { + if (in_array($keysize, array(512, 1024, 2048, 4096))) + { + trigger_error("checkDebianVulnerability(): Blacklist for ". + "$keysize bit keys not accessible. Expected at ". + "$blacklist", E_USER_ERROR); + return null; + } + + trigger_error("checkDebianVulnerability(): $blacklist is not ". + "readable. Unsupported key size?", E_USER_WARNING); + return false; + } + + + /* Extract RSA modulus */ + if (!preg_match('/^\s*Modulus \(\d+ bit\):\n'. + '((?:\s*[0-9a-f][0-9a-f]:(?:\n)?)+[0-9a-f][0-9a-f])$/m', + $text, $modulus)) + { + trigger_error("checkDebianVulnerability(): Couldn't extract the ". + "RSA modulus", E_USER_WARNING); + return null; + } else { + $modulus = $modulus[1]; + // strip whitespace and colon leftovers + $modulus = str_replace(array(" ", "\t", "\n", ":"), "", $modulus); + + // when using "openssl xxx -text" first byte was 00 in all my test + // cases but 00 not present in the "openssl xxx -modulus" output + if ($modulus[0] === "0" && $modulus[1] === "0") + { + $modulus = substr($modulus, 2); + } else { + trigger_error("checkDebianVulnerability(): First byte is not ". + "zero", E_USER_NOTICE); + } + + $modulus = strtoupper($modulus); + } + + + /* calculate checksum and look it up in the blacklist */ + $checksum = substr(sha1("Modulus=$modulus\n"), 20); + + // $checksum and $blacklist should be safe, but just to make sure + $checksum = escapeshellarg($checksum); + $blacklist = escapeshellarg($blacklist); + exec("grep $checksum $blacklist", $dummy, $debianVuln); + if ($debianVuln === 0) // grep returned something => it is on the list + { + return true; + } elseif ($debianVuln === 1) { // grep returned nothing + return false; + } else { + trigger_error("checkDebianVulnerability(): Something went wrong ". + "when looking up the key with checksum $checksum in the ". + "blacklist $blacklist", E_USER_ERROR); + return null; + } + + // Should not get here + return null; + } ?> -- cgit v1.2.1 From cd9e6e79631835fddda384801f5e3c415cbc5d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Mon, 11 Apr 2011 00:49:26 +0200 Subject: #918: add checkWeakKeyX509() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #918: "Weak keys in certificates" Signed-off-by: Michael Tänzer --- includes/account_stuff.php | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/includes/account_stuff.php b/includes/account_stuff.php index e8beb7f..7c8980c 100644 --- a/includes/account_stuff.php +++ b/includes/account_stuff.php @@ -353,6 +353,53 @@ function hideall() { return checkWeakKeyText($csrText); } + /** + * Checks whether the given X509 certificate contains a vulnerable key + * + * @param $cert string + * The X509 certificate to be checked + * @param $encoding string [optional] + * The encoding the certificate is in (for the "-inform" parameter of + * OpenSSL, currently only "PEM" (default), "DER" or "NET" allowed) + * @return string containing the reason if the key is considered weak, + * empty string otherwise + */ + function checkWeakKeyX509($cert, $encoding = "PEM") + { + // non-PEM-encodings may be binary so don't use echo + $descriptorspec = array( + 0 => array("pipe", "r"), // STDIN for child + 1 => array("pipe", "w"), // STDOUT for child + ); + $encoding = escapeshellarg($encoding); + $proc = proc_open("openssl x509 -inform $encoding -text -noout", + $descriptorspec, $pipes); + + if (is_resource($proc)) + { + fwrite($pipes[0], $cert); + fclose($pipes[0]); + + $certText = ""; + while (!feof($pipes[1])) + { + $certText .= fread($pipes[1], 8192); + } + fclose($pipes[1]); + + if (($status = proc_close($proc)) !== 0 || $certText === "") + { + return _("I didn't receive a valid Certificate Request, hit ". + "the back button and try again."); + } + } else { + return failWithId("checkWeakKeyCSR(): Failed to start OpenSSL"); + } + + + return checkWeakKeyText($certText); + } + /** * Checks whether the given SPKAC contains a vulnerable key * -- cgit v1.2.1 From a4ca549c1b58bd0d891d76dbdf2ceb76fcc5557d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=A4nzer?= Date: Mon, 11 Apr 2011 19:44:27 +0200 Subject: #918: Check for weak keys on submission, renewal and in the API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #918: "Weak keys in certificates" Signed-off-by: Michael Tänzer --- includes/account.php | 157 +++++++++++++++++++++++++++++++++++++++++++++------ www/api/ccsr.php | 6 ++ 2 files changed, 147 insertions(+), 16 deletions(-) diff --git a/includes/account.php b/includes/account.php index 685b53a..14702b9 100644 --- a/includes/account.php +++ b/includes/account.php @@ -299,6 +299,15 @@ $_SESSION['_config']['rootcert'] = 1; $emails .= "SPKAC = $spkac"; + if (($weakKey = checkWeakKeySPKAC($emails)) !== "") + { + $id = 4; + showheader(_("My CAcert.org Account!")); + echo $weakKey; + showfooter(); + exit; + } + $query = "insert into emailcerts set `CN`='$defaultemail', `keytype`='NS', @@ -330,6 +339,16 @@ } else if($_REQUEST['keytype'] == "MS" || $_REQUEST['keytype'] == "VI") { if($csr == "") $csr = "-----BEGIN CERTIFICATE REQUEST-----\n".clean_csr($_REQUEST['CSR'])."\n-----END CERTIFICATE REQUEST-----\n"; + + if (($weakKey = checkWeakKeyCSR($csr)) !== "") + { + $id = 4; + showheader(_("My CAcert.org Account!")); + echo $weakKey; + showfooter(); + exit; + } + $tmpfname = tempnam("/tmp", "id4CSR"); $fp = fopen($tmpfname, "w"); fputs($fp, $csr); @@ -613,17 +632,23 @@ if($process != "" && $oldid == 10) { $CSR = clean_csr($_REQUEST['CSR']); - $_SESSION['_config']['tmpfname'] = tempnam("/tmp", "id10CSR"); - $fp = fopen($_SESSION['_config']['tmpfname'], "w"); if(strpos($CSR,"---BEGIN")===FALSE) { // In case the CSR is missing the ---BEGIN lines, add them automatically: - fputs($fp,"-----BEGIN CERTIFICATE REQUEST-----\n".$CSR."\n-----END CERTIFICATE REQUEST-----\n"); + $CSR = "-----BEGIN CERTIFICATE REQUEST-----\n".$CSR."\n-----END CERTIFICATE REQUEST-----\n"; } - else + + if (($weakKey = checkWeakKeyCSR($CSR)) !== "") { - fputs($fp, $CSR); + showheader(_("My CAcert.org Account!")); + echo $weakKey; + showfooter(); + exit; } + + $_SESSION['_config']['tmpfname'] = tempnam("/tmp", "id10CSR"); + $fp = fopen($_SESSION['_config']['tmpfname'], "w"); + fputs($fp, $CSR); fclose($fp); $CSR = $_SESSION['_config']['tmpfname']; $_SESSION['_config']['subject'] = trim(`/usr/bin/openssl req -text -noout -in "$CSR"|tr -d "\\0"|grep "Subject:"`); @@ -658,6 +683,23 @@ if($process != "" && $oldid == 11) { + if(!file_exists($_SESSION['_config']['tmpfname'])) + { + showheader(_("My CAcert.org Account!")); + printf(_("Your certificate request has failed to be processed correctly, see %sthe WIKI page%s for reasons and solutions."), "", ""); + showfooter(); + exit; + } + + if (($weakKey = checkWeakKeyCSR(file_get_contents( + $_SESSION['_config']['tmpfname']))) !== "") + { + showheader(_("My CAcert.org Account!")); + echo $weakKey; + showfooter(); + exit; + } + $id = 11; if($_SESSION['_config']['0.CN'] == "" && $_SESSION['_config']['0.subjectAltName'] == "") { @@ -731,13 +773,6 @@ mysql_query("insert into `domlink` set `certid`='$CSRid', `domid`='$dom'"); $CSRname=generatecertpath("csr","server",$CSRid); - if(!file_exists($_SESSION['_config']['tmpfname'])) - { - showheader(_("My CAcert.org Account!")); - printf(_("Your certificate request has failed to be processed correctly, see %sthe WIKI page%s for reasons and solutions."), "", ""); - showfooter(); - exit; - } rename($_SESSION['_config']['tmpfname'], $CSRname); chmod($CSRname,0644); mysql_query("update `domaincerts` set `CSR_name`='$CSRname' where `id`='$CSRid'"); @@ -780,8 +815,17 @@ printf(_("Invalid ID '%s' presented, can't do anything with it.")."
\n", $id); continue; } - mysql_query("update `domaincerts` set `renewed`='1' where `id`='$id'"); + $row = mysql_fetch_assoc($res); + + if (($weakKey = checkWeakKeyX509(file_get_contents( + $row['crt_name']))) !== "") + { + echo $weakKey, "
\n"; + continue; + } + + mysql_query("update `domaincerts` set `renewed`='1' where `id`='$id'"); $query = "insert into `domaincerts` set `domid`='".$row['domid']."', `CN`='".mysql_real_escape_string($row['CN'])."', @@ -946,8 +990,17 @@ printf(_("Invalid ID '%s' presented, can't do anything with it.")."
\n", $id); continue; } - mysql_query("update `emailcerts` set `renewed`='1' where `id`='$id'"); + $row = mysql_fetch_assoc($res); + + if (($weakKey = checkWeakKeyX509(file_get_contents( + $row['crt_name']))) !== "") + { + echo $weakKey, "
\n"; + continue; + } + + mysql_query("update `emailcerts` set `renewed`='1' where `id`='$id'"); $query = "insert into emailcerts set `memid`='".$row['memid']."', `CN`='".mysql_real_escape_string($row['CN'])."', @@ -1378,6 +1431,15 @@ $_SESSION['_config']['rootcert'] = 1; $emails .= "SPKAC = $spkac"; + if (($weakKey = checkWeakKeySPKAC($emails)) !== "") + { + $id = 17; + showheader(_("My CAcert.org Account!")); + echo $weakKey; + showfooter(); + exit; + } + $query = "insert into `orgemailcerts` set `CN`='$defaultemail', `keytype`='NS', @@ -1408,6 +1470,16 @@ mysql_query("update `orgemailcerts` set `csr_name`='$CSRname' where `id`='$emailid'"); } else if($_REQUEST['keytype'] == "MS" || $_REQUEST['keytype']=="VI") { $csr = "-----BEGIN CERTIFICATE REQUEST-----\n".clean_csr($_REQUEST['CSR'])."-----END CERTIFICATE REQUEST-----\n"; + + if (($weakKey = checkWeakKeyCSR($csr)) !== "") + { + $id = 17; + showheader(_("My CAcert.org Account!")); + echo $weakKey; + showfooter(); + exit; + } + $tmpfname = tempnam("/tmp", "id17CSR"); $fp = fopen($tmpfname, "w"); fputs($fp, $csr); @@ -1514,8 +1586,17 @@ printf(_("Invalid ID '%s' presented, can't do anything with it.")."
\n", $id); continue; } - mysql_query("update `orgemailcerts` set `renewed`='1' where `id`='$id'"); + $row = mysql_fetch_assoc($res); + + if (($weakKey = checkWeakKeyX509(file_get_contents( + $row['crt_name']))) !== "") + { + echo $weakKey, "
\n"; + continue; + } + + mysql_query("update `orgemailcerts` set `renewed`='1' where `id`='$id'"); if($row['revoke'] > 0) { printf(_("It would seem '%s' has already been revoked. I'll skip this for now.")."
\n", $row['CN']); @@ -1625,6 +1706,16 @@ if($process != "" && $oldid == 20) { $CSR = clean_csr($_REQUEST['CSR']); + + if (($weakKey = checkWeakKeyCSR($CSR)) !== "") + { + $id = 20; + showheader(_("My CAcert.org Account!")); + echo $weakKey; + showfooter(); + exit; + } + $_SESSION['_config']['tmpfname'] = tempnam("/tmp", "id20CSR"); $fp = fopen($_SESSION['_config']['tmpfname'], "w"); fputs($fp, $CSR); @@ -1674,6 +1765,23 @@ if($process != "" && $oldid == 21) { $id = 21; + + if(!file_exists($_SESSION['_config']['tmpfname'])) + { + showheader(_("My CAcert.org Account!")); + printf(_("Your certificate request has failed to be processed correctly, see %sthe WIKI page%s for reasons and solutions."), "", ""); + showfooter(); + exit; + } + + if (($weakKey = checkWeakKeyCSR(file_get_contents( + $_SESSION['_config']['tmpfname']))) !== "") + { + showheader(_("My CAcert.org Account!")); + echo $weakKey; + showfooter(); + exit; + } if($_SESSION['_config']['0.CN'] == "" && $_SESSION['_config']['0.subjectAltName'] == "") { @@ -1799,8 +1907,17 @@ printf(_("Invalid ID '%s' presented, can't do anything with it.")."
\n", $id); continue; } - mysql_query("update `orgdomaincerts` set `renewed`='1' where `id`='$id'"); + $row = mysql_fetch_assoc($res); + + if (($weakKey = checkWeakKeyX509(file_get_contents( + $row['crt_name']))) !== "") + { + echo $weakKey, "
\n"; + continue; + } + + mysql_query("update `orgdomaincerts` set `renewed`='1' where `id`='$id'"); if($row['revoke'] > 0) { printf(_("It would seem '%s' has already been revoked. I'll skip this for now.")."
\n", $row['CN']); @@ -2497,6 +2614,14 @@ showfooter(); exit; } + + if (($weakKey = checkWeakKeyCSR($CSR)) !== "") + { + showheader(_("My CAcert.org Account!")); + echo $weakKey; + showfooter(); + exit; + } $query = "insert into `domaincerts` set `CN`='".$_SESSION['_config']['0.CN']."', diff --git a/www/api/ccsr.php b/www/api/ccsr.php index e81c738..a4ec71e 100644 --- a/www/api/ccsr.php +++ b/www/api/ccsr.php @@ -59,6 +59,12 @@ $codesign = 1; $CSR = trim($_REQUEST['optionalCSR']); + + if (($weakKey = checkWeakKeyCSR($CSR)) !== "") + { + die("403, $weakKey"); + } + $incsr = tempnam("/tmp", "ccsrIn"); $checkedcsr = tempnam("/tmp", "ccsrOut"); $fp = fopen($incsr, "w"); -- cgit v1.2.1 From 7f1f10b52ab565d582de1ddb933872ce12e104f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Fr=C3=B6hlich?= Date: Thu, 14 Apr 2011 23:54:10 +0200 Subject: Activated openssl-vulnkey call --- scripts/DumpWeakCerts.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/DumpWeakCerts.pl b/scripts/DumpWeakCerts.pl index 894d06d..85648fe 100755 --- a/scripts/DumpWeakCerts.pl +++ b/scripts/DumpWeakCerts.pl @@ -65,9 +65,9 @@ sub IsWeak($) { 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"; - #} + if (system("openssl-vulnkey -q $CertFileName") != 0) { + $result = "openssl-vulnkey"; + } } return $result; -- cgit v1.2.1