SimulatedBelgianCard constructor
SimulatedBelgianCard({
- String cardNumber = '591000000106',
- DateTime? validFrom,
- DateTime? validUntil,
- String issuingMunicipality = 'Bruxelles',
- String nationalNumber = '90051512391',
- String lastName = 'Specimen',
- String firstNames = 'Alice Marie',
- String? thirdGivenNameInitial = 'J',
- String nationality = 'Belge',
- String birthPlace = 'Namur',
- String birthDate = '15 MAI 1990',
- String sex = 'F',
- BelgianDocumentType documentType = BelgianDocumentType.eid,
- String streetAndNumber = 'Rue de la Loi 16',
- String postalCode = '1000',
- String municipality = 'Bruxelles',
- Uint8List? photo,
- Map<
int, Object> extraIdentityFields = const {}, - String pin = '1234',
- int appletVersion = 0x18,
- Duration latency = Duration.zero,
- String? tamperedLastName,
- bool cloned = false,
- bool holderCertificates = true,
A card holding the given data, by default that of a fictional citizen.
birthDate is written as on the card, such as 15 MAI 1990, and sex
as M or F. extraIdentityFields adds or replaces identity fields by
tag. An appletVersion below 0x18 gives an older card. latency
delays every answer.
tamperedLastName is written after signing, so the signature fails. A
cloned card fails BelgianEidReader.proveGenuine. holderCertificates
false leaves out the holder's certificates, as on a Kids ID.
Implementation
SimulatedBelgianCard({
String cardNumber = '591000000106',
DateTime? validFrom,
DateTime? validUntil,
String issuingMunicipality = 'Bruxelles',
String nationalNumber = '90051512391',
String lastName = 'Specimen',
String firstNames = 'Alice Marie',
String? thirdGivenNameInitial = 'J',
String nationality = 'Belge',
String birthPlace = 'Namur',
String birthDate = '15 MAI 1990',
String sex = 'F',
BelgianDocumentType documentType = BelgianDocumentType.eid,
String streetAndNumber = 'Rue de la Loi 16',
String postalCode = '1000',
String municipality = 'Bruxelles',
Uint8List? photo,
Map<int, Object> extraIdentityFields = const {},
String pin = '1234',
this.appletVersion = 0x18,
this.latency = Duration.zero,
String? tamperedLastName,
bool cloned = false,
bool holderCertificates = true,
}) : _pinBlock = pinBlock(pin),
_basicKey = cloned
? SimulatedPki.instance.cloneKey
: SimulatedPki.instance.basicKey {
final cardPhoto = photo ?? specimenPhoto;
final basicPublicKey = SimulatedPki.instance.basicPublicKeyFile;
final pki = SimulatedPki.instance;
Uint8List identityWith(String lastName) => _tlv({
0x00: const [0x00, 0x02],
0x01: cardNumber,
0x02: serialNumber,
0x03: _dotted(validFrom ?? DateTime.utc(2024, 3, 14)),
0x04: _dotted(validUntil ?? DateTime.utc(2034, 3, 13)),
0x05: issuingMunicipality,
0x06: nationalNumber,
0x07: lastName,
0x08: firstNames,
0x09: thirdGivenNameInitial ?? '',
0x0A: nationality,
0x0B: birthPlace,
0x0C: birthDate,
0x0D: sex,
0x0E: '',
0x0F: '${documentType.code}',
0x10: '0',
0x11: _photoHash(cardPhoto),
if (appletVersion >= 0x18) 0x1A: sha384.convert(basicPublicKey).bytes,
...extraIdentityFields,
});
final address = _tlv({
0x00: const [0x00, 0x02],
0x01: streetAndNumber,
0x02: postalCode,
0x03: municipality,
});
// Signing is asynchronous on the web: the first command waits for it.
_files = _sign(
identity: identityWith(tamperedLastName ?? lastName),
signedIdentity: identityWith(lastName),
address: address,
photo: cardPhoto,
basicPublicKey: basicPublicKey,
holderCertificates: holderCertificates
? pki.holderCertificates(
lastName: lastName,
firstNames: firstNames,
nationalNumber: nationalNumber,
)
: null,
);
// A failure surfaces on the first command, not as an unhandled error.
_files.ignore();
}