server.rs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. use std::net::SocketAddr;
  2. use std::path::Path;
  3. use tonic::transport::{Certificate, Identity, Server, ServerTlsConfig};
  4. use tonic::{Request, Response, Status};
  5. use crate::proto::{self, signatory_server};
  6. use crate::signatory::Signatory;
  7. pub struct CdkSignatoryServer<T>
  8. where
  9. T: Signatory + Send + Sync + 'static,
  10. {
  11. inner: T,
  12. }
  13. #[tonic::async_trait]
  14. impl<T> signatory_server::Signatory for CdkSignatoryServer<T>
  15. where
  16. T: Signatory + Send + Sync + 'static,
  17. {
  18. async fn blind_sign(
  19. &self,
  20. request: Request<proto::BlindedMessages>,
  21. ) -> Result<Response<proto::BlindSignResponse>, Status> {
  22. let result = match self
  23. .inner
  24. .blind_sign(
  25. request
  26. .into_inner()
  27. .blinded_messages
  28. .into_iter()
  29. .map(|blind_message| blind_message.try_into())
  30. .collect::<Result<Vec<_>, _>>()?,
  31. )
  32. .await
  33. {
  34. Ok(blind_signatures) => proto::BlindSignResponse {
  35. sigs: Some(proto::BlindSignatures {
  36. blind_signatures: blind_signatures
  37. .into_iter()
  38. .map(|blind_sign| blind_sign.into())
  39. .collect(),
  40. }),
  41. ..Default::default()
  42. },
  43. Err(err) => proto::BlindSignResponse {
  44. error: Some(err.into()),
  45. ..Default::default()
  46. },
  47. };
  48. Ok(Response::new(result))
  49. }
  50. async fn verify_proofs(
  51. &self,
  52. request: Request<proto::Proofs>,
  53. ) -> Result<Response<proto::BooleanResponse>, Status> {
  54. let result = match self
  55. .inner
  56. .verify_proofs(
  57. request
  58. .into_inner()
  59. .proof
  60. .into_iter()
  61. .map(|x| x.try_into())
  62. .collect::<Result<Vec<_>, _>>()?,
  63. )
  64. .await
  65. {
  66. Ok(()) => proto::BooleanResponse {
  67. success: true,
  68. ..Default::default()
  69. },
  70. Err(cdk_common::Error::DHKE(_)) => proto::BooleanResponse {
  71. success: false,
  72. ..Default::default()
  73. },
  74. Err(err) => proto::BooleanResponse {
  75. error: Some(err.into()),
  76. ..Default::default()
  77. },
  78. };
  79. Ok(Response::new(result))
  80. }
  81. async fn keysets(
  82. &self,
  83. _request: Request<proto::EmptyRequest>,
  84. ) -> Result<Response<proto::KeysResponse>, Status> {
  85. let result = match self.inner.keysets().await {
  86. Ok(result) => proto::KeysResponse {
  87. keysets: Some(result.into()),
  88. ..Default::default()
  89. },
  90. Err(err) => proto::KeysResponse {
  91. error: Some(err.into()),
  92. ..Default::default()
  93. },
  94. };
  95. Ok(Response::new(result))
  96. }
  97. async fn rotate_keyset(
  98. &self,
  99. request: Request<proto::RotationRequest>,
  100. ) -> Result<Response<proto::KeyRotationResponse>, Status> {
  101. let mint_keyset_info = match self
  102. .inner
  103. .rotate_keyset(request.into_inner().try_into()?)
  104. .await
  105. {
  106. Ok(result) => proto::KeyRotationResponse {
  107. keyset: Some(result.into()),
  108. ..Default::default()
  109. },
  110. Err(err) => proto::KeyRotationResponse {
  111. error: Some(err.into()),
  112. ..Default::default()
  113. },
  114. };
  115. Ok(Response::new(mint_keyset_info))
  116. }
  117. }
  118. #[derive(thiserror::Error, Debug)]
  119. pub enum Error {
  120. /// Transport error
  121. #[error(transparent)]
  122. Transport(#[from] tonic::transport::Error),
  123. /// Io error
  124. #[error(transparent)]
  125. Io(#[from] std::io::Error),
  126. }
  127. /// Runs the signatory server
  128. pub async fn grpc_server<T, I: AsRef<Path>>(
  129. signatory: T,
  130. addr: SocketAddr,
  131. tls_dir: Option<I>,
  132. ) -> Result<(), Error>
  133. where
  134. T: Signatory + Send + Sync + 'static,
  135. {
  136. tracing::info!("Starting RPC server {}", addr);
  137. let mut server = match tls_dir {
  138. Some(tls_dir) => {
  139. tracing::info!("TLS configuration found, starting secure server");
  140. let tls_dir = tls_dir.as_ref();
  141. let server_pem_path = tls_dir.join("server.pem");
  142. let server_key_path = tls_dir.join("server.key");
  143. let ca_pem_path = tls_dir.join("ca.pem");
  144. if !server_pem_path.exists() {
  145. tracing::error!(
  146. "Server certificate file does not exist: {}",
  147. server_pem_path.display()
  148. );
  149. return Err(Error::Io(std::io::Error::new(
  150. std::io::ErrorKind::NotFound,
  151. format!(
  152. "Server certificate file not found: {}",
  153. server_pem_path.display()
  154. ),
  155. )));
  156. }
  157. if !server_key_path.exists() {
  158. tracing::error!(
  159. "Server key file does not exist: {}",
  160. server_key_path.display()
  161. );
  162. return Err(Error::Io(std::io::Error::new(
  163. std::io::ErrorKind::NotFound,
  164. format!("Server key file not found: {}", server_key_path.display()),
  165. )));
  166. }
  167. if !ca_pem_path.exists() {
  168. tracing::error!(
  169. "CA certificate file does not exist: {}",
  170. ca_pem_path.display()
  171. );
  172. return Err(Error::Io(std::io::Error::new(
  173. std::io::ErrorKind::NotFound,
  174. format!("CA certificate file not found: {}", ca_pem_path.display()),
  175. )));
  176. }
  177. let cert = std::fs::read_to_string(&server_pem_path)?;
  178. let key = std::fs::read_to_string(&server_key_path)?;
  179. let client_ca_cert = std::fs::read_to_string(&ca_pem_path)?;
  180. let client_ca_cert = Certificate::from_pem(client_ca_cert);
  181. let server_identity = Identity::from_pem(cert, key);
  182. let tls_config = ServerTlsConfig::new()
  183. .identity(server_identity)
  184. .client_ca_root(client_ca_cert);
  185. Server::builder().tls_config(tls_config)?
  186. }
  187. None => {
  188. tracing::warn!("No valid TLS configuration found, starting insecure server");
  189. Server::builder()
  190. }
  191. };
  192. server
  193. .add_service(signatory_server::SignatoryServer::new(CdkSignatoryServer {
  194. inner: signatory,
  195. }))
  196. .serve(addr)
  197. .await?;
  198. Ok(())
  199. }