Skip to content

Commit

Permalink
tls,crypto: remove SSLv2 support
Browse files Browse the repository at this point in the history
openssl-1.0.1s disables SSLv2 by default for against DROWN attack.
There no needs to support SSLv2 in Node.
  • Loading branch information
Shigeki Ohtsu committed Mar 1, 2016
1 parent fa26b13 commit bd65f9c
Show file tree
Hide file tree
Showing 11 changed files with 18 additions and 185 deletions.
8 changes: 0 additions & 8 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,6 @@ parser.add_option('--without-ssl',
dest='without_ssl',
help='build without SSL')

parser.add_option('--without-ssl2',
action='store_true',
dest='ssl2',
help='Disable SSL v2')

parser.add_option('--without-ssl3',
action='store_true',
dest='ssl3',
Expand Down Expand Up @@ -687,9 +682,6 @@ def configure_openssl(o):
if options.without_ssl:
return

if options.ssl2:
o['defines'] += ['OPENSSL_NO_SSL2=1']

if options.ssl3:
o['defines'] += ['OPENSSL_NO_SSL3=1']

Expand Down
23 changes: 9 additions & 14 deletions doc/api/tls.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,23 @@ To create .pfx or .p12, do this:

## Protocol support

Node.js is compiled with SSLv2 and SSLv3 protocol support by default, but these
Node.js is compiled with SSLv3 protocol support by default, but these
protocols are **disabled**. They are considered insecure and could be easily
compromised as was shown by [CVE-2014-3566][]. However, in some situations, it
may cause problems with legacy clients/servers (such as Internet Explorer 6).
If you wish to enable SSLv2 or SSLv3, run node with the `--enable-ssl2` or
`--enable-ssl3` flag respectively. In future versions of Node.js SSLv2 and
SSLv3 will not be compiled in by default.
If you wish to enable SSLv3, run node with `--enable-ssl3` flag. In
future versions of Node.js SSLv3 will not be compiled in by default.

There is a way to force node into using SSLv3 or SSLv2 only mode by explicitly
specifying `secureProtocol` to `'SSLv3_method'` or `'SSLv2_method'`.
There is a way to force node into using SSLv3 only mode by explicitly
specifying `secureProtocol` to `'SSLv3_method'`.

The default protocol method Node.js uses is `SSLv23_method` which would be more
accurately named `AutoNegotiate_method`. This method will try and negotiate
from the highest level down to whatever the client supports. To provide a
secure default, Node.js (since v0.10.33) explicitly disables the use of SSLv3
and SSLv2 by setting the `secureOptions` to be
`SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2` (again, unless you have passed
`--enable-ssl3`, or `--enable-ssl2`, or `SSLv3_method` as `secureProtocol`).
secure default, Node.js (since v0.10.33) explicitly disables the use
of SSLv3 by setting the `secureOptions` to be `SSL_OP_NO_SSLv3`
(again, unless you have passed `--enable-ssl3`, or `SSLv3_method` as
`secureProtocol`).

If you have set `secureOptions` to anything, we will not override your
options.
Expand Down Expand Up @@ -219,10 +218,6 @@ automatically set as a listener for the [secureConnection][] event. The
use this option in conjunction with the `ciphers` option to mitigate
BEAST attacks.

Note: If SSLv2 is used, the server will send its list of preferences to the
client, and the client chooses the cipher. Support for SSLv2 is disabled
unless node.js was configured with `./configure --with-sslv2`.

- `requestCert`: If `true` the server will request a certificate from
clients that connect and attempt to verify that certificate. Default:
`false`.
Expand Down
11 changes: 4 additions & 7 deletions doc/node.1
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ and servers.

--max-stack-size=val set max v8 stack size (bytes)

--enable-ssl2 enable ssl2 in crypto, tls, and https
modules

--enable-ssl3 enable ssl3 in crypto, tls, and https
modules

Expand Down Expand Up @@ -113,7 +110,7 @@ If set to 1 then colors will not be used in the REPL.
--crankshaft (use crankshaft)
type: bool default: true
--hydrogen_filter (optimization filter)
type: string default:
type: string default:
--use_range (use hydrogen range analysis)
type: bool default: true
--eliminate_dead_phis (eliminate dead phis)
Expand Down Expand Up @@ -391,9 +388,9 @@ If set to 1 then colors will not be used in the REPL.
--debugger_port (Port to use for remote debugging)
type: int default: 5858
--map_counters (Map counters to a file)
type: string default:
type: string default:
--js_arguments (Pass all remaining arguments to the script. Alias for "--".)
type: arguments default:
type: arguments default:
--debug_compile_events (Enable debugger compile events)
type: bool default: true
--debug_script_collected_events (Enable debugger script collected events)
Expand All @@ -405,7 +402,7 @@ If set to 1 then colors will not be used in the REPL.
--gdbjit_dump (dump elf objects with debug info to disk)
type: bool default: false
--gdbjit_dump_filter (dump only objects containing this substring)
type: string default:
type: string default:
--force_marking_deque_overflows (force overflows of marking deque by reducing its size to 64 words)
type: bool default: false
--stress_compaction (stress the GC compactor to flush out bugs (implies --force_marking_deque_overflows))
Expand Down
2 changes: 0 additions & 2 deletions lib/_tls_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ function getSecureOptions(secureProtocol, secureOptions) {
if (!binding.SSL3_ENABLE)
CONTEXT_DEFAULT_OPTIONS |= constants.SSL_OP_NO_SSLv3;

if (!binding.SSL2_ENABLE)
CONTEXT_DEFAULT_OPTIONS |= constants.SSL_OP_NO_SSLv2;
}

if (secureOptions === undefined) {
Expand Down
5 changes: 0 additions & 5 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3012,7 +3012,6 @@ static void PrintHelp() {
" present.\n"
#endif
#endif
" --enable-ssl2 enable ssl2\n"
" --enable-ssl3 enable ssl3\n"
"\n"
"Environment variables:\n"
Expand Down Expand Up @@ -3081,10 +3080,6 @@ static void ParseArgs(int* argc,
} else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
printf("%s\n", NODE_VERSION);
exit(0);
} else if (strcmp(arg, "--enable-ssl2") == 0) {
#if HAVE_OPENSSL
SSL2_ENABLE = true;
#endif
} else if (strcmp(arg, "--enable-ssl3") == 0) {
#if HAVE_OPENSSL
SSL3_ENABLE = true;
Expand Down
8 changes: 0 additions & 8 deletions src/node_constants.cc
Original file line number Diff line number Diff line change
Expand Up @@ -787,10 +787,6 @@ void DefineOpenSSLConstants(Handle<Object> target) {
NODE_DEFINE_CONSTANT(target, SSL_OP_MICROSOFT_SESS_ID_BUG);
#endif

#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
NODE_DEFINE_CONSTANT(target, SSL_OP_MSIE_SSLV2_RSA_PADDING);
#endif

#ifdef SSL_OP_NETSCAPE_CA_DN_BUG
NODE_DEFINE_CONSTANT(target, SSL_OP_NETSCAPE_CA_DN_BUG);
#endif
Expand Down Expand Up @@ -819,10 +815,6 @@ void DefineOpenSSLConstants(Handle<Object> target) {
NODE_DEFINE_CONSTANT(target, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#endif

#ifdef SSL_OP_NO_SSLv2
NODE_DEFINE_CONSTANT(target, SSL_OP_NO_SSLv2);
#endif

#ifdef SSL_OP_NO_SSLv3
NODE_DEFINE_CONSTANT(target, SSL_OP_NO_SSLv3);
#endif
Expand Down
22 changes: 1 addition & 21 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL

namespace node {

bool SSL2_ENABLE = false;
bool SSL3_ENABLE = false;
bool ALLOW_INSECURE_SERVER_DHPARAM = false;

Expand Down Expand Up @@ -316,25 +315,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
if (args.Length() == 1 && args[0]->IsString()) {
const node::Utf8Value sslmethod(args[0]);

if (strcmp(*sslmethod, "SSLv2_method") == 0) {
#ifndef OPENSSL_NO_SSL2
method = SSLv2_method();
#else
return env->ThrowError("SSLv2 methods disabled");
#endif
} else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
#ifndef OPENSSL_NO_SSL2
method = SSLv2_server_method();
#else
return env->ThrowError("SSLv2 methods disabled");
#endif
} else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
#ifndef OPENSSL_NO_SSL2
method = SSLv2_client_method();
#else
return env->ThrowError("SSLv2 methods disabled");
#endif
} else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
if (strcmp(*sslmethod, "SSLv3_method") == 0) {
#ifndef OPENSSL_NO_SSL3
method = SSLv3_method();
#else
Expand Down Expand Up @@ -5171,7 +5152,6 @@ void InitCrypto(Handle<Object> target,
EVP_PKEY_decrypt>);

NODE_DEFINE_CONSTANT(target, SSL3_ENABLE);
NODE_DEFINE_CONSTANT(target, SSL2_ENABLE);
}

} // namespace crypto
Expand Down
1 change: 0 additions & 1 deletion src/node_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@

namespace node {

extern bool SSL2_ENABLE;
extern bool SSL3_ENABLE;
extern bool ALLOW_INSECURE_SERVER_DHPARAM;

Expand Down
54 changes: 1 addition & 53 deletions src/node_crypto_clienthello.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ void ClientHelloParser::Parse(const uint8_t* data, size_t avail) {
break;
// Fall through
case kTLSHeader:
case kSSL2Header:
ParseHeader(data, avail);
break;
case kPaused:
Expand All @@ -59,20 +58,8 @@ bool ClientHelloParser::ParseRecordHeader(const uint8_t* data, size_t avail) {
state_ = kTLSHeader;
body_offset_ = 5;
} else {
#ifdef OPENSSL_NO_SSL2
frame_len_ = ((data[0] << 8) & kSSL2HeaderMask) + data[1];
state_ = kSSL2Header;
if (data[0] & kSSL2TwoByteHeaderBit) {
// header without padding
body_offset_ = 2;
} else {
// header with padding
body_offset_ = 3;
}
#else
End();
return false;
#endif // OPENSSL_NO_SSL2
}

// Sanity check (too big frame, or too small)
Expand All @@ -85,12 +72,6 @@ bool ClientHelloParser::ParseRecordHeader(const uint8_t* data, size_t avail) {
return true;
}

#ifdef OPENSSL_NO_SSL2
# define NODE_SSL2_VER_CHECK(buf) false
#else
# define NODE_SSL2_VER_CHECK(buf) ((buf)[0] == 0x00 && (buf)[1] == 0x02)
#endif // OPENSSL_NO_SSL2


void ClientHelloParser::ParseHeader(const uint8_t* data, size_t avail) {
ClientHello hello;
Expand All @@ -101,22 +82,14 @@ void ClientHelloParser::ParseHeader(const uint8_t* data, size_t avail) {

// Skip unsupported frames and gather some data from frame
// Check hello protocol version
if (!(data[body_offset_ + 4] == 0x03 && data[body_offset_ + 5] <= 0x03) &&
!NODE_SSL2_VER_CHECK(data + body_offset_ + 4)) {
if (!(data[body_offset_ + 4] == 0x03 && data[body_offset_ + 5] <= 0x03)) {
goto fail;
}

if (data[body_offset_] == kClientHello) {
if (state_ == kTLSHeader) {
if (!ParseTLSClientHello(data, avail))
goto fail;
} else if (state_ == kSSL2Header) {
#ifdef OPENSSL_NO_SSL2
if (!ParseSSL2ClientHello(data, avail))
goto fail;
#else
abort(); // Unreachable
#endif // OPENSSL_NO_SSL2
} else {
// We couldn't get here, but whatever
goto fail;
Expand Down Expand Up @@ -145,7 +118,6 @@ void ClientHelloParser::ParseHeader(const uint8_t* data, size_t avail) {
}


#undef NODE_SSL2_VER_CHECK


void ClientHelloParser::ParseExtension(ClientHelloParser::ExtensionType type,
Expand Down Expand Up @@ -269,28 +241,4 @@ bool ClientHelloParser::ParseTLSClientHello(const uint8_t* data, size_t avail) {
return true;
}


#ifdef OPENSSL_NO_SSL2
bool ClientHelloParser::ParseSSL2ClientHello(const uint8_t* data,
size_t avail) {
const uint8_t* body;

// Skip header, version
size_t session_offset = body_offset_ + 3;

if (session_offset + 4 < avail) {
body = data + session_offset;

uint16_t ciphers_size = (body[0] << 8) + body[1];

if (body + 4 + ciphers_size < data + avail) {
session_size_ = (body[2] << 8) + body[3];
session_id_ = body + 4 + ciphers_size;
}
}

return true;
}
#endif // OPENSSL_NO_SSL2

} // namespace node
6 changes: 0 additions & 6 deletions src/node_crypto_clienthello.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ class ClientHelloParser {
inline bool IsEnded() const;

private:
static const uint8_t kSSL2TwoByteHeaderBit = 0x80;
static const uint8_t kSSL2HeaderMask = 0x3f;
static const size_t kMaxTLSFrameLen = 16 * 1024 + 5;
static const size_t kMaxSSLExFrameLen = 32 * 1024;
static const uint8_t kServernameHostname = 0;
Expand All @@ -91,7 +89,6 @@ class ClientHelloParser {
enum ParseState {
kWaiting,
kTLSHeader,
kSSL2Header,
kPaused,
kEnded
};
Expand Down Expand Up @@ -120,9 +117,6 @@ class ClientHelloParser {
const uint8_t* data,
size_t len);
bool ParseTLSClientHello(const uint8_t* data, size_t avail);
#ifdef OPENSSL_NO_SSL2
bool ParseSSL2ClientHello(const uint8_t* data, size_t avail);
#endif // OPENSSL_NO_SSL2

ParseState state_;
OnHelloCb onhello_cb_;
Expand Down
Loading

0 comments on commit bd65f9c

Please sign in to comment.