Merge remote-tracking branch 'ry/v0.6' into v0.6-merge
Conflicts: ChangeLog deps/uv/include/uv-private/uv-unix.h deps/uv/src/unix/core.c deps/uv/src/unix/sunos.c deps/v8/src/runtime.cc doc/api/crypto.markdown lib/http.js src/node_version.h test/gc/test-http-client-timeout.js wscript
This commit is contained in:
commit
5164ae3838
29
ChangeLog
29
ChangeLog
@ -255,6 +255,35 @@
|
|||||||
* Bug fixes
|
* Bug fixes
|
||||||
|
|
||||||
|
|
||||||
|
2012.05.15 Version 0.6.18 (stable), 4bc1d395de6abed2cf1e4d0b7b3a1480a21c368f
|
||||||
|
|
||||||
|
* windows: skip GetFileAttributes call when opening a file (Bert Belder)
|
||||||
|
|
||||||
|
* crypto: add PKCS12/PFX support (Sambasiva Suda)
|
||||||
|
|
||||||
|
* #3240: child_process: delete NODE_CHANNEL_FD from env in spawn (Ben Noordhuis)
|
||||||
|
|
||||||
|
* windows: add test for path.normalize with UNC paths (Bert Belder)
|
||||||
|
|
||||||
|
* windows: make path.normalize convert all slashes to backslashes (Bert Belder)
|
||||||
|
|
||||||
|
* fs: Automatically close FSWatcher on error (Bert Belder)
|
||||||
|
|
||||||
|
* #3258: fs.ReadStream.pause() emits duplicate data event (koichik)
|
||||||
|
|
||||||
|
* pipe_wrap: don't assert() on pipe accept errors (Ben Noordhuis)
|
||||||
|
|
||||||
|
* Better exception output for module load and process.nextTick (Felix Geisendörfer)
|
||||||
|
|
||||||
|
* zlib: fix error reporting (Ben Noordhuis)
|
||||||
|
|
||||||
|
* http: Don't destroy on timeout (isaacs)
|
||||||
|
|
||||||
|
* #3231: http: Don't try to emit error on a null'ed req object (isaacs)
|
||||||
|
|
||||||
|
* #3236: http: Refactor ClientRequest.onSocket (isaacs)
|
||||||
|
|
||||||
|
|
||||||
2012.05.04 Version 0.6.17 (stable), 4ced23deaf36493f4303a18f6fdce768c58becc0
|
2012.05.04 Version 0.6.17 (stable), 4ced23deaf36493f4303a18f6fdce768c58becc0
|
||||||
|
|
||||||
* Upgrade npm to 1.1.21
|
* Upgrade npm to 1.1.21
|
||||||
|
2
Makefile
2
Makefile
@ -154,7 +154,7 @@ out/doc/api/%.html: doc/api/%.markdown
|
|||||||
out/Release/node tools/doc/generate.js --format=html --template=doc/template.html $< > $@
|
out/Release/node tools/doc/generate.js --format=html --template=doc/template.html $< > $@
|
||||||
|
|
||||||
email.md: ChangeLog tools/email-footer.md
|
email.md: ChangeLog tools/email-footer.md
|
||||||
bash tools/changelog-head.sh > $@
|
bash tools/changelog-head.sh | sed 's|^\* #|* \\#|g' > $@
|
||||||
cat tools/email-footer.md | sed -e 's|__VERSION__|'$(VERSION)'|g' >> $@
|
cat tools/email-footer.md | sed -e 's|__VERSION__|'$(VERSION)'|g' >> $@
|
||||||
|
|
||||||
blog.html: email.md
|
blog.html: email.md
|
||||||
|
@ -70,7 +70,7 @@ Allocates a new buffer containing the given `str`.
|
|||||||
|
|
||||||
* `string` String - data to be written to buffer
|
* `string` String - data to be written to buffer
|
||||||
* `offset` Number, Optional, Default: 0
|
* `offset` Number, Optional, Default: 0
|
||||||
* `length` Number, Optional
|
* `length` Number, Optional, Default: `buffer.length - offset`
|
||||||
* `encoding` String, Optional, Default: 'utf8'
|
* `encoding` String, Optional, Default: 'utf8'
|
||||||
|
|
||||||
Writes `string` to the buffer at `offset` using the given encoding.
|
Writes `string` to the buffer at `offset` using the given encoding.
|
||||||
@ -93,7 +93,7 @@ next time `buf.write()` is called.
|
|||||||
|
|
||||||
* `encoding` String, Optional, Default: 'utf8'
|
* `encoding` String, Optional, Default: 'utf8'
|
||||||
* `start` Number, Optional, Default: 0
|
* `start` Number, Optional, Default: 0
|
||||||
* `end` Number, Optional
|
* `end` Number, Optional, Default: `buffer.length`
|
||||||
|
|
||||||
Decodes and returns a string from buffer data encoded with `encoding`
|
Decodes and returns a string from buffer data encoded with `encoding`
|
||||||
(defaults to `'utf8'`) beginning at `start` (defaults to `0`) and ending at
|
(defaults to `'utf8'`) beginning at `start` (defaults to `0`) and ending at
|
||||||
@ -171,7 +171,7 @@ buffer object. It does not change when the contents of the buffer are changed.
|
|||||||
* `targetBuffer` Buffer object - Buffer to copy into
|
* `targetBuffer` Buffer object - Buffer to copy into
|
||||||
* `targetStart` Number, Optional, Default: 0
|
* `targetStart` Number, Optional, Default: 0
|
||||||
* `sourceStart` Number, Optional, Default: 0
|
* `sourceStart` Number, Optional, Default: 0
|
||||||
* `sourceEnd` Number, Optional, Default: 0
|
* `sourceEnd` Number, Optional, Default: `buffer.length`
|
||||||
|
|
||||||
Does copy between buffers. The source and target regions can be overlapped.
|
Does copy between buffers. The source and target regions can be overlapped.
|
||||||
`targetStart` and `sourceStart` default to `0`.
|
`targetStart` and `sourceStart` default to `0`.
|
||||||
@ -197,7 +197,7 @@ into `buf2`, starting at the 8th byte in `buf2`.
|
|||||||
### buf.slice([start], [end])
|
### buf.slice([start], [end])
|
||||||
|
|
||||||
* `start` Number, Optional, Default: 0
|
* `start` Number, Optional, Default: 0
|
||||||
* `end` Number, Optional, Default: 0
|
* `end` Number, Optional, Default: `buffer.length`
|
||||||
|
|
||||||
Returns a new buffer which references the same memory as the old, but offset
|
Returns a new buffer which references the same memory as the old, but offset
|
||||||
and cropped by the `start` (defaults to `0`) and `end` (defaults to
|
and cropped by the `start` (defaults to `0`) and `end` (defaults to
|
||||||
|
@ -14,8 +14,9 @@ It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, decipher, sig
|
|||||||
|
|
||||||
Creates a credentials object, with the optional details being a dictionary with keys:
|
Creates a credentials object, with the optional details being a dictionary with keys:
|
||||||
|
|
||||||
|
* `pfx` : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates
|
||||||
* `key` : A string holding the PEM encoded private key
|
* `key` : A string holding the PEM encoded private key
|
||||||
* `passphrase` : A string of passphrase for the private key
|
* `passphrase` : A string of passphrase for the private key or pfx
|
||||||
* `cert` : A string holding the PEM encoded certificate
|
* `cert` : A string holding the PEM encoded certificate
|
||||||
* `ca` : Either a string or list of strings of PEM encoded CA certificates to trust.
|
* `ca` : Either a string or list of strings of PEM encoded CA certificates to trust.
|
||||||
* `crl` : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)
|
* `crl` : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)
|
||||||
|
@ -32,6 +32,19 @@ Example:
|
|||||||
res.end("hello world\n");
|
res.end("hello world\n");
|
||||||
}).listen(8000);
|
}).listen(8000);
|
||||||
|
|
||||||
|
Or
|
||||||
|
|
||||||
|
var https = require('https');
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
pfx: fs.readFileSync('server.pfx')
|
||||||
|
};
|
||||||
|
|
||||||
|
https.createServer(options, function (req, res) {
|
||||||
|
res.writeHead(200);
|
||||||
|
res.end("hello world\n");
|
||||||
|
}).listen(8000);
|
||||||
|
|
||||||
## https.request(options, callback)
|
## https.request(options, callback)
|
||||||
|
|
||||||
@ -91,8 +104,9 @@ The options argument has the following options
|
|||||||
The following options from [tls.connect()](tls.html#tls.connect) can also be
|
The following options from [tls.connect()](tls.html#tls.connect) can also be
|
||||||
specified. However, a [globalAgent](#https.globalAgent) silently ignores these.
|
specified. However, a [globalAgent](#https.globalAgent) silently ignores these.
|
||||||
|
|
||||||
|
- `pfx`: Certificate, Private key and CA certificates to use for SSL. Default `null`.
|
||||||
- `key`: Private key to use for SSL. Default `null`.
|
- `key`: Private key to use for SSL. Default `null`.
|
||||||
- `passphrase`: A string of passphrase for the private key. Default `null`.
|
- `passphrase`: A string of passphrase for the private key or pfx. Default `null`.
|
||||||
- `cert`: Public x509 certificate to use. Default `null`.
|
- `cert`: Public x509 certificate to use. Default `null`.
|
||||||
- `ca`: An authority certificate or array of authority certificates to check
|
- `ca`: An authority certificate or array of authority certificates to check
|
||||||
the remote host against.
|
the remote host against.
|
||||||
|
@ -74,11 +74,6 @@ Resumes the incoming `'data'` events after a `pause()`.
|
|||||||
|
|
||||||
Closes the underlying file descriptor. Stream will not emit any more events.
|
Closes the underlying file descriptor. Stream will not emit any more events.
|
||||||
|
|
||||||
|
|
||||||
### stream.destroySoon()
|
|
||||||
|
|
||||||
After the write queue is drained, close the file descriptor.
|
|
||||||
|
|
||||||
### stream.pipe(destination, [options])
|
### stream.pipe(destination, [options])
|
||||||
|
|
||||||
This is a `Stream.prototype` method available on all `Stream`s.
|
This is a `Stream.prototype` method available on all `Stream`s.
|
||||||
|
@ -28,6 +28,17 @@ Alternatively you can send the CSR to a Certificate Authority for signing.
|
|||||||
(TODO: docs on creating a CA, for now interested users should just look at
|
(TODO: docs on creating a CA, for now interested users should just look at
|
||||||
`test/fixtures/keys/Makefile` in the Node source code)
|
`test/fixtures/keys/Makefile` in the Node source code)
|
||||||
|
|
||||||
|
To create .pfx or .p12, do this:
|
||||||
|
|
||||||
|
openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \
|
||||||
|
-certfile ca-cert.pem -out agent5.pfx
|
||||||
|
|
||||||
|
- `in`: certificate
|
||||||
|
- `inkey`: private key
|
||||||
|
- `certfile`: all CA certs concatenated in one file like
|
||||||
|
`cat ca1-cert.pem ca2-cert.pem > ca-cert.pem`
|
||||||
|
|
||||||
|
|
||||||
## Client-initiated renegotiation attack mitigation
|
## Client-initiated renegotiation attack mitigation
|
||||||
|
|
||||||
<!-- type=misc -->
|
<!-- type=misc -->
|
||||||
@ -72,10 +83,14 @@ The `connectionListener` argument is automatically set as a listener for the
|
|||||||
[secureConnection](#event_secureConnection_) event.
|
[secureConnection](#event_secureConnection_) event.
|
||||||
The `options` object has these possibilities:
|
The `options` object has these possibilities:
|
||||||
|
|
||||||
|
- `pfx`: A string or `Buffer` containing the private key, certificate and
|
||||||
|
CA certs of the server in PFX or PKCS12 format. (Mutually exclusive with
|
||||||
|
the `key`, `cert` and `ca` options.)
|
||||||
|
|
||||||
- `key`: A string or `Buffer` containing the private key of the server in
|
- `key`: A string or `Buffer` containing the private key of the server in
|
||||||
PEM format. (Required)
|
PEM format. (Required)
|
||||||
|
|
||||||
- `passphrase`: A string of passphrase for the private key.
|
- `passphrase`: A string of passphrase for the private key or pfx.
|
||||||
|
|
||||||
- `cert`: A string or `Buffer` containing the certificate key of the server in
|
- `cert`: A string or `Buffer` containing the certificate key of the server in
|
||||||
PEM format. (Required)
|
PEM format. (Required)
|
||||||
@ -155,7 +170,29 @@ Here is a simple example echo server:
|
|||||||
console.log('server bound');
|
console.log('server bound');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Or
|
||||||
|
|
||||||
|
var tls = require('tls');
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
pfx: fs.readFileSync('server.pfx'),
|
||||||
|
|
||||||
|
// This is necessary only if using the client certificate authentication.
|
||||||
|
requestCert: true,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var server = tls.createServer(options, function(cleartextStream) {
|
||||||
|
console.log('server connected',
|
||||||
|
cleartextStream.authorized ? 'authorized' : 'unauthorized');
|
||||||
|
cleartextStream.write("welcome!\n");
|
||||||
|
cleartextStream.setEncoding('utf8');
|
||||||
|
cleartextStream.pipe(cleartextStream);
|
||||||
|
});
|
||||||
|
server.listen(8000, function() {
|
||||||
|
console.log('server bound');
|
||||||
|
});
|
||||||
You can test this server by connecting to it with `openssl s_client`:
|
You can test this server by connecting to it with `openssl s_client`:
|
||||||
|
|
||||||
|
|
||||||
@ -177,10 +214,13 @@ Creates a new client connection to the given `port` and `host` (old API) or
|
|||||||
creating a new socket. If this option is specified, `host` and `port`
|
creating a new socket. If this option is specified, `host` and `port`
|
||||||
are ignored.
|
are ignored.
|
||||||
|
|
||||||
|
- `pfx`: A string or `Buffer` containing the private key, certificate and
|
||||||
|
CA certs of the server in PFX or PKCS12 format.
|
||||||
|
|
||||||
- `key`: A string or `Buffer` containing the private key of the client in
|
- `key`: A string or `Buffer` containing the private key of the client in
|
||||||
PEM format.
|
PEM format.
|
||||||
|
|
||||||
- `passphrase`: A string of passphrase for the private key.
|
- `passphrase`: A string of passphrase for the private key or pfx.
|
||||||
|
|
||||||
- `cert`: A string or `Buffer` containing the certificate key of the client in
|
- `cert`: A string or `Buffer` containing the certificate key of the client in
|
||||||
PEM format.
|
PEM format.
|
||||||
@ -233,6 +273,28 @@ Here is an example of a client of echo server as described previously:
|
|||||||
server.close();
|
server.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Or
|
||||||
|
|
||||||
|
var tls = require('tls');
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
pfx: fs.readFileSync('client.pfx')
|
||||||
|
};
|
||||||
|
|
||||||
|
var cleartextStream = tls.connect(8000, options, function() {
|
||||||
|
console.log('client connected',
|
||||||
|
cleartextStream.authorized ? 'authorized' : 'unauthorized');
|
||||||
|
process.stdin.pipe(cleartextStream);
|
||||||
|
process.stdin.resume();
|
||||||
|
});
|
||||||
|
cleartextStream.setEncoding('utf8');
|
||||||
|
cleartextStream.on('data', function(data) {
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
cleartextStream.on('end', function() {
|
||||||
|
server.close();
|
||||||
|
});
|
||||||
|
|
||||||
## tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])
|
## tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])
|
||||||
|
|
||||||
|
@ -115,6 +115,14 @@ exports.createCredentials = function(options, context) {
|
|||||||
c.context.setSessionIdContext(options.sessionIdContext);
|
c.context.setSessionIdContext(options.sessionIdContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.pfx) {
|
||||||
|
if (options.passphrase) {
|
||||||
|
c.context.loadPKCS12(options.pfx, options.passphrase);
|
||||||
|
} else {
|
||||||
|
c.context.loadPKCS12(options.pfx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -740,6 +740,7 @@ function FSWatcher() {
|
|||||||
|
|
||||||
this._handle.onchange = function(status, event, filename) {
|
this._handle.onchange = function(status, event, filename) {
|
||||||
if (status) {
|
if (status) {
|
||||||
|
self._handle.close();
|
||||||
self.emit('error', errnoException(errno, 'watch'));
|
self.emit('error', errnoException(errno, 'watch'));
|
||||||
} else {
|
} else {
|
||||||
self.emit('change', event, filename);
|
self.emit('change', event, filename);
|
||||||
@ -1286,8 +1287,9 @@ ReadStream.prototype.resume = function() {
|
|||||||
this.paused = false;
|
this.paused = false;
|
||||||
|
|
||||||
if (this.buffer) {
|
if (this.buffer) {
|
||||||
this._emitData(this.buffer);
|
var buffer = this.buffer;
|
||||||
this.buffer = null;
|
this.buffer = null;
|
||||||
|
this._emitData(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasn't opened yet.
|
// hasn't opened yet.
|
||||||
|
@ -1315,6 +1315,7 @@ function socketErrorListener(err) {
|
|||||||
socket.destroy();
|
socket.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function responseOnEnd() {
|
function responseOnEnd() {
|
||||||
var req = this.req;
|
var req = this.req;
|
||||||
var socket = req.socket;
|
var socket = req.socket;
|
||||||
@ -1397,7 +1398,6 @@ function socketOnEnd() {
|
|||||||
socket.destroy();
|
socket.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function socketOnData(d, start, end) {
|
function socketOnData(d, start, end) {
|
||||||
var socket = this;
|
var socket = this;
|
||||||
var req = this._httpMessage;
|
var req = this._httpMessage;
|
||||||
@ -1461,7 +1461,6 @@ ClientRequest.prototype.onSocket = function(socket) {
|
|||||||
|
|
||||||
socket._httpMessage = req;
|
socket._httpMessage = req;
|
||||||
|
|
||||||
|
|
||||||
// Setup "drain" propogation.
|
// Setup "drain" propogation.
|
||||||
httpSocketSetup(socket);
|
httpSocketSetup(socket);
|
||||||
socket.ondata = socketOnData;
|
socket.ondata = socketOnData;
|
||||||
|
@ -179,6 +179,9 @@ if (isWindows) {
|
|||||||
tail += '\\';
|
tail += '\\';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert slashes to backslashes when `device` points to an UNC root.
|
||||||
|
device = device.replace(/\//g, '\\');
|
||||||
|
|
||||||
return device + (isAbsolute ? '\\' : '') + tail;
|
return device + (isAbsolute ? '\\' : '') + tail;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -932,6 +932,7 @@ function Server(/* [options], listener */) {
|
|||||||
this.setOptions(options);
|
this.setOptions(options);
|
||||||
|
|
||||||
var sharedCreds = crypto.createCredentials({
|
var sharedCreds = crypto.createCredentials({
|
||||||
|
pfx : self.pfx,
|
||||||
key: self.key,
|
key: self.key,
|
||||||
passphrase: self.passphrase,
|
passphrase: self.passphrase,
|
||||||
cert: self.cert,
|
cert: self.cert,
|
||||||
@ -1016,6 +1017,7 @@ Server.prototype.setOptions = function(options) {
|
|||||||
this.rejectUnauthorized = false;
|
this.rejectUnauthorized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.pfx) this.pfx = options.pfx;
|
||||||
if (options.key) this.key = options.key;
|
if (options.key) this.key = options.key;
|
||||||
if (options.passphrase) this.passphrase = options.passphrase;
|
if (options.passphrase) this.passphrase = options.passphrase;
|
||||||
if (options.cert) this.cert = options.cert;
|
if (options.cert) this.cert = options.cert;
|
||||||
|
@ -480,6 +480,10 @@
|
|||||||
// start parsing data from that stream.
|
// start parsing data from that stream.
|
||||||
if (process.env.NODE_CHANNEL_FD) {
|
if (process.env.NODE_CHANNEL_FD) {
|
||||||
assert(parseInt(process.env.NODE_CHANNEL_FD) >= 0);
|
assert(parseInt(process.env.NODE_CHANNEL_FD) >= 0);
|
||||||
|
|
||||||
|
// Make sure it's not accidentally inherited by child processes.
|
||||||
|
delete process.env.NODE_CHANNEL_FD;
|
||||||
|
|
||||||
var cp = NativeModule.require('child_process');
|
var cp = NativeModule.require('child_process');
|
||||||
|
|
||||||
// Load tcp_wrap to avoid situation where we might immediately receive
|
// Load tcp_wrap to avoid situation where we might immediately receive
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||||
# define OPENSSL_CONST const
|
# define OPENSSL_CONST const
|
||||||
#else
|
#else
|
||||||
@ -150,6 +151,7 @@ void SecureContext::Initialize(Handle<Object> target) {
|
|||||||
NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
|
NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
|
||||||
SecureContext::SetSessionIdContext);
|
SecureContext::SetSessionIdContext);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
|
NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "loadPKCS12", SecureContext::LoadPKCS12);
|
||||||
|
|
||||||
target->Set(String::NewSymbol("SecureContext"), t->GetFunction());
|
target->Set(String::NewSymbol("SecureContext"), t->GetFunction());
|
||||||
}
|
}
|
||||||
@ -576,6 +578,83 @@ Handle<Value> SecureContext::Close(const Arguments& args) {
|
|||||||
return False();
|
return False();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Takes .pfx or .p12 and password in string or buffer format
|
||||||
|
Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
|
||||||
|
HandleScope scope;
|
||||||
|
|
||||||
|
BIO* in = NULL;
|
||||||
|
PKCS12* p12 = NULL;
|
||||||
|
EVP_PKEY* pkey = NULL;
|
||||||
|
X509* cert = NULL;
|
||||||
|
STACK_OF(X509)* extraCerts = NULL;
|
||||||
|
char* pass = NULL;
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
|
||||||
|
|
||||||
|
if (args.Length() < 1) {
|
||||||
|
return ThrowException(Exception::TypeError(
|
||||||
|
String::New("Bad parameter")));
|
||||||
|
}
|
||||||
|
|
||||||
|
in = LoadBIO(args[0]);
|
||||||
|
if (in == NULL) {
|
||||||
|
return ThrowException(Exception::Error(
|
||||||
|
String::New("Unable to load BIO")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length() >= 2) {
|
||||||
|
ASSERT_IS_STRING_OR_BUFFER(args[1]);
|
||||||
|
|
||||||
|
int passlen = DecodeBytes(args[1], BINARY);
|
||||||
|
if (passlen < 0) {
|
||||||
|
BIO_free(in);
|
||||||
|
return ThrowException(Exception::TypeError(
|
||||||
|
String::New("Bad password")));
|
||||||
|
}
|
||||||
|
pass = new char[passlen + 1];
|
||||||
|
int pass_written = DecodeWrite(pass, passlen, args[1], BINARY);
|
||||||
|
|
||||||
|
assert(pass_written == passlen);
|
||||||
|
pass[passlen] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d2i_PKCS12_bio(in, &p12) &&
|
||||||
|
PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
|
||||||
|
SSL_CTX_use_certificate(sc->ctx_, cert) &&
|
||||||
|
SSL_CTX_use_PrivateKey(sc->ctx_, pkey))
|
||||||
|
{
|
||||||
|
// set extra certs
|
||||||
|
while (X509* x509 = sk_X509_pop(extraCerts)) {
|
||||||
|
if (!sc->ca_store_) {
|
||||||
|
sc->ca_store_ = X509_STORE_new();
|
||||||
|
SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_STORE_add_cert(sc->ca_store_, x509);
|
||||||
|
SSL_CTX_add_client_CA(sc->ctx_, x509);
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
X509_free(cert);
|
||||||
|
sk_X509_free(extraCerts);
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PKCS12_free(p12);
|
||||||
|
BIO_free(in);
|
||||||
|
delete[] pass;
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
unsigned long err = ERR_get_error();
|
||||||
|
const char *str = ERR_reason_error_string(err);
|
||||||
|
return ThrowException(Exception::Error(String::New(str)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return True();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SSL_PRINT_DEBUG
|
#ifdef SSL_PRINT_DEBUG
|
||||||
# define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
|
# define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <openssl/x509v3.h>
|
#include <openssl/x509v3.h>
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/pkcs12.h>
|
||||||
|
|
||||||
#ifdef OPENSSL_NPN_NEGOTIATED
|
#ifdef OPENSSL_NPN_NEGOTIATED
|
||||||
#include "node_buffer.h"
|
#include "node_buffer.h"
|
||||||
@ -68,6 +69,7 @@ class SecureContext : ObjectWrap {
|
|||||||
static v8::Handle<v8::Value> SetOptions(const v8::Arguments& args);
|
static v8::Handle<v8::Value> SetOptions(const v8::Arguments& args);
|
||||||
static v8::Handle<v8::Value> SetSessionIdContext(const v8::Arguments& args);
|
static v8::Handle<v8::Value> SetSessionIdContext(const v8::Arguments& args);
|
||||||
static v8::Handle<v8::Value> Close(const v8::Arguments& args);
|
static v8::Handle<v8::Value> Close(const v8::Arguments& args);
|
||||||
|
static v8::Handle<v8::Value> LoadPKCS12(const v8::Arguments& args);
|
||||||
|
|
||||||
SecureContext() : ObjectWrap() {
|
SecureContext() : ObjectWrap() {
|
||||||
ctx_ = NULL;
|
ctx_ = NULL;
|
||||||
|
@ -205,8 +205,8 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
|
|||||||
assert(wrap->object_.IsEmpty() == false);
|
assert(wrap->object_.IsEmpty() == false);
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
// TODO Handle server error (set errno and call onconnection with NULL)
|
SetErrno(uv_last_error(uv_default_loop()));
|
||||||
assert(0);
|
MakeCallback(wrap->object_, "onconnection", 0, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
test/fixtures/test_cert.pfx
vendored
Normal file
BIN
test/fixtures/test_cert.pfx
vendored
Normal file
Binary file not shown.
@ -13,7 +13,7 @@ var http = require('http'),
|
|||||||
done = 0,
|
done = 0,
|
||||||
count = 0,
|
count = 0,
|
||||||
countGC = 0,
|
countGC = 0,
|
||||||
todo = 400,
|
todo = 550,
|
||||||
common = require('../common.js'),
|
common = require('../common.js'),
|
||||||
assert = require('assert'),
|
assert = require('assert'),
|
||||||
PORT = common.PORT;
|
PORT = common.PORT;
|
||||||
|
53
test/simple/test-child-process-fork-and-spawn.js
Normal file
53
test/simple/test-child-process-fork-and-spawn.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright Joyent, Inc. and other Node contributors.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||||
|
// persons to whom the Software is furnished to do so, subject to the
|
||||||
|
// following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included
|
||||||
|
// in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
var common = require('../common');
|
||||||
|
var assert = require('assert');
|
||||||
|
var spawn = require('child_process').spawn;
|
||||||
|
var fork = require('child_process').fork;
|
||||||
|
|
||||||
|
// Fork, then spawn. The spawned process should not hang.
|
||||||
|
switch (process.argv[2] || '') {
|
||||||
|
case '':
|
||||||
|
fork(__filename, ['fork']).on('exit', checkExit);
|
||||||
|
process.on('exit', haveExit);
|
||||||
|
break;
|
||||||
|
case 'fork':
|
||||||
|
spawn(process.execPath, [__filename, 'spawn']).on('exit', checkExit);
|
||||||
|
process.on('exit', haveExit);
|
||||||
|
break;
|
||||||
|
case 'spawn':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var seenExit = false;
|
||||||
|
|
||||||
|
function checkExit(statusCode) {
|
||||||
|
seenExit = true;
|
||||||
|
assert.equal(statusCode, 0);
|
||||||
|
process.nextTick(process.exit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function haveExit() {
|
||||||
|
assert.equal(seenExit, true);
|
||||||
|
}
|
@ -38,6 +38,7 @@ var path = require('path');
|
|||||||
// Test Certificates
|
// Test Certificates
|
||||||
var caPem = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii');
|
var caPem = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii');
|
||||||
var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii');
|
var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii');
|
||||||
|
var certPfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx');
|
||||||
var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii');
|
var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii');
|
||||||
var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem',
|
var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem',
|
||||||
'ascii');
|
'ascii');
|
||||||
@ -54,8 +55,24 @@ try {
|
|||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test HMAC
|
// PFX tests
|
||||||
|
assert.doesNotThrow(function() {
|
||||||
|
crypto.createCredentials({pfx:certPfx, passphrase:'sample'});
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(function() {
|
||||||
|
crypto.createCredentials({pfx:certPfx});
|
||||||
|
}, 'mac verify failure');
|
||||||
|
|
||||||
|
assert.throws(function() {
|
||||||
|
crypto.createCredentials({pfx:certPfx, passphrase:'test'});
|
||||||
|
}, 'mac verify failure');
|
||||||
|
|
||||||
|
assert.throws(function() {
|
||||||
|
crypto.createCredentials({pfx:'sample', passphrase:'test'});
|
||||||
|
}, 'not enough data');
|
||||||
|
|
||||||
|
// Test HMAC
|
||||||
var h1 = crypto.createHmac('sha1', 'Node')
|
var h1 = crypto.createHmac('sha1', 'Node')
|
||||||
.update('some data')
|
.update('some data')
|
||||||
.update('to hmac')
|
.update('to hmac')
|
||||||
|
51
test/simple/test-fs-read-stream-resume.js
Normal file
51
test/simple/test-fs-read-stream-resume.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright Joyent, Inc. and other Node contributors.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||||
|
// persons to whom the Software is furnished to do so, subject to the
|
||||||
|
// following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included
|
||||||
|
// in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
var common = require('../common');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
var file = path.join(common.fixturesDir, 'x.txt');
|
||||||
|
var data = '';
|
||||||
|
var first = true;
|
||||||
|
|
||||||
|
var stream = fs.createReadStream(file);
|
||||||
|
stream.setEncoding('utf8');
|
||||||
|
stream.on('data', function(chunk) {
|
||||||
|
data += chunk;
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
stream.resume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
process.nextTick(function() {
|
||||||
|
stream.pause();
|
||||||
|
setTimeout(function() {
|
||||||
|
stream.resume();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert.equal(data, 'xyz\n');
|
||||||
|
});
|
56
test/simple/test-https-pfx.js
Normal file
56
test/simple/test-https-pfx.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright Joyent, Inc. and other Node contributors.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||||
|
// persons to whom the Software is furnished to do so, subject to the
|
||||||
|
// following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included
|
||||||
|
// in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
var common = require('../common');
|
||||||
|
var assert = require('assert');
|
||||||
|
var https = require('https');
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
var pfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx');
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
host: '127.0.0.1',
|
||||||
|
port: common.PORT,
|
||||||
|
path: '/',
|
||||||
|
pfx: pfx,
|
||||||
|
passphrase: 'sample',
|
||||||
|
requestCert: true
|
||||||
|
};
|
||||||
|
|
||||||
|
var server = https.createServer(options, function(req, res) {
|
||||||
|
assert.equal(req.socket.authorized, false); // not a client cert
|
||||||
|
assert.equal(req.socket.authorizationError, 'UNABLE_TO_GET_ISSUER_CERT');
|
||||||
|
res.writeHead(200);
|
||||||
|
res.end('OK');
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(options.port, options.host, function() {
|
||||||
|
var data = '';
|
||||||
|
|
||||||
|
https.get(options, function(res) {
|
||||||
|
res.on('data', function(data_) { data += data_ });
|
||||||
|
res.on('end', function() { server.close() });
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert.equal(data, 'OK');
|
||||||
|
});
|
||||||
|
});
|
@ -194,6 +194,8 @@ if (isWindows) {
|
|||||||
assert.equal(path.normalize('a//b//../b'), 'a\\b');
|
assert.equal(path.normalize('a//b//../b'), 'a\\b');
|
||||||
assert.equal(path.normalize('a//b//./c'), 'a\\b\\c');
|
assert.equal(path.normalize('a//b//./c'), 'a\\b\\c');
|
||||||
assert.equal(path.normalize('a//b//.'), 'a\\b');
|
assert.equal(path.normalize('a//b//.'), 'a\\b');
|
||||||
|
assert.equal(path.normalize('//server/share/dir/file.ext'),
|
||||||
|
'\\\\server\\share\\dir\\file.ext');
|
||||||
} else {
|
} else {
|
||||||
assert.equal(path.normalize('./fixtures///b/../b/c.js'),
|
assert.equal(path.normalize('./fixtures///b/../b/c.js'),
|
||||||
'fixtures/b/c.js');
|
'fixtures/b/c.js');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user