1#![deny(missing_docs)]
4use rand::RngCore;
5
6pub use crate::{handshake::handshake_struct::PublicKey, peer_id::PeerId};
7
8pub mod codec;
10pub mod crypto;
12mod dh_compat;
13pub mod error;
15pub mod handshake;
17pub mod peer_id;
19mod secp256k1_compat;
21mod sha256_compat;
22mod support;
24
25pub type EphemeralPublicKey = Vec<u8>;
27
28#[derive(Clone, Debug)]
30pub struct SecioKeyPair {
31 inner: KeyPairInner,
32}
33
34impl SecioKeyPair {
35 pub fn secp256k1_generated() -> SecioKeyPair {
37 loop {
38 let mut key = [0; crate::secp256k1_compat::SECRET_KEY_SIZE];
39 rand::thread_rng().fill_bytes(&mut key);
40 if let Ok(private) = crate::secp256k1_compat::secret_key_from_slice(&key) {
41 return SecioKeyPair {
42 inner: KeyPairInner::Secp256k1 { private },
43 };
44 }
45 }
46 }
47
48 pub fn secp256k1_raw_key<K>(key: K) -> Result<SecioKeyPair, error::SecioError>
50 where
51 K: AsRef<[u8]>,
52 {
53 let private = crate::secp256k1_compat::secret_key_from_slice(key.as_ref())
54 .map_err(|_| error::SecioError::SecretGenerationFailed)?;
55
56 Ok(SecioKeyPair {
57 inner: KeyPairInner::Secp256k1 { private },
58 })
59 }
60
61 pub fn public_key(&self) -> PublicKey {
63 match self.inner {
64 KeyPairInner::Secp256k1 { ref private } => {
65 let pubkey = crate::secp256k1_compat::from_secret_key(private);
66 PublicKey {
67 key: crate::secp256k1_compat::serialize_pubkey(&pubkey),
68 }
69 }
70 }
71 }
72
73 pub fn peer_id(&self) -> PeerId {
75 self.public_key().peer_id()
76 }
77}
78
79#[derive(Clone)]
80enum KeyPairInner {
81 Secp256k1 {
82 private: crate::secp256k1_compat::SecretKey,
83 },
84}
85
86impl std::fmt::Debug for KeyPairInner {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 f.debug_struct("KeyPair").finish()
89 }
90}
91
92#[derive(Copy, Clone, Debug, PartialEq, Eq)]
94pub enum Digest {
95 Sha256,
97 Sha512,
99}
100
101impl Digest {
102 #[inline]
104 pub fn num_bytes(self) -> usize {
105 match self {
106 Digest::Sha256 => 256 / 8,
107 Digest::Sha512 => 512 / 8,
108 }
109 }
110}
111
112#[cfg_attr(feature = "async-sign", async_trait::async_trait)]
114pub trait KeyProvider: std::clone::Clone + Send + Sync + 'static {
115 type Error: Into<crate::error::SecioError>;
117
118 #[cfg(feature = "async-sign")]
120 async fn sign_ecdsa_async<T: AsRef<[u8]> + Send>(
121 &self,
122 message: T,
123 ) -> Result<Vec<u8>, Self::Error> {
124 self.sign_ecdsa(message)
125 }
126
127 fn sign_ecdsa<T: AsRef<[u8]>>(&self, message: T) -> Result<Vec<u8>, Self::Error>;
129
130 fn pubkey(&self) -> Vec<u8>;
132
133 fn verify_ecdsa<P, T, F>(&self, pubkey: P, message: T, signature: F) -> bool
135 where
136 P: AsRef<[u8]>,
137 T: AsRef<[u8]>,
138 F: AsRef<[u8]>;
139}
140
141impl KeyProvider for SecioKeyPair {
142 type Error = error::SecioError;
143
144 fn sign_ecdsa<T: AsRef<[u8]>>(&self, message: T) -> Result<Vec<u8>, Self::Error> {
145 let msg = match crate::secp256k1_compat::message_from_slice(message.as_ref()) {
146 Ok(m) => m,
147 Err(_) => {
148 log::debug!("message has wrong format");
149 return Err(error::SecioError::InvalidMessage);
150 }
151 };
152 let signature = match self.inner {
153 KeyPairInner::Secp256k1 { ref private } => crate::secp256k1_compat::sign(&msg, private),
154 };
155
156 Ok(crate::secp256k1_compat::signature_to_vec(signature))
157 }
158
159 fn pubkey(&self) -> Vec<u8> {
160 match self.inner {
161 KeyPairInner::Secp256k1 { ref private } => crate::secp256k1_compat::serialize_pubkey(
162 &crate::secp256k1_compat::from_secret_key(private),
163 ),
164 }
165 }
166
167 fn verify_ecdsa<P, T, F>(&self, pubkey: P, message: T, signature: F) -> bool
168 where
169 P: AsRef<[u8]>,
170 T: AsRef<[u8]>,
171 F: AsRef<[u8]>,
172 {
173 let signature = crate::secp256k1_compat::signature_from_der(signature.as_ref());
174 let msg = crate::secp256k1_compat::message_from_slice(message.as_ref());
175 let pubkey = crate::secp256k1_compat::pubkey_from_slice(pubkey.as_ref());
176
177 if let (Ok(signature), Ok(message), Ok(pubkey)) = (signature, msg, pubkey) {
178 if !crate::secp256k1_compat::verify(&message, &signature, &pubkey) {
179 log::debug!("failed to verify the remote's signature");
180 return false;
181 }
182 } else {
183 log::debug!("remote's secp256k1 signature has wrong format");
184 return false;
185 }
186 true
187 }
188}
189#[derive(Debug, Clone)]
191pub struct NoopKeyProvider;
192
193impl KeyProvider for NoopKeyProvider {
194 type Error = error::SecioError;
195
196 fn sign_ecdsa<T: AsRef<[u8]>>(&self, _message: T) -> Result<Vec<u8>, Self::Error> {
197 Err(error::SecioError::NotSupportKeyProvider)
198 }
199
200 fn pubkey(&self) -> Vec<u8> {
201 Vec::new()
202 }
203
204 fn verify_ecdsa<P, T, F>(&self, _pubkey: P, _message: T, _signature: F) -> bool
205 where
206 P: AsRef<[u8]>,
207 T: AsRef<[u8]>,
208 F: AsRef<[u8]>,
209 {
210 false
211 }
212}