Typo in openssl-vulnkey call
[cacert-devel.git] / scripts / DumpWeakCerts.pl
1 #!/usr/bin/perl
2 # Script to dump weak RSA certs (Exponent 3 or Modulus size < 1024) according to https://bugs.cacert.org/view.php?id=918
3 # and https://wiki.cacert.org/Arbitrations/a20110312.1
4
5 use strict;
6 use warnings;
7
8 use DBI;
9
10 my $cacert_db_config;
11 my $cacert_db_user;
12 my $cacert_db_password;
13
14 # Read database access data from the config file
15 eval `cat perl_mysql`;
16
17 my $dbh = DBI->connect($cacert_db_config, $cacert_db_user, $cacert_db_password, { RaiseError => 1, AutoCommit => 0 } ) || die "Cannot connect database: $DBI::errstr";
18
19 my $sth_certs;
20 my $sth_userdata;
21
22 my $cert_domid;
23 my $cert_userid;
24 my $cert_orgid;
25 my $cert_CN;
26 my $cert_expire;
27 my $cert_filename;
28
29 my $user_email;
30 my $user_firstname;
31
32 my $reason;
33
34 my @row;
35
36 sub IsWeak($) {
37 my ($CertFileName) = @_;
38
39 my $ModulusSize = 0;
40 my $Exponent = 0;
41 my $result = 0;
42
43 # Do key size and exponent checking for RSA keys
44 open(CERTTEXT, '-|', "openssl x509 -in $CertFileName -noout -text") || die "Cannot start openssl";
45 while (<CERTTEXT>) {
46 if (/^ +([^ ]+) Public Key:/) {
47 last if ($1 ne "RSA");
48 }
49 if (/^ +Modulus \((\d+) bit\)/) {
50 $ModulusSize = $1;
51 }
52 if (/^ +Exponent: (\d+)/) {
53 $Exponent = $1;
54 last;
55 }
56 }
57 close(CERTTEXT);
58 if ($ModulusSize > 0 && $Exponent > 0) {
59 if ($ModulusSize < 1024 || $Exponent==3) {
60 $result = "SmallKey";
61 }
62 }
63
64 if (!$result) {
65 # Check with openssl-vulnkey
66 # This is currently not tested, if you don't know what you are doing leave it commented!
67 #if (system("openssl-vulnkey -q $CertFileName") != 0) {
68 # $result = "openssl-vulnkey";
69 #}
70 }
71
72 return $result;
73 }
74
75 # Select only certificates expiring in more than two weeks, since two weeks will probably be needed as turnaround time
76 # Get all domain certificates
77 $sth_certs = $dbh->prepare(
78 "SELECT `dc`.`domid`, `dc`.`CN`, `dc`.`expire`, `dc`.`crt_name` ".
79 " FROM `domaincerts` AS `dc` ".
80 " WHERE `dc`.`revoked`=0 AND `dc`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)");
81 $sth_certs->execute();
82
83 $sth_userdata = $dbh->prepare(
84 "SELECT `u`.`email`, `u`.`fname` ".
85 " FROM `domains` AS `d`, `users` AS `u` ".
86 " WHERE `d`.`memid`=`u`.`id` AND `d`.`id`=?");
87
88 while(($cert_domid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) {
89 if (-f $cert_filename) {
90 $reason = IsWeak($cert_filename);
91 if ($reason) {
92 $sth_userdata->execute($cert_domid);
93 ($user_email, $user_firstname) = $sth_userdata->fetchrow_array();
94 print join("\t", ('DomainCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason)). "\n";
95 $sth_userdata->finish();
96 }
97 }
98 }
99 $sth_certs->finish();
100
101 # Get all email certificates
102 $sth_certs = $dbh->prepare(
103 "SELECT `ec`.`memid`, `ec`.`CN`, `ec`.`expire`, `ec`.`crt_name` ".
104 " FROM `emailcerts` AS `ec` ".
105 " WHERE `ec`.`revoked`=0 AND `ec`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)");
106 $sth_certs->execute();
107
108 $sth_userdata = $dbh->prepare(
109 "SELECT `u`.`email`, `u`.`fname` ".
110 " FROM `users` AS `u` ".
111 " WHERE `u`.`id`=?");
112
113 while(($cert_userid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) {
114 if (-f $cert_filename) {
115 $reason = IsWeak($cert_filename);
116 if ($reason) {
117 $sth_userdata->execute($cert_userid);
118 ($user_email, $user_firstname) = $sth_userdata->fetchrow_array();
119 print join("\t", ('EmailCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason)). "\n";
120 $sth_userdata->finish();
121 }
122 }
123 }
124 $sth_certs->finish();
125
126 # Get all Org Server certificates, notify all admins of the Org!
127 $sth_certs = $dbh->prepare(
128 "SELECT `dc`.`orgid`, `dc`.`CN`, `dc`.`expire`, `dc`.`crt_name` ".
129 " FROM `orgdomaincerts` AS `dc` ".
130 " WHERE `dc`.`revoked`=0 AND `dc`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)");
131 $sth_certs->execute();
132
133 $sth_userdata = $dbh->prepare(
134 "SELECT `u`.`email`, `u`.`fname` ".
135 " FROM `users` AS `u`, `org` ".
136 " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?");
137
138 while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) {
139 if (-f $cert_filename) {
140 $reason = IsWeak($cert_filename);
141 if ($reason) {
142 $sth_userdata->execute($cert_orgid);
143 while(($user_email, $user_firstname) = $sth_userdata->fetchrow_array()) {
144 print join("\t", ('OrgServerCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason)). "\n";
145 }
146 $sth_userdata->finish();
147 }
148 }
149 }
150 $sth_certs->finish();
151
152 # Get all Org Email certificates, notify all admins of the Org!
153 $sth_certs = $dbh->prepare(
154 "SELECT `ec`.`orgid`, `ec`.`CN`, `ec`.`expire`, `ec`.`crt_name` ".
155 " FROM `orgemailcerts` AS `ec` ".
156 " WHERE `ec`.`revoked`=0 AND `ec`.`expire` > DATE_ADD(NOW(), INTERVAL 14 DAY)");
157 $sth_certs->execute();
158
159 $sth_userdata = $dbh->prepare(
160 "SELECT `u`.`email`, `u`.`fname` ".
161 " FROM `users` AS `u`, `org` ".
162 " WHERE `u`.`id`=`org`.`memid` and `org`.`orgid`=?");
163
164 while(($cert_orgid, $cert_CN, $cert_expire, $cert_filename) = $sth_certs->fetchrow_array) {
165 if (-f $cert_filename) {
166 $reason = IsWeak($cert_filename);
167 if ($reason) {
168 $sth_userdata->execute($cert_orgid);
169 while(($user_email, $user_firstname) = $sth_userdata->fetchrow_array()) {
170 print join("\t", ('OrgEmailCert', $user_email, $user_firstname, $cert_expire, $cert_CN, $reason)). "\n";
171 }
172 $sth_userdata->finish();
173 }
174 }
175 }
176 $sth_certs->finish();
177
178 $dbh->disconnect();