]> Pileus Git - ~andy/fetchmail/commitdiff
Abort verification if Subject CommonName/AltName contains NUL.
authorMatthias Andree <matthias.andree@gmx.de>
Tue, 4 Aug 2009 09:27:10 +0000 (09:27 -0000)
committerMatthias Andree <matthias.andree@gmx.de>
Tue, 4 Aug 2009 09:27:10 +0000 (09:27 -0000)
svn path=/branches/BRANCH_6-3/; revision=5389

NEWS
po/de.po
socket.c

diff --git a/NEWS b/NEWS
index edab25a3ee08396c0d7ce5aeab382dae456602b1..701339a21a19df059c2a2f21a5a9f4ef6acc9149 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,11 @@ removed from a 6.4.0 or newer release.)
 
 fetchmail 6.3.11 (released XXXX-XX-XX - i. e. not yet):
 
+# SECURITY BUGFIXES
+* Fetchmail checks the Subject CommonName and Subject AltName X.509 certificate
+  fields for embedded NUL characters and aborts certificate verification to
+  counter recent SSL certificate verification attacks. Untested.
+
 # BUGFIXES
 * Remove the spurious message "message delimiter found while scanning headers".
   RFC-5322 syntax states that the delimiter is part of the body, and the body is
index 9ce1ccc7c7bacdb05eb9d8cce573be46b892d13b..843e3c414584afb623541632ee0ef1527696d55d 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: fetchmail 6.3.10-beta1\n"
 "Report-Msgid-Bugs-To: fetchmail-devel@lists.berlios.de\n"
-"POT-Creation-Date: 2009-07-02 21:34+0200\n"
+"POT-Creation-Date: 2009-08-04 11:24+0200\n"
 "PO-Revision-Date: 2009-05-26 00:53+0200\n"
 "Last-Translator: Matthias Andree <matthias.andree@gmx.de>\n"
 "Language-Team: Deutsch <de@li.org>\n"
@@ -2935,79 +2935,93 @@ msgstr "Server-CommonName: %s\n"
 msgid "Bad certificate: Subject CommonName too long!\n"
 msgstr "Ungültiges Zertifikat: Server-CommonName zu lang!\n"
 
-#: socket.c:678
+#: socket.c:638
+msgid "Bad certificate: Subject CommonName contains NUL, aborting!\n"
+msgstr "Ungültiges Zertifikat: Subject-CommonName enthält NUL, breche ab!\n"
+
+#: socket.c:661
+msgid "Bad certificate: Subject Alternative Name contains NUL, aborting!\n"
+msgstr ""
+"Ungültiges Zertifikat: Subject-Alternative-Name enthält NUL, breche ab!\n"
+
+#: socket.c:666
+#, c-format
+msgid "Subject Alternative Name: %s\n"
+msgstr "\"Subject Alternative Name\": %s\n"
+
+#: socket.c:691
 #, c-format
 msgid "Server CommonName mismatch: %s != %s\n"
 msgstr "Server-CommonName stimmt nicht überein: %s != %s\n"
 
-#: socket.c:684
+#: socket.c:697
 msgid "Server name not set, could not verify certificate!\n"
 msgstr "Server-Name nicht gesetzt, konnte Zertifikat nicht verifizieren!\n"
 
-#: socket.c:689
+#: socket.c:702
 msgid "Unknown Server CommonName\n"
 msgstr "Unbekannter Server-CommonName\n"
 
-#: socket.c:691
+#: socket.c:704
 msgid "Server name not specified in certificate!\n"
 msgstr "Server-Name nicht in Zertifikat spezifiziert!\n"
 
-#: socket.c:703
+#: socket.c:716
 msgid "EVP_md5() failed!\n"
 msgstr "EVP_md5() fehlgeschlagen!\n"
 
-#: socket.c:707
+#: socket.c:720
 msgid "Out of memory!\n"
 msgstr "Kein Speicher mehr frei!\n"
 
-#: socket.c:715
+#: socket.c:728
 msgid "Digest text buffer too small!\n"
 msgstr "Textpuffer für Digest zu klein!\n"
 
-#: socket.c:721
+#: socket.c:734
 #, c-format
 msgid "%s key fingerprint: %s\n"
 msgstr "%s-Schlüssel-Fingerabdruck: %s\n"
 
-#: socket.c:725
+#: socket.c:738
 #, c-format
 msgid "%s fingerprints match.\n"
 msgstr "%s-Fingerabdrücke stimmen überein.\n"
 
-#: socket.c:727
+#: socket.c:740
 #, c-format
 msgid "%s fingerprints do not match!\n"
 msgstr "%s-Fingerabdrücke stimmen nicht überein!\n"
 
-#: socket.c:736
+#: socket.c:749
 #, c-format
 msgid "Server certificate verification error: %s\n"
 msgstr "Fehler bei Server-Zertifikat-Überprüfung: %s\n"
 
-#: socket.c:742
+#: socket.c:755
 #, c-format
 msgid "unknown issuer (first %d characters): %s\n"
 msgstr "unbekannter Herausgeber (erste %d Zeichen): %s\n"
 
-#: socket.c:829
+#: socket.c:842
 msgid "File descriptor out of range for SSL"
 msgstr "Datei-Deskriptor außerhalb des Bereichs für SSL"
 
-#: socket.c:845
+#: socket.c:858
 #, c-format
 msgid "Invalid SSL protocol '%s' specified, using default (SSLv23).\n"
 msgstr ""
 "Ungültiges SSL-Protokoll „%s“ angegeben, benutze Voreinstellung (SSLv23).\n"
 
-#: socket.c:921
+#: socket.c:934
 msgid "Certificate/fingerprint verification was somehow skipped!\n"
 msgstr "Zertifikat-/Fingerabdruck-Überprüfung wurde irgendwie übersprungen!\n"
 
-#: socket.c:999
+#: socket.c:1012
 msgid "Cygwin socket read retry\n"
 msgstr "Cygwin-Socket-Lese-Wiederholung\n"
 
-#: socket.c:1002
+#: socket.c:1015
 msgid "Cygwin socket read retry failed!\n"
 msgstr "Cygwin-Socket-Lese-Wiederholung fehlgeschlagen!\n"
 
@@ -3054,50 +3068,46 @@ msgstr "keine „Received“-Adresse gefunden\n"
 msgid "found Received address `%s'\n"
 msgstr "„Received“-Adresse „%s“ gefunden\n"
 
-#: transact.c:566
-msgid "message delimiter found while scanning headers\n"
-msgstr "Nachrichtentrenner gefunden beim Scannen der Kopfzeilen\n"
-
-#: transact.c:597
+#: transact.c:592
 msgid "incorrect header line found while scanning headers\n"
 msgstr "inkorrekte Kopfzeile gefunden beim Scannen der Kopfzeilen\n"
 
-#: transact.c:599
+#: transact.c:594
 #, c-format
 msgid "line: %s"
 msgstr "Zeile: %s"
 
-#: transact.c:1138
+#: transact.c:1133
 #, c-format
 msgid "no local matches, forwarding to %s\n"
 msgstr "keine lokalen Übereinstimmungen, Weiterleitung an %s\n"
 
-#: transact.c:1153
+#: transact.c:1148
 msgid "forwarding and deletion suppressed due to DNS errors\n"
 msgstr "Weiterleiten und Löschen wegen DNS-Fehlern unterdrückt\n"
 
-#: transact.c:1263
+#: transact.c:1258
 msgid "writing RFC822 msgblk.headers\n"
 msgstr "schreibe RFC822 msgblk.headers\n"
 
-#: transact.c:1282
+#: transact.c:1277
 msgid "no recipient addresses matched declared local names"
 msgstr "keine Empfängeradresse stimmt mit deklarierten lokalen Namen überein"
 
-#: transact.c:1289
+#: transact.c:1284
 #, c-format
 msgid "recipient address %s didn't match any local name"
 msgstr "Empfängeradresse %s stimmt mit keinem lokalen Namen überein"
 
-#: transact.c:1298
+#: transact.c:1293
 msgid "message has embedded NULs"
 msgstr "Nachricht hat eingebettete NUL-Zeichen"
 
-#: transact.c:1306
+#: transact.c:1301
 msgid "SMTP listener rejected local recipient addresses: "
 msgstr "SMTP-Server lehnte Adressen mit lokalem Empfänger ab: "
 
-#: transact.c:1445
+#: transact.c:1440
 msgid "error writing message text\n"
 msgstr "Fehler beim Schreiben des Nachrichtentextes\n"
 
@@ -3172,3 +3182,6 @@ msgstr "malloc fehlgeschlagen\n"
 #: xmalloc.c:47
 msgid "realloc failed\n"
 msgstr "realloc fehlgeschlagen\n"
+
+#~ msgid "message delimiter found while scanning headers\n"
+#~ msgstr "Nachrichtentrenner gefunden beim Scannen der Kopfzeilen\n"
index 474928d03ef7c764b33d5999df670b6986893e6c..45f03a6b83d733d7aa173e230829775081855108 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -608,7 +608,7 @@ static int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )
 
        if (depth == 0 && !_depth0ck) {
                _depth0ck = 1;
-               
+
                if (outlevel >= O_VERBOSE) {
                        if ((i = X509_NAME_get_text_by_NID(issuer, NID_organizationName, buf, sizeof(buf))) != -1) {
                                report(stdout, GT_("Issuer Organization: %s\n"), buf);
@@ -632,6 +632,12 @@ static int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )
                                report(stderr, GT_("Bad certificate: Subject CommonName too long!\n"));
                                return (0);
                        }
+                       if ((size_t)i > strlen(buf)) {
+                               /* Name contains embedded NUL characters, so we complain. This is likely
+                                * a certificate spoofing attack. */
+                               report(stderr, GT_("Bad certificate: Subject CommonName contains NUL, aborting!\n"));
+                               return 0;
+                       }
                        if (_ssl_server_cname != NULL) {
                                char *p1 = buf;
                                char *p2 = _ssl_server_cname;
@@ -643,14 +649,21 @@ static int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )
                                 * first find a match among alternative names */
                                gens = (STACK_OF(GENERAL_NAME) *)X509_get_ext_d2i(x509_cert, NID_subject_alt_name, NULL, NULL);
                                if (gens) {
-                                       int i, r;
-                                       for (i = 0, r = sk_GENERAL_NAME_num(gens); i < r; ++i) {
-                                               const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i);
+                                       int j, r;
+                                       for (j = 0, r = sk_GENERAL_NAME_num(gens); j < r; ++j) {
+                                               const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, j);
                                                if (gn->type == GEN_DNS) {
                                                        char *p1 = (char *)gn->d.ia5->data;
                                                        char *p2 = _ssl_server_cname;
+                                                       /* Name contains embedded NUL characters, so we complain. This
+                                                        * is likely a certificate spoofing attack. */
+                                                       if ((size_t)gn->d.ia5->length != strlen(p1)) {
+                                                               report(stderr, GT_("Bad certificate: Subject Alternative Name contains NUL, aborting!\n"));
+                                                               sk_GENERAL_NAME_free(gens);
+                                                               return 0;
+                                                       }
                                                        if (outlevel >= O_VERBOSE)
-                                                               report(stderr, "Subject Alternative Name: %s\n", p1);
+                                                               report(stdout, GT_("Subject Alternative Name: %s\n"), p1);
                                                        if (*p1 == '*') {
                                                                ++p1;
                                                                n = strlen(p2) - strlen(p1);
@@ -669,9 +682,9 @@ static int SSL_verify_callback( int ok_return, X509_STORE_CTX *ctx, int strict )
                                        n = strlen(p2) - strlen(p1);
                                        if (n >= 0)
                                                p2 += n;
-                               }       
+                               }
                                if (0 == strcasecmp(p1, p2)) {
-                                 matched = 1;
+                                       matched = 1;
                                }
                                if (!matched) {
                                        report(stderr,