5 releases (3 breaking)
| 0.4.0 | Nov 10, 2025 |
|---|---|
| 0.3.0 | Sep 11, 2025 |
| 0.2.1 | Sep 8, 2025 |
| 0.2.0 | Apr 24, 2025 |
| 0.1.0 | Apr 22, 2025 |
#644 in Authentication
251 downloads per month
405KB
7K
SLoC
bhmdoc
This library provides functionality for working with the mDL/mdoc specification as defined in ISO/IEC 18013-5 and expanded on in ISO/IEC TS 18013-7:2024 to include integration with openid4vc.
Details
The primary way to use this library is to use the Issuer, Device and
Verifier structs to issue, present and verify issued mdoc documents as defined
in the openid4vc specifications.
For additional documentation & examples, take a look at the crate documentation.
Changelog
The changelog can be found here.
License
Licensed under GNU Affero General Public License, Version 3.
lib.rs:
This crate provides the functionality for handling mobile driving licenses (mDLs) and other
mso_mdoc Credentials in compliance with the ISO/IEC 18013-5:2021 & ISO/IEC TS
18013-7:2024 standards, but modified to work with OpenID for Verifiable Presentations
and Verifiable Credential Issuance specifications.
Details
The crate defines multiple modules, which can be roughly divided as follows.
- High-level modules:
device,issuerandverifier. - The
errormodule describing the error values. - Low-level data model --
models.
A typical user of this crate is expected to care only about the high-level modules. The lower
level data model is exposed for advanced users wishing to adapt the crate to their mso_mdoc
use case.
Examples
The bhmdoc repository contains the full examples, so you should take a look there
to see how things fit together.
Here we will just summarize the most common use cases of the crate.
Issuing a Mobile Driving License (mDL)
use std::str::FromStr;
use bhmdoc::models::{
mdl::*,
FullDate,
};
let mut rng = rand::thread_rng();
let issuer_signer = _; // Implementation of [`bh_jws_utils::Signer`]
let device_key = _; // Instance of [`bhmdoc::DeviceKey`].
let current_time = 100;
let mdl_mandatory = MDLMandatory {
family_name: "Doe".to_owned(),
given_name: "John".to_owned(),
birth_date: "1980-01-02".parse().unwrap(),
issue_date: FullDate::from_str("2024-01-01").unwrap().into(),
expiry_date: FullDate::from_str("2029-01-01").unwrap().into(),
issuing_authority: "MUP".to_owned(),
issuing_country: "RH".to_owned(),
document_number: "1234".to_owned(),
portrait: vec![1u8, 2, 3].into(),
driving_privileges: 7,
un_distinguishing_sign: "sign".to_owned(),
};
let mdl = MDL::new(mdl_mandatory);
let issued = bhmdoc::Issuer
.issue_mdl(mdl, device_key, &issuer_signer, &mut rng, current_time)
.unwrap();
Verifying an Issued mso_mdoc Credential
let verifier = bhmdoc::Verifier::from_parts(
"example verifier client id".to_owned(),
"https://example.response.uri".to_owned(),
"example nonce".to_owned(),
);
// `vp_token` as per <https://openid.net/specs/openid-4-verifiable-presentations-1_0.html>
let vp_token = "Base64url encoded Verifiable Presentation";
let device_response = bhmdoc::models::DeviceResponse::from_base64_cbor(vp_token).unwrap();
let current_time = 100;
// This should return `Some(bh_jws_utils::SignatureVerifier)`
// based on the received `bh_jws_utils::SigningAlgorithm`.
let get_signature_verifier = |_alg| None;
let claims = verifier
.verify(
device_response,
current_time,
"example mdoc generated nonce",
None,
get_signature_verifier,
)
.unwrap();
Dependencies
~9.5MB
~194K SLoC