Skip to content

Commit 92b6417

Browse files
committed
crypto: introduce .setEngine(engine, [flags])
1 parent a40b463 commit 92b6417

6 files changed

Lines changed: 168 additions & 2 deletions

File tree

deps/openssl/openssl.gyp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,15 @@
928928
'-lgdi32.lib',
929929
'-luser32.lib',
930930
]
931-
}
931+
},
932+
'defines': [
933+
'DSO_WIN32',
934+
],
935+
}, {
936+
'defines': [
937+
'DSO_DLFCN',
938+
'HAVE_DLFCN_H'
939+
],
932940
}],
933941
['target_arch=="arm"', {
934942
'sources': ['openssl/crypto/armcap.c'],
@@ -1028,7 +1036,14 @@
10281036
'-luser32.lib',
10291037
],
10301038
},
1031-
}]
1039+
}],
1040+
[ 'OS in "linux android"', {
1041+
'link_settings': {
1042+
'libraries': [
1043+
'-ldl',
1044+
],
1045+
},
1046+
}],
10321047
]
10331048
}
10341049
],

doc/api/crypto.markdown

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,30 @@ It also offers a set of wrappers for OpenSSL's hash, hmac, cipher,
1212
decipher, sign and verify methods.
1313

1414

15+
## crypto.setEngine(engine, [flags])
16+
17+
Load and set engine for some/all OpenSSL functions (selected by flags).
18+
19+
`engine` could be either an id or a path to the to the engine's shared library.
20+
21+
`flags` is optional and has `ENGINE_METHOD_ALL` value by default. It could take
22+
one of or mix of following flags (defined in `constants` module):
23+
24+
* `ENGINE_METHOD_RSA`
25+
* `ENGINE_METHOD_DSA`
26+
* `ENGINE_METHOD_DH`
27+
* `ENGINE_METHOD_RAND`
28+
* `ENGINE_METHOD_ECDH`
29+
* `ENGINE_METHOD_ECDSA`
30+
* `ENGINE_METHOD_CIPHERS`
31+
* `ENGINE_METHOD_DIGESTS`
32+
* `ENGINE_METHOD_STORE`
33+
* `ENGINE_METHOD_PKEY_METH`
34+
* `ENGINE_METHOD_PKEY_ASN1_METH`
35+
* `ENGINE_METHOD_ALL`
36+
* `ENGINE_METHOD_NONE`
37+
38+
1539
## crypto.getCiphers()
1640

1741
Returns an array with the names of the supported ciphers.

lib/crypto.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ try {
3535
throw new Error('node.js not compiled with openssl crypto support.');
3636
}
3737

38+
var constants = require('constants');
3839
var stream = require('stream');
3940
var util = require('util');
4041

@@ -621,6 +622,21 @@ Certificate.prototype.exportChallenge = function(object, encoding) {
621622
};
622623

623624

625+
exports.setEngine = function setEngine(id, flags) {
626+
if (!util.isString(id))
627+
throw new TypeError('id should be a string');
628+
629+
if (flags && !util.isNumber(flags))
630+
throw new TypeError('flags should be a number, if present');
631+
flags = flags >>> 0;
632+
633+
// Use provided engine for everything by default
634+
if (flags === 0)
635+
flags = constants.ENGINE_METHOD_ALL;
636+
637+
return binding.setEngine(id, flags);
638+
};
639+
624640
exports.randomBytes = randomBytes;
625641
exports.pseudoRandomBytes = pseudoRandomBytes;
626642

src/node_constants.cc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434

3535
#if HAVE_OPENSSL
3636
# include <openssl/ssl.h>
37+
# ifndef OPENSSL_NO_ENGINE
38+
# include <openssl/engine.h>
39+
# endif // !OPENSSL_NO_ENGINE
3740
#endif
3841

3942
namespace node {
@@ -875,6 +878,58 @@ void DefineOpenSSLConstants(Handle<Object> target) {
875878
NODE_DEFINE_CONSTANT(target, SSL_OP_TLS_ROLLBACK_BUG);
876879
#endif
877880

881+
# ifndef OPENSSL_NO_ENGINE
882+
883+
# ifdef ENGINE_METHOD_DSA
884+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DSA);
885+
# endif
886+
887+
# ifdef ENGINE_METHOD_DH
888+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DH);
889+
# endif
890+
891+
# ifdef ENGINE_METHOD_RAND
892+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_RAND);
893+
# endif
894+
895+
# ifdef ENGINE_METHOD_ECDH
896+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ECDH);
897+
# endif
898+
899+
# ifdef ENGINE_METHOD_ECDSA
900+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ECDSA);
901+
# endif
902+
903+
# ifdef ENGINE_METHOD_CIPHERS
904+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_CIPHERS);
905+
# endif
906+
907+
# ifdef ENGINE_METHOD_DIGESTS
908+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DIGESTS);
909+
# endif
910+
911+
# ifdef ENGINE_METHOD_STORE
912+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_STORE);
913+
# endif
914+
915+
# ifdef ENGINE_METHOD_PKEY_METHS
916+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_PKEY_METHS);
917+
# endif
918+
919+
# ifdef ENGINE_METHOD_PKEY_ASN1_METHS
920+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_PKEY_ASN1_METHS);
921+
# endif
922+
923+
# ifdef ENGINE_METHOD_ALL
924+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ALL);
925+
# endif
926+
927+
# ifdef ENGINE_METHOD_NONE
928+
NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_NONE);
929+
# endif
930+
931+
# endif // !OPENSSL_NO_ENGINE
932+
878933
#ifdef OPENSSL_NPN_NEGOTIATED
879934
#define NPN_ENABLED 1
880935
NODE_DEFINE_CONSTANT(target, NPN_ENABLED);

src/node_crypto.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4069,7 +4069,54 @@ void InitCryptoOnce() {
40694069
sk_SSL_COMP_zero(comp_methods);
40704070
assert(sk_SSL_COMP_num(comp_methods) == 0);
40714071
#endif
4072+
4073+
#ifndef OPENSSL_NO_ENGINE
4074+
ERR_load_ENGINE_strings();
4075+
ENGINE_load_builtin_engines();
4076+
#endif // !OPENSSL_NO_ENGINE
4077+
}
4078+
4079+
4080+
#ifndef OPENSSL_NO_ENGINE
4081+
void SetEngine(const FunctionCallbackInfo<Value>& args) {
4082+
CHECK(args.Length() >= 2 && args[0]->IsString());
4083+
unsigned int flags = args[1]->Uint32Value();
4084+
4085+
ClearErrorOnReturn clear_error_on_return;
4086+
(void) &clear_error_on_return; // Silence compiler warning.
4087+
4088+
const String::Utf8Value engine_id(args[0]);
4089+
ENGINE* engine = ENGINE_by_id(*engine_id);
4090+
4091+
// Engine not found, try loading dynamically
4092+
if (engine == NULL) {
4093+
engine = ENGINE_by_id("dynamic");
4094+
if (engine != NULL) {
4095+
if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH", *engine_id, 0) ||
4096+
!ENGINE_ctrl_cmd_string(engine, "LOAD", NULL, 0)) {
4097+
ENGINE_free(engine);
4098+
engine = NULL;
4099+
}
4100+
}
4101+
}
4102+
4103+
if (engine == NULL) {
4104+
int err = ERR_get_error();
4105+
if (err == 0) {
4106+
char tmp[1024];
4107+
snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id);
4108+
return ThrowError(tmp);
4109+
} else {
4110+
return ThrowCryptoError(err);
4111+
}
4112+
}
4113+
4114+
int r = ENGINE_set_default(engine, flags);
4115+
ENGINE_free(engine);
4116+
if (r == 0)
4117+
return ThrowCryptoError(ERR_get_error());
40724118
}
4119+
#endif // !OPENSSL_NO_ENGINE
40734120

40744121

40754122
// FIXME(bnoordhuis) Handle global init correctly.
@@ -4090,6 +4137,9 @@ void InitCrypto(Handle<Object> target,
40904137
Verify::Initialize(env, target);
40914138
Certificate::Initialize(target);
40924139

4140+
#ifndef OPENSSL_NO_ENGINE
4141+
NODE_SET_METHOD(target, "setEngine", SetEngine);
4142+
#endif // !OPENSSL_NO_ENGINE
40934143
NODE_SET_METHOD(target, "PBKDF2", PBKDF2);
40944144
NODE_SET_METHOD(target, "randomBytes", RandomBytes<false>);
40954145
NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<true>);

src/node_crypto.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
#include "v8.h"
4040

4141
#include <openssl/ssl.h>
42+
#ifndef OPENSSL_NO_ENGINE
43+
# include <openssl/engine.h>
44+
#endif // !OPENSSL_NO_ENGINE
4245
#include <openssl/err.h>
4346
#include <openssl/evp.h>
4447
#include <openssl/pem.h>
@@ -574,6 +577,9 @@ class Certificate : public AsyncWrap {
574577
};
575578

576579
bool EntropySource(unsigned char* buffer, size_t length);
580+
#ifndef OPENSSL_NO_ENGINE
581+
void SetEngine(const v8::FunctionCallbackInfo<v8::Value>& args);
582+
#endif // !OPENSSL_NO_ENGINE
577583
void InitCrypto(v8::Handle<v8::Object> target);
578584

579585
} // namespace crypto

0 commit comments

Comments
 (0)