MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / verify

Function verify

atomic-canonical/src/delegation.rs:146–191  ·  view source on GitHub ↗

Verify a certificate against the delegator's public key and return the typed view. Checks, in order: 1. the document is an `AgentDelegation`; 2. content hash recomputes, the proof verifies, and its `verificationMethod` belongs to `delegator_public_key` ([`proof::verify_value`]); 3. the `delegator` DID is that same key — otherwise a certificate signed by one key could name another as the delegato

(document: &Value, delegator_public_key: &PublicKey)

Source from the content-addressed store, hash-verified

144/// 5. `@id` recomputes from the body, so the identifier cannot be swapped for
145/// one belonging to a different (perhaps revoked) certificate.
146pub fn verify(document: &Value, delegator_public_key: &PublicKey) -> Result<Delegation> {
147 expect_type(document, TYPE_DELEGATION)?;
148 proof::verify_value(document, delegator_public_key)?;
149
150 let parsed = parse(document)?;
151
152 // 3. The signer must be the delegator the document names.
153 let delegator_id = IdentityId::from_did(&parsed.delegator)
154 .map_err(|e| CanonicalError::Verification(format!("delegator DID is malformed: {e}")))?;
155 if !delegator_id.matches_public_key(delegator_public_key) {
156 return Err(CanonicalError::Verification(
157 "delegator DID does not match the verifying key".into(),
158 ));
159 }
160
161 // 3b. The delegator's own two renderings must agree too, so a
162 // self-contained verifier that starts from `delegatorKey` reaches the
163 // same conclusion as one that starts from a key it already trusts.
164 let stated_delegator_key = self::delegator_public_key(&parsed)?;
165 if &stated_delegator_key != delegator_public_key {
166 return Err(CanonicalError::Verification(
167 "delegatorKey does not match the verifying key".into(),
168 ));
169 }
170
171 // 4. The two renderings of the delegate's key must agree. Without this a
172 // certificate could name agent A in `delegate` while handing out agent
173 // B's key in `delegateKey`.
174 let delegate_key = delegate_public_key(&parsed)?;
175 let delegate_id = IdentityId::from_did(&parsed.delegate)
176 .map_err(|e| CanonicalError::Verification(format!("delegate DID is malformed: {e}")))?;
177 if !delegate_id.matches_public_key(&delegate_key) {
178 return Err(CanonicalError::Verification(
179 "delegateKey does not match the delegate DID".into(),
180 ));
181 }
182
183 // 5. The id is a claim like any other; recompute it.
184 if !parsed.id_matches(&delegator_id, &delegate_id) {
185 return Err(CanonicalError::Verification(
186 "delegation @id does not match its delegator, delegate and issue time".into(),
187 ));
188 }
189
190 Ok(parsed)
191}
192
193/// Parse a certificate into its typed view **without** verifying the proof.
194///

Calls 7

expect_typeFunction · 0.85
verify_valueFunction · 0.85
delegator_public_keyFunction · 0.85
delegate_public_keyFunction · 0.85
matches_public_keyMethod · 0.80
id_matchesMethod · 0.80
parseFunction · 0.70