sail_sdk/keys/
mod.rs

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}