ServerSecureChannelLayer.prototype._process_certificates = function(message,callback) {

    var self = this;

    self.receiverPublicKey = null;
    self.receiverPublicKeyLength = 0;
    self.receiverCertificate = message.securityHeader ? message.securityHeader.senderCertificate : null;

    // ignore receiverCertificate that have a zero length
    /* istanbul ignore next */
    if (self.receiverCertificate && self.receiverCertificate.length === 0) {
        self.receiverCertificate = null;
    }

    if (self.receiverCertificate) {
        // extract public key
        crypto_utils.extractPublicKeyFromCertificate(self.receiverCertificate,function (err, key) {
            if (!err) {
                self.receiverPublicKey = key;
                self.receiverPublicKeyLength = crypto_utils.rsa_length(key);
            }
            callback(err);
        });
    } else {
        self.receiverPublicKey = null;
        callback();
    }
};
Ejemplo n.º 2
0
    it("should extract a public key from a certificate", function (done) {

        var certificate = fs.readFileSync('certificates/client_cert_1024.pem').toString('ascii');
        //xx console.log(" certificate");

        var certificate2 = crypto_utils.readCertificate('certificates/client_cert_1024.pem');
        //xx console.log(hexDump(certificate2));

        var publickey2 = crypto_utils.readKey('certificates/client_public_key_1024.pub');
        //xx console.log(hexDump(publickey2));

        crypto_utils.extractPublicKeyFromCertificate(certificate2, function (err, publicKey) {

            var raw_public_key = crypto_utils.readPEM(publicKey);
            //xx console.log(hexDump(raw_public_key));

            raw_public_key.toString("base64").should.eql(publickey2.toString("base64"));
            done(err);
        });

    });
ClientSecureChannelLayer.prototype.create = function (endpoint_url, callback) {

    assert(_.isFunction(callback));
    var self = this;

    if (self.securityMode !== MessageSecurityMode.NONE) {

        if (!crypto_utils.isFullySupported()) {
            return callback(new Error("Crypto is not fully supported"));
        }

        if (!self.serverCertificate) {
            return callback(new Error("invalid server certificate"));
        }

        // take the opportunity of this async method to perform some async pre-processing
        if (_.isUndefined(self.receiverPublicKey)) {

            crypto_utils.extractPublicKeyFromCertificate(self.serverCertificate, function (err, publicKey) {
                /* istanbul ignore next */
                if (err) {
                    return callback(err);
                }
                self.receiverPublicKey = publicKey;
                self.create(endpoint_url, callback);
            });
            return undefined;
        }
        assert(typeof self.receiverPublicKey  === "string");
    }


    this.endpoint_url = endpoint_url;
    var transport = new ClientTCP_transport();
    transport.protocolVersion = self.protocolVersion;

    transport.connect(endpoint_url, _on_connection.bind(this, transport, callback));

};
Ejemplo n.º 4
0
ClientSecureChannelLayer.prototype.create = function (endpoint_url, callback) {

    assert(_.isFunction(callback));
    var self = this;

    if (self.securityMode !== MessageSecurityMode.NONE) {

        if (!crypto_utils.isFullySupported()) {
            return callback(new Error("ClientSecureChannelLayer#create : this version of node doesn't fully support crypto"));
        }

        if (!self.serverCertificate) {
            return callback(new Error("ClientSecureChannelLayer#create : expecting a  server certificate when securityMode is not NONE"));
        }

        // take the opportunity of this async method to perform some async pre-processing
        if (_.isUndefined(self.receiverPublicKey)) {

            crypto_utils.extractPublicKeyFromCertificate(self.serverCertificate, function (err, publicKey) {
                /* istanbul ignore next */
                if (err) {
                    return callback(err);
                }
                self.receiverPublicKey = publicKey;
                assert(!_.isUndefined(self.receiverPublicKey)); // make sure we wont go into infinite recursion calling create again.
                self.create(endpoint_url, callback);
            });
            return undefined;
        }
        assert(typeof self.receiverPublicKey  === "string");
    }


    self.endpoint_url = endpoint_url;
    var transport = new ClientTCP_transport();
    transport.timeout = self.transportTimeout;
    transport.protocolVersion = self.protocolVersion;


    // -------------------------------------------------------------------------
    // Handle reconnection
    // --------------------------------------------------------------------------
    var _establish_connection = function (transport,endpoint_url,callback) {

        var backoff = require('backoff');

        var last_err= null;

        function _connect(_i_callback) {

            if (self.__call && self.__call._cancelBackoff) {
                return;
            }
            transport.connect(endpoint_url, function (err) {

                // force Backoff to fail if err is not ECONNRESET or ECONNREFUSE
                // this mean that the connection to the server has succeeded but for some reason
                // the server has denied the connection
                // the cause could be:
                //   - invalid protocol version specified by client
                //   - server going to shutdown
                //   - server too busy -
                //   - server shielding itself from a DOS attack
                if (err) {

                    last_err = err;

                    if (true) {
                        // connection cannot be establish ? if not, abort the backoff process
                        if (err.message.match(/ECONNRESET/)) {
                            debugLog(" Aborting backoff process prematuraly - err = ", err.message);
                            self.__call.abort();
                            //xx call emit fail ( this line should be removed when new version of backoff will be posted)
                            //xx self.__call.backoff_.emit("fail",err);
                            //xx self.__call.failAfter(1);

                        } else {
                            debugLog(" backoff - keep trying - err = ", err.message);
                        }
                    }
                }
                _i_callback(err);
            });
        }

        function _backoff_completion(err) {

            if (self.__call) {
                // console log =
                transport.numberOfRetry = transport.numberOfRetry || 0;
                transport.numberOfRetry += self.__call.getNumRetries();
                self.__call.removeAllListeners();
                self.__call = null;

                //console.log('xxx Num retries: ' + transport.numberOfRetry );
                if (err) {
                    //xx console.log('xxx Error: ' + err.message,last_err.message);
                    callback(last_err);
                } else {
                    callback();
                }
            }
        }
        self.__call = backoff.call(_connect,_backoff_completion);

        self.__call._cancelBackoff = false;
        self.__call.failAfter(self.connectionStrategy.maxRetry);


        self.__call.on('backoff', function(number, delay) {

            debugLog(" Backoff #".bgWhite.cyan,number,"delay = ",delay);
            // Do something when backoff starts, e.g. show to the
            // user the delay before next reconnection attempt.
            /**
             * @event backoff
             */
            self.emit("backoff",number,delay);
        });

        self.__call.on('abort', function(err) {
            debugLog(" abort #".bgWhite.cyan," after ",self.__call.getNumRetries(), " retries");
            // Do something when backoff starts, e.g. show to the
            // user the delay before next reconnection attempt.
            /**
             * @event backoff
             */
            self.emit("abort");

            setImmediate(function() {
                _backoff_completion(null,new Error("Connection abandoned"));
            });

        });

        self.__call.setStrategy(new backoff.ExponentialStrategy(self.connectionStrategy));
        self.__call.start();
    };

    _establish_connection(transport,endpoint_url, _on_connection.bind(this, transport, callback));

};