-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(keybroker-client): add a client library and a demo application
The core of the functionality is provided as a library, with 2 main routines: - get_wrapped_key: is the core routine to get a key, with the crypto related to the ephemeral wrapping key left to the caller. - get_key: is a convenience routine which calls get_wrapped_key and handle the crypto when there is no specific requirement. The demo application illustrates how to use the client library to connect to the keybroker server and get an attestation. This enables running a demo of the 2 API calls needed to request the key, supply the evidence and RSA-decrypt the result. Co-authored-by: Paul Howard <paul.howard@arm.com> Signed-off-by: Arnaud de Grandmaison <arnaud.degrandmaison@arm.com>
- Loading branch information
1 parent
befccb3
commit 8b10f98
Showing
5 changed files
with
567 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,54 @@ | ||
// Copyright 2024 Contributors to the Veraison project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use clap::Parser; | ||
use keybroker_client::error::Error as KeybrokerError; | ||
use keybroker_client::{CcaExampleToken, KeyBrokerClient, TsmAttestationReport}; | ||
|
||
/// Structure for parsing and storing the command-line arguments | ||
#[derive(Clone, Parser, Debug)] | ||
#[command(version, about, long_about = None)] | ||
struct Args { | ||
/// The address this client should connect to to request a key. | ||
#[arg(short, long, default_value = "http://127.0.0.1:8088")] | ||
endpoint: String, | ||
|
||
/// The key to use | ||
#[arg(short, long, default_value = "skywalker")] | ||
key_name: String, | ||
|
||
/// Use a CCA example token (instead of the TSM report) | ||
#[arg(short, long, default_value_t = false)] | ||
mock_evidence: bool, | ||
|
||
/// Set the application verbosity | ||
#[arg(short, long, default_value_t = false)] | ||
verbose: bool, | ||
} | ||
|
||
fn main() { | ||
println!("Hello, world!"); | ||
let args = Args::parse(); | ||
|
||
let client = KeyBrokerClient::new(&args.endpoint, args.verbose); | ||
|
||
let attestation_result = if args.mock_evidence { | ||
client.get_key(&args.key_name, &CcaExampleToken {}) | ||
} else { | ||
client.get_key(&args.key_name, &TsmAttestationReport {}) | ||
}; | ||
|
||
match attestation_result { | ||
Ok(key) => { | ||
let plainstring_key = String::from_utf8(key).unwrap(); | ||
println!("Attestation success :-) ! The key returned from the keybroker is '{plainstring_key}'") | ||
} | ||
|
||
Err(error) => { | ||
if let KeybrokerError::AttestationFailure(reason, details) = error { | ||
println!("Attestation failure :-( ! {reason}: {details}") | ||
} else { | ||
panic!("The key request failed with: {error:?}"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright 2024 Contributors to the Veraison project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use thiserror::Error; | ||
|
||
/// Top-level error type for a keybroker client. | ||
#[derive(Error, Debug)] | ||
pub enum Error { | ||
/// Represents genuine attestation failures. | ||
#[error("Attestation failure: {0} ({1})")] | ||
AttestationFailure(String, String), | ||
/// Represents all kind of runtime errors that can be faced by a client, like a bogus HTTP connection for example. | ||
#[error(transparent)] | ||
RuntimeError(#[from] RuntimeErrorKind), | ||
} | ||
|
||
/// Enumeration holding the different kind of runtime errors (in contrast to genuine | ||
/// attestation failure) that a client can get. | ||
#[derive(Error, Debug)] | ||
pub enum RuntimeErrorKind { | ||
/// Can not connect to the keybroker server. | ||
#[error("HTTP connection to {0} failed with error: {1}")] | ||
HTTPConnect(String, String), | ||
|
||
/// Unexpected response from the keybroker server. | ||
#[error("Unhandled HTTP response: {0}")] | ||
HTTPResponse(String), | ||
|
||
/// Represents errors due to base64 decoding. | ||
#[error("Failed to base64-decode {0} with error: {1}")] | ||
Base64Decode(String, String), | ||
|
||
/// Represents errors due to base64 decoding. | ||
#[error("Failed to JSON-deserialize {0} with error: {1}")] | ||
JSONDeserialize(String, String), | ||
|
||
/// Represents errors related to TSM report generation. | ||
#[error(transparent)] | ||
TSMReport(#[from] tsm_report::TsmReportError), | ||
|
||
/// Represents errors in the key decryption. | ||
#[error("Failed to decrypt {0} with error: {1}")] | ||
Decrypt(String, String), | ||
|
||
/// Represents errors in the retrieval of the challenge from the keybroker server. | ||
#[error("Challenge retrieval error: {0}")] | ||
ChallengeRetrieval(String), | ||
|
||
/// Represents the error when the challenge has an incorrect number of bytes. | ||
#[error("Challenge length error, expecting {0} but got {1} instead")] | ||
ChallengeLength(usize, usize), | ||
|
||
/// Represents error that occured when attempting to generate the evidence. | ||
#[error("Evidence generation error: {0}")] | ||
EvidenceGeneration(String), | ||
|
||
/// Used when the response from the keybroker is missing the location field. | ||
#[error("Missing location field in HTTP requets")] | ||
MissingLocation, | ||
} | ||
|
||
pub type Result<T> = std::result::Result<T, Error>; |
Oops, something went wrong.