// Helpers of the tests of the signatures of alg 2 and the seals of // seal_type 2 against the vectors of Go: the areas of // test/vectors/securitycms_vectors.json, which tool/security_go_vectors.go // makes and evaluates with package capsule of the reference, put together // again from their pieces, or from a base and its edit. They read no file, // so that the tests that run on Node.js can use them. library; import 'dart:typed_data'; import 'package:datekeys/datekeys.dart'; import 'package:datekeys/src/sha256.dart' show sha256; import 'open_vectors_support.dart'; import 'tlock_support.dart' show applyEdits; /// The bytes of [pieces]: the hexadecimal of some bytes, or the index of a /// chunk of [chunks]. Uint8List joinPieces(List pieces, List chunks) => concatBytes([ for (final p in pieces) p is int ? chunks[p] : fromHex(p! as String), ]); /// The chunks of a vector file, each made of the ones before it. List chunksOf(Json f) { final out = []; for (final c in (f['chunks']! as List).cast()) { out.add(joinPieces(c['pieces']! as List, out)); } return out; } /// The bases of the file, from their pieces, or their hexadecimal in the /// part of the file that the tests compiled to JavaScript read. List basesOf(Json f, List chunks) => [ for (final b in f['bases']! as List) b is String ? fromHex(b) : joinPieces((b as Json)['pieces']! as List, chunks), ]; /// The area of the case [c]: its hexadecimal, its pieces, or its base with /// the edit of its target, the SignedData of key 2 (value), its SIGNERS /// (signers) or the token of key 3 (token), written again with the /// encoders of this library as Go writes it with those of capsule. The /// first 8 bytes of its SHA-256 must be those of Go's. Uint8List cmsAreaOf(Json c, List chunks, List bases) { final Uint8List area; final hex = c['hex'] as String?; final pieces = c['pieces'] as List?; if (hex != null) { area = fromHex(hex); } else if (pieces != null) { area = joinPieces(pieces, chunks); } else { final w = decodeSecurity(bases[c['base']! as int])!; final edits = (c['edits']! as List).cast(); var signature = w.signature; var seal = w.seal; switch (c['target']) { case 'value' || 'signers': final a = decodeAuthorSignature(signature!)!; final value = c['target'] == 'value'; signature = encodeAuthorSignature( algCms, value ? a.key : applyEdits(a.key, edits), value ? applyEdits(a.value, edits) : a.value, ); case 'token': final s = decodeSeal(seal!)!; seal = encodeSeal(sealTypeRfc3161, applyEdits(s.token, edits)); default: throw StateError('a target ${c['target']}'); } area = encodeSecurityWith(signature: signature, seal: seal); } if (toHex(sha256(area).sublist(0, 8)) != c['sha256']) { throw StateError('the area of ${canonical(c)} is not the one of Go'); } return area; }