mDocs Holder SDK
Overview
The mDocs Holder SDK is based around the ISO/IEC 18013-5 standard which establishes an interoperable digital representation for mobile based credentials such as mobile drivers licenses (mDL). However, this SDK is designed to work for more then just mDLs, but rather any conforming mobile document (mDoc) - a term defined in ISO/IEC 18013-5.
The general responsibilities of the SDK can be summarized as the following:
Generate, store and manage access to:
mDocs issued to an application integrating the SDK.
Device keys which are bound to issued mDocs.
Manage lists of:
Trusted issuer certificates which issued mDocs can be validated against.
Trusted verifier certificates which are used to validate OID4VP(OpenID for Verifiable Presentations) authorization requests fetched as part of an mDoc retrieval flow.
Use referenced Status lists to to check mDocs' revocation status.
Interface with an issuer to obtain an mDoc as per OpenID4VCI (OpenID for Verifiable Credential Issuance). The SDK supports both the Authorization Code and Pre-Authorized Code flows.
Interface with a verifier and present an issued mDoc for verification/inspection:
In-person via Bluetooth as per ISO/IEC 18013-5:2021.
Remotely via internet connection as per ISO/IEC 18013-7:2024 and OID4VP.
In this SDK mDocs are referred to as Mobile Credentials.
Supported ISO/IEC 18013-5 Features
ISO/IEC 18013-5 as a standard contains many different features, some of which are not currently supported by this SDK. Below is a summary of supported features:
Device Engagement | QR Code-based | QR Code-based |
Device Retrieval Data Transport | BLE-based with mDocPeripheralServer and mDocCentralClient mode | BLE-based using mDocPeripheralServer |
Ephemeral Session Key Curve | NIST P-\*-based keys | P-256-based key using Secure Enclave |
Device Authentication Mode | Both Digital Signature and ECDH-agreed MAC | Digital Signature, P-256-based key using Secure Enclave |
Supported ISO/IEC 18013-7 Features
The ISO/IEC 18013-7 technical specification contains many different features, some of which are not currently supported by this SDK. Below is a summary of supported features:
Data Retrieval methods | OID4VP | OID4VP |
Wallet Invocation | Custom URL and QR Code-based | Both |
MDoc Reader validation | Stored verifier certificates, client Metadata retrieval | Both |
Authorization Response Encryption | ECDH in Direct Key Agreement mode | ECDH in Direct Key Agreement mode |
System requirements
This SDK is developed in the Kotlin programming language and is meant for integration into Android applications. It currently supports Android 7 (API level 24) and above. The SDK is compiled using API level 35.
Gradle version used to build the project: 8.7 AGP version used to build the project: 8.6.1 JVM target version: 1.8
Library dependencies
A set of external libraries was used to build the SDK.
Standard libraries
androidx.core:core-ktx:1.13.1
androidx.appcompat:appcompat:1.7.0
androidx.activity:activity-ktx:1.9.0
androidx.fragment:fragment:1.5.4
androidx.annotation:annotation:1.8.0
androidx.biometric:biometric-ktx:1.2.0-alpha05
androidx.browser:browser:1.8.0
org.jetbrains.kotlin:kotlin-reflect:1.9.22
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
org.jetbrains.kotlinx:kotlinx-datetime:0.4.0
org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3
org.jetbrains.kotlinx:kotlinx-io-core:0.6.0
org.jetbrains.kotlinx:kotlinx-io-bytestring:0.6.0
Third-party libraries
com.upokecenter:cbor:4.5.2
com.jakewharton.timber:timber:5.0.1
Android Permissions and Features
This SDK automatically adds a number of permissions and features to your Android Manifest. To control how these appear in your final APK you can use Android's manifest merger.
For example, to remove the internet permission, if you are not using OID4VCI in the Holder and do not need the internet permission otherwise, add the below to instruct the build tools to remove the internet permission node from the final merged manifest.
<uses-permission tools:node="remove" android:name="android.permission.INTERNET" />
To inspect your final APK, you can use the AndroidSDK tool aapt
, which can be found under the build-tools
directory of your Android SDK install.
$ aapt d badging path/to/your.apk
The Android documentation for this can be found here.
License & Compliance
Request or download the MATTR Pi SDK Trial License Agreement and the MATTR Customer Agreement and review these terms carefully.
Sign and return the MATTR SDK Trial License Agreement to us.
SDK Change Log
3.0.0 (26 May 2025)
Breaking changes
Spelling standardization change (UK → US English)
The following changes reflect the update of the SDK's spelling convention from UK English to US English:
Renamed the
initialise
function toinitialize
Renamed the
deinitialise
function todeinitialize
The following exceptions under the
HolderException
namespace have been renamed:SdkNotInitialisedException
->SdkNotInitializedException
.SdkInitialisedException
->SdkInitializedException
.AuthenticationCancelledException
->AuthenticationCanceledException
.SdkInitialisedWithDifferentInstanceIdException
->SdkInitializedWithDifferentInstanceIdException
.InvalidAuthorisationRequestUriException
->InvalidAuthorizationRequestUriException
.InvalidAuthorisationRequestVerifiedByCertificateException
->InvalidAuthorizationRequestVerifiedByDomainException
.InvalidAuthorisationRequestVerifiedByDomainException
->InvalidAuthorizationRequestVerifiedByDomainException
.InvalidAuthorisationRequestVerifiedByCertificateException
->InvalidAuthorizationRequestVerifiedByCertificateException
.InvalidAuthorisationRequestUriException
->InvalidAuthorizationRequestUriException
.UserAuthenticationCancelledException
->UserAuthenticationCanceledException
.StorageInitialisationException
->StorageInitializationException
.
OpenID4VCI Pre-authorized Code flow support
The SDK now supports claiming credentials via the OID4VCI Pre-Authorized Code flow,
Below is a summary of the technical changes introduced as part of this update:
retrieveCredentials
function:Now accepts a raw URL-encoded credential offer instead of a
DiscoverCredentialOffer
object. Thus, callingdiscoverCredentialOffer
is now optional.Does not accept
redirectUri
andautoTrustMobileCredentialIaca
. These are now configured during SDK initialization.Accepts
transactionCode
as an optional parameter. This is required when the Pre-Authorized Code flow includes a transaction code.The
initialize
function now accepts acredentialIssuanceConfiguration
parameter which
containsredirectUri
andautoTrustMobileCredentialIaca
(these were previously passed to theretrieveCredentials
function).DiscoveredCredentialOffer
data class:Removed
authorizeEndpoint
,tokenEndpoint
,credentialEndpoint
, andmdocIacasUri
properties.Added a
transactionCode
property to indicate whether or not a transaction code is required.RetrieveCredentialResult
data class: Renameddoctype
todocType
to align with other data classes in the SDK.RetrieveCredentialError
enum: Renamedname
property totype
in the JSON representation of the enum entities.
For more details, please refer to the corresponding methods and classes documentation.
Error handling consolidation
In order to provide a more cohesive and manageable error handling experience in the OID4VCI flow, we have consolidated several exceptions into broader ones. This change aims to make it easier for developers to handle errors consistently. Below is a summary of the changes:
discoverCredentialOffer()
no longer throws the following exceptions:CredentialOfferNotFoundException
InvalidCredentialOfferException
CredentialOfferNotInCredentialIssuerMetadataException
IssuerMetadataServiceException
SupportedCredentialsNotFoundException
These have been consolidated into:
InvalidCredentialOfferException
FailedToDiscoverCredentialOfferException
retrieveCredentials()
no longer throws the following exceptions:InvalidCredentialOfferException
GenerateAuthorisationUrlFailedException
AuthCodeNotFoundException
AuthenticationFailedException
TokenServiceException
UnsupportedTokenTypeException
DeviceKeyGenerationException
UserAuthenticationOnDeviceNotSetupException
AuthenticationCancelledException
UserAuthenticationUnrecoverableKeyException
UserAuthenticationBiometryLockoutException
UserAuthenticationException
IacaCertDownloadException
These have been consolidated into:
InvalidCredentialOfferException
FailedToRetrieveCredentialsException
WebAuthenticationFailedException
FailedToDiscoverCredentialOfferException
While the following exception types were added:
RedirectUriNotFoundException
InvalidTransactionCodeException
For a complete list of exceptions thrown by the discoverCredentialOffer()
and retrieveCredentials()
methods, refer to the methods' documentation.
Other breaking changes
ProximityPresentationSessionListener
interface was moved from global.mattr.mobilecredential.common.session
to global.mattr.mobilecredential.verifier
.
Dependencies updates
Added
org.jetbrains.kotlinx:kotlinx-io-core:0.6.0
.Added
org.jetbrains.kotlinx:kotlinx-io-bytestring:0.6.0
.Updated
com.upokecenter:cbor
from4.2.0
to4.5.2
.
Bug fixes
Fixed an issue where proximity presentation sessions would not terminate when Bluetooth was disabled.
Fixed an issue where large credentials were being cut off when sent with a terminating session status.
Fixed an issue which resulted in endless user authentication loop on some Samsung devices.
Sample App
Standardized spelling from UK to US English throughout the sample app codebase.
Added support for claiming a credential via the OID4VCI Pre-Authorized Code flow.
2.0.0
Breaking changes
Removed
statusInfo
fromMobileCredentialPresentation
,MobileCredential
andMobileCredentialMetadata
.Removed the
skipStatusCheck
parameter fromgetCredentials
.Removed
deviceKeyId
fromMobileCredential
andMobileCredentialMetadata
.During an online presentation flow, the authorization request certificate must include the
client_id
as a subject alternative name record.
Sample apps
The sample app now supports product flavours for different SDK types.
Fixed minor bugs.
1.1.0
This release compared to 1.0.1 includes:
Features
Feature to have two SDKs in one app.
Bug fixes
Fix logger configuration.
Improved cryptography for older devices.
Improved BLE hardware handling.
Improved read performance from local storage.
Change
HolderException.EmptyClientIdException
from internal to public.
1.0.4 (Internal)
Bug fixes
Change
HolderException.EmptyClientIdException
from internal to public.
1.0.3 (Internal)
Features
Feature to have two SDKs in one app.
Bug fixes
Fix logger configuration.
Improved cryptography for older devices.
Improved BLE hardware handling.
Improved read performance from local storage.
1.0.1
Breaking changes
All functions may now throw standard
Error
s that were previously masked.All non-public methods and classes are now marked as internal or private.
The
global.mattr.mobilecredentialholder
package was renamed toglobal.mattr.mobilecredential.holder
.discoverCredentialOffer
function:Throws a new
ConnectivityException
exception.IssuerMetadataServiceErrorException
was renamed toIssuerMetadataServiceException
.retrieveCredentials
function:Throws new
ConnectivityException
andIacaCertDownloadException
exceptions.TokenServiceErrorException
was renamed toTokenServiceException
.createOnlinePresentationSession
function:Throws new
ConnectivityException
exception.RequestServiceException
andInvalidAuthorisationRequestException
were removed.DiscoveredCredentialOffer
data class:credentialsEndpoint
was renamed tocredentialEndpoint
.The
getCredentials
function now returns a list ofMobileCredentialMetaData
instead ofMobileCredential
.The
destroy
function throwsSdkInitialisedException
instead ofSdkNotInitialisedException
.The following exceptions were renamed:
UserAuthenticationCancelledException
was renamed toAuthenticationCancelledException
.UserAuthenticationNotSetUpException
was renamed toUserAuthenticationOnDeviceNotSetupException
.RequestNotReceivedException
was renamed toMobileCredentialRequestNotReceivedException
.GenerateAuthorizationUrlFailedException
was renamed toGenerateAuthorisationUrlFailedException
.DeviceKeyInUseException
was renamed toDeviceKeyAlreadyInUseException
.DataTransportException
was renamed toDataTransportFailedException
.
Features
The SDK can now display and check credentials' revocation and suspension status:
The
getCredentials
function now takes an optionalskipStatusCheck
boolean flag that will skip the status check when set totrue
. Defaults tofalse
.The
getCredential
function now takes an optionalskipStatusCheck
boolean flag that will skip the status check when set totrue
. Defaults tofalse
.Operations now throw an
UnsupportedCurveException
exception when encountering an unsupported cryptographic curve.Increased debug logging throughout SDK.
Updated to support Android 15.
Storage engine replacement, resulting in the removal the Realm dependency.
HTTP Client replacement to support Android 7, resulting in the removal of the OkHttp dependency.
Updated all 3rd party libraries to recent versions.
Bug fixes
Occasional errors when using biometrics to unlock the KeyStore certain devices will now fallback to using PIN/password.
Sample app
Displays credentials' revocation and suspension status.
Allows copying of IACA PEM data.
0.6.1 (Internal)
Breaking changes
Authentication on SDK initialization
MobileCredentialHolder.initialise()
is now optional.Authentication flow timeout changed from 1 to 3 seconds.
Features
Updated to support Android 14.
Sample app
Support for optional authentication.
0.6.0 (Internal)
Features
Support for online mDocs presentation via OpenID4VP.
Sample app
Supports Online Presentation of mDocs via the OpenID4VP workflow.
0.5.4 (Initial)
Features
Support for claiming mDocs via the OpenID4VCI workflow.
Sample app
Supports claiming mDoca mDoc via the OpenID4VCI workflow.