deutlich striktere Checks bei hochgeladenen Zertifikaten, User können sonst mit unsinnigen oder veralteten Zertifikaten den Apache lahmlegen
Hanno Böck

Hanno Böck commited on 2021-05-02 17:35:45
Zeige 1 geänderte Dateien mit 27 Einfügungen und 6 Löschungen.

... ...
@@ -138,20 +138,32 @@ function validate_certificate($cert, $key)
138 138
         system_failure("In dem eingetragenen Zertifikat wurde kein öffentlicher Schlüssel gefunden.");
139 139
     }
140 140
     // Parse Details über den pubkey
141
-    $certinfo = openssl_pkey_get_details($pubkey);
142
-    DEBUG($certinfo);
143
-    if ($certinfo === false) {
141
+    $pubkeyinfo = openssl_pkey_get_details($pubkey);
142
+    DEBUG($pubkeyinfo);
143
+    if ($pubkeyinfo === false) {
144 144
         system_failure("Der öffentliche Schlüssel des Zertifikats konnte nicht gelesen werden");
145 145
     }
146 146
 
147 147
     // Apache unterstützt nur Schlüssel vom Typ RSA oder DSA
148
-    if (! in_array($certinfo['type'], array(OPENSSL_KEYTYPE_RSA, OPENSSL_KEYTYPE_DSA))) {
148
+    if ($pubkeyinfo['type'] !== OPENSSL_KEYTYPE_RSA) {
149 149
         system_failure("Dieser Schlüssel nutzt einen nicht unterstützten Algorithmus.");
150 150
     }
151 151
 
152 152
     // Bei ECC-Keys treten kürzere Schlüssellängen auf, die können wir aktuell aber sowieso nicht unterstützen
153
-    if ($certinfo['bits'] < 2048) {
154
-        warning("Dieser Schlüssel hat eine sehr geringe Bitlänge und ist daher als nicht besonders sicher einzustufen!");
153
+    // Wir blockieren zu kurze und zu lange Schlüssel hart, da Apache sonst nicht startet
154
+    if ($pubkeyinfo['bits'] < 2048) {
155
+        system_failure("Schlüssellänge ist zu kurz");
156
+    }
157
+    if ($pubkeyinfo['bits'] > 4096) {
158
+        system_failure("Schlüssellänge ist zu lang");
159
+    }
160
+
161
+    $x509info = openssl_x509_parse($cert);
162
+    if ($x509info === false) {
163
+        system_failure("Zertifikat konnte nicht verarbeitet werden");
164
+    }
165
+    if (!in_array($x509info['signatureTypeSN'], array("RSA-SHA256", "RSA-SHA385", "RSA-SHA512"))) {
166
+        system_failure("Nicht unterstützer Signatur-Hashalgorithmus!");
155 167
     }
156 168
 
157 169
     // Prüfe ob Key und Zertifikat zusammen passen
... ...
@@ -160,6 +172,15 @@ function validate_certificate($cert, $key)
160 172
         return CERT_INVALID;
161 173
     }
162 174
 
175
+    // Check von openssl_x509_check_private_key() ist leider nicht ausreichend
176
+    $testdata = base64_encode(random_bytes(32));
177
+    if (openssl_sign($testdata, $signature, $seckey) !== true) {
178
+        system_failure("Kann keine Testsignatur erstellen, Key ungültig!");
179
+    }
180
+    if (openssl_verify($testdata, $signature, $pubkey) !== 1) {
181
+        system_failure("Testsignatur ungültig, Key vermutlich fehlerhaft!");
182
+    }
183
+
163 184
     $cacerts = array('/etc/ssl/certs');
164 185
     $chain = (int) get_chain($cert);
165 186
     if ($chain) {
166 187