Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
encryptBufferWithDerivedKeys,
makeMessageChunkSignature,
makeMessageChunkSignatureWithDerivedKeys,
makeSHA1Thumbprint,
publicEncrypt_long,
readCertificate,
readKeyPem,
RSA_PKCS1_PADDING
} from "node-opcua-crypto";
import { AsymmetricAlgorithmSecurityHeader, SymmetricAlgorithmSecurityHeader } from "node-opcua-service-secure-channel";
import { SecureMessageChunkManager, SequenceNumberGenerator } from "../source";
// tslint:disable:no-var-requires
const getFixture = require("node-opcua-test-fixtures").getFixture;
const senderCertificate = readCertificate(getFixture("certs/client_cert_1024.pem"));
const senderPrivateKey = readKeyPem(getFixture("certs/client_key_1024.pem"));
const receiverCertificate = readCertificate(getFixture("certs/server_cert_1024.pem"));
const receiverCertificateThumbprint = makeSHA1Thumbprint(receiverCertificate);
const receiverPublicKey = fs.readFileSync(getFixture("certs/server_public_key_1024.pub", "ascii")).toString();
const sequenceNumberGenerator = new SequenceNumberGenerator();
export type ChunkVisitorFunc = (err: Error | null, chunk?: Buffer) => void;
export function iterateOnSignedMessageChunks(buffer: Buffer, callback: ChunkVisitorFunc) {
const params = {
algorithm: "RSA-SHA1",
privateKey: senderPrivateKey,
makeSHA1Thumbprint,
publicEncrypt_long,
readCertificate,
readKeyPem,
RSA_PKCS1_PADDING
} from "node-opcua-crypto";
import { AsymmetricAlgorithmSecurityHeader, SymmetricAlgorithmSecurityHeader } from "node-opcua-service-secure-channel";
import { SecureMessageChunkManager, SequenceNumberGenerator } from "../source";
// tslint:disable:no-var-requires
const getFixture = require("node-opcua-test-fixtures").getFixture;
const senderCertificate = readCertificate(getFixture("certs/client_cert_1024.pem"));
const senderPrivateKey = readKeyPem(getFixture("certs/client_key_1024.pem"));
const receiverCertificate = readCertificate(getFixture("certs/server_cert_1024.pem"));
const receiverCertificateThumbprint = makeSHA1Thumbprint(receiverCertificate);
const receiverPublicKey = fs.readFileSync(getFixture("certs/server_public_key_1024.pub", "ascii")).toString();
const sequenceNumberGenerator = new SequenceNumberGenerator();
export type ChunkVisitorFunc = (err: Error | null, chunk?: Buffer) => void;
export function iterateOnSignedMessageChunks(buffer: Buffer, callback: ChunkVisitorFunc) {
const params = {
algorithm: "RSA-SHA1",
privateKey: senderPrivateKey,
signatureLength: 128,
};
return (chunk: Buffer) => {
const options = {
algorithm: "RSA-SHA256",
privateKey,
signatureLength: 128,
};
const buf = makeMessageChunkSignature(chunk, options); // Buffer
assert(buf instanceof Buffer, "expecting a Buffer");
return buf;
};
}
return function (chunk) {
const options = {
algorithm: "RSA-SHA256",
signatureLength: 128,
privateKey: privateKey
};
const buf = crypto_utils.makeMessageChunkSignature(chunk, options); // Buffer
assert(buf instanceof Buffer, "expecting a Buffer");
return buf;
};
}
makeMessageChunkSignature,
makeMessageChunkSignatureWithDerivedKeys,
makeSHA1Thumbprint,
publicEncrypt_long,
readCertificate,
readKeyPem,
RSA_PKCS1_PADDING
} from "node-opcua-crypto";
import { AsymmetricAlgorithmSecurityHeader, SymmetricAlgorithmSecurityHeader } from "node-opcua-service-secure-channel";
import { SecureMessageChunkManager, SequenceNumberGenerator } from "../source";
// tslint:disable:no-var-requires
const getFixture = require("node-opcua-test-fixtures").getFixture;
const senderCertificate = readCertificate(getFixture("certs/client_cert_1024.pem"));
const senderPrivateKey = readKeyPem(getFixture("certs/client_key_1024.pem"));
const receiverCertificate = readCertificate(getFixture("certs/server_cert_1024.pem"));
const receiverCertificateThumbprint = makeSHA1Thumbprint(receiverCertificate);
const receiverPublicKey = fs.readFileSync(getFixture("certs/server_public_key_1024.pub", "ascii")).toString();
const sequenceNumberGenerator = new SequenceNumberGenerator();
export type ChunkVisitorFunc = (err: Error | null, chunk?: Buffer) => void;
export function iterateOnSignedMessageChunks(buffer: Buffer, callback: ChunkVisitorFunc) {
const params = {
algorithm: "RSA-SHA1",
privateKey: senderPrivateKey,
signatureLength: 128,
function _check_certificate_validity(certificate) {
// Is the signature on the SoftwareCertificate valid .?
if (!certificate) {
// missing certificate
return StatusCodes.BadSecurityChecksFailed;
}
//-- const split_der = require("node-opcua-crypto").crypto_explore_certificate.split_der;
//-- const chain = split_der(securityHeader.senderCertificate);
//-- //xx console.log("xxx NB CERTIFICATE IN CHAIN = ".red,chain.length);
// Has SoftwareCertificate passed its issue date and has it not expired ?
// check dates
const cert = crypto_utils.exploreCertificateInfo(certificate);
const now = new Date();
if (cert.notBefore.getTime() > now.getTime()) {
// certificate is not active yet
console.log(
" Sender certificate is invalid : certificate is not active yet !".red +
" not before date =" +
cert.notBefore
);
return StatusCodes.BadCertificateTimeInvalid;
}
if (cert.notAfter.getTime() <= now.getTime()) {
// certificate is obsolete
console.log(
" Sender certificate is invalid : certificate has expired !".red + " not after date =" + cert.notAfter
// then verify the signature
const signatureLength = cert.publicKeyLength; // 1024 bits = 128Bytes or 2048=256Bytes or 3072 or 4096
assert(signatureLength === 128 || signatureLength === 256 || signatureLength === 384 || signatureLength === 512 );
const chunk = binaryStream._buffer;
const signatureIsOK = this.cryptoFactory.asymmetricVerifyChunk(chunk, this.securityHeader.senderCertificate);
if (!signatureIsOK) {
console.log(hexDump(binaryStream._buffer));
this._report_error("SIGN and ENCRYPT asymmetricVerify : Invalid packet signature");
return false;
}
// remove signature
binaryStream._buffer = crypto_utils.reduceLength(binaryStream._buffer, signatureLength);
// remove padding
if (this.securityHeader.receiverCertificateThumbprint) {
binaryStream._buffer = crypto_utils.removePadding(binaryStream._buffer);
}
return true; // success
};
OPCUAClient.prototype._getApplicationUri = function () {
// get applicationURI from certificate
const exploreCertificate = require("node-opcua-crypto").exploreCertificate;
const certificate = this.getCertificate();
let applicationUri;
if (certificate) {
const e = exploreCertificate(certificate);
if (!e.tbsCertificate.extensions || !e.tbsCertificate.extensions.subjectAltName) {
console.log(chalk.red(" Warning: client certificate is invalid : subjectAltName is missing"));
applicationUri = makeApplicationUrn(hostname, this.applicationName);
} else {
applicationUri = e.tbsCertificate.extensions.subjectAltName.uniformResourceIdentifier[0];
}
} else {
applicationUri = makeApplicationUrn(hostname, this.applicationName);
}
return applicationUri;
};
// We shall decrypt it with the receiver private key.
const buf = binaryStream.buffer.slice(binaryStream.length);
if (!securityTokenData.derivedKeys) {
console.log("xxxxxxx NO DERIVED KEYX");
return false;
}
const derivedKeys: DerivedKeys = securityTokenData.derivedKeys;
assert(derivedKeys !== null);
assert(derivedKeys.signatureLength > 0, " must provide a signature length");
if (this.securityMode === MessageSecurityMode.SignAndEncrypt) {
const decryptedBuffer = decryptBufferWithDerivedKeys(buf, derivedKeys);
// replace decrypted buffer in initial buffer
decryptedBuffer.copy(binaryStream.buffer, binaryStream.length);
// adjust length
binaryStream.buffer = binaryStream.buffer.slice(0, binaryStream.length + decryptedBuffer.length);
/* istanbul ignore next */
if (doDebug) {
debugLog(chalk.cyan("DE-----------------------------"));
debugLog(hexDump(binaryStream.buffer));
debugLog(chalk.cyan("-------------------------------"));
}
}
// now check signature ....
switch (request.securityMode) {
case MessageSecurityMode.None:
securityHeader = new AsymmetricAlgorithmSecurityHeader({
receiverCertificateThumbprint: null, // message not encrypted
securityPolicyUri: "http://opcfoundation.org/UA/SecurityPolicy#None",
senderCertificate: null // message not signed
});
break;
case MessageSecurityMode.Sign:
case MessageSecurityMode.SignAndEncrypt:
default: {
// get the thumbprint of the client certificate
const thumbprint = this.receiverCertificate
? makeSHA1Thumbprint(this.receiverCertificate)
: null;
if (!this.clientSecurityHeader) {
throw new Error("Internal");
}
const asymmClientSecurityHeader = this.clientSecurityHeader as AsymmetricAlgorithmSecurityHeader;
securityHeader = new AsymmetricAlgorithmSecurityHeader({
receiverCertificateThumbprint: thumbprint, // message not encrypted (????)
securityPolicyUri: asymmClientSecurityHeader.securityPolicyUri,
senderCertificate: this.getCertificateChain() // certificate of the private key used to sign the message
});
}
}
return securityHeader;
}