1'use strict'; 2 3const common = require('../common'); 4 5if (!common.hasCrypto) 6 common.skip('missing crypto'); 7 8const assert = require('assert'); 9const { subtle } = require('crypto').webcrypto; 10 11const rsa_pkcs = require('../fixtures/crypto/rsa_pkcs'); 12const rsa_pss = require('../fixtures/crypto/rsa_pss'); 13 14async function testVerify({ 15 algorithm, 16 hash, 17 publicKeyBuffer, 18 privateKeyBuffer, 19 signature, 20 plaintext, 21}) { 22 const [ 23 publicKey, 24 noVerifyPublicKey, 25 privateKey, 26 hmacKey, 27 ecdsaKeys, 28 ] = await Promise.all([ 29 subtle.importKey( 30 'spki', 31 publicKeyBuffer, 32 { name: algorithm.name, hash }, 33 false, 34 ['verify']), 35 subtle.importKey( 36 'spki', 37 publicKeyBuffer, 38 { name: algorithm.name, hash }, 39 false, 40 [ /* No usages */ ]), 41 subtle.importKey( 42 'pkcs8', 43 privateKeyBuffer, 44 { name: algorithm.name, hash }, 45 false, 46 ['sign']), 47 subtle.generateKey( 48 { name: 'HMAC', hash: 'SHA-256' }, 49 false, 50 ['sign']), 51 subtle.generateKey( 52 { 53 name: 'ECDSA', 54 namedCurve: 'P-521', 55 hash: 'SHA-256', 56 }, 57 false, 58 ['sign']), 59 ]); 60 61 assert(await subtle.verify(algorithm, publicKey, signature, plaintext)); 62 63 // Test verification with altered buffers 64 const copy = Buffer.from(plaintext); 65 const sigcopy = Buffer.from(signature); 66 const p = subtle.verify(algorithm, publicKey, sigcopy, copy); 67 copy[0] = 255 - copy[0]; 68 sigcopy[0] = 255 - sigcopy[0]; 69 assert(await p); 70 71 // Test failure when using wrong key 72 await assert.rejects( 73 subtle.verify(algorithm, privateKey, signature, plaintext), { 74 message: /Unable to use this key to verify/ 75 }); 76 77 await assert.rejects( 78 subtle.verify(algorithm, noVerifyPublicKey, signature, plaintext), { 79 message: /Unable to use this key to verify/ 80 }); 81 82 // Test failure when using the wrong algorithms 83 await assert.rejects( 84 subtle.verify(algorithm, hmacKey, signature, plaintext), { 85 message: /Unable to use this key to verify/ 86 }); 87 88 await assert.rejects( 89 subtle.verify(algorithm, ecdsaKeys.publicKey, signature, plaintext), { 90 message: /Unable to use this key to verify/ 91 }); 92 93 // Test failure when signature is altered 94 { 95 const copy = Buffer.from(signature); 96 copy[0] = 255 - copy[0]; 97 assert(!(await subtle.verify(algorithm, publicKey, copy, plaintext))); 98 assert(!(await subtle.verify( 99 algorithm, 100 publicKey, 101 copy.slice(1), 102 plaintext))); 103 } 104 105 // Test failure when data is altered 106 { 107 const copy = Buffer.from(plaintext); 108 copy[0] = 255 - copy[0]; 109 assert(!(await subtle.verify(algorithm, publicKey, signature, copy))); 110 } 111 112 // Test failure when wrong hash is used 113 { 114 const otherhash = hash === 'SHA-1' ? 'SHA-256' : 'SHA-1'; 115 const keyWithOtherHash = await subtle.importKey( 116 'spki', 117 publicKeyBuffer, 118 { name: algorithm.name, hash: otherhash }, 119 false, 120 ['verify']); 121 assert(!(await subtle.verify(algorithm, keyWithOtherHash, signature, plaintext))); 122 } 123} 124 125async function testSign({ 126 algorithm, 127 hash, 128 publicKeyBuffer, 129 privateKeyBuffer, 130 signature, 131 plaintext, 132}) { 133 const [ 134 publicKey, 135 privateKey, 136 hmacKey, 137 ecdsaKeys, 138 ] = await Promise.all([ 139 subtle.importKey( 140 'spki', 141 publicKeyBuffer, 142 { name: algorithm.name, hash }, 143 false, 144 ['verify']), 145 subtle.importKey( 146 'pkcs8', 147 privateKeyBuffer, 148 { name: algorithm.name, hash }, 149 false, 150 ['sign']), 151 subtle.generateKey( 152 { name: 'HMAC', hash: 'SHA-256' }, 153 false, 154 ['sign']), 155 subtle.generateKey( 156 { 157 name: 'ECDSA', 158 namedCurve: 'P-521', 159 hash: 'SHA-256', 160 }, 161 false, 162 ['sign']), 163 ]); 164 165 { 166 const sig = await subtle.sign(algorithm, privateKey, plaintext); 167 assert.strictEqual(sig.byteLength, signature.byteLength); 168 assert(await subtle.verify(algorithm, publicKey, sig, plaintext)); 169 } 170 171 { 172 const copy = Buffer.from(plaintext); 173 const p = subtle.sign(algorithm, privateKey, copy); 174 copy[0] = 255 - copy[0]; 175 const sig = await p; 176 assert(await subtle.verify(algorithm, publicKey, sig, plaintext)); 177 } 178 179 // Test failure when using wrong key 180 await assert.rejects( 181 subtle.sign(algorithm, publicKey, plaintext), { 182 message: /Unable to use this key to sign/ 183 }); 184 185 // Test failure when using the wrong algorithms 186 await assert.rejects( 187 subtle.sign(algorithm, hmacKey, plaintext), { 188 message: /Unable to use this key to sign/ 189 }); 190 191 await assert.rejects( 192 subtle.sign(algorithm, ecdsaKeys.privateKey, plaintext), { 193 message: /Unable to use this key to sign/ 194 }); 195} 196 197(async function() { 198 const variations = []; 199 200 rsa_pkcs().forEach((vector) => { 201 variations.push(testVerify(vector)); 202 variations.push(testSign(vector)); 203 }); 204 rsa_pss().forEach((vector) => { 205 variations.push(testVerify(vector)); 206 variations.push(testSign(vector)); 207 }); 208 209 await Promise.all(variations); 210})().then(common.mustCall()); 211