1// Flags: --experimental-global-webcrypto
2'use strict';
3
4const common = require('../common');
5
6if (!common.hasCrypto)
7  common.skip('missing crypto');
8
9const assert = require('assert');
10
11// Test CryptoKey constructor
12{
13  assert.throws(() => new CryptoKey(), {
14    name: 'TypeError', message: 'Illegal constructor', code: 'ERR_ILLEGAL_CONSTRUCTOR'
15  });
16}
17
18// Test SubtleCrypto constructor
19{
20  assert.throws(() => new SubtleCrypto(), {
21    name: 'TypeError', message: 'Illegal constructor', code: 'ERR_ILLEGAL_CONSTRUCTOR'
22  });
23}
24
25// Test Crypto constructor
26{
27  assert.throws(() => new Crypto(), {
28    name: 'TypeError', message: 'Illegal constructor', code: 'ERR_ILLEGAL_CONSTRUCTOR'
29  });
30}
31
32const notCrypto = Reflect.construct(function() {}, [], Crypto);
33const notSubtle = Reflect.construct(function() {}, [], SubtleCrypto);
34
35// Test Crypto.prototype.subtle
36{
37  assert.throws(() => notCrypto.subtle, {
38    name: 'TypeError', code: 'ERR_INVALID_THIS',
39  });
40}
41
42// Test Crypto.prototype.randomUUID
43{
44  assert.throws(() => notCrypto.randomUUID(), {
45    name: 'TypeError', code: 'ERR_INVALID_THIS',
46  });
47}
48
49// Test Crypto.prototype.getRandomValues
50{
51  assert.throws(() => notCrypto.getRandomValues(new Uint8Array(12)), {
52    name: 'TypeError', code: 'ERR_INVALID_THIS',
53  });
54}
55
56// Test SubtleCrypto.prototype.encrypt
57{
58  assert.rejects(() => notSubtle.encrypt(), {
59    name: 'TypeError', code: 'ERR_INVALID_THIS',
60  }).then(common.mustCall());
61}
62
63// Test SubtleCrypto.prototype.decrypt
64{
65  assert.rejects(() => notSubtle.decrypt(), {
66    name: 'TypeError', code: 'ERR_INVALID_THIS',
67  }).then(common.mustCall());
68}
69
70// Test SubtleCrypto.prototype.sign
71{
72  assert.rejects(() => notSubtle.sign(), {
73    name: 'TypeError', code: 'ERR_INVALID_THIS',
74  }).then(common.mustCall());
75}
76
77// Test SubtleCrypto.prototype.verify
78{
79  assert.rejects(() => notSubtle.verify(), {
80    name: 'TypeError', code: 'ERR_INVALID_THIS',
81  }).then(common.mustCall());
82}
83
84// Test SubtleCrypto.prototype.digest
85{
86  assert.rejects(() => notSubtle.digest(), {
87    name: 'TypeError', code: 'ERR_INVALID_THIS',
88  }).then(common.mustCall());
89}
90
91// Test SubtleCrypto.prototype.generateKey
92{
93  assert.rejects(() => notSubtle.generateKey(), {
94    name: 'TypeError', code: 'ERR_INVALID_THIS',
95  }).then(common.mustCall());
96}
97
98// Test SubtleCrypto.prototype.deriveKey
99{
100  assert.rejects(() => notSubtle.deriveKey(), {
101    name: 'TypeError', code: 'ERR_INVALID_THIS',
102  }).then(common.mustCall());
103}
104
105// Test SubtleCrypto.prototype.deriveBits
106{
107  assert.rejects(() => notSubtle.deriveBits(), {
108    name: 'TypeError', code: 'ERR_INVALID_THIS',
109  }).then(common.mustCall());
110}
111
112// Test SubtleCrypto.prototype.importKey
113{
114  assert.rejects(() => notSubtle.importKey(), {
115    name: 'TypeError', code: 'ERR_INVALID_THIS',
116  }).then(common.mustCall());
117}
118
119// Test SubtleCrypto.prototype.exportKey
120{
121  assert.rejects(() => notSubtle.exportKey(), {
122    name: 'TypeError', code: 'ERR_INVALID_THIS',
123  }).then(common.mustCall());
124}
125
126// Test SubtleCrypto.prototype.wrapKey
127{
128  assert.rejects(() => notSubtle.wrapKey(), {
129    name: 'TypeError', code: 'ERR_INVALID_THIS',
130  }).then(common.mustCall());
131}
132
133// Test SubtleCrypto.prototype.unwrapKey
134{
135  assert.rejects(() => notSubtle.unwrapKey(), {
136    name: 'TypeError', code: 'ERR_INVALID_THIS',
137  }).then(common.mustCall());
138}
139
140{
141  globalThis.crypto.subtle.importKey(
142    'raw',
143    globalThis.crypto.getRandomValues(new Uint8Array(4)),
144    'PBKDF2',
145    false,
146    ['deriveKey'],
147  ).then((key) => {
148    globalThis.crypto.subtle.importKey = common.mustNotCall();
149    return globalThis.crypto.subtle.deriveKey({
150      name: 'PBKDF2',
151      hash: 'SHA-512',
152      salt: globalThis.crypto.getRandomValues(new Uint8Array()),
153      iterations: 5,
154    }, key, {
155      name: 'AES-GCM',
156      length: 256
157    }, true, ['encrypt', 'decrypt']);
158  }).then(common.mustCall());
159}
160