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