paying more attention to TLS

This commit is contained in:
psyc://psyced.org/~lynX 2011-08-02 17:43:05 +02:00
parent 0c482f5104
commit da6ce92529
12 changed files with 106 additions and 48 deletions

2
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "psyclpc"] [submodule "psyclpc"]
path = psyclpc path = psyclpc
url = git://git.tgbit.net/psyclpc url = git://git.psyced.org/git/psyclpc

View File

@ -1,6 +1,15 @@
<PSYC:TEXTDB> ## vim:syntax=mail <PSYC:TEXTDB> ## vim:syntax=mail
## Check utf-8: Praise Atatürk! ## Check utf-8: Praise Atatürk!
_status_circuit_encryption_cipher
|Gratuliere! Deine Verbindung ist mit Folgenlosigkeit verschlüsselt.
_warning_circuit_encryption_cipher
|Deine Verbindung ist leider ohne Folgenlosigkeit verschlüsselt.
_error_circuit_encryption_cipher
|Deine Verbindung ist ohne Folgenlosigkeit verschlüsselt.
_failure_disabled_function_register _failure_disabled_function_register
|Registrierung ist auf diesem Server deaktiviert. |Registrierung ist auf diesem Server deaktiviert.

View File

@ -1,6 +1,15 @@
<PSYC:TEXTDB> ## vim:syntax=mail <PSYC:TEXTDB> ## vim:syntax=mail
## Check utf-8: Praise Atatürk! ## Check utf-8: Praise Atatürk!
_status_circuit_encryption_cipher
|Congratulations. Your connection is encrypted with forward secrecy.
_warning_circuit_encryption_cipher
|Your cipher choice does not provide forward secrecy.
_error_circuit_encryption_cipher
|Unfortunately your cipher choice does not provide forward secrecy.
_failure_disabled_function_register _failure_disabled_function_register
|Registration disabled on this server. |Registration disabled on this server.

View File

@ -1,6 +1,15 @@
<PSYC:TEXTDB> ## vim:syntax=mail <PSYC:TEXTDB> ## vim:syntax=mail
## tradotto al 30% ... cerca /TODO/ per continuare ## tradotto al 30% ... cerca /TODO/ per continuare
_status_circuit_encryption_cipher
|Muy bueno! La tua connessione è crittata senza conseguenze.
_warning_circuit_encryption_cipher
|La tua connessione non è crittata senza conseguenze.
_error_circuit_encryption_cipher
|Purtroppo la tua connessione non è crittata senza conseguenze.
_failure_disabled_function_register _failure_disabled_function_register
|Registrazione di nuovi utenti disabilitata su questo server. |Registrazione di nuovi utenti disabilitata su questo server.

View File

@ -315,7 +315,7 @@ tls_logon(result) {
mixed cert = tls_certificate(ME, 0); mixed cert = tls_certificate(ME, 0);
P3(("active::certinfo %O\n", cert)) P3(("active::certinfo %O\n", cert))
if (mappingp(cert)) { if (mappingp(cert)) {
unless (certificate_check_name(hostname, cert, "xmpp-server")) { unless (tls_check_certificate_data(cert, hostname, "xmpp-server")) {
#ifdef _flag_report_bogus_certificates #ifdef _flag_report_bogus_certificates
monitor_report("_error_invalid_certificate_identity", monitor_report("_error_invalid_certificate_identity",
sprintf("%O presented a certificate that " sprintf("%O presented a certificate that "

View File

@ -393,7 +393,8 @@ xmpp_error(node, xmpperror) {
return 0; return 0;
} }
// deprecated - use certificate_check_name from library/tls.c instead // deprecated - use tls_check_certificate_data from library/tls.c instead
// is this being used at all?
#ifdef WANT_S2S_TLS #ifdef WANT_S2S_TLS
certificate_check_jabbername(name, cert) { certificate_check_jabbername(name, cert) {
mixed t; mixed t;

View File

@ -291,7 +291,7 @@ jabberMsg(XMLNode node) {
// paranoia note: as with XEP 0178 we might want to check dns anyway to // paranoia note: as with XEP 0178 we might want to check dns anyway to
// protect against stolen certificates // protect against stolen certificates
if (mappingp(certinfo) && certinfo[0] == 0 if (mappingp(certinfo) && certinfo[0] == 0
&& node["@from"] && certificate_check_name(node["@from"], certinfo, "xmpp-server")) { && node["@from"] && tls_check_certificate_data(certinfo, node["@from"], "xmpp-server")) {
P2(("dialback without dialback %O\n", certinfo)) P2(("dialback without dialback %O\n", certinfo))
verify_connection(node["@to"], node["@from"], "valid"); verify_connection(node["@to"], node["@from"], "valid");
} else { } else {
@ -414,7 +414,7 @@ jabberMsg(XMLNode node) {
*/ */
int success = 0; int success = 0;
success = certificate_check_name(t, certinfo, "xmpp-server"); success = tls_check_certificate_data(certinfo, t, "xmpp-server");
if (success) { if (success) {
emitraw("<success xmlns='" NS_XMPP "xmpp-sasl'/>"); emitraw("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
P2(("successful sasl external authentication with " P2(("successful sasl external authentication with "
@ -542,8 +542,8 @@ open_stream(XMLNode node) {
// sasl external if we know that it will succeed // sasl external if we know that it will succeed
// later on // later on
if (node["@from"] && if (node["@from"] &&
certificate_check_name(node["@from"], tls_check_certificate_data(certinfo, node["@from"],
certinfo, "xmpp-server")) { "xmpp-server")) {
packet += "<mechanisms xmlns='" NS_XMPP "xmpp-sasl'>"; packet += "<mechanisms xmlns='" NS_XMPP "xmpp-sasl'>";
packet += "<mechanism>EXTERNAL</mechanism>"; packet += "<mechanism>EXTERNAL</mechanism>";
packet += "</mechanisms>"; packet += "</mechanisms>";

View File

@ -490,6 +490,7 @@ open_stream(XMLNode node) {
#if __EFUN_DEFINED__(tls_available) #if __EFUN_DEFINED__(tls_available)
if (tls_available() && tls_query_connection_state(ME) > 0 if (tls_available() && tls_query_connection_state(ME) > 0
&& mappingp(certinfo) && certinfo[0] == 0 && mappingp(certinfo) && certinfo[0] == 0
// why do we use the old one here?
&& certificate_check_jabbername(0, certinfo)) { && certificate_check_jabbername(0, certinfo)) {
features += "<mechanism>EXTERNAL</mechanism>"; features += "<mechanism>EXTERNAL</mechanism>";
} }

View File

@ -1,4 +1,7 @@
#include <net.h> // vim syntax=lpc #include <net.h> // vim syntax=lpc
#include <proto.h>
#include <sys/tls.h>
mapping tls_certificate(object who, int longnames) { mapping tls_certificate(object who, int longnames) {
mixed *extra, extensions; mixed *extra, extensions;
mapping cert; mapping cert;
@ -85,7 +88,7 @@ mapping tls_certificate(object who, int longnames) {
// generalized variant of the old certificate_check_jabbername // generalized variant of the old certificate_check_jabbername
// RFC 6125 describes the process in more detail // RFC 6125 describes the process in more detail
int certificate_check_name(string name, mixed cert, string scheme) { int tls_check_certificate_data(mixed cert, string name, string scheme) {
mixed t; mixed t;
string idn; string idn;
// FIXME: should probably be more careful about internationalized // FIXME: should probably be more careful about internationalized
@ -159,3 +162,20 @@ int certificate_check_name(string name, mixed cert, string scheme) {
} }
return 0; return 0;
} }
int tls_check_cipher(object sock, string scheme) {
string t;
mixed m = tls_query_connection_info(sock);
P3(("%O is using the %O cipher.\n", sock, m[TLS_CIPHER]))
// shouldn't our negotiation have ensured we have PFS?
if (stringp(t = m[TLS_CIPHER]) &&! abbrev("DHE", t)) {
monitor_report("_warning_circuit_encryption_cipher_details",
object_name(sock) +" · using "+ t +" cipher");
// we can't expect that degree of privacy from jabber, for now
if (scheme != "xmpp") return 0;
}
return 1;
}

View File

@ -209,48 +209,41 @@ int logon(int neverfails) {
#ifdef __TLS__ #ifdef __TLS__
sAuthHosts(([ ])); // reset authhosts sAuthHosts(([ ])); // reset authhosts
if (tls_available() && tls_query_connection_state(ME) == 1 && mappingp(cert = tls_certificate(ME, 0))) { if (tls_available() && tls_query_connection_state(ME) == 1) {
if (cert[0] != 0) { unless (tls_check_cipher(ME, "psyc")) {
// log error 17 or 18 + cert here croak("_error_circuit_encryption_cipher",
P0(("%O encountered a cert verify error %O in %O\n", ME, "Your cipher choice does not provide forward secrecy.");
cert[0], cert)) QUIT
// and goodbye. }
if (mappingp(cert = tls_certificate(ME, 0))) {
if (cert[0] != 0) {
// log error 17 or 18 + cert here
P0(("%O encountered a cert verify error %O in %O\n", ME,
cert[0], cert))
// and goodbye.
# ifdef _flag_enable_certificate_any # ifdef _flag_enable_certificate_any
remove_interactive(ME); remove_interactive(ME);
return 0; return 0;
# endif # endif
}
if (m = cert["2.5.29.17:dNSName"]) {
// FIXME: this does not yet handle wildcard DNS names
P1(("%O believing dNSName %O\n", ME, m))
// probably also: register_target?
// but be careful never to register_target wildcards
if (stringp(m)) sAuthenticated(m);
else foreach(t : m) sAuthenticated(t);
}
//#ifdef _flag_allow_certificate_name_common // to be switched this year
# ifndef _flag_disallow_certificate_name_common
// assume that CN is a host
// as this is an assumption only, we may NEVER register_target it
// note: CN is deprecated for good reasons.
else if (t = cert["2.5.4.3"]) {
P1(("%O believing CN %O\n", ME, t))
sAuthenticated(t);
}
# endif
if (m = tls_query_connection_info(ME)) {
P2(("%O is using the %O cipher.\n", ME, m[TLS_CIPHER]))
// shouldn't our negotiation have ensured we have PFS?
if (stringp(t = m[TLS_CIPHER]) &&! abbrev("DHE", t)) {
// croak("_warning_circuit_encryption_cipher",
// "Your cipher choice does not provide forward secrecy.");
monitor_report(
"_warning_circuit_encryption_cipher_details",
object_name(ME) +" · using "+ t +" cipher");
//debug_message(sprintf(
// "TLS connection info for %O is %O\n", ME, m));
//QUIT // are we ready for *this* !???
} }
if (m = cert["2.5.29.17:dNSName"]) {
// FIXME: this does not yet handle wildcard DNS names
P1(("%O believing dNSName %O\n", ME, m))
// probably also: register_target?
// but be careful never to register_target wildcards
if (stringp(m)) sAuthenticated(m);
else foreach(t : m) sAuthenticated(t);
}
//#ifdef _flag_allow_certificate_name_common // to be switched this year
# ifndef _flag_disallow_certificate_name_common
// assume that CN is a host
// as this is an assumption only, we may NEVER register_target it
// note: CN is deprecated for good reasons.
else if (t = cert["2.5.4.3"]) {
P1(("%O believing CN %O\n", ME, t))
sAuthenticated(t);
}
# endif
} }
} }
#endif #endif

View File

@ -117,6 +117,12 @@ int logon(int failure) {
} else if (tls_query_connection_state(ME) == 1) { } else if (tls_query_connection_state(ME) == 1) {
certinfo = tls_certificate(ME, 0); certinfo = tls_certificate(ME, 0);
P0(("certinfo: %O\n", certinfo)) P0(("certinfo: %O\n", certinfo))
unless (tls_check_cipher(ME, "psyc")) {
croak("_error_circuit_encryption_cipher",
"Your cipher choice does not provide forward secrecy.");
//destruct(ME);
}
} }
} }
#endif #endif
@ -207,7 +213,7 @@ void circuit_msg(string mc, mapping vars, string data) {
} else if (tls_query_connection_state(ME) == 1 } else if (tls_query_connection_state(ME) == 1
&& mappingp(certinfo) && mappingp(certinfo)
&& certinfo[0] == 0 && certinfo[0] == 0
&& certificate_check_name(su[UHost], certinfo, "psyc") == 1) { && tls_check_certificate_data(certinfo, su[UHost], "psyc") == 1) {
sAuthenticated(su[UHost]); sAuthenticated(su[UHost]);
if (flags & TCP_PENDING_TIMEOUT) { if (flags & TCP_PENDING_TIMEOUT) {
P0(("removing call out\n")) P0(("removing call out\n"))

View File

@ -1555,6 +1555,16 @@ logon() {
return remove_interactive(ME); return remove_interactive(ME);
// and the object will deteriorate when user gives up.. // and the object will deteriorate when user gives up..
} }
#ifdef __TLS__
if (tls_query_connection_state(ME) == 1) {
if (tls_check_cipher(ME, v("scheme"))) {
w("_status_circuit_encryption_cipher");
} else {
w("_warning_circuit_encryption_cipher");
//return remove_interactive(ME);
}
}
#endif
// shouldn't this be qScheme() instead? little paranoid TODO // shouldn't this be qScheme() instead? little paranoid TODO
// but then we would have to move qScheme() from the server.c's // but then we would have to move qScheme() from the server.c's
// into the common.c's .. well, we could do that some day // into the common.c's .. well, we could do that some day