Browse Source

pair.cleartext, pair.encrypted now instances of tls.CryptoStream

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
137c361517
  1. 135
      lib/tls.js
  2. 1
      test/simple/test-securepair-client.js

135
lib/tls.js

@ -16,7 +16,52 @@ if (debugLevel & 0x2) {
/* Lazy Loaded crypto object */ /* Lazy Loaded crypto object */
var SecureStream = null; var SecureStream = null; // note SecureStream is not a "real" stream.
// Base class of both CleartextStream and EncryptedStream
function CryptoStream (pair) {
stream.Stream.call(this);
this.pair = pair;
this.readable = this.writable = true;
this._writeState = true;
this._pending = [];
}
util.inherits(CryptoStream, stream.Stream);
CryptoStream.prototype.write = function(data) {
if (typeof data == 'string') data = Buffer(data);
debug('clearIn data');
this._pending.push(data);
this.pair._cycle();
return this._writeState;
};
CryptoStream.prototype.pause = function() {
debug('paused cleartext');
this._writeState = false;
};
CryptoStream.prototype.resume = function() {
debug('resumed cleartext');
this._writeState = true;
};
CryptoStream.prototype.end = function(err) {
debug('cleartext end');
if (!this.pair._done) {
this.pair._ssl.shutdown();
this.pair._cycle();
}
this.pair._destroy(err);
};
/** /**
* Provides a pair of streams to do encrypted communication. * Provides a pair of streams to do encrypted communication.
@ -75,68 +120,10 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized) {
/* Acts as a r/w stream to the cleartext side of the stream. */ /* Acts as a r/w stream to the cleartext side of the stream. */
this.cleartext = new stream.Stream(); this.cleartext = new CryptoStream(this);
this.cleartext.readable = true;
this.cleartext.writable = true;
/* Acts as a r/w stream to the encrypted side of the stream. */ /* Acts as a r/w stream to the encrypted side of the stream. */
this.encrypted = new stream.Stream(); this.encrypted = new CryptoStream(this);
this.encrypted.readable = true;
this.encrypted.writable = true;
this.cleartext.write = function(data) {
if (typeof data == 'string') data = Buffer(data);
debug('clearIn data');
self._clearInPending.push(data);
self._cycle();
return self._cleartextWriteState;
};
this.cleartext.pause = function() {
debug('paused cleartext');
self._cleartextWriteState = false;
};
this.cleartext.resume = function() {
debug('resumed cleartext');
self._cleartextWriteState = true;
};
this.cleartext.end = function(err) {
debug('cleartext end');
if (!self._done) {
self._ssl.shutdown();
self._cycle();
}
self._destroy(err);
};
this.encrypted.write = function(data) {
debug('encIn data');
self._encInPending.push(data);
self._cycle();
return self._encryptedWriteState;
};
this.encrypted.pause = function() {
if (typeof data == 'string') data = Buffer(data);
debug('pause encrypted');
self._encryptedWriteState = false;
};
this.encrypted.resume = function() {
debug('resume encrypted');
self._encryptedWriteState = true;
};
this.encrypted.end = function(err) {
debug('encrypted end');
if (!self._done) {
self._ssl.shutdown();
self._cycle();
}
self._destroy(err);
};
process.nextTick(function() { process.nextTick(function() {
self._ssl.start(); self._ssl.start();
@ -240,9 +227,9 @@ SecurePair.prototype._cycle = function() {
// pair.encrypted.write(d) // pair.encrypted.write(d)
// }); // });
// //
var encPending = this._encInPending.length > 0; var encPending = this.encrypted._pending.length > 0;
while (this._encInPending.length > 0) { while (this.encrypted._pending.length > 0) {
tmp = this._encInPending.shift(); tmp = this.encrypted._pending.shift();
try { try {
debug('writing from encIn'); debug('writing from encIn');
@ -252,7 +239,7 @@ SecurePair.prototype._cycle = function() {
} }
if (rv === 0) { if (rv === 0) {
this._encInPending.unshift(tmp); this.encrypted._pending.unshift(tmp);
break; break;
} }
@ -260,7 +247,7 @@ SecurePair.prototype._cycle = function() {
} }
// If we've cleared all of incoming encrypted data, emit drain. // If we've cleared all of incoming encrypted data, emit drain.
if (encPending && this._encInPending.length === 0) { if (this.encrypted._pending && this.encrypted._pending.length === 0) {
debug('encrypted drain'); debug('encrypted drain');
this.encrypted.emit('drain'); this.encrypted.emit('drain');
} }
@ -271,9 +258,9 @@ SecurePair.prototype._cycle = function() {
// //
// pair.cleartext.write("hello world"); // pair.cleartext.write("hello world");
// //
var clearPending = this._clearInPending.length > 0; var clearPending = this.cleartext._pending.length > 0;
while (this._clearInPending.length > 0) { while (this.cleartext._pending.length > 0) {
tmp = this._clearInPending.shift(); tmp = this.cleartext._pending.shift();
try { try {
debug('writng from clearIn'); debug('writng from clearIn');
rv = this._ssl.clearIn(tmp, 0, tmp.length); rv = this._ssl.clearIn(tmp, 0, tmp.length);
@ -282,7 +269,7 @@ SecurePair.prototype._cycle = function() {
} }
if (rv === 0) { if (rv === 0) {
this._clearInPending.unshift(tmp); this.cleartext._pending.unshift(tmp);
break; break;
} }
@ -290,7 +277,7 @@ SecurePair.prototype._cycle = function() {
} }
// If we've cleared all of incoming cleartext data, emit drain. // If we've cleared all of incoming cleartext data, emit drain.
if (clearPending && this._clearInPending.length === 0) { if (clearPending && this.cleartext._pending.length === 0) {
debug('cleartext drain'); debug('cleartext drain');
this.cleartext.emit('drain'); this.cleartext.emit('drain');
} }
@ -308,7 +295,7 @@ SecurePair.prototype._cycle = function() {
self.cleartext.emit('data', chunk); self.cleartext.emit('data', chunk);
}, },
function() { function() {
return self._cleartextWriteState === true; return self.cleartext._writeState === true;
}); });
// Move encrypted data to the stream. From the user's perspective this // Move encrypted data to the stream. From the user's perspective this
@ -330,7 +317,7 @@ SecurePair.prototype._cycle = function() {
}, },
function() { function() {
if (!self._ssl) return false; if (!self._ssl) return false;
return self._encryptedWriteState === true; return self.encrypted._writeState === true;
}); });
@ -559,3 +546,5 @@ Server.prototype.setOptions = function(options) {
if (options.ca) this.ca = options.ca; if (options.ca) this.ca = options.ca;
}; };

1
test/simple/test-securepair-client.js

@ -35,6 +35,7 @@ var serverStdoutBuffer = '';
server.stdout.setEncoding('utf8'); server.stdout.setEncoding('utf8');
server.stdout.on('data', function(s) { server.stdout.on('data', function(s) {
serverStdoutBuffer += s; serverStdoutBuffer += s;
console.error(state);
switch (state) { switch (state) {
case 'WAIT-ACCEPT': case 'WAIT-ACCEPT':
if (/ACCEPT/g.test(serverStdoutBuffer)) { if (/ACCEPT/g.test(serverStdoutBuffer)) {

Loading…
Cancel
Save