Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mobile-sdk-rs"
version = "0.13.14"
version = "0.13.17"
edition = "2021"
authors = ["Spruce Systems, Inc."]
license = "Apache-2.0 OR MIT"
Expand All @@ -19,7 +19,7 @@ path = "uniffi-bindgen.rs"
cose-rs = { git = "https://github.com/spruceid/cose-rs", rev = "0018c9b", features = [
"time",
] }
isomdl = { git = "https://github.com/spruceid/isomdl", rev = "6c6f03a" }
isomdl = { git = "https://github.com/spruceid/isomdl", rev = "17b6354" }
oid4vci = { git = "https://github.com/spruceid/oid4vci-rs", rev = "081eb4" }
openid4vp = { git = "https://github.com/spruceid/openid4vp", rev = "2b0c8ba" }
ssi = { version = "0.12", features = ["secp256r1", "secp384r1"] }
Expand Down
56 changes: 46 additions & 10 deletions rust/MobileSdkRs/Sources/MobileSdkRs/mobile_sdk_rs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6788,6 +6788,23 @@ public static func newFromBase64urlEncodedIssuerSigned(base64urlEncodedIssuerSig
})
}

/**
* Construct a new MDoc from IssuerSigned CBOR bytes.
*
* Provisioned data represents the element values in the issuer signed namespaces.
* If provisioned data exists, it will update the issuer signed namespace values
* with the provisioned data.
*/
public static func newFromCborEncodedIssuerSignedDehydrated(cborEncodedIssuerSignedDehydrated: Data, namespacedData: Data, keyAlias: KeyAlias)throws -> Mdoc {
return try FfiConverterTypeMdoc_lift(try rustCallWithError(FfiConverterTypeMdocInitError_lift) {
uniffi_mobile_sdk_rs_fn_constructor_mdoc_new_from_cbor_encoded_issuer_signed_dehydrated(
FfiConverterData.lower(cborEncodedIssuerSignedDehydrated),
FfiConverterData.lower(namespacedData),
FfiConverterTypeKeyAlias_lower(keyAlias),$0
)
})
}



open func activityLog(storage: StorageManagerInterface)async throws -> ActivityLog {
Expand Down Expand Up @@ -17717,6 +17734,9 @@ public enum MdocInitError: Swift.Error {
)
case IssuerSignedBase64UrlDecoding
case IssuerSignedCborDecoding
case ProvisionedDataCborDecoding(String
)
case ProvisionedDataPopulation
case IssuerAuthPayloadMissing
case IssuerAuthPayloadDecoding
case KeyAliasMissing
Expand All @@ -17743,11 +17763,15 @@ public struct FfiConverterTypeMdocInitError: FfiConverterRustBuffer {
)
case 2: return .IssuerSignedBase64UrlDecoding
case 3: return .IssuerSignedCborDecoding
case 4: return .IssuerAuthPayloadMissing
case 5: return .IssuerAuthPayloadDecoding
case 6: return .KeyAliasMissing
case 7: return .NamespacesMissing
case 8: return .DocumentUtf8Decoding
case 4: return .ProvisionedDataCborDecoding(
try FfiConverterString.read(from: &buf)
)
case 5: return .ProvisionedDataPopulation
case 6: return .IssuerAuthPayloadMissing
case 7: return .IssuerAuthPayloadDecoding
case 8: return .KeyAliasMissing
case 9: return .NamespacesMissing
case 10: return .DocumentUtf8Decoding

default: throw UniffiInternalError.unexpectedEnumCase
}
Expand All @@ -17773,24 +17797,33 @@ public struct FfiConverterTypeMdocInitError: FfiConverterRustBuffer {
writeInt(&buf, Int32(3))


case .IssuerAuthPayloadMissing:
case let .ProvisionedDataCborDecoding(v1):
writeInt(&buf, Int32(4))
FfiConverterString.write(v1, into: &buf)


case .ProvisionedDataPopulation:
writeInt(&buf, Int32(5))


case .IssuerAuthPayloadMissing:
writeInt(&buf, Int32(6))


case .IssuerAuthPayloadDecoding:
writeInt(&buf, Int32(5))
writeInt(&buf, Int32(7))


case .KeyAliasMissing:
writeInt(&buf, Int32(6))
writeInt(&buf, Int32(8))


case .NamespacesMissing:
writeInt(&buf, Int32(7))
writeInt(&buf, Int32(9))


case .DocumentUtf8Decoding:
writeInt(&buf, Int32(8))
writeInt(&buf, Int32(10))

}
}
Expand Down Expand Up @@ -24635,6 +24668,9 @@ private let initializationResult: InitializationResult = {
if (uniffi_mobile_sdk_rs_checksum_constructor_mdoc_new_from_base64url_encoded_issuer_signed() != 17520) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_mobile_sdk_rs_checksum_constructor_mdoc_new_from_cbor_encoded_issuer_signed_dehydrated() != 46552) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_mobile_sdk_rs_checksum_constructor_mobileidcapabilitydescriptorbuilder_new() != 3324) {
return InitializationResult.apiChecksumMismatch
}
Expand Down
65 changes: 64 additions & 1 deletion rust/src/credential/mdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use std::{

use base64::prelude::*;
use isomdl::{
definitions::{helpers::Tag24, IssuerSigned, Mso},
definitions::{
helpers::Tag24,
issuer_signed_dehydrated::{IssuerSignedDehydrated, NameSpacedData},
IssuerSigned, Mso,
},
presentation::{device::Document, Stringify},
};
use time::format_description::well_known::Iso8601;
Expand Down Expand Up @@ -57,6 +61,31 @@ impl Mdoc {
Self::new_from_issuer_signed(key_alias, issuer_signed)
}

#[uniffi::constructor]
/// Construct a new MDoc from IssuerSigned CBOR bytes.
///
/// Provisioned data represents the element values in the issuer signed namespaces.
/// If provisioned data exists, it will update the issuer signed namespace values
/// with the provisioned data.
pub fn new_from_cbor_encoded_issuer_signed_dehydrated(
cbor_encoded_issuer_signed_dehydrated: Vec<u8>,
namespaced_data: Vec<u8>,
key_alias: KeyAlias,
) -> Result<Arc<Self>, MdocInitError> {
let issuer_signed_dehdrated: IssuerSignedDehydrated =
isomdl::cbor::from_slice(&cbor_encoded_issuer_signed_dehydrated)
.map_err(|_| MdocInitError::IssuerSignedCborDecoding)?;

let namespace_data: NameSpacedData = isomdl::cbor::from_slice(&namespaced_data)
.map_err(|e| MdocInitError::ProvisionedDataCborDecoding(e.to_string()))?;

let issuer_signed = issuer_signed_dehdrated
.combine_namespaced_data(&namespace_data)
.map_err(|e| MdocInitError::ProvisionedDataCborDecoding(e.to_string()))?;

Self::new_from_issuer_signed(key_alias, issuer_signed)
}

#[uniffi::constructor]
/// Compatibility feature: construct an MDoc from a
/// [stringified spruceid/isomdl `Document`](https://github.com/spruceid/isomdl/blob/main/src/presentation/mod.rs#L100)
Expand Down Expand Up @@ -236,6 +265,10 @@ pub enum MdocInitError {
IssuerSignedBase64UrlDecoding,
#[error("failed to decode IssuerSigned from CBOR")]
IssuerSignedCborDecoding,
#[error("failed to decode ProvisionedData from CBOR: {0}")]
ProvisionedDataCborDecoding(String),
#[error("failed to populate ProvisionedData")]
ProvisionedDataPopulation,
#[error("IssuerAuth CoseSign1 has no payload")]
IssuerAuthPayloadMissing,
#[error("failed to decode IssuerAuth CoseSign1 payload as an MSO")]
Expand Down Expand Up @@ -316,3 +349,33 @@ fn to_json_for_display(value: &ciborium::Value) -> Option<serde_json::Value> {
}
}
}

#[cfg(test)]
mod tests {
use base64::{prelude::BASE64_STANDARD, Engine};

use crate::{credential::mdoc::Mdoc, crypto::KeyAlias};

#[test]
fn test_cbor_auth_data_parsing() {
const B64_AUTH_DATA: &str = include_str!("../../tests/examples/auth_data.txt");
const B64_PROVISIONED_DATA: &str = include_str!("../../tests/examples/provision_data.txt");

let decoded_auth_data = BASE64_STANDARD
.decode(B64_AUTH_DATA)
.expect("failed to decode b64 auth data");

let decoded_provisioned_data = BASE64_STANDARD
.decode(B64_PROVISIONED_DATA)
.expect("failed to decode b64 provisioned data");

let mdoc = Mdoc::new_from_cbor_encoded_issuer_signed_dehydrated(
decoded_auth_data,
decoded_provisioned_data,
KeyAlias("default".into()),
)
.expect("failed to create mdoc");

println!("Mdoc: {mdoc:?}")
}
}
Loading