@@ -69,10 +69,14 @@ const char* root_certs[] = {
6969 NULL
7070};
7171
72+ bool SSL2_ENABLE = false ;
73+ bool SSL3_ENABLE = false ;
74+
7275namespace crypto {
7376
7477using namespace v8 ;
7578
79+
7680// Forcibly clear OpenSSL's error stack on return. This stops stale errors
7781// from popping up later in the lifecycle of crypto operations where they
7882// would cause spurious failures. It's a rather blunt method, though.
@@ -234,6 +238,24 @@ Handle<Value> SecureContext::New(const Arguments& args) {
234238}
235239
236240
241+ bool MaybeThrowSSL3 () {
242+ if (!SSL3_ENABLE) {
243+ ThrowException (Exception::Error (String::New (" SSLv3 is considered unsafe, see node --help" )));
244+ return true ;
245+ } else {
246+ return false ;
247+ }
248+ }
249+
250+ bool MaybeThrowSSL2 () {
251+ if (!SSL2_ENABLE) {
252+ ThrowException (Exception::Error (String::New (" SSLv2 is considered unsafe, see node --help" )));
253+ return true ;
254+ } else {
255+ return false ;
256+ }
257+ }
258+
237259Handle<Value> SecureContext::Init (const Arguments& args) {
238260 HandleScope scope;
239261
@@ -246,28 +268,46 @@ Handle<Value> SecureContext::Init(const Arguments& args) {
246268
247269 if (strcmp (*sslmethod, " SSLv2_method" ) == 0 ) {
248270#ifndef OPENSSL_NO_SSL2
271+ if (MaybeThrowSSL2 ()) return Undefined ();
249272 method = SSLv2_method ();
250273#else
251274 return ThrowException (Exception::Error (String::New (" SSLv2 methods disabled" )));
252275#endif
253276 } else if (strcmp (*sslmethod, " SSLv2_server_method" ) == 0 ) {
254277#ifndef OPENSSL_NO_SSL2
278+ if (MaybeThrowSSL2 ()) return Undefined ();
255279 method = SSLv2_server_method ();
256280#else
257281 return ThrowException (Exception::Error (String::New (" SSLv2 methods disabled" )));
258282#endif
259283 } else if (strcmp (*sslmethod, " SSLv2_client_method" ) == 0 ) {
260284#ifndef OPENSSL_NO_SSL2
285+ if (MaybeThrowSSL2 ()) return Undefined ();
261286 method = SSLv2_client_method ();
262287#else
263288 return ThrowException (Exception::Error (String::New (" SSLv2 methods disabled" )));
264289#endif
265290 } else if (strcmp (*sslmethod, " SSLv3_method" ) == 0 ) {
291+ #ifndef OPENSSL_NO_SSL3
292+ if (MaybeThrowSSL3 ()) return Undefined ();
266293 method = SSLv3_method ();
294+ #else
295+ return ThrowException (Exception::Error (String::New (" SSLv3 methods disabled" )));
296+ #endif
267297 } else if (strcmp (*sslmethod, " SSLv3_server_method" ) == 0 ) {
298+ #ifndef OPENSSL_NO_SSL3
299+ if (MaybeThrowSSL3 ()) return Undefined ();
268300 method = SSLv3_server_method ();
301+ #else
302+ return ThrowException (Exception::Error (String::New (" SSLv3 methods disabled" )));
303+ #endif
269304 } else if (strcmp (*sslmethod, " SSLv3_client_method" ) == 0 ) {
305+ #ifndef OPENSSL_NO_SSL3
306+ if (MaybeThrowSSL3 ()) return Undefined ();
270307 method = SSLv3_client_method ();
308+ #else
309+ return ThrowException (Exception::Error (String::New (" SSLv3 methods disabled" )));
310+ #endif
271311 } else if (strcmp (*sslmethod, " SSLv23_method" ) == 0 ) {
272312 method = SSLv23_method ();
273313 } else if (strcmp (*sslmethod, " SSLv23_server_method" ) == 0 ) {
@@ -295,6 +335,20 @@ Handle<Value> SecureContext::Init(const Arguments& args) {
295335 SSL_CTX_sess_set_get_cb (sc->ctx_ , GetSessionCallback);
296336 SSL_CTX_sess_set_new_cb (sc->ctx_ , NewSessionCallback);
297337
338+ int options = 0 ;
339+
340+ #ifndef OPENSSL_NO_SSL2
341+ if (!SSL2_ENABLE)
342+ options |= SSL_OP_NO_SSLv2;
343+ #endif
344+
345+ #ifndef OPENSSL_NO_SSL3
346+ if (!SSL3_ENABLE)
347+ options |= SSL_OP_NO_SSLv3;
348+ #endif
349+
350+ SSL_CTX_set_options (sc->ctx_ , options);
351+
298352 sc->ca_store_ = NULL ;
299353 return True ();
300354}
0 commit comments