Crates.io | affinidi-messaging-didcomm |
lib.rs | affinidi-messaging-didcomm |
version | 0.7.6 |
source | src |
created_at | 2024-09-09 18:01:49.482421 |
updated_at | 2024-09-24 11:30:39.666622 |
description | DIDComm for Rust |
homepage | |
repository | https://github.com/sicpa-dlab/didcomm-rust |
max_upload_size | |
id | 1369602 |
size | 1,888,620 |
IMPORTANT
This project is a modified version of the didcomm-rust project from GitHub.
The repository consists of the following main components:
The docs below are provided for the main DIDComm Rust.
See wasm/README.md for DIDComm JavaScript/TypeScript docs.
See wrappers/swift/README.md for DIDComm Swift docs.
To use didcomm
, add this to your Cargo.toml
:
[dependencies]
didcomm = "0.4"
Use cargo run --example {example-name}
for example cargo run --example basic
.
Rust 2018 edition is required.
In order to use the library, SecretsResolver
and DIDResolver
traits must be implemented on the application level.
Implementation of that traits is out of DIDComm library scope, but we provide 2 simple implementation ExampleDIDResolver
and ExampleSecretsResolver
that allows resolve locally known DID docs and secrets for tests/demo purposes.
SecretsResolver
must match the corresponding key IDs from DID Doc verification methods.did#key-id
.The following curves and algorithms are supported:
Forward protocol is implemented and used by default.
DID rotation (fromPrior
field) is supported.
DIDComm has been implemented under the following Assumptions
See examples for details.
A general usage of the API is the following:
Message
(plaintext, payload).Message::pack_encrypted
to build an Encrypted DIDComm messageMessage::pack_signed
to build a Signed DIDComm messageMessage::pack_plaintext
to build a Plaintext DIDComm messageMessage::unpack
on receiver side that will decrypt the message, verify signature if needed
and return a Message
for further processing on the application level.This is the most common DIDComm message to be used in most of the applications.
A DIDComm encrypted message is an encrypted JWM (JSON Web Messages) that
It is important in privacy-preserving routing. It is what normally moves over network transports in DIDComm applications, and is the safest format for storing DIDComm data at rest.
See Message::pack_encrypted
documentation for more details.
Authentication encryption example (most common case):
// --- Build message from ALICE to BOB ---
let msg = Message::build(
"example-1".to_owned(),
"example/v1".to_owned(),
json!("example-body"),
)
.to(ALICE_DID.to_owned())
.from(BOB_DID.to_owned())
.finalize();
// --- Pack encrypted and authenticated message ---
let did_resolver = ExampleDIDResolver::new(vec![ALICE_DID_DOC.clone(), BOB_DID_DOC.clone()]);
let secrets_resolver = ExampleSecretsResolver::new(ALICE_SECRETS.clone());
let (msg, metadata) = msg
.pack_encrypted(
BOB_DID,
Some(ALICE_DID),
None,
&did_resolver,
&secrets_resolver,
&PackEncryptedOptions::default(),
)
.await
.expect("Unable pack_encrypted");
println!("Encryption metadata is\n{:?}\n", metadata);
// --- Send message ---
println!("Sending message \n{}\n", msg);
// --- Unpacking message ---
let did_resolver = ExampleDIDResolver::new(vec![ALICE_DID_DOC.clone(), BOB_DID_DOC.clone()]);
let secrets_resolver = ExampleSecretsResolver::new(BOB_SECRETS.clone());
let (msg, metadata) = Message::unpack(
&msg,
&did_resolver,
&secrets_resolver,
&UnpackOptions::default(),
)
.await
.expect("Unable unpack");
println!("Receved message is \n{:?}\n", msg);
println!("Receved message unpack metadata is \n{:?}\n", metadata);
Anonymous encryption example:
let (msg, metadata) = msg
.pack_encrypted(
BOB_DID,
None, // Keep sender as None here
None,
&did_resolver,
&secrets_resolver,
&PackEncryptedOptions::default(),
)
.await
.expect("Unable pack_encrypted");
Encryption with non-repudiation example:
let (msg, metadata) = msg
.pack_encrypted(
BOB_DID,
Some(ALICE_DID),
Some(ALICE_DID), // Provide information about signer here
&did_resolver,
&secrets_resolver,
&PackEncryptedOptions::default(),
)
.await
.expect("Unable pack_encrypted");
Signed messages are only necessary when
Adding a signature when one is not needed can degrade rather than enhance security because it relinquishes the sender’s ability to speak off the record.
See Message::pack_signed
documentation for more details.
// ALICE
let msg = Message::build(
"example-1".to_owned(),
"example/v1".to_owned(),
json!("example-body"),
)
.to(ALICE_DID.to_owned())
.from(BOB_DID.to_owned())
.finalize();
let (msg, metadata) = msg
.pack_signed(ALICE_DID, &did_resolver, &secrets_resolver)
.await
.expect("Unable pack_signed");
// BOB
let (msg, metadata) = Message::unpack(
&msg,
&did_resolver,
&secrets_resolver,
&UnpackOptions::default(),
)
.await
.expect("Unable unpack");
A DIDComm message in its plaintext form that
They are therefore not normally transported across security boundaries.
// ALICE
let msg = Message::build(
"example-1".to_owned(),
"example/v1".to_owned(),
json!("example-body"),
)
.to(ALICE_DID.to_owned())
.from(BOB_DID.to_owned())
.finalize();
let msg = msg
.pack_plaintext(&did_resolver)
.expect("Unable pack_plaintext");
// BOB
let (msg, metadata) = Message::unpack(
&msg,
&did_resolver,
&secrets_resolver,
&UnpackOptions::default(),
)
.await
.expect("Unable unpack");
PRs are welcome!
The following CI checks are run against every PR:
cargo check --all-targets
cargo test
cargo fmt --all