You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
3.0 KiB
82 lines
3.0 KiB
// 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<Object?> pieces, List<Uint8List> 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<Uint8List> chunksOf(Json f) {
|
|
final out = <Uint8List>[];
|
|
for (final c in (f['chunks']! as List).cast<Json>()) {
|
|
out.add(joinPieces(c['pieces']! as List<Object?>, 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<Uint8List> basesOf(Json f, List<Uint8List> chunks) => [
|
|
for (final b in f['bases']! as List)
|
|
b is String
|
|
? fromHex(b)
|
|
: joinPieces((b as Json)['pieces']! as List<Object?>, 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<Uint8List> chunks, List<Uint8List> bases) {
|
|
final Uint8List area;
|
|
final hex = c['hex'] as String?;
|
|
final pieces = c['pieces'] as List<Object?>?;
|
|
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<Object?>();
|
|
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;
|
|
}
|