Add bearer challenge-response proofs

This commit is contained in:
Eric Wendland 2026-05-19 19:08:08 +02:00
commit 72cd018a3e
11 changed files with 444 additions and 10 deletions

View file

@ -1224,7 +1224,7 @@ fn bearer_access_create_list_revoke_uses_resource_scoped_auth_ops() {
geth_control::ControlRequest::SecretBearerCreate {
resource: "resource:cas:local".to_owned(),
capabilities: vec!["cas.fetch".to_owned(), "cas.pin".to_owned()],
expires_at_ms: Some(1234),
expires_at_ms: Some(4_102_444_800_000),
},
)
.expect("create bearer");
@ -1232,7 +1232,10 @@ fn bearer_access_create_list_revoke_uses_resource_scoped_auth_ops() {
geth_control::ControlResponse::SecretBearerCreated { access } => {
assert_eq!(access.resource.to_string(), "resource:cas:local");
assert_eq!(access.capabilities.len(), 2);
assert_eq!(access.expires_at.map(|expires_at| expires_at.0), Some(1234));
assert_eq!(
access.expires_at.map(|expires_at| expires_at.0),
Some(4_102_444_800_000)
);
assert!(!access.may_delegate);
access.secret.to_string()
}
@ -1250,6 +1253,79 @@ fn bearer_access_create_list_revoke_uses_resource_scoped_auth_ops() {
other => panic!("unexpected response: {other:?}"),
}
let response = geth_node::handle_request(
&node,
geth_control::ControlRequest::SecretBearerChallenge {
resource: "resource:cas:local".to_owned(),
capabilities: vec!["cas.fetch".to_owned()],
},
)
.expect("create bearer challenge");
let nonce = match response {
geth_control::ControlResponse::SecretBearerChallenge { challenge } => {
assert_eq!(challenge.resource.to_string(), "resource:cas:local");
assert_eq!(challenge.capabilities[0].to_string(), "cas.fetch");
challenge.nonce
}
other => panic!("unexpected response: {other:?}"),
};
let response = geth_node::handle_request(
&node,
geth_control::ControlRequest::SecretBearerProve {
secret: secret.clone(),
resource: "resource:cas:local".to_owned(),
capabilities: vec!["cas.fetch".to_owned()],
nonce: nonce.clone(),
},
)
.expect("prove bearer challenge");
let proof_response = match response {
geth_control::ControlResponse::SecretBearerProof { proof } => {
assert_eq!(proof.secret.to_string(), secret);
assert_eq!(proof.resource.to_string(), "resource:cas:local");
assert!(!proof.response.is_empty());
proof.response
}
other => panic!("unexpected response: {other:?}"),
};
let response = geth_node::handle_request(
&node,
geth_control::ControlRequest::SecretBearerVerify {
secret: secret.clone(),
resource: "resource:cas:local".to_owned(),
capabilities: vec!["cas.fetch".to_owned()],
nonce: nonce.clone(),
response: proof_response.clone(),
},
)
.expect("verify bearer proof");
match response {
geth_control::ControlResponse::SecretBearerVerified { verified, .. } => {
assert!(verified);
}
other => panic!("unexpected response: {other:?}"),
}
let response = geth_node::handle_request(
&node,
geth_control::ControlRequest::SecretBearerVerify {
secret: secret.clone(),
resource: "resource:cas:local".to_owned(),
capabilities: vec!["cas.pin".to_owned()],
nonce,
response: proof_response,
},
)
.expect("verify bearer proof for wrong capability");
match response {
geth_control::ControlResponse::SecretBearerVerified {
verified, reason, ..
} => {
assert!(!verified);
assert!(reason.contains("did not match"));
}
other => panic!("unexpected response: {other:?}"),
}
geth_node::handle_request(
&node,
geth_control::ControlRequest::SecretBearerRevoke {