• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22// Note: In 0.8 and before, crypto functions all defaulted to using
23// binary-encoded strings rather than buffers.
24
25'use strict';
26
27const {
28  ObjectDefineProperty,
29  ObjectDefineProperties,
30} = primordials;
31
32const {
33  assertCrypto,
34  deprecate,
35} = require('internal/util');
36assertCrypto();
37
38const {
39  ERR_CRYPTO_FIPS_FORCED,
40} = require('internal/errors').codes;
41const constants = internalBinding('constants').crypto;
42const { getOptionValue } = require('internal/options');
43const {
44  getFipsCrypto,
45  setFipsCrypto,
46  timingSafeEqual,
47} = internalBinding('crypto');
48const {
49  checkPrime,
50  checkPrimeSync,
51  generatePrime,
52  generatePrimeSync,
53  randomBytes,
54  randomFill,
55  randomFillSync,
56  randomInt,
57  randomUUID,
58} = require('internal/crypto/random');
59const {
60  pbkdf2,
61  pbkdf2Sync,
62} = require('internal/crypto/pbkdf2');
63const {
64  scrypt,
65  scryptSync,
66} = require('internal/crypto/scrypt');
67const {
68  hkdf,
69  hkdfSync,
70} = require('internal/crypto/hkdf');
71const {
72  generateKeyPair,
73  generateKeyPairSync,
74  generateKey,
75  generateKeySync,
76} = require('internal/crypto/keygen');
77const {
78  createSecretKey,
79  createPublicKey,
80  createPrivateKey,
81  KeyObject,
82} = require('internal/crypto/keys');
83const {
84  DiffieHellman,
85  DiffieHellmanGroup,
86  ECDH,
87  diffieHellman,
88} = require('internal/crypto/diffiehellman');
89const {
90  Cipher,
91  Cipheriv,
92  Decipher,
93  Decipheriv,
94  privateDecrypt,
95  privateEncrypt,
96  publicDecrypt,
97  publicEncrypt,
98  getCipherInfo,
99} = require('internal/crypto/cipher');
100const {
101  Sign,
102  signOneShot,
103  Verify,
104  verifyOneShot,
105} = require('internal/crypto/sig');
106const {
107  Hash,
108  Hmac,
109} = require('internal/crypto/hash');
110const {
111  X509Certificate,
112} = require('internal/crypto/x509');
113const {
114  getCiphers,
115  getCurves,
116  getDefaultEncoding,
117  getHashes,
118  setDefaultEncoding,
119  setEngine,
120  secureHeapUsed,
121} = require('internal/crypto/util');
122const Certificate = require('internal/crypto/certificate');
123
124let webcrypto;
125function lazyWebCrypto() {
126  webcrypto ??= require('internal/crypto/webcrypto');
127  return webcrypto;
128}
129
130// These helper functions are needed because the constructors can
131// use new, in which case V8 cannot inline the recursive constructor call
132function createHash(algorithm, options) {
133  return new Hash(algorithm, options);
134}
135
136function createCipher(cipher, password, options) {
137  return new Cipher(cipher, password, options);
138}
139
140function createCipheriv(cipher, key, iv, options) {
141  return new Cipheriv(cipher, key, iv, options);
142}
143
144function createDecipher(cipher, password, options) {
145  return new Decipher(cipher, password, options);
146}
147
148function createDecipheriv(cipher, key, iv, options) {
149  return new Decipheriv(cipher, key, iv, options);
150}
151
152function createDiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) {
153  return new DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding);
154}
155
156function createDiffieHellmanGroup(name) {
157  return new DiffieHellmanGroup(name);
158}
159
160function createECDH(curve) {
161  return new ECDH(curve);
162}
163
164function createHmac(hmac, key, options) {
165  return new Hmac(hmac, key, options);
166}
167
168function createSign(algorithm, options) {
169  return new Sign(algorithm, options);
170}
171
172function createVerify(algorithm, options) {
173  return new Verify(algorithm, options);
174}
175
176module.exports = {
177  // Methods
178  checkPrime,
179  checkPrimeSync,
180  createCipheriv,
181  createDecipheriv,
182  createDiffieHellman,
183  createDiffieHellmanGroup,
184  createECDH,
185  createHash,
186  createHmac,
187  createPrivateKey,
188  createPublicKey,
189  createSecretKey,
190  createSign,
191  createVerify,
192  diffieHellman,
193  generatePrime,
194  generatePrimeSync,
195  getCiphers,
196  getCipherInfo,
197  getCurves,
198  getDiffieHellman: createDiffieHellmanGroup,
199  getHashes,
200  hkdf,
201  hkdfSync,
202  pbkdf2,
203  pbkdf2Sync,
204  generateKeyPair,
205  generateKeyPairSync,
206  generateKey,
207  generateKeySync,
208  privateDecrypt,
209  privateEncrypt,
210  publicDecrypt,
211  publicEncrypt,
212  randomBytes,
213  randomFill,
214  randomFillSync,
215  randomInt,
216  randomUUID,
217  scrypt,
218  scryptSync,
219  sign: signOneShot,
220  setEngine,
221  timingSafeEqual,
222  getFips,
223  setFips,
224  verify: verifyOneShot,
225
226  // Classes
227  Certificate,
228  Cipher,
229  Cipheriv,
230  Decipher,
231  Decipheriv,
232  DiffieHellman,
233  DiffieHellmanGroup,
234  ECDH,
235  Hash,
236  Hmac,
237  KeyObject,
238  Sign,
239  Verify,
240  X509Certificate,
241  secureHeapUsed,
242};
243
244function getFips() {
245  return getOptionValue('--force-fips') ? 1 : getFipsCrypto();
246}
247
248function setFips(val) {
249  if (getOptionValue('--force-fips')) {
250    if (val) return;
251    throw new ERR_CRYPTO_FIPS_FORCED();
252  } else {
253    setFipsCrypto(val);
254  }
255}
256
257function getRandomValues(array) {
258  return lazyWebCrypto().crypto.getRandomValues(array);
259}
260
261ObjectDefineProperty(constants, 'defaultCipherList', {
262  __proto__: null,
263  get() {
264    const value = getOptionValue('--tls-cipher-list');
265    ObjectDefineProperty(this, 'defaultCipherList', {
266      __proto__: null,
267      writable: true,
268      configurable: true,
269      enumerable: true,
270      value,
271    });
272    return value;
273  },
274  set(val) {
275    ObjectDefineProperty(this, 'defaultCipherList', {
276      __proto__: null,
277      writable: true,
278      configurable: true,
279      enumerable: true,
280      value: val,
281    });
282  },
283  configurable: true,
284  enumerable: true,
285});
286
287function getRandomBytesAlias(key) {
288  return {
289    enumerable: false,
290    configurable: true,
291    get() {
292      let value;
293      if (getOptionValue('--pending-deprecation')) {
294        value = deprecate(
295          randomBytes,
296          `crypto.${key} is deprecated.`,
297          'DEP0115');
298      } else {
299        value = randomBytes;
300      }
301      ObjectDefineProperty(
302        this,
303        key,
304        {
305          __proto__: null,
306          enumerable: false,
307          configurable: true,
308          writable: true,
309          value: value,
310        },
311      );
312      return value;
313    },
314    set(value) {
315      ObjectDefineProperty(
316        this,
317        key,
318        {
319          __proto__: null,
320          enumerable: true,
321          configurable: true,
322          writable: true,
323          value,
324        },
325      );
326    },
327  };
328}
329
330ObjectDefineProperties(module.exports, {
331  createCipher: {
332    __proto__: null,
333    enumerable: false,
334    value: deprecate(createCipher,
335                     'crypto.createCipher is deprecated.', 'DEP0106'),
336  },
337  createDecipher: {
338    __proto__: null,
339    enumerable: false,
340    value: deprecate(createDecipher,
341                     'crypto.createDecipher is deprecated.', 'DEP0106'),
342  },
343  // crypto.fips is deprecated. DEP0093. Use crypto.getFips()/crypto.setFips()
344  fips: {
345    __proto__: null,
346    get: getFips,
347    set: setFips,
348  },
349  DEFAULT_ENCODING: {
350    __proto__: null,
351    enumerable: false,
352    configurable: true,
353    get: deprecate(getDefaultEncoding,
354                   'crypto.DEFAULT_ENCODING is deprecated.', 'DEP0091'),
355    set: deprecate(setDefaultEncoding,
356                   'crypto.DEFAULT_ENCODING is deprecated.', 'DEP0091'),
357  },
358  constants: {
359    __proto__: null,
360    configurable: false,
361    enumerable: true,
362    value: constants,
363  },
364
365  webcrypto: {
366    __proto__: null,
367    configurable: false,
368    enumerable: true,
369    get() { return lazyWebCrypto().crypto; },
370    set: undefined,
371  },
372
373  subtle: {
374    __proto__: null,
375    configurable: false,
376    enumerable: true,
377    get() { return lazyWebCrypto().crypto.subtle; },
378    set: undefined,
379  },
380
381  getRandomValues: {
382    __proto__: null,
383    configurable: false,
384    enumerable: true,
385    get: () => getRandomValues,
386    set: undefined,
387  },
388
389  // Aliases for randomBytes are deprecated.
390  // The ecosystem needs those to exist for backwards compatibility.
391  prng: getRandomBytesAlias('prng'),
392  pseudoRandomBytes: getRandomBytesAlias('pseudoRandomBytes'),
393  rng: getRandomBytesAlias('rng'),
394});
395