node-opcua-crypto 2.1.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.fossa.yml +18 -18
  2. package/.github/FUNDING.yml +12 -12
  3. package/.github/workflows/main.yml +106 -106
  4. package/.prettierrc.js +6 -6
  5. package/LICENSE +23 -23
  6. package/README.md +14 -14
  7. package/dist/source/asn1.d.ts +73 -73
  8. package/dist/source/asn1.js +359 -359
  9. package/dist/source/buffer_utils.d.ts +6 -6
  10. package/dist/source/buffer_utils.js +21 -21
  11. package/dist/source/common.d.ts +14 -14
  12. package/dist/source/common.js +2 -2
  13. package/dist/source/crypto_explore_certificate.d.ts +107 -107
  14. package/dist/source/crypto_explore_certificate.js +601 -601
  15. package/dist/source/crypto_utils.d.ts +76 -76
  16. package/dist/source/crypto_utils.js +329 -329
  17. package/dist/source/derived_keys.d.ts +72 -72
  18. package/dist/source/derived_keys.js +248 -248
  19. package/dist/source/explore_certificate.d.ts +30 -30
  20. package/dist/source/explore_certificate.js +43 -43
  21. package/dist/source/explore_certificate_revocation_list.d.ts +28 -28
  22. package/dist/source/explore_certificate_revocation_list.js +69 -69
  23. package/dist/source/explore_certificate_signing_request.d.ts +13 -13
  24. package/dist/source/explore_certificate_signing_request.js +44 -44
  25. package/dist/source/explore_private_key.d.ts +29 -29
  26. package/dist/source/explore_private_key.js +97 -97
  27. package/dist/source/index.d.ts +13 -13
  28. package/dist/source/index.js +29 -29
  29. package/dist/source/oid_map.d.ts +7 -7
  30. package/dist/source/oid_map.js +303 -303
  31. package/dist/source/public_private_match.d.ts +3 -3
  32. package/dist/source/public_private_match.js +36 -36
  33. package/dist/source/verify_certificate_signature.d.ts +10 -10
  34. package/dist/source/verify_certificate_signature.js +101 -101
  35. package/dist/source_nodejs/index.d.ts +3 -3
  36. package/dist/source_nodejs/index.js +19 -19
  37. package/dist/source_nodejs/read.d.ts +23 -23
  38. package/dist/source_nodejs/read.js +106 -106
  39. package/dist/source_nodejs/read_certificate_revocation_list.d.ts +2 -2
  40. package/dist/source_nodejs/read_certificate_revocation_list.js +27 -27
  41. package/dist/source_nodejs/read_certificate_signing_request.d.ts +3 -3
  42. package/dist/source_nodejs/read_certificate_signing_request.js +27 -27
  43. package/index.d.ts +2 -2
  44. package/index.js +4 -4
  45. package/index_web.js +3 -3
  46. package/package.json +9 -9
  47. package/source/asn1.ts +404 -404
  48. package/source/buffer_utils.ts +18 -18
  49. package/source/crypto_explore_certificate.ts +764 -764
  50. package/source/derived_keys.ts +287 -287
  51. package/source/explore_certificate.ts +66 -66
  52. package/source/explore_certificate_revocation_list.ts +122 -122
  53. package/source/explore_certificate_signing_request.ts +58 -58
  54. package/source/index.ts +13 -13
  55. package/source/oid_map.ts +310 -310
  56. package/source/verify_certificate_signature.ts +105 -105
  57. package/source_nodejs/index.ts +2 -2
  58. package/source_nodejs/read_certificate_revocation_list.ts +14 -14
  59. package/source_nodejs/read_certificate_signing_request.ts +17 -17
  60. package/test_certificate.ts +34 -34
  61. package/tsconfig.json +18 -18
  62. package/tslint.json +34 -34
  63. package/dist/source/certificate_matches_private_key.d.ts +0 -2
  64. package/dist/source/certificate_matches_private_key.js +0 -22
  65. package/dist/source/certificate_matches_private_key.js.map +0 -1
@@ -1,72 +1,72 @@
1
- /// <reference types="node" />
2
- import { Nonce } from "./common";
3
- import { VerifyMessageChunkSignatureOptions } from "./crypto_utils";
4
- export declare function makePseudoRandomBuffer(secret: Nonce, seed: Nonce, minLength: number, sha1or256: "SHA1" | "SHA256"): Buffer;
5
- export interface ComputeDerivedKeysOptions {
6
- signatureLength: number;
7
- signingKeyLength: number;
8
- encryptingKeyLength: number;
9
- encryptingBlockSize: number;
10
- algorithm: string;
11
- sha1or256?: "SHA1" | "SHA256";
12
- }
13
- export interface DerivedKeys extends ComputeDerivedKeysOptions {
14
- signatureLength: number;
15
- signingKeyLength: number;
16
- encryptingKeyLength: number;
17
- encryptingBlockSize: number;
18
- algorithm: string;
19
- sha1or256: "SHA1" | "SHA256";
20
- signingKey: Buffer;
21
- encryptingKey: Buffer;
22
- initializationVector: Buffer;
23
- }
24
- export declare function computeDerivedKeys(secret: Nonce, seed: Nonce, options: ComputeDerivedKeysOptions): DerivedKeys;
25
- /**
26
- * @method reduceLength
27
- * @param buffer
28
- * @param byteToRemove
29
- * @return buffer
30
- */
31
- export declare function reduceLength(buffer: Buffer, byteToRemove: number): Buffer;
32
- /**
33
- * @method removePadding
34
- * @param buffer
35
- * @return buffer with padding removed
36
- */
37
- export declare function removePadding(buffer: Buffer): Buffer;
38
- export type VerifyChunkSignatureOptions = VerifyMessageChunkSignatureOptions;
39
- /**
40
- * @method verifyChunkSignature
41
- *
42
- * const signer = {
43
- * signatureLength : 128,
44
- * algorithm : "RSA-SHA256",
45
- * public_key: "qsdqsdqsd"
46
- * };
47
- *
48
- * @param chunk The message chunk to verify.
49
- * @param options
50
- * @param options.signatureLength
51
- * @param options.algorithm the algorithm.
52
- * @param options.publicKey
53
- * @return {*}
54
- */
55
- export declare function verifyChunkSignature(chunk: Buffer, options: VerifyChunkSignatureOptions): boolean;
56
- export declare function computePaddingFooter(buffer: Buffer, derivedKeys: DerivedKeys): Buffer;
57
- export declare function encryptBufferWithDerivedKeys(buffer: Buffer, derivedKeys: DerivedKeys): Buffer;
58
- export declare function decryptBufferWithDerivedKeys(buffer: Buffer, derivedKeys: DerivedKeys): Buffer;
59
- /**
60
- * @method makeMessageChunkSignatureWithDerivedKeys
61
- * @param message
62
- * @param derivedKeys
63
- * @return
64
- */
65
- export declare function makeMessageChunkSignatureWithDerivedKeys(message: Buffer, derivedKeys: DerivedKeys): Buffer;
66
- /**
67
- * @method verifyChunkSignatureWithDerivedKeys
68
- * @param chunk
69
- * @param derivedKeys
70
- * @return
71
- */
72
- export declare function verifyChunkSignatureWithDerivedKeys(chunk: Buffer, derivedKeys: DerivedKeys): boolean;
1
+ /// <reference types="node" />
2
+ import { Nonce } from "./common";
3
+ import { VerifyMessageChunkSignatureOptions } from "./crypto_utils";
4
+ export declare function makePseudoRandomBuffer(secret: Nonce, seed: Nonce, minLength: number, sha1or256: "SHA1" | "SHA256"): Buffer;
5
+ export interface ComputeDerivedKeysOptions {
6
+ signatureLength: number;
7
+ signingKeyLength: number;
8
+ encryptingKeyLength: number;
9
+ encryptingBlockSize: number;
10
+ algorithm: string;
11
+ sha1or256?: "SHA1" | "SHA256";
12
+ }
13
+ export interface DerivedKeys extends ComputeDerivedKeysOptions {
14
+ signatureLength: number;
15
+ signingKeyLength: number;
16
+ encryptingKeyLength: number;
17
+ encryptingBlockSize: number;
18
+ algorithm: string;
19
+ sha1or256: "SHA1" | "SHA256";
20
+ signingKey: Buffer;
21
+ encryptingKey: Buffer;
22
+ initializationVector: Buffer;
23
+ }
24
+ export declare function computeDerivedKeys(secret: Nonce, seed: Nonce, options: ComputeDerivedKeysOptions): DerivedKeys;
25
+ /**
26
+ * @method reduceLength
27
+ * @param buffer
28
+ * @param byteToRemove
29
+ * @return buffer
30
+ */
31
+ export declare function reduceLength(buffer: Buffer, byteToRemove: number): Buffer;
32
+ /**
33
+ * @method removePadding
34
+ * @param buffer
35
+ * @return buffer with padding removed
36
+ */
37
+ export declare function removePadding(buffer: Buffer): Buffer;
38
+ export type VerifyChunkSignatureOptions = VerifyMessageChunkSignatureOptions;
39
+ /**
40
+ * @method verifyChunkSignature
41
+ *
42
+ * const signer = {
43
+ * signatureLength : 128,
44
+ * algorithm : "RSA-SHA256",
45
+ * public_key: "qsdqsdqsd"
46
+ * };
47
+ *
48
+ * @param chunk The message chunk to verify.
49
+ * @param options
50
+ * @param options.signatureLength
51
+ * @param options.algorithm the algorithm.
52
+ * @param options.publicKey
53
+ * @return {*}
54
+ */
55
+ export declare function verifyChunkSignature(chunk: Buffer, options: VerifyChunkSignatureOptions): boolean;
56
+ export declare function computePaddingFooter(buffer: Buffer, derivedKeys: DerivedKeys): Buffer;
57
+ export declare function encryptBufferWithDerivedKeys(buffer: Buffer, derivedKeys: DerivedKeys): Buffer;
58
+ export declare function decryptBufferWithDerivedKeys(buffer: Buffer, derivedKeys: DerivedKeys): Buffer;
59
+ /**
60
+ * @method makeMessageChunkSignatureWithDerivedKeys
61
+ * @param message
62
+ * @param derivedKeys
63
+ * @return
64
+ */
65
+ export declare function makeMessageChunkSignatureWithDerivedKeys(message: Buffer, derivedKeys: DerivedKeys): Buffer;
66
+ /**
67
+ * @method verifyChunkSignatureWithDerivedKeys
68
+ * @param chunk
69
+ * @param derivedKeys
70
+ * @return
71
+ */
72
+ export declare function verifyChunkSignatureWithDerivedKeys(chunk: Buffer, derivedKeys: DerivedKeys): boolean;
@@ -1,249 +1,249 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.verifyChunkSignatureWithDerivedKeys = exports.makeMessageChunkSignatureWithDerivedKeys = exports.decryptBufferWithDerivedKeys = exports.encryptBufferWithDerivedKeys = exports.computePaddingFooter = exports.verifyChunkSignature = exports.removePadding = exports.reduceLength = exports.computeDerivedKeys = exports.makePseudoRandomBuffer = void 0;
4
- /**
5
- * @module node_opcua_crypto
6
- */
7
- const crypto = require("crypto");
8
- const buffer_utils_1 = require("./buffer_utils");
9
- const crypto_utils_1 = require("./crypto_utils");
10
- const explore_certificate_1 = require("./explore_certificate");
11
- const assert = require("assert");
12
- function HMAC_HASH(sha1or256, secret, message) {
13
- return crypto.createHmac(sha1or256, secret).update(message).digest();
14
- }
15
- function plus(buf1, buf2) {
16
- return Buffer.concat([buf1, buf2]);
17
- }
18
- // OPC-UA Spec 1.02 part 6 - 6.7.5 Deriving Keys page 42
19
- // Once the SecureChannel is established the Messages are signed and encrypted with keys derived
20
- // from the Nonces exchanged in t he OpenSecureChannel call. These keys are derived by passing the
21
- // Nonces to a pseudo - random function which produces a sequence of bytes from a set of inputs. A
22
- // pseudo- random function is represented by the following function declaration:
23
- // Byte[] PRF(
24
- // Byte[] secret,
25
- // Byte[] seed,
26
- // Int32 length,
27
- // Int32 offset
28
- // )
29
- // Where length is the number of bytes to return and offset is a number of bytes from the beginning of
30
- // the sequence.
31
- // The lengths of the keys that need to be generated depend on the SecurityPolicy used for the
32
- // channel. The following information is specified by the SecurityPolicy:
33
- // a) SigningKeyLength (from the DerivedSignatureKeyLength);
34
- // b) EncryptingKeyLength (implied by the SymmetricEncryptionAlgorithm);
35
- // c) EncryptingBlockSize (implied by the SymmetricEncryptionAlgorithm).
36
- // The parameters passed to the pseudo random function are specified in Table 36.
37
- // Table 36 - Cryptography Key Generation Parameters
38
- //
39
- // Key Secret Seed Length Offset
40
- // ClientSigningKey ServerNonce ClientNonce SigningKeyLength 0
41
- // ClientEncryptingKey ServerNonce ClientNonce EncryptingKeyLength SigningKeyLength
42
- // ClientInitializationVector ServerNonce ClientNonce EncryptingBlockSize SigningKeyLength+ EncryptingKeyLength
43
- // ServerSigningKey ClientNonce ServerNonce SigningKeyLength 0
44
- // ServerEncryptingKey ClientNonce ServerNonce EncryptingKeyLength SigningKeyLength
45
- // ServerInitializationVector ClientNonce ServerNonce EncryptingBlockSize SigningKeyLength+ EncryptingKeyLength
46
- //
47
- // The Client keys are used to secure Messages sent by the Client. The Server keys are used to
48
- // secure Messages sent by the Server.
49
- // The SSL/TLS specification defines a pseudo random function called P_HASH which is used for this purpose.
50
- //
51
- // The P_HASH algorithm is defined as follows:
52
- //
53
- // P_HASH(secret, seed) = HMAC_HASH(secret, A(1) + seed) +
54
- // HMAC_HASH(secret, A(2) + seed) +
55
- // HMAC_HASH(secret, A(3) + seed) + ...
56
- // Where A(n) is defined as:
57
- // A(0) = seed
58
- // A(n) = HMAC_HASH(secret, A(n-1))
59
- // + indicates that the results are appended to previous results.
60
- // Where HASH is a hash function such as SHA1 or SHA256. The hash function to use depends on the SecurityPolicyUri.
61
- //
62
- //
63
- // see also http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/ws-secureconversation-1.3-os.html
64
- // http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
65
- function makePseudoRandomBuffer(secret, seed, minLength, sha1or256) {
66
- assert(seed instanceof Buffer);
67
- assert(sha1or256 === "SHA1" || sha1or256 === "SHA256");
68
- const a = [];
69
- a[0] = seed;
70
- let index = 1;
71
- let p_hash = (0, buffer_utils_1.createFastUninitializedBuffer)(0);
72
- while (p_hash.length <= minLength) {
73
- /* eslint new-cap:0 */
74
- a[index] = HMAC_HASH(sha1or256, secret, a[index - 1]);
75
- p_hash = plus(p_hash, HMAC_HASH(sha1or256, secret, plus(a[index], seed)));
76
- index += 1;
77
- }
78
- return p_hash.slice(0, minLength);
79
- }
80
- exports.makePseudoRandomBuffer = makePseudoRandomBuffer;
81
- function computeDerivedKeys(secret, seed, options) {
82
- assert(Number.isFinite(options.signatureLength));
83
- assert(Number.isFinite(options.encryptingKeyLength));
84
- assert(Number.isFinite(options.encryptingBlockSize));
85
- assert(typeof options.algorithm === "string");
86
- options.sha1or256 = options.sha1or256 || "SHA1";
87
- assert(typeof options.sha1or256 === "string");
88
- const offset1 = options.signingKeyLength;
89
- const offset2 = offset1 + options.encryptingKeyLength;
90
- const minLength = offset2 + options.encryptingBlockSize;
91
- const buf = makePseudoRandomBuffer(secret, seed, minLength, options.sha1or256);
92
- // +---------------+---------------------+-----------------------+
93
- // + signingKey + encryptingKey + initializationVector +
94
- // +---------------+---------------------+-----------------------+
95
- return {
96
- signatureLength: options.signatureLength,
97
- signingKeyLength: options.signingKeyLength,
98
- encryptingKeyLength: options.encryptingKeyLength,
99
- encryptingBlockSize: options.encryptingBlockSize,
100
- algorithm: options.algorithm,
101
- sha1or256: options.sha1or256,
102
- signingKey: buf.slice(0, offset1),
103
- encryptingKey: buf.slice(offset1, offset2),
104
- initializationVector: buf.slice(offset2, minLength),
105
- };
106
- }
107
- exports.computeDerivedKeys = computeDerivedKeys;
108
- /**
109
- * @method reduceLength
110
- * @param buffer
111
- * @param byteToRemove
112
- * @return buffer
113
- */
114
- function reduceLength(buffer, byteToRemove) {
115
- return buffer.slice(0, buffer.length - byteToRemove);
116
- }
117
- exports.reduceLength = reduceLength;
118
- /**
119
- * @method removePadding
120
- * @param buffer
121
- * @return buffer with padding removed
122
- */
123
- function removePadding(buffer) {
124
- const nbPaddingBytes = buffer.readUInt8(buffer.length - 1) + 1;
125
- return reduceLength(buffer, nbPaddingBytes);
126
- }
127
- exports.removePadding = removePadding;
128
- /**
129
- * @method verifyChunkSignature
130
- *
131
- * const signer = {
132
- * signatureLength : 128,
133
- * algorithm : "RSA-SHA256",
134
- * public_key: "qsdqsdqsd"
135
- * };
136
- *
137
- * @param chunk The message chunk to verify.
138
- * @param options
139
- * @param options.signatureLength
140
- * @param options.algorithm the algorithm.
141
- * @param options.publicKey
142
- * @return {*}
143
- */
144
- function verifyChunkSignature(chunk, options) {
145
- assert(chunk instanceof Buffer);
146
- let signatureLength = options.signatureLength || 0;
147
- if (signatureLength === 0) {
148
- // let's get the signatureLength by checking the size
149
- // of the certificate's public key
150
- const cert = (0, explore_certificate_1.exploreCertificateInfo)(options.publicKey);
151
- signatureLength = cert.publicKeyLength || 0; // 1024 bits = 128Bytes or 2048=256Bytes
152
- }
153
- const block_to_verify = chunk.slice(0, chunk.length - signatureLength);
154
- const signature = chunk.slice(chunk.length - signatureLength);
155
- return (0, crypto_utils_1.verifyMessageChunkSignature)(block_to_verify, signature, options);
156
- }
157
- exports.verifyChunkSignature = verifyChunkSignature;
158
- // /**
159
- // * extract the public key from a certificate - using the pem module
160
- // *
161
- // * @method extractPublicKeyFromCertificate_WithPem
162
- // * @async
163
- // * @param certificate
164
- // * @param callback {Function}
165
- // * @param callback.err
166
- // * @param callback.publicKey as pem
167
- // */
168
- // exports.extractPublicKeyFromCertificate_WithPem = function (certificate, callback) {
169
- //
170
- // const err1 = new Error();
171
- // const cert_pem = crypto_utils.toPem(certificate, "CERTIFICATE");
172
- // require("pem").getPublicKey(cert_pem, function (err, data) {
173
- // if (err) {
174
- // console.log(err1.stack);
175
- // console.log(" CANNOT EXTRAT PUBLIC KEY from Certificate".red, certificate);
176
- // return callback(err);
177
- // }
178
- // callback(err, data.publicKey);
179
- // });
180
- // };
181
- //
182
- function computePaddingFooter(buffer, derivedKeys) {
183
- assert(Object.prototype.hasOwnProperty.call(derivedKeys, "encryptingBlockSize"));
184
- const paddingSize = derivedKeys.encryptingBlockSize - ((buffer.length + 1) % derivedKeys.encryptingBlockSize);
185
- const padding = (0, buffer_utils_1.createFastUninitializedBuffer)(paddingSize + 1);
186
- padding.fill(paddingSize);
187
- return padding;
188
- }
189
- exports.computePaddingFooter = computePaddingFooter;
190
- function derivedKeys_algorithm(derivedKeys) {
191
- assert(Object.prototype.hasOwnProperty.call(derivedKeys, "algorithm"));
192
- const algorithm = derivedKeys.algorithm || "aes-128-cbc";
193
- assert(algorithm === "aes-128-cbc" || algorithm === "aes-256-cbc");
194
- return algorithm;
195
- }
196
- function encryptBufferWithDerivedKeys(buffer, derivedKeys) {
197
- const algorithm = derivedKeys_algorithm(derivedKeys);
198
- const key = derivedKeys.encryptingKey;
199
- const initVector = derivedKeys.initializationVector;
200
- const cypher = crypto.createCipheriv(algorithm, key, initVector);
201
- cypher.setAutoPadding(false);
202
- const encrypted_chunks = [];
203
- encrypted_chunks.push(cypher.update(buffer));
204
- encrypted_chunks.push(cypher.final());
205
- return Buffer.concat(encrypted_chunks);
206
- }
207
- exports.encryptBufferWithDerivedKeys = encryptBufferWithDerivedKeys;
208
- function decryptBufferWithDerivedKeys(buffer, derivedKeys) {
209
- const algorithm = derivedKeys_algorithm(derivedKeys);
210
- const key = derivedKeys.encryptingKey;
211
- const initVector = derivedKeys.initializationVector;
212
- const cypher = crypto.createDecipheriv(algorithm, key, initVector);
213
- cypher.setAutoPadding(false);
214
- const decrypted_chunks = [];
215
- decrypted_chunks.push(cypher.update(buffer));
216
- decrypted_chunks.push(cypher.final());
217
- return Buffer.concat(decrypted_chunks);
218
- }
219
- exports.decryptBufferWithDerivedKeys = decryptBufferWithDerivedKeys;
220
- /**
221
- * @method makeMessageChunkSignatureWithDerivedKeys
222
- * @param message
223
- * @param derivedKeys
224
- * @return
225
- */
226
- function makeMessageChunkSignatureWithDerivedKeys(message, derivedKeys) {
227
- assert(message instanceof Buffer);
228
- assert(derivedKeys.signingKey instanceof Buffer);
229
- assert(typeof derivedKeys.sha1or256 === "string");
230
- assert(derivedKeys.sha1or256 === "SHA1" || derivedKeys.sha1or256 === "SHA256");
231
- const signature = crypto.createHmac(derivedKeys.sha1or256, derivedKeys.signingKey).update(message).digest();
232
- assert(signature.length === derivedKeys.signatureLength);
233
- return signature;
234
- }
235
- exports.makeMessageChunkSignatureWithDerivedKeys = makeMessageChunkSignatureWithDerivedKeys;
236
- /**
237
- * @method verifyChunkSignatureWithDerivedKeys
238
- * @param chunk
239
- * @param derivedKeys
240
- * @return
241
- */
242
- function verifyChunkSignatureWithDerivedKeys(chunk, derivedKeys) {
243
- const message = chunk.slice(0, chunk.length - derivedKeys.signatureLength);
244
- const signature = chunk.slice(chunk.length - derivedKeys.signatureLength);
245
- const verif = makeMessageChunkSignatureWithDerivedKeys(message, derivedKeys);
246
- return verif.toString("hex") === signature.toString("hex");
247
- }
248
- exports.verifyChunkSignatureWithDerivedKeys = verifyChunkSignatureWithDerivedKeys;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyChunkSignatureWithDerivedKeys = exports.makeMessageChunkSignatureWithDerivedKeys = exports.decryptBufferWithDerivedKeys = exports.encryptBufferWithDerivedKeys = exports.computePaddingFooter = exports.verifyChunkSignature = exports.removePadding = exports.reduceLength = exports.computeDerivedKeys = exports.makePseudoRandomBuffer = void 0;
4
+ /**
5
+ * @module node_opcua_crypto
6
+ */
7
+ const crypto = require("crypto");
8
+ const buffer_utils_1 = require("./buffer_utils");
9
+ const crypto_utils_1 = require("./crypto_utils");
10
+ const explore_certificate_1 = require("./explore_certificate");
11
+ const assert = require("assert");
12
+ function HMAC_HASH(sha1or256, secret, message) {
13
+ return crypto.createHmac(sha1or256, secret).update(message).digest();
14
+ }
15
+ function plus(buf1, buf2) {
16
+ return Buffer.concat([buf1, buf2]);
17
+ }
18
+ // OPC-UA Spec 1.02 part 6 - 6.7.5 Deriving Keys page 42
19
+ // Once the SecureChannel is established the Messages are signed and encrypted with keys derived
20
+ // from the Nonces exchanged in t he OpenSecureChannel call. These keys are derived by passing the
21
+ // Nonces to a pseudo - random function which produces a sequence of bytes from a set of inputs. A
22
+ // pseudo- random function is represented by the following function declaration:
23
+ // Byte[] PRF(
24
+ // Byte[] secret,
25
+ // Byte[] seed,
26
+ // Int32 length,
27
+ // Int32 offset
28
+ // )
29
+ // Where length is the number of bytes to return and offset is a number of bytes from the beginning of
30
+ // the sequence.
31
+ // The lengths of the keys that need to be generated depend on the SecurityPolicy used for the
32
+ // channel. The following information is specified by the SecurityPolicy:
33
+ // a) SigningKeyLength (from the DerivedSignatureKeyLength);
34
+ // b) EncryptingKeyLength (implied by the SymmetricEncryptionAlgorithm);
35
+ // c) EncryptingBlockSize (implied by the SymmetricEncryptionAlgorithm).
36
+ // The parameters passed to the pseudo random function are specified in Table 36.
37
+ // Table 36 - Cryptography Key Generation Parameters
38
+ //
39
+ // Key Secret Seed Length Offset
40
+ // ClientSigningKey ServerNonce ClientNonce SigningKeyLength 0
41
+ // ClientEncryptingKey ServerNonce ClientNonce EncryptingKeyLength SigningKeyLength
42
+ // ClientInitializationVector ServerNonce ClientNonce EncryptingBlockSize SigningKeyLength+ EncryptingKeyLength
43
+ // ServerSigningKey ClientNonce ServerNonce SigningKeyLength 0
44
+ // ServerEncryptingKey ClientNonce ServerNonce EncryptingKeyLength SigningKeyLength
45
+ // ServerInitializationVector ClientNonce ServerNonce EncryptingBlockSize SigningKeyLength+ EncryptingKeyLength
46
+ //
47
+ // The Client keys are used to secure Messages sent by the Client. The Server keys are used to
48
+ // secure Messages sent by the Server.
49
+ // The SSL/TLS specification defines a pseudo random function called P_HASH which is used for this purpose.
50
+ //
51
+ // The P_HASH algorithm is defined as follows:
52
+ //
53
+ // P_HASH(secret, seed) = HMAC_HASH(secret, A(1) + seed) +
54
+ // HMAC_HASH(secret, A(2) + seed) +
55
+ // HMAC_HASH(secret, A(3) + seed) + ...
56
+ // Where A(n) is defined as:
57
+ // A(0) = seed
58
+ // A(n) = HMAC_HASH(secret, A(n-1))
59
+ // + indicates that the results are appended to previous results.
60
+ // Where HASH is a hash function such as SHA1 or SHA256. The hash function to use depends on the SecurityPolicyUri.
61
+ //
62
+ //
63
+ // see also http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/ws-secureconversation-1.3-os.html
64
+ // http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
65
+ function makePseudoRandomBuffer(secret, seed, minLength, sha1or256) {
66
+ assert(seed instanceof Buffer);
67
+ assert(sha1or256 === "SHA1" || sha1or256 === "SHA256");
68
+ const a = [];
69
+ a[0] = seed;
70
+ let index = 1;
71
+ let p_hash = (0, buffer_utils_1.createFastUninitializedBuffer)(0);
72
+ while (p_hash.length <= minLength) {
73
+ /* eslint new-cap:0 */
74
+ a[index] = HMAC_HASH(sha1or256, secret, a[index - 1]);
75
+ p_hash = plus(p_hash, HMAC_HASH(sha1or256, secret, plus(a[index], seed)));
76
+ index += 1;
77
+ }
78
+ return p_hash.slice(0, minLength);
79
+ }
80
+ exports.makePseudoRandomBuffer = makePseudoRandomBuffer;
81
+ function computeDerivedKeys(secret, seed, options) {
82
+ assert(Number.isFinite(options.signatureLength));
83
+ assert(Number.isFinite(options.encryptingKeyLength));
84
+ assert(Number.isFinite(options.encryptingBlockSize));
85
+ assert(typeof options.algorithm === "string");
86
+ options.sha1or256 = options.sha1or256 || "SHA1";
87
+ assert(typeof options.sha1or256 === "string");
88
+ const offset1 = options.signingKeyLength;
89
+ const offset2 = offset1 + options.encryptingKeyLength;
90
+ const minLength = offset2 + options.encryptingBlockSize;
91
+ const buf = makePseudoRandomBuffer(secret, seed, minLength, options.sha1or256);
92
+ // +---------------+---------------------+-----------------------+
93
+ // + signingKey + encryptingKey + initializationVector +
94
+ // +---------------+---------------------+-----------------------+
95
+ return {
96
+ signatureLength: options.signatureLength,
97
+ signingKeyLength: options.signingKeyLength,
98
+ encryptingKeyLength: options.encryptingKeyLength,
99
+ encryptingBlockSize: options.encryptingBlockSize,
100
+ algorithm: options.algorithm,
101
+ sha1or256: options.sha1or256,
102
+ signingKey: buf.slice(0, offset1),
103
+ encryptingKey: buf.slice(offset1, offset2),
104
+ initializationVector: buf.slice(offset2, minLength),
105
+ };
106
+ }
107
+ exports.computeDerivedKeys = computeDerivedKeys;
108
+ /**
109
+ * @method reduceLength
110
+ * @param buffer
111
+ * @param byteToRemove
112
+ * @return buffer
113
+ */
114
+ function reduceLength(buffer, byteToRemove) {
115
+ return buffer.slice(0, buffer.length - byteToRemove);
116
+ }
117
+ exports.reduceLength = reduceLength;
118
+ /**
119
+ * @method removePadding
120
+ * @param buffer
121
+ * @return buffer with padding removed
122
+ */
123
+ function removePadding(buffer) {
124
+ const nbPaddingBytes = buffer.readUInt8(buffer.length - 1) + 1;
125
+ return reduceLength(buffer, nbPaddingBytes);
126
+ }
127
+ exports.removePadding = removePadding;
128
+ /**
129
+ * @method verifyChunkSignature
130
+ *
131
+ * const signer = {
132
+ * signatureLength : 128,
133
+ * algorithm : "RSA-SHA256",
134
+ * public_key: "qsdqsdqsd"
135
+ * };
136
+ *
137
+ * @param chunk The message chunk to verify.
138
+ * @param options
139
+ * @param options.signatureLength
140
+ * @param options.algorithm the algorithm.
141
+ * @param options.publicKey
142
+ * @return {*}
143
+ */
144
+ function verifyChunkSignature(chunk, options) {
145
+ assert(chunk instanceof Buffer);
146
+ let signatureLength = options.signatureLength || 0;
147
+ if (signatureLength === 0) {
148
+ // let's get the signatureLength by checking the size
149
+ // of the certificate's public key
150
+ const cert = (0, explore_certificate_1.exploreCertificateInfo)(options.publicKey);
151
+ signatureLength = cert.publicKeyLength || 0; // 1024 bits = 128Bytes or 2048=256Bytes
152
+ }
153
+ const block_to_verify = chunk.slice(0, chunk.length - signatureLength);
154
+ const signature = chunk.slice(chunk.length - signatureLength);
155
+ return (0, crypto_utils_1.verifyMessageChunkSignature)(block_to_verify, signature, options);
156
+ }
157
+ exports.verifyChunkSignature = verifyChunkSignature;
158
+ // /**
159
+ // * extract the public key from a certificate - using the pem module
160
+ // *
161
+ // * @method extractPublicKeyFromCertificate_WithPem
162
+ // * @async
163
+ // * @param certificate
164
+ // * @param callback {Function}
165
+ // * @param callback.err
166
+ // * @param callback.publicKey as pem
167
+ // */
168
+ // exports.extractPublicKeyFromCertificate_WithPem = function (certificate, callback) {
169
+ //
170
+ // const err1 = new Error();
171
+ // const cert_pem = crypto_utils.toPem(certificate, "CERTIFICATE");
172
+ // require("pem").getPublicKey(cert_pem, function (err, data) {
173
+ // if (err) {
174
+ // console.log(err1.stack);
175
+ // console.log(" CANNOT EXTRAT PUBLIC KEY from Certificate".red, certificate);
176
+ // return callback(err);
177
+ // }
178
+ // callback(err, data.publicKey);
179
+ // });
180
+ // };
181
+ //
182
+ function computePaddingFooter(buffer, derivedKeys) {
183
+ assert(Object.prototype.hasOwnProperty.call(derivedKeys, "encryptingBlockSize"));
184
+ const paddingSize = derivedKeys.encryptingBlockSize - ((buffer.length + 1) % derivedKeys.encryptingBlockSize);
185
+ const padding = (0, buffer_utils_1.createFastUninitializedBuffer)(paddingSize + 1);
186
+ padding.fill(paddingSize);
187
+ return padding;
188
+ }
189
+ exports.computePaddingFooter = computePaddingFooter;
190
+ function derivedKeys_algorithm(derivedKeys) {
191
+ assert(Object.prototype.hasOwnProperty.call(derivedKeys, "algorithm"));
192
+ const algorithm = derivedKeys.algorithm || "aes-128-cbc";
193
+ assert(algorithm === "aes-128-cbc" || algorithm === "aes-256-cbc");
194
+ return algorithm;
195
+ }
196
+ function encryptBufferWithDerivedKeys(buffer, derivedKeys) {
197
+ const algorithm = derivedKeys_algorithm(derivedKeys);
198
+ const key = derivedKeys.encryptingKey;
199
+ const initVector = derivedKeys.initializationVector;
200
+ const cypher = crypto.createCipheriv(algorithm, key, initVector);
201
+ cypher.setAutoPadding(false);
202
+ const encrypted_chunks = [];
203
+ encrypted_chunks.push(cypher.update(buffer));
204
+ encrypted_chunks.push(cypher.final());
205
+ return Buffer.concat(encrypted_chunks);
206
+ }
207
+ exports.encryptBufferWithDerivedKeys = encryptBufferWithDerivedKeys;
208
+ function decryptBufferWithDerivedKeys(buffer, derivedKeys) {
209
+ const algorithm = derivedKeys_algorithm(derivedKeys);
210
+ const key = derivedKeys.encryptingKey;
211
+ const initVector = derivedKeys.initializationVector;
212
+ const cypher = crypto.createDecipheriv(algorithm, key, initVector);
213
+ cypher.setAutoPadding(false);
214
+ const decrypted_chunks = [];
215
+ decrypted_chunks.push(cypher.update(buffer));
216
+ decrypted_chunks.push(cypher.final());
217
+ return Buffer.concat(decrypted_chunks);
218
+ }
219
+ exports.decryptBufferWithDerivedKeys = decryptBufferWithDerivedKeys;
220
+ /**
221
+ * @method makeMessageChunkSignatureWithDerivedKeys
222
+ * @param message
223
+ * @param derivedKeys
224
+ * @return
225
+ */
226
+ function makeMessageChunkSignatureWithDerivedKeys(message, derivedKeys) {
227
+ assert(message instanceof Buffer);
228
+ assert(derivedKeys.signingKey instanceof Buffer);
229
+ assert(typeof derivedKeys.sha1or256 === "string");
230
+ assert(derivedKeys.sha1or256 === "SHA1" || derivedKeys.sha1or256 === "SHA256");
231
+ const signature = crypto.createHmac(derivedKeys.sha1or256, derivedKeys.signingKey).update(message).digest();
232
+ assert(signature.length === derivedKeys.signatureLength);
233
+ return signature;
234
+ }
235
+ exports.makeMessageChunkSignatureWithDerivedKeys = makeMessageChunkSignatureWithDerivedKeys;
236
+ /**
237
+ * @method verifyChunkSignatureWithDerivedKeys
238
+ * @param chunk
239
+ * @param derivedKeys
240
+ * @return
241
+ */
242
+ function verifyChunkSignatureWithDerivedKeys(chunk, derivedKeys) {
243
+ const message = chunk.slice(0, chunk.length - derivedKeys.signatureLength);
244
+ const signature = chunk.slice(chunk.length - derivedKeys.signatureLength);
245
+ const verif = makeMessageChunkSignatureWithDerivedKeys(message, derivedKeys);
246
+ return verif.toString("hex") === signature.toString("hex");
247
+ }
248
+ exports.verifyChunkSignatureWithDerivedKeys = verifyChunkSignatureWithDerivedKeys;
249
249
  //# sourceMappingURL=derived_keys.js.map