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.
75 lines
2.3 KiB
75 lines
2.3 KiB
// The DER elements of the security areas of security_cms.json, the
|
|
// signatures and the tokens, as the seeds of FuzzDERCheck of datekeys-go:
|
|
// check accepts each, split, content and parseTime read it element by
|
|
// element, and so for every mutation of them that check accepts.
|
|
@TestOn('vm')
|
|
library;
|
|
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'dart:math';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:datekeys/datekeys.dart' show fromHex;
|
|
import 'package:datekeys/src/der.dart' as der;
|
|
import 'package:test/test.dart';
|
|
|
|
import 'der_support.dart';
|
|
|
|
/// The outermost runs of bytes of [b] that are one DER SEQUENCE of more than
|
|
/// 127 bytes each, as derElements of der_test.go.
|
|
List<Uint8List> derElements(Uint8List b) {
|
|
final out = <Uint8List>[];
|
|
for (var i = 0; i + 2 < b.length; i++) {
|
|
if (b[i] != 0x30 || b[i + 1] < 0x81 || b[i + 1] > 0x83) continue;
|
|
final rest = Uint8List.sublistView(b, i);
|
|
final Uint8List element;
|
|
try {
|
|
final content = der.content(rest);
|
|
final headerLength = content.offsetInBytes - rest.offsetInBytes;
|
|
element = Uint8List.sublistView(b, i, i + headerLength + content.length);
|
|
der.check(element);
|
|
} on der.DerException {
|
|
continue;
|
|
}
|
|
out.add(element);
|
|
i += element.length - 1;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
void main() {
|
|
final file = jsonDecode(
|
|
File('testdata/vectors/security_cms.json').readAsStringSync(),
|
|
) as Map<String, Object?>;
|
|
final areas = [
|
|
for (final c in (file['cases']! as List).cast<Map<String, Object?>>())
|
|
fromHex(c['security_cbor']! as String),
|
|
];
|
|
final seeds = [for (final a in areas) ...derElements(a)];
|
|
|
|
test('the signatures and tokens of security_cms.json are DER', () {
|
|
expect(areas, isNotEmpty);
|
|
// Some cases hold no DER on purpose: a signature that is not a CMS, a
|
|
// seal that is not DER, SIGNERS out of order or empty.
|
|
expect(seeds, isNotEmpty);
|
|
seeds.forEach(walkAccepted);
|
|
});
|
|
|
|
test('what check accepts of their mutations, the readers read', () {
|
|
final r = Random(8);
|
|
var accepted = 0;
|
|
for (var i = 0; i < 3000; i++) {
|
|
final b = mutateDer(r, seeds[r.nextInt(seeds.length)]);
|
|
try {
|
|
der.check(b);
|
|
} on der.DerException {
|
|
continue;
|
|
}
|
|
accepted++;
|
|
walkAccepted(b);
|
|
}
|
|
expect(accepted, greaterThan(0));
|
|
});
|
|
}
|