aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Andree <matthias.andree@gmx.de>2009-08-04 09:27:10 +0000
committerMatthias Andree <matthias.andree@gmx.de>2009-08-04 09:27:10 +0000
commit62acd57d67fff935e1c8a1796853e911869ee9f8 (patch)
tree1310b419884542bd10f106e46246765d7b92b9ee
parentcce6e3905c62ae2ffbddbea4d8ff4ed4fd253329 (diff)
downloadfetchmail-62acd57d67fff935e1c8a1796853e911869ee9f8.tar.gz
fetchmail-62acd57d67fff935e1c8a1796853e911869ee9f8.tar.bz2
fetchmail-62acd57d67fff935e1c8a1796853e911869ee9f8.zip
Abort verification if Subject CommonName/AltName contains NUL.
svn path=/branches/BRANCH_6-3/; revision=5389
-rw-r--r--NEWS5
-rw-r--r--po/de.po77
-rw-r--r--socket.c27
3 files changed, 70 insertions, 39 deletions
diff --git a/NEWS b/NEWS
index edab25a3..701339a2 100644
--- 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
diff --git a/po/de.po b/po/de.po
index 9ce1ccc7..843e3c41 100644
--- 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"
diff --git a/socket.c b/socket.c
index 474928d0..45f03a6b 100644
--- 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,