1use anyhow::Error as AnyhowError;
2use cached::proc_macro::once;
3use rand::SeedableRng;
4use rand_chacha::ChaCha20Rng;
5use reqwest;
6use sev_snp_utilities::guest::derived_key::derived_key::DerivedKey;
7use sev_snp_utilities::guest::derived_key::get_derived_key::DerivedKeyRequestBuilder;
8use sev_snp_utilities::guest::derived_key::get_derived_key::DerivedKeyRequester;
9use sha2::{Digest, Sha256};
10use solana_sdk::signer::keypair::keypair_from_seed;
11
12pub const DEFAULT_DK_URL: &str = "http://127.0.0.1:8006/aa/derived_key";
13
14#[once(result = true)]
15pub fn get_derived_key() -> Result<[u8; 32], AnyhowError> {
16 let coco_attest_service = DEFAULT_DK_URL.to_string();
17 println!("Debug: Using URL: {}", coco_attest_service);
18
19 let client = reqwest::blocking::Client::new();
20
21 let response = match client.get(coco_attest_service).send() {
22 Ok(r) => {
23 println!("Debug: Got response with status: {}", r.status());
24 if !r.status().is_success() {
25 return Err(anyhow::anyhow!(
26 "server returned error status: {}",
27 r.status()
28 ));
29 }
30 r
31 }
32 Err(e) => {
33 println!("Debug: Request failed: {:?}", e);
34 return Err(e.into());
35 }
36 };
37
38 let derived_key = match response.bytes() {
39 Ok(b) => {
40 if b.is_empty() {
41 return Err(anyhow::anyhow!("server returned empty response"));
42 }
43 b
44 }
45 Err(e) => {
46 println!("Debug: Failed to get text: {:?}", e);
47 return Err(e.into());
48 }
49 };
50
51 if derived_key.len() != 32 {
52 return Err(anyhow::anyhow!(
53 "expected 32 bytes, got {} bytes",
54 derived_key.len()
55 ));
56 }
57
58 let array: [u8; 32] = derived_key
59 .to_vec()
60 .try_into()
61 .map_err(|_| anyhow::anyhow!("failed to convert bytes to array"))?;
62
63 Ok(array)
64}
65
66pub struct EnclaveKeys;
67impl EnclaveKeys {
68 pub fn get_derived_key() -> Result<[u8; 32], AnyhowError> {
69 get_derived_key()
70 }
71
72 pub fn get_derived_key_with_options(
73 mut options: DerivedKeyRequestBuilder,
74 ) -> Result<[u8; 32], AnyhowError> {
75 let derived_key = DerivedKey::request(options.build())?;
76 Ok(derived_key.into())
77 }
78
79 pub fn get_enclave_ed25519_keypair() -> Result<[u8; 64], AnyhowError> {
80 let derived_key = Self::get_derived_key()?;
81 let keypair =
82 keypair_from_seed(&derived_key).map_err(|e| AnyhowError::msg(e.to_string()))?;
83 Ok(keypair.to_bytes())
84 }
85
86 pub fn get_enclave_secp256k1_keypair() -> Result<[u8; 32], AnyhowError> {
87 let source = Self::get_derived_key()?;
88 let mut rng = ChaCha20Rng::from_seed(Sha256::digest(&source).into());
89 let secp_key = libsecp256k1::SecretKey::random(&mut rng);
90 Ok(secp_key.serialize())
91 }
92}