Skip to content
File

Blob: src/workerd/api/node/tests/crypto_spkac-test.js

javascript122 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4//
5// Adapted from Node.js. Copyright Joyent, Inc. and other Node contributors.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a
8// copy of this software and associated documentation files (the
9// "Software"), to deal in the Software without restriction, including
10// without limitation the rights to use, copy, modify, merge, publish,
11// distribute, sublicense, and/or sell copies of the Software, and to permit
12// persons to whom the Software is furnished to do so, subject to the
13// following conditions:
14//
15// The above copyright notice and this permission notice shall be included
16// in all copies or substantial portions of the Software.
17//
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
21// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24// USE OR OTHER DEALINGS IN THE SOFTWARE.
25 
26import { Buffer } from 'node:buffer';
27 
28import * as assert from 'node:assert';
29import { Certificate } from 'node:crypto';
30 
31const valid = Buffer.from(
32 'MIICUzCCATswggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC33FiIiiexwLe/P8DZx5HsqFlmUO7/lvJ7necJVNwqdZ3ax5jpQB0p6uxfqeOvzcN3k5V7UFb/Am+nkSNZMAZhsWzCU2Z4Pjh50QYz3f0Hour7/yIGStOLyYY3hgLK2K8TbhgjQPhdkw9+QtKlpvbL8fLgONAoGrVOFnRQGcr70iFffsm79mgZhKVMgYiHPJqJgGHvCtkGg9zMgS7p63+Q3ZWedtFS2RhMX3uCBy/mH6EOlRCNBbRmA4xxNzyf5GQaki3T+Iz9tOMjdPP+CwV2LqEdylmBuik8vrfTb3qIHLKKBAI8lXN26wWtA3kN4L7NP+cbKlCRlqctvhmylLH1AgMBAAEWE3RoaXMtaXMtYS1jaGFsbGVuZ2UwDQYJKoZIhvcNAQEEBQADggEBAIozmeW1kfDfAVwRQKileZGLRGCD7AjdHLYEe16xTBPve8Af1bDOyuWsAm4qQLYA4FAFROiKeGqxCtIErEvm87/09tCfF1My/1Uj+INjAk39DK9J9alLlTsrwSgd1lb3YlXY7TyitCmh7iXLo4pVhA2chNA3njiMq3CUpSvGbpzrESL2dv97lv590gUD988wkTDVyYsf0T8+X0Kww3AgPWGji+2f2i5/jTfD/s1lK1nqi7ZxFm0pGZoy1MJ51SCEy7Y82ajroI+5786nC02mo9ak7samca4YDZOoxN4d3tax4B/HDF5dqJSm1/31xYLDTfujCM5FkSjRc4m6hnriEkc='
33);
34 
35const invalid = Buffer.from(
36 'UzCCATswggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC33FiIiiexwLe/P8DZx5HsqFlmUO7/lvJ7necJVNwqdZ3ax5jpQB0p6uxfqeOvzcN3k5V7UFb/Am+nkSNZMAZhsWzCU2Z4Pjh50QYz3f0Hour7/yIGStOLyYY3hgLK2K8TbhgjQPhdkw9+QtKlpvbL8fLgONAoGrVOFnRQGcr70iFffsm79mgZhKVMgYiHPJqJgGHvCtkGg9zMgS7p63+Q3ZWedtFS2RhMX3uCBy/mH6EOlRCNBbRmA4xxNzyf5GQaki3T+Iz9tOMjdPP+CwV2LqEdylmBuik8vrfTb3qIHLKKBAI8lXN26wWtA3kN4L7NP+cbKlCRlqctvhmylLH1AgMBAAEWE3RoaXMtaXMtYS1jaGFsbGVuZ2UwDQYJKoZIhvcNAQEEBQADggEBAIozmeW1kfDfAVwRQKileZGLRGCD7AjdHLYEe16xTBPve8Af1bDOyuWsAm4qQLYA4FAFROiKeGqxCtIErEvm87/09tCfF1My/1Uj+INjAk39DK9J9alLlTsrwSgd1lb3YlXY7TyitCmh7iXLo4pVhA2chNA3njiMq3CUpSvGbpzrESL2dv97lv590gUD988wkTDVyYsf0T8+X0Kww3AgPWGji+2f2i5/jTfD/s1lK1nqi7ZxFm0pGZoy1MJ51SCEy7Y82ajroI+5786nC02mo9ak7samca4YDZOoxN4d3tax4B/HDF5dqJSm1/31xYLDTfujCM5FkSjRc4m6hnriEkc='
37);
38 
39const key = Buffer.from(`-----BEGIN PUBLIC KEY-----
40MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt9xYiIonscC3vz/A2ceR
417KhZZlDu/5bye53nCVTcKnWd2seY6UAdKersX6njr83Dd5OVe1BW/wJvp5EjWTAG
42YbFswlNmeD44edEGM939B6Lq+/8iBkrTi8mGN4YCytivE24YI0D4XZMPfkLSpab2
43y/Hy4DjQKBq1ThZ0UBnK+9IhX37Ju/ZoGYSlTIGIhzyaiYBh7wrZBoPczIEu6et/
44kN2VnnbRUtkYTF97ggcv5h+hDpUQjQW0ZgOMcTc8n+RkGpIt0/iM/bTjI3Tz/gsF
45di6hHcpZgbopPL630296iByyigQCPJVzdusFrQN5DeC+zT/nGypQkZanLb4ZspSx
469QIDAQAB
47-----END PUBLIC KEY-----`);
48 
49const challenge = 'this-is-a-challenge';
50 
51export const spkac = {
52 test() {
53 // In workerd, this following check works fine but in the internal
54 // system we prevent anyone from creating a TypedArray with this
55 // size... which means this check passes in workerd but fails internally,
56 // but in exactly the way we want. Just going to comment this out for now.
57 //
58 // const buf = new Uint8Array(2 ** 31);
59 // assert.throws(
60 // () => Certificate.verifySpkac(buf), {
61 // name: 'RangeError',
62 // });
63 // assert.throws(
64 // () => Certificate.exportChallenge(buf), {
65 // name: 'RangeError',
66 // });
67 // assert.throws(
68 // () => Certificate.exportPublicKey(buf), {
69 // name: 'RangeError',
70 // });
71 
72 // We should decide what we want to do here. The fact that we run
73 // with fips enabled and SPKAC requires using md5 has the digest
74 // for the signature means that verifySpkac will always fail since
75 // fips mode disables the ability to use md5 here. This check also
76 // fails in Node.js but there we have the options of disabling fips.
77 // assert.ok(Certificate.verifySpkac(valid));
78 assert.ok(!Certificate.verifySpkac(invalid));
79 
80 assert.strictEqual(
81 stripLineEndings(Certificate.exportPublicKey(valid).toString('utf8')),
82 stripLineEndings(key.toString('utf8'))
83 );
84 assert.strictEqual(
85 Certificate.exportPublicKey(invalid).toString('utf8'),
86 ''
87 );
88 
89 assert.strictEqual(
90 Certificate.exportChallenge(valid).toString('utf8'),
91 challenge
92 );
93 assert.strictEqual(
94 Certificate.exportChallenge(invalid).toString('utf8'),
95 ''
96 );
97 
98 const ab = copyArrayBuffer(key);
99 assert.ok(!Certificate.verifySpkac(ab));
100 assert.ok(!Certificate.verifySpkac(new Uint8Array(ab)));
101 assert.ok(!Certificate.verifySpkac(new DataView(ab)));
102 
103 assert.ok(Certificate() instanceof Certificate);
104 
105 const errObj = { code: 'ERR_INVALID_ARG_TYPE' };
106 
107 [1, {}, [], Infinity, true, undefined, null].forEach((val) => {
108 assert.throws(() => Certificate.verifySpkac(val), errObj);
109 assert.throws(() => Certificate.exportPublicKey(val), errObj);
110 assert.throws(() => Certificate.exportChallenge(val), errObj);
111 });
112 },
113};
114 
115function stripLineEndings(obj) {
116 return obj.replace(/\n/g, '');
117}
118 
119function copyArrayBuffer(buf) {
120 return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
121}