actix_web_detached_jws_middleware/
lib.rs

1//! Actix-web middleware to sign and verify detached jws ([Detached JWS](https://medium.com/gin-and-tonic/implementing-detached-json-web-signature-9ca5665ddcfc))
2//!
3//! # Example:
4//! ```ignore
5//! use std::{io::Read, sync::Arc};
6//! 
7//! use actix_web::{
8//!     dev::ServiceRequest,
9//!     error::{ErrorForbidden, ErrorInternalServerError},
10//!     web::{self},
11//!     App, Error, HttpServer, Responder,
12//! };
13//! use actix_web_detached_jws_middleware::{
14//!     DetachedJwsSign, DetachedJwsSignConfig, DetachedJwsVerify, DetachedJwsVerifyConfig,
15//!     VerifyErrorType,
16//! };
17//! use detached_jws::JwsHeader;
18//! use futures::future::{ready, Ready};
19//! use openssl::{
20//!     hash::MessageDigest,
21//!     pkcs12::{ParsedPkcs12, Pkcs12},
22//!     rsa::Padding,
23//!     sign::{Signer, Verifier},
24//! };
25//! 
26//! async fn index() -> impl Responder {
27//!     "this_is_response_body"
28//! }
29//! 
30//! #[actix_web::main]
31//! async fn main() -> std::io::Result<()> {
32//!     let config = Arc::new(Config::new());
33//! 
34//!     HttpServer::new(move || {
35//!         App::new()
36//!             .service(
37//!                 web::resource("/protected")
38//!                     .wrap(DetachedJwsVerify::new(config.clone()))
39//!                     .wrap(DetachedJwsSign::new(config.clone()))
40//!                     .route(web::post().to(index)),
41//!             )
42//!             .service(web::resource("/simple").route(web::post().to(index)))
43//!     })
44//!     .bind("127.0.0.1:8080")?
45//!     .run()
46//!     .await
47//! }
48//! 
49//! struct Config {
50//!     cert_rs256: ParsedPkcs12,
51//!     cert_ps256: ParsedPkcs12,
52//! }
53//! 
54//! impl Config {
55//!     fn new() -> Self {
56//!         let load_pkcs12 = |path, pass| {
57//!             let mut file = std::fs::File::open(path).unwrap();
58//!             let mut pkcs12 = vec![];
59//!             file.read_to_end(&mut pkcs12).unwrap();
60//! 
61//!             let pkcs12 = Pkcs12::from_der(&pkcs12).unwrap();
62//!             pkcs12.parse(pass).unwrap()
63//!         };
64//! 
65//!         Self {
66//!             cert_rs256: load_pkcs12("examples/cert_for_rs256.pfx", "123456"),
67//!             cert_ps256: load_pkcs12("examples/cert_for_ps256.pfx", "123456"),
68//!         }
69//!     }
70//! }
71//! 
72//! impl<'a> DetachedJwsVerifyConfig<'a> for Config {
73//!     type Verifier = Verifier<'a>;
74//!     type ErrorHandler = Ready<Error>;
75//! 
76//!     fn get_verifier(&'a self, h: &JwsHeader) -> Option<Self::Verifier> {
77//!         match h.get("alg")?.as_str()? {
78//!             "RS256" => {
79//!                 let mut verifier =
80//!                     Verifier::new(MessageDigest::sha256(), &self.cert_rs256.pkey).unwrap();
81//!                 verifier.set_rsa_padding(Padding::PKCS1).unwrap();
82//!                 Some(verifier)
83//!             }
84//!             "PS256" => {
85//!                 let mut verifier =
86//!                     Verifier::new(MessageDigest::sha256(), &self.cert_ps256.pkey).unwrap();
87//!                 verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
88//!                 Some(verifier)
89//!             }
90//!             _ => None,
91//!         }
92//!     }
93//! 
94//!     fn error_handler(
95//!         &'a self,
96//!         _: &'a mut ServiceRequest,
97//!         error: VerifyErrorType,
98//!     ) -> Self::ErrorHandler {
99//!         ready(match error {
100//!             VerifyErrorType::HeaderNotFound => ErrorForbidden("Header Not Found"),
101//!             VerifyErrorType::IncorrectSignature => ErrorForbidden("Incorrect Signature"),
102//!             VerifyErrorType::Other(e) => ErrorInternalServerError(e),
103//!         })
104//!     }
105//! }
106//! 
107//! impl<'a> DetachedJwsSignConfig<'a> for Config {
108//!     type Signer = Signer<'a>;
109//! 
110//!     fn get_signer(&'a self) -> (Self::Signer, String, JwsHeader) {
111//!         let mut signer = Signer::new(MessageDigest::sha256(), &self.cert_ps256.pkey).unwrap();
112//!         signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
113//! 
114//!         (signer, "PS256".into(), JwsHeader::new())
115//!     }
116//! }
117//! 
118//! ```
119pub mod sign;
120pub mod verify;
121
122pub use crate::sign::{DetachedJwsSign, DetachedJwsSignConfig};
123pub use crate::verify::{DetachedJwsVerify, DetachedJwsVerifyConfig, VerifyErrorType};