|
3 | 3 | * SPDX-License-Identifier: BSD-3-Clause |
4 | 4 | */ |
5 | 5 | import { |
6 | | - assertIssuedVc, |
7 | | - config, |
8 | | - createInitialVc, |
9 | | - createValidCredential, |
| 6 | + assertDataIntegrityProof, |
| 7 | + assertSecuredCredential |
| 8 | +} from './assertions.js'; |
| 9 | +import { |
| 10 | + baseCredential, |
10 | 11 | getProofs, |
11 | | - isValidDatetime, |
12 | | - isValidUtf8, |
| 12 | + secureCredential, |
13 | 13 | setupReportableTestSuite, |
14 | 14 | setupRow |
15 | 15 | } from './helpers.js'; |
| 16 | +import canonicalize from 'json-canon'; |
16 | 17 | import chai from 'chai'; |
17 | 18 | import {endpoints} from 'vc-test-suite-implementations'; |
| 19 | +import {expect} from 'chai'; |
18 | 20 |
|
19 | 21 | const should = chai.should(); |
20 | 22 |
|
21 | | -const cryptosuite = 'ecdsa-jcs-2019'; |
22 | | -const {tags} = config.suites[ |
23 | | - cryptosuite |
| 23 | +const cryptosuites = [ |
| 24 | + 'ecdsa-jcs-2019', |
24 | 25 | ]; |
| 26 | + |
25 | 27 | const {match: issuers} = endpoints.filterByTag({ |
26 | | - tags: [...tags], |
| 28 | + tags: cryptosuites, |
27 | 29 | property: 'issuers' |
28 | 30 | }); |
29 | 31 |
|
30 | | -describe('ecdsa-jcs-2019 - Algorithms - Create Proof', function() { |
31 | | - setupReportableTestSuite(this); |
32 | | - this.implemented = [...issuers.keys()]; |
33 | | - let validCredential; |
34 | | - before(async function() { |
35 | | - validCredential = await createValidCredential(); |
36 | | - }); |
37 | | - for(const [columnId, {endpoints}] of issuers) { |
38 | | - describe(columnId, function() { |
39 | | - const [issuer] = endpoints; |
40 | | - let issuedVc; |
41 | | - let proofs; |
42 | | - let filteredProofs = []; |
43 | | - before(async function() { |
44 | | - issuedVc = await createInitialVc({issuer, vc: validCredential}); |
45 | | - proofs = getProofs(issuedVc); |
46 | | - if(proofs?.length) { |
47 | | - filteredProofs = proofs.filter( |
48 | | - proof => proof?.cryptosuite === cryptosuite); |
49 | | - } |
50 | | - }); |
51 | | - beforeEach(setupRow); |
52 | | - it('If unsecuredDocument.@context is present, ' + |
53 | | - 'set proof.@context to unsecuredDocument.@context.', |
54 | | - async function() { |
55 | | - this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#create-proof-ecdsa-jcs-2019'; |
56 | | - assertIssuedVc(issuedVc, proofs, filteredProofs); |
57 | | - for(const proof of filteredProofs) { |
58 | | - proof.should.have('@context', |
59 | | - 'Expected proof to have context.'); |
60 | | - } |
61 | | - }); |
62 | | - }); |
63 | | - } |
64 | | -}); |
65 | | - |
66 | | -describe('ecdsa-jcs-2019 - Algorithms - Transformation', function() { |
67 | | - setupReportableTestSuite(this); |
68 | | - this.implemented = [...issuers.keys()]; |
69 | | - let validCredential; |
70 | | - before(async function() { |
71 | | - validCredential = await createValidCredential(); |
72 | | - }); |
73 | | - for(const [columnId, {endpoints}] of issuers) { |
74 | | - describe(columnId, function() { |
75 | | - const [issuer] = endpoints; |
76 | | - let issuedVc; |
77 | | - let proofs; |
78 | | - let filteredProofs = []; |
79 | | - before(async function() { |
80 | | - issuedVc = await createInitialVc({issuer, vc: validCredential}); |
81 | | - proofs = getProofs(issuedVc); |
82 | | - if(proofs?.length) { |
83 | | - filteredProofs = proofs.filter( |
84 | | - proof => proof?.cryptosuite === cryptosuite); |
85 | | - } |
86 | | - }); |
87 | | - beforeEach(setupRow); |
88 | | - it('The proof options MUST contain a type identifier for the ' + |
89 | | - 'cryptographic suite (type) and MAY contain a cryptosuite ' + |
90 | | - 'identifier (cryptosuite).', |
91 | | - async function() { |
92 | | - this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#proof-serialization-ecdsa-jcs-2019'; |
93 | | - assertIssuedVc(issuedVc, proofs, filteredProofs); |
94 | | - for(const proof of filteredProofs) { |
95 | | - should.exist(proof.type, |
96 | | - 'Expected a type identifier on the proof.'); |
97 | | - } |
98 | | - }); |
99 | | - it('The transformation options MUST contain a type identifier ' + |
100 | | - 'for the cryptographic suite (type) and a cryptosuite identifier ' + |
101 | | - '(cryptosuite).', |
102 | | - async function() { |
103 | | - this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#transformation-ecdsa-jcs-2019'; |
104 | | - assertIssuedVc(issuedVc, proofs, filteredProofs); |
105 | | - for(const proof of filteredProofs) { |
106 | | - should.exist(proof.type, 'Expected a type identifier on ' + |
107 | | - 'the proof.'); |
108 | | - should.exist(proof.cryptosuite, |
109 | | - 'Expected a cryptosuite identifier on the proof.'); |
110 | | - } |
111 | | - }); |
112 | | - it('Whenever this algorithm encodes strings, ' + |
113 | | - 'it MUST use UTF-8 encoding.', |
114 | | - async function() { |
115 | | - this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#transformation-ecdsa-jcs-2019'; |
116 | | - assertIssuedVc(issuedVc, proofs, filteredProofs); |
117 | | - for(const proof of filteredProofs) { |
118 | | - should.exist(proof?.proofValue, |
119 | | - 'Expected proofValue to exist.'); |
120 | | - isValidUtf8(proof.proofValue).should.equal( |
121 | | - true, |
122 | | - 'Expected proofValue value to be a valid UTF-8 encoded string.' |
123 | | - ); |
124 | | - } |
125 | | - }); |
126 | | - it('If options.type is not set to the string DataIntegrityProof or ' + |
127 | | - 'options.cryptosuite is not set to the string ecdsa-jcs-2019, ' + |
128 | | - 'an error MUST be raised and SHOULD convey an error type ' + |
129 | | - 'of PROOF_TRANSFORMATION_ERROR.', |
130 | | - async function() { |
131 | | - this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#transformation-ecdsa-jcs-2019'; |
132 | | - assertIssuedVc(issuedVc, proofs, filteredProofs); |
133 | | - for(const proof of filteredProofs) { |
134 | | - should.exist(proof.type, |
135 | | - 'Expected a type identifier on the proof.'); |
136 | | - should.exist(proof.cryptosuite, |
137 | | - 'Expected a cryptosuite identifier on the proof.'); |
138 | | - proof.type.should.equal('DataIntegrityProof', |
139 | | - 'Expected DataIntegrityProof type.'); |
140 | | - proof.cryptosuite.should.equal('ecdsa-jcs-2019', |
141 | | - 'Expected ecdsa-jcs-2019 cryptosuite.'); |
142 | | - } |
143 | | - }); |
144 | | - }); |
145 | | - } |
| 32 | +const {match: verifiers} = endpoints.filterByTag({ |
| 33 | + tags: cryptosuites, |
| 34 | + property: 'verifiers' |
146 | 35 | }); |
147 | 36 |
|
148 | | -describe('ecdsa-jcs-2019 - Algorithms - Proof Configuration', function() { |
| 37 | +describe('Create Proof (ecdsa-jcs-2019)', function() { |
149 | 38 | setupReportableTestSuite(this); |
150 | 39 | this.implemented = [...issuers.keys()]; |
151 | | - let validCredential; |
152 | | - before(async function() { |
153 | | - validCredential = await createValidCredential(); |
154 | | - }); |
155 | 40 | for(const [columnId, {endpoints}] of issuers) { |
156 | 41 | describe(columnId, function() { |
157 | 42 | const [issuer] = endpoints; |
158 | | - let issuedVc; |
159 | | - let proofs; |
160 | | - let filteredProofs = []; |
| 43 | + let securedCredential; |
| 44 | + let proof; |
161 | 45 | before(async function() { |
162 | | - issuedVc = await createInitialVc({issuer, vc: validCredential}); |
163 | | - proofs = getProofs(issuedVc); |
164 | | - if(proofs?.length) { |
165 | | - filteredProofs = proofs.filter( |
166 | | - proof => proof?.cryptosuite === cryptosuite); |
167 | | - } |
| 46 | + securedCredential = await secureCredential( |
| 47 | + {issuer, vc: baseCredential()}); |
| 48 | + proof = getProofs(securedCredential)[0]; |
168 | 49 | }); |
169 | 50 | beforeEach(setupRow); |
170 | | - it('The proof options MUST contain a type identifier for the ' + |
171 | | - 'cryptographic suite (type) and MUST contain a cryptosuite ' + |
172 | | - 'identifier (cryptosuite).', |
| 51 | + it('The following algorithm specifies how to create a ' + |
| 52 | + 'data integrity proof given an unsecured data document. ' + |
| 53 | + 'Required inputs are an unsecured data document ' + |
| 54 | + '(map unsecuredDocument), and a set of proof options ' + |
| 55 | + '(map options). A data integrity proof (map), or an error, ' + |
| 56 | + 'is produced as output.', |
173 | 57 | async function() { |
174 | | - this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#proof-configuration-ecdsa-jcs-2019'; |
175 | | - assertIssuedVc(issuedVc, proofs, filteredProofs); |
176 | | - for(const proof of filteredProofs) { |
177 | | - should.exist(proof.type, |
178 | | - 'Expected a type identifier on the proof.'); |
179 | | - should.exist(proof.cryptosuite, |
180 | | - 'Expected a cryptosuite identifier on the proof.'); |
181 | | - } |
| 58 | + this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#create-proof-ecdsa-jcs-2019'; |
| 59 | + assertSecuredCredential(securedCredential); |
| 60 | + assertDataIntegrityProof(proof, 'ecdsa-jcs-2019'); |
182 | 61 | }); |
183 | | - it('If proofConfig.type is not set to DataIntegrityProof ' + |
184 | | - 'and/or proofConfig.cryptosuite is not set to ecdsa-jcs-2019, ' + |
185 | | - 'an error MUST be raised and SHOULD convey an error type ' + |
186 | | - 'of PROOF_GENERATION_ERROR.', |
| 62 | + it('If unsecuredDocument.@context is present, ' + |
| 63 | + 'set proof.@context to unsecuredDocument.@context.', |
187 | 64 | async function() { |
188 | | - this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#proof-configuration-ecdsa-jcs-2019'; |
189 | | - assertIssuedVc(issuedVc, proofs, filteredProofs); |
190 | | - for(const proof of filteredProofs) { |
191 | | - should.exist(proof.type, |
192 | | - 'Expected a type identifier on the proof.'); |
193 | | - should.exist(proof.cryptosuite, |
194 | | - 'Expected a cryptosuite identifier on the proof.'); |
195 | | - proof.type.should.equal('DataIntegrityProof', |
196 | | - 'Expected DataIntegrityProof type.'); |
197 | | - proof.cryptosuite.should.equal('ecdsa-jcs-2019', |
198 | | - 'Expected ecdsa-jcs-2019 cryptosuite.'); |
199 | | - } |
| 65 | + this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#create-proof-ecdsa-jcs-2019'; |
| 66 | + should.exist(proof['@context'], |
| 67 | + 'Expected proof to have context.'); |
| 68 | + canonicalize(proof['@context']).should.equal( |
| 69 | + canonicalize(securedCredential['@context']), |
| 70 | + 'Expected proof context to match document context.' |
| 71 | + ); |
200 | 72 | }); |
201 | | - it('If proofConfig.created is set and if the value is not a ' + |
202 | | - 'valid [XMLSCHEMA11-2] datetime, an error MUST be raised and ' + |
203 | | - 'SHOULD convey an error type of PROOF_GENERATION_ERROR.', |
| 73 | + it('Let proof.proofValue be a base58-btc-encoded ' + |
| 74 | + 'Multibase value of the proofBytes.', |
204 | 75 | async function() { |
205 | | - this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#proof-configuration-ecdsa-jcs-2019'; |
206 | | - assertIssuedVc(issuedVc, proofs, filteredProofs); |
207 | | - for(const proof of filteredProofs) { |
208 | | - if(proof?.created) { |
209 | | - isValidDatetime(proof.created).should.equal( |
210 | | - true, |
211 | | - 'Expected created value to be a valid datetime string.' |
212 | | - ); |
213 | | - } |
214 | | - } |
| 76 | + this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#create-proof-ecdsa-jcs-2019'; |
| 77 | + should.exist(proof.proofValue, |
| 78 | + 'Expected proof to have proofValue.'); |
| 79 | + expect(proof.proofValue.startsWith('z')).to.be.true; |
215 | 80 | }); |
216 | 81 | }); |
217 | 82 | } |
218 | 83 | }); |
219 | 84 |
|
220 | | -describe('ecdsa-jcs-2019 - Algorithms - Proof Serialization', function() { |
| 85 | +describe('Algorithms - Verify Proof (ecdsa-jcs-2019)', function() { |
221 | 86 | setupReportableTestSuite(this); |
222 | | - this.implemented = [...issuers.keys()]; |
223 | | - let validCredential; |
224 | | - before(async function() { |
225 | | - validCredential = await createValidCredential(); |
226 | | - }); |
227 | | - for(const [columnId, {endpoints}] of issuers) { |
| 87 | + for(const [columnId, {endpoints}] of verifiers) { |
228 | 88 | describe(columnId, function() { |
229 | | - const [issuer] = endpoints; |
230 | | - let issuedVc; |
231 | | - let proofs; |
232 | | - let filteredProofs = []; |
| 89 | + const [issuer] = issuers.get(columnId).endpoints; |
| 90 | + const [verifier] = endpoints; |
| 91 | + let securedCredential; |
233 | 92 | before(async function() { |
234 | | - issuedVc = await createInitialVc({issuer, vc: validCredential}); |
235 | | - proofs = getProofs(issuedVc); |
236 | | - if(proofs?.length) { |
237 | | - filteredProofs = proofs.filter( |
238 | | - proof => proof?.cryptosuite === cryptosuite); |
239 | | - } |
| 93 | + securedCredential = await secureCredential( |
| 94 | + {issuer, vc: baseCredential()}); |
240 | 95 | }); |
241 | 96 | beforeEach(setupRow); |
242 | | - it('The proof options MUST contain a type identifier for the ' + |
243 | | - 'cryptographic suite (type) and MAY contain a cryptosuite identifier ' + |
244 | | - '(cryptosuite).', |
245 | | - async function() { |
246 | | - this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#proof-serialization-ecdsa-jcs-2019'; |
247 | | - assertIssuedVc(issuedVc, proofs, filteredProofs); |
248 | | - for(const proof of filteredProofs) { |
249 | | - should.exist(proof.type, |
250 | | - 'Expected a type identifier on the proof.'); |
251 | | - } |
252 | | - }); |
| 97 | + it('', |
| 98 | + async function() { |
| 99 | + this.test.link = 'https://www.w3.org/TR/vc-di-ecdsa/#verify-proof-ecdsa-rdfc-2019'; |
| 100 | + }); |
253 | 101 | }); |
254 | 102 | } |
255 | 103 | }); |
256 | | - |
0 commit comments