1pub mod did;
39pub mod did_web;
40pub mod key_management;
41pub mod kms;
42pub mod proof;
43pub mod rdf_integration;
44pub mod revocation;
45#[cfg(feature = "bbs-plus")]
46pub mod signatures;
47pub mod signed_graph;
48pub mod url;
49pub mod vc;
50#[cfg(feature = "zkp")]
51pub mod zkp;
52
53pub mod document_versioning;
55
56pub mod credential_exchange;
58
59pub mod key_agreement;
61
62pub mod presentation_builder;
64
65pub mod vc_verifier;
67
68pub mod vc_presenter;
70
71pub mod trust_chain;
73
74pub mod authentication;
76
77pub mod presentation_request;
79
80pub mod did_resolver;
82
83pub mod identity_registry;
85
86pub mod credential_schema;
88
89pub mod key_manager;
91
92pub mod proof_purpose;
94pub(crate) mod proof_purpose_registry;
95#[cfg(test)]
96mod proof_purpose_tests;
97pub mod proof_purpose_types;
98pub(crate) mod proof_purpose_verifier;
99
100use chrono::{DateTime, Utc};
101use serde::{Deserialize, Serialize};
102use thiserror::Error;
103
104#[cfg(feature = "did-ethr")]
106pub use did::methods::{DidEthr, DidEthrMethod, EthNetwork};
107#[cfg(feature = "did-ion")]
108pub use did::methods::{
109 DidIon, DidIonMethod, IonCreateOperation, IonDocument, IonKeyDescriptor, IonKeyPurpose,
110 IonOperationType, IonService,
111};
112pub use did::{ChainNamespace, Did, DidDocument, DidPkh, DidPkhMethod, DidResolver};
113pub use key_management::{
114 generate_rotation_key, KeyExpiry, KeyRotation, KeyRotationManager, KeyRotationReason,
115 KeyRotationRecord, KeyRotationRegistry, Keystore, LifecycleKeyRotationRecord,
116 VerificationKey as ManagedVerificationKey,
117};
118pub use kms::{
119 audit::{AuditEvent, AuditEventKind, AuditLog},
120 pkcs11::{KeyHandle, Pkcs11Mechanism, Pkcs11Slot},
121 KeyUsage, KmsAlgorithm, KmsBackend, KmsDidSigner, KmsKeyMetadata,
122};
123pub use proof::{
128 jws::{
129 attach_jws_proof, extract_jws_proof, sign_document, verify_document, CompactJws,
130 JsonWebSignature2020, JwsAlgorithm, JwsHeader, JwsSigner, JwsVerifier,
131 },
132 Proof, ProofPurpose, ProofType,
133};
134pub use revocation::{
135 BloomFilter, CredentialStatus, RevocationEntry, RevocationList2020, RevocationRegistry,
136 RevocationRegistry2020, RevocationStatus, StatusList2021, StatusList2021Inner,
137 StatusListCredential, StatusPurpose, MIN_LIST_SIZE,
138};
139#[cfg(feature = "bbs-plus")]
140pub use signatures::{
141 BbsKeyPair, BbsPlusSignature, BbsProof, BbsProofRequest, EcdsaJwsSigner, EcdsaJwsVerifier,
142 Ed25519JwsSigner, Ed25519JwsVerifier, Es256Signer, Es256Verifier,
143 JwsAlgorithm as SignaturesJwsAlgorithm, JwsHeader as SignaturesJwsHeader, JwsPayload,
144 JwsSignature, JwsSignatureHeader, JwsSigner as SignaturesJwsSigner, JwsSignerTrait,
145 JwsVerifier as SignaturesJwsVerifier, JwsVerifierTrait, MockJwsSigner, MockJwsVerifier,
146 P256KeyPair, Rs256Signer, Rs256Verifier, RsaKeyPair,
147};
148pub use signed_graph::SignedGraph;
149pub use url::{DereferencedResource, DidDereferencer, DidUrl};
150pub use vc::{
151 decode_jwt_vc, encode_vc_as_jwt, CredentialIssuer, CredentialSubject, CredentialVerifier,
152 JwtVc, JwtVcHeader, JwtVcPayload, VerifiableCredential, VerifiablePresentation,
153};
154#[cfg(feature = "zkp")]
155pub use zkp::{
156 prove_selective, verify_selective, AttributeCommitment, CredentialAttribute,
157 DisclosurePresentation, PedersenParams, PedersenSelectiveDisclosureProof, SchnorrProof,
158 SelectiveDisclosureCredential, SelectiveDisclosureProof, SelectiveDisclosureRequest,
159 ZkpProofRequest,
160};
161
162#[derive(Error, Debug)]
164pub enum DidError {
165 #[error("Invalid DID format: {0}")]
166 InvalidFormat(String),
167
168 #[error("Unsupported DID method: {0}")]
169 UnsupportedMethod(String),
170
171 #[error("Resolution failed: {0}")]
172 ResolutionFailed(String),
173
174 #[error("Verification failed: {0}")]
175 VerificationFailed(String),
176
177 #[error("Signing failed: {0}")]
178 SigningFailed(String),
179
180 #[error("Key not found: {0}")]
181 KeyNotFound(String),
182
183 #[error("Invalid key: {0}")]
184 InvalidKey(String),
185
186 #[error("Credential expired")]
187 CredentialExpired,
188
189 #[error("Invalid proof: {0}")]
190 InvalidProof(String),
191
192 #[error("Canonicalization failed: {0}")]
193 CanonicalizationFailed(String),
194
195 #[error("Serialization error: {0}")]
196 SerializationError(String),
197
198 #[error("Network error: {0}")]
199 NetworkError(String),
200
201 #[error("Internal error: {0}")]
202 InternalError(String),
203
204 #[error("Invalid credential: {0}")]
205 InvalidCredential(String),
206}
207
208pub type DidResult<T> = Result<T, DidError>;
209
210#[derive(Debug, Clone, Serialize, Deserialize)]
212#[serde(rename_all = "camelCase")]
213pub struct VerificationMethod {
214 pub id: String,
216 #[serde(rename = "type")]
218 pub method_type: String,
219 pub controller: String,
221 #[serde(skip_serializing_if = "Option::is_none")]
223 pub public_key_multibase: Option<String>,
224 #[serde(skip_serializing_if = "Option::is_none")]
226 pub public_key_jwk: Option<serde_json::Value>,
227 #[serde(skip_serializing_if = "Option::is_none")]
229 pub blockchain_account_id: Option<String>,
230}
231
232impl VerificationMethod {
233 pub fn ed25519(id: &str, controller: &str, public_key: &[u8]) -> Self {
235 let multibase = format!("z{}", bs58::encode(public_key).into_string());
237
238 Self {
239 id: id.to_string(),
240 method_type: "Ed25519VerificationKey2020".to_string(),
241 controller: controller.to_string(),
242 public_key_multibase: Some(multibase),
243 public_key_jwk: None,
244 blockchain_account_id: None,
245 }
246 }
247
248 pub fn blockchain(
252 id: &str,
253 controller: &str,
254 method_type: &str,
255 blockchain_account_id: &str,
256 ) -> Self {
257 Self {
258 id: id.to_string(),
259 method_type: method_type.to_string(),
260 controller: controller.to_string(),
261 public_key_multibase: None,
262 public_key_jwk: None,
263 blockchain_account_id: Some(blockchain_account_id.to_string()),
264 }
265 }
266
267 pub fn jwk(id: &str, controller: &str, method_type: &str, jwk: serde_json::Value) -> Self {
269 Self {
270 id: id.to_string(),
271 method_type: method_type.to_string(),
272 controller: controller.to_string(),
273 public_key_multibase: None,
274 public_key_jwk: Some(jwk),
275 blockchain_account_id: None,
276 }
277 }
278
279 pub fn get_public_key_bytes(&self) -> DidResult<Vec<u8>> {
281 if let Some(ref multibase) = self.public_key_multibase {
282 if let Some(stripped) = multibase.strip_prefix('z') {
284 bs58::decode(stripped)
285 .into_vec()
286 .map_err(|e| DidError::InvalidKey(e.to_string()))
287 } else {
288 Err(DidError::InvalidKey("Unknown multibase prefix".to_string()))
289 }
290 } else if self.blockchain_account_id.is_some() {
291 Err(DidError::InvalidKey(
292 "Blockchain account verification methods do not expose raw public keys".to_string(),
293 ))
294 } else {
295 Err(DidError::InvalidKey("No public key available".to_string()))
296 }
297 }
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize)]
302#[serde(rename_all = "camelCase")]
303pub struct Service {
304 pub id: String,
306 #[serde(rename = "type")]
308 pub service_type: String,
309 pub service_endpoint: String,
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize)]
315pub struct VerificationResult {
316 pub valid: bool,
318 pub issuer: Option<String>,
320 pub verified_at: DateTime<Utc>,
322 pub error: Option<String>,
324 pub checks: Vec<VerificationCheck>,
326}
327
328#[derive(Debug, Clone, Serialize, Deserialize)]
330pub struct VerificationCheck {
331 pub name: String,
333 pub passed: bool,
335 pub details: Option<String>,
337}
338
339impl VerificationResult {
340 pub fn success(issuer: &str) -> Self {
341 Self {
342 valid: true,
343 issuer: Some(issuer.to_string()),
344 verified_at: Utc::now(),
345 error: None,
346 checks: vec![],
347 }
348 }
349
350 pub fn failure(error: &str) -> Self {
351 Self {
352 valid: false,
353 issuer: None,
354 verified_at: Utc::now(),
355 error: Some(error.to_string()),
356 checks: vec![],
357 }
358 }
359
360 pub fn with_check(mut self, name: &str, passed: bool, details: Option<&str>) -> Self {
361 self.checks.push(VerificationCheck {
362 name: name.to_string(),
363 passed,
364 details: details.map(String::from),
365 });
366 self
367 }
368}
369
370#[cfg(test)]
371mod tests {
372 use super::*;
373
374 #[test]
375 fn test_verification_method_ed25519() {
376 let public_key = vec![
377 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
378 25, 26, 27, 28, 29, 30, 31, 32,
379 ];
380
381 let vm = VerificationMethod::ed25519("did:key:z123#key-1", "did:key:z123", &public_key);
382
383 assert_eq!(vm.method_type, "Ed25519VerificationKey2020");
384 assert!(vm.public_key_multibase.is_some());
385
386 let recovered = vm.get_public_key_bytes().unwrap();
387 assert_eq!(recovered, public_key);
388 }
389
390 #[test]
391 fn test_verification_result() {
392 let result = VerificationResult::success("did:key:z123")
393 .with_check("signature", true, None)
394 .with_check("expiration", true, Some("Not expired"));
395
396 assert!(result.valid);
397 assert_eq!(result.checks.len(), 2);
398 }
399}