The purpose of this builder is to hide away as much of the complexity of mDoc building away as possible, so when using the library, you can focus on filling the data wanted.
This package requires building a Document type class out, for example, GBDrivingLicenceV1
import uk.gov.dvla.mwc.cose.KeyCert;
import uk.gov.dvla.mwc.documents.Document;
import uk.gov.dvla.mwc.cbor.objects.DrivingPrivilege;
import uk.gov.dvla.mwc.documents.builders.GBDrivingLicenceV1Builder;
import java.time.Duration;
DrivingPrivilege[] privileges = List.of(new DrivingPrivilege(categoryCode, issueDate, expiryDate, new String[]{"restriction", "codes"})).toArray();
// Driving licence building
Document drivingDoc = new GBDrivingLicenceV1Builder()
// GB Specific
.setWelshLicence(false)
.setTitle("Dr")
.setProvisionalDrivingPrivileges(privileges)
// Standard mDL
.setGivenName()
.setFamilyName()
.setBirthDate()
.setIssueDate()
.setExpiryDate()
.setIssuingCountry("GB")
.setIssuingAuthority("DVLA")
.setDocumentNumber()
.setPortrait()
.setDrivingPrivileges(privileges)
.setBirthPlace()
.setUnDistinguishingSign()
.setAddress()
.setCity()
.setPostCode()
// Then Build
.build();
// Key & Cert required for signing
KeyCert key = new KeyCert(issuerPrivateKey, issuerCert);
// mDoc building, not specific to driving licence
byte[] mDoc = MDoc.builder()
.setDocument(drivingDoc)
.setValidFor(Duration.ofDays(365))
.setDeviceKey()
.setIssuerKey(key)
// builds to byte[]
.build();
/*
There are several different ways to build:
.build() -> issuerSigned
.buildToHex() -> issuerSigned as hex string
.buildToBase64() -> issuerSigned as base64 string
.buildAsMdoc() -> mDoc with the issuerSigned included
.buildAsDeviceResponse() -> deviceResponse with mDoc included
*/When building with an external signing service, all document building is the same, but there are a few extra steps to take when building the mDoc:
// The keyCert now just takes in just the certificate
KeyCert key = new KeyCert(issuerCert);
// mDoc building, not specific to driving licence
MDoc mDoc = MDoc.builder()
.setDocument(drivingDoc)
.setValidFor(Duration.ofDays(365))
.setDeviceKey()
.setIssuerKey(key)
// builds everything in preparation for signing
.prepareForSigning();
byte[] bytesToSign = mDoc.getToSign();
// Sign the bytes with any external service
byte[] signature = externalService.sign(bytesToSign);
// Build the mDoc with the signature (just the issuerSigned part as per updated spec)
byte[] signedMdoc = mDoc.buildWithSignature(signature);Base64 encoding is required to be specifically base64 url encoding, but apart from that, hex and base64 encoding is as standard. But this library provides convenience methods to be able to encode byte[] to hex or base64 easily:
import uk.gov.dvla.mwc.cbor.ByteConversion;
String base64String = ByteConversion.toBase64(bytes);
String hexString = ByteConversion.toHex(bytes);As spec is subject to change, all documents are versioned to know what spec version you'll be using.
Driving licence, for example, is "org.iso.18013.5.1.mDL". The version of the document class matches the bold number.
The current documents are:
- DrivingLicence (V1)
- GBDrivingLicence (V1)
View the design decision doc