Esempio n. 1
0
function createUserNameIdentityToken(session, userName, password) {

    // assert(endpoint instanceof EndpointDescription);
    assert(userName === null || typeof userName === "string");
    assert(password === null || typeof password === "string");
    var endpoint_desc = session.endpoint;
    assert(endpoint_desc instanceof EndpointDescription);

    var userTokenPolicy = findUserTokenPolicy(endpoint_desc, UserIdentityTokenType.USERNAME);

    // istanbul ignore next
    if (!userTokenPolicy) {
        throw new Error("Cannot find USERNAME user token policy in end point description");
    }

    var securityPolicy = securityPolicy_m.fromURI(userTokenPolicy.securityPolicyUri);

    // if the security policy is not specified we use the session security policy
    if (securityPolicy === SecurityPolicy.Invalid) {
        securityPolicy = session._client._secureChannel.securityPolicy;
        assert(securityPolicy);
    }

    var serverCertificate = session.serverCertificate;
    assert(serverCertificate instanceof Buffer);

    serverCertificate = crypto_utils.toPem(serverCertificate, "CERTIFICATE");
    var publicKey = crypto_utils.extractPublicKeyFromCertificateSync(serverCertificate);

    var serverNonce = session.serverNonce;
    assert(serverNonce instanceof Buffer);


    // see Release 1.02 155 OPC Unified Architecture, Part 4
    var cryptoFactory = securityPolicy_m.getCryptoFactory(securityPolicy);

    // istanbul ignore next
    if (!cryptoFactory) {
        throw new Error(" Unsupported security Policy");
    }

    var userIdentityToken = new UserNameIdentityToken({
        userName: userName,
        password: new Buffer(password, "utf-8"),
        encryptionAlgorithm: cryptoFactory.asymmetricEncryptionAlgorithm,
        policyId: userTokenPolicy.policyId
    });


    // now encrypt password as requested
    var lenBuf = new Buffer(4);
    lenBuf.writeUInt32LE(userIdentityToken.password.length + serverNonce.length, 0);
    var block = Buffer.concat([lenBuf, userIdentityToken.password, serverNonce]);
    userIdentityToken.password = cryptoFactory.asymmetricEncrypt(block, publicKey);

    return userIdentityToken;
}
ClientSecureChannelLayer.prototype._get_security_options_for_OPN = function () {

    var self = this;
    if (self.securityMode === MessageSecurityMode.NONE) {
        return null;
    }

    assert(crypto_utils.isFullySupported(),
        "crypto is not fully supported, therefore we cannot create a secure channel for client");

    self._construct_security_header();
    this.messageChunker.securityHeader = self.securityHeader;

    var senderPrivateKey = self.getPrivateKey();


    assert(self.receiverPublicKey);
    assert(typeof self.receiverPublicKey === "string", "expecting a valid public key");

    var cryptoFactory = securityPolicy_m.getCryptoFactory(self.securityPolicy);

    if (!cryptoFactory) {
        return null; // may be a not yet supported security Policy
    }

    assert(cryptoFactory, "expecting a cryptoFactory");
    assert(_.isFunction(cryptoFactory.asymmetricSign));

    var options = {};

    options.signatureLength = crypto_utils.rsa_length(senderPrivateKey);
    options.signingFunc = function (chunk) {
        var s = cryptoFactory.asymmetricSign(chunk, senderPrivateKey);
        assert(s.length === options.signatureLength);
        return s;
    };

    assert(self.receiverPublicKey);
    var keyLength = crypto_utils.rsa_length(self.receiverPublicKey);
    options.plainBlockSize = keyLength - cryptoFactory.blockPaddingSize;
    options.cipherBlockSize = keyLength;

    options.encrypt_buffer = function (chunk) {
        return cryptoFactory.asymmetricEncrypt(chunk, self.receiverPublicKey);
    };

    return options;
};
MessageBuilder.prototype._read_headers = function (binaryStream) {

    MessageBuilderBase.prototype._read_headers.apply(this, arguments);
    assert(binaryStream.length === 12);

    var msgType = this.messageHeader.msgType;

    if (msgType === "HEL" || msgType === "ACK") {

        this.securityPolicy = SecurityPolicy.None;
    } else if (msgType === "ERR") {

        // extract Error StatusCode and additional message
        binaryStream.length = 8;
        var errorCode = decodeStatusCode(binaryStream);
        var message = decodeString(binaryStream);

        console.log(" ERROR RECEIVED FROM SENDER".red.bold, errorCode.toString().cyan, message);
        console.log(hexDump(binaryStream._buffer));
        return true;

    } else {

        this.securityHeader = chooseSecurityHeader(msgType);
        this.securityHeader.decode(binaryStream);

        if (msgType === "OPN") {
            this.securityPolicy = securityPolicy_m.fromURI(this.securityHeader.securityPolicyUri);
            this.cryptoFactory = securityPolicy_m.getCryptoFactory(this.securityPolicy);
        }

        if (!this._decrypt(binaryStream)) {
            return false;
        }

        this.sequenceHeader = new SequenceHeader();
        this.sequenceHeader.decode(binaryStream);

        /* istanbul ignore next */
        if (doDebug) {
            debugLog(" Sequence Header", this.sequenceHeader);
        }

        this._validateSequenceNumber(this.sequenceHeader.sequenceNumber);
    }
    return true;
};
function _build_client_nonce() {

    /* jshint validthis: true */
    var self = this;

    if (self.securityMode === MessageSecurityMode.NONE) {
        return null;
    }
    // create a client Nonce if secure mode is requested
    // Release 1.02 page 23 OPC Unified Architecture, Part 4 Table 7 – OpenSecureChannel Service Parameters
    // clientNonce
    // "This parameter shall have a length equal to key size used for the symmetric
    //  encryption algorithm that is identified by the securityPolicyUri"

    var cryptoFactory = securityPolicy_m.getCryptoFactory(self.securityPolicy);
    if (!cryptoFactory) {
        // this securityPolicy may not be support yet ... let's return null
        return null;
    }
    assert(_.isObject(cryptoFactory));

    return crypto.randomBytes(cryptoFactory.symmetricKeyLength);

}