ssh/algorithm/key_exchange/
ecdh_sha2_nistp256.rs1use super::{super::hash::HashType, KeyExchange};
2use ring::agreement::{EphemeralPrivateKey, PublicKey, UnparsedPublicKey, ECDH_P256};
3
4use crate::{SshError, SshResult};
5
6pub(super) struct EcdhP256 {
7 pub private_key: EphemeralPrivateKey,
8 pub public_key: PublicKey,
9}
10
11impl KeyExchange for EcdhP256 {
12 fn new() -> SshResult<Self> {
13 let rng = ring::rand::SystemRandom::new();
14 let private_key = match EphemeralPrivateKey::generate(&ECDH_P256, &rng) {
15 Ok(v) => v,
16 Err(e) => return Err(SshError::KexError(e.to_string())),
17 };
18 match private_key.compute_public_key() {
19 Ok(public_key) => Ok(EcdhP256 {
20 private_key,
21 public_key,
22 }),
23 Err(e) => Err(SshError::KexError(e.to_string())),
24 }
25 }
26
27 fn get_public_key(&self) -> &[u8] {
28 self.public_key.as_ref()
29 }
30
31 fn get_shared_secret(&self, puk: Vec<u8>) -> SshResult<Vec<u8>> {
32 let mut public_key = [0u8; 65];
33 public_key.copy_from_slice(&puk);
34 let server_pub = UnparsedPublicKey::new(&ECDH_P256, puk);
35 let private_key = unsafe { (&self.private_key as *const EphemeralPrivateKey).read() };
36 crate::algorithm::key_exchange::agree_ephemeral(private_key, &server_pub)
37 }
38
39 fn get_hash_type(&self) -> HashType {
40 HashType::SHA256
41 }
42}