|
1 | | -import { decryptAndVerifySignedData, encryptAndDetachSignData } from '../../../../src/tss/ecdsa-dkls/commsLayer'; |
| 1 | +import { |
| 2 | + decryptAndVerifySignedData, |
| 3 | + encryptAndDetachSignData, |
| 4 | + verifySignedData, |
| 5 | + SIGNATURE_DATE_TOLERANCE_MS, |
| 6 | +} from '../../../../src/tss/ecdsa-dkls/commsLayer'; |
2 | 7 | import * as openpgp from 'openpgp'; |
3 | 8 |
|
4 | 9 | describe('DKLS Communication Layer', function () { |
@@ -94,4 +99,69 @@ describe('DKLS Communication Layer', function () { |
94 | 99 | .toHex()}` |
95 | 100 | ); |
96 | 101 | }); |
| 102 | + |
| 103 | + describe('signature date tolerance', function () { |
| 104 | + it('should confirm tolerance constant is 24 hours', function () { |
| 105 | + SIGNATURE_DATE_TOLERANCE_MS.should.equal(24 * 60 * 60 * 1000); |
| 106 | + }); |
| 107 | + |
| 108 | + it('should reject encryption to an expired key', async function () { |
| 109 | + // Key created 48h ago with a 23h lifetime → expired 25h ago. |
| 110 | + const expiredKey = await openpgp.generateKey({ |
| 111 | + userIDs: [{ name: 'expired', email: 'expired@username.com' }], |
| 112 | + curve: 'secp256k1', |
| 113 | + date: new Date(Date.now() - 48 * 60 * 60 * 1000), |
| 114 | + keyExpirationTime: 23 * 3600, |
| 115 | + }); |
| 116 | + |
| 117 | + await encryptAndDetachSignData( |
| 118 | + Buffer.from('ffffffff', 'base64'), |
| 119 | + expiredKey.publicKey, |
| 120 | + senderKey.privateKey |
| 121 | + ).should.be.rejectedWith('Error encrypting message: Primary key is expired'); |
| 122 | + }); |
| 123 | + |
| 124 | + it('should accept verification of a signature created by a device whose clock is ahead', async function () { |
| 125 | + // Simulate a signature created by a device whose clock is 12 hours |
| 126 | + // ahead. The verify tolerance (now + 24h) should accept it. |
| 127 | + const futureDate = new Date(Date.now() + 12 * 60 * 60 * 1000); |
| 128 | + const message = await openpgp.createMessage({ binary: Buffer.from('ffffffff', 'base64') }); |
| 129 | + const privateKey = await openpgp.readPrivateKey({ armoredKey: senderKey.privateKey }); |
| 130 | + const signature = await openpgp.sign({ |
| 131 | + message, |
| 132 | + signingKeys: privateKey, |
| 133 | + format: 'armored', |
| 134 | + detached: true, |
| 135 | + date: futureDate, |
| 136 | + config: { rejectCurves: new Set(), showVersion: false, showComment: false }, |
| 137 | + }); |
| 138 | + |
| 139 | + const result = await verifySignedData( |
| 140 | + { message: Buffer.from('ffffffff', 'base64').toString('base64'), signature }, |
| 141 | + senderKey.publicKey |
| 142 | + ); |
| 143 | + result.should.equal(true); |
| 144 | + }); |
| 145 | + |
| 146 | + it('should reject verification of a signature created more than 24h in the future', async function () { |
| 147 | + // Simulate a signature from a device whose clock is 25 hours ahead. |
| 148 | + const farFutureDate = new Date(Date.now() + 25 * 60 * 60 * 1000); |
| 149 | + const message = await openpgp.createMessage({ binary: Buffer.from('ffffffff', 'base64') }); |
| 150 | + const privateKey = await openpgp.readPrivateKey({ armoredKey: senderKey.privateKey }); |
| 151 | + const signature = await openpgp.sign({ |
| 152 | + message, |
| 153 | + signingKeys: privateKey, |
| 154 | + format: 'armored', |
| 155 | + detached: true, |
| 156 | + date: farFutureDate, |
| 157 | + config: { rejectCurves: new Set(), showVersion: false, showComment: false }, |
| 158 | + }); |
| 159 | + |
| 160 | + const result = await verifySignedData( |
| 161 | + { message: Buffer.from('ffffffff', 'base64').toString('base64'), signature }, |
| 162 | + senderKey.publicKey |
| 163 | + ); |
| 164 | + result.should.equal(false); |
| 165 | + }); |
| 166 | + }); |
97 | 167 | }); |
0 commit comments