Use biscuit's JWK structures to format /get_keys.
New method to load a .pem and a loop over current dir for any .pem
This commit is contained in:
parent
467a449457
commit
e6f9148865
|
@ -14,3 +14,7 @@ base64 = "0.10.0"
|
||||||
serde = "1.0.40"
|
serde = "1.0.40"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
serde_derive = "1.0.40"
|
serde_derive = "1.0.40"
|
||||||
|
biscuit = "0.3.1"
|
||||||
|
ring = "0.16.5"
|
||||||
|
num = "0.2"
|
||||||
|
openssl = "0.10.28"
|
||||||
|
|
83
src/main.rs
83
src/main.rs
|
@ -1,4 +1,5 @@
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
extern crate biscuit;
|
||||||
extern crate base64;
|
extern crate base64;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
extern crate ldap3;
|
extern crate ldap3;
|
||||||
|
@ -8,6 +9,10 @@ extern crate tokio;
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::io;
|
||||||
|
use std::fs;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::Path;
|
||||||
use std::str::{
|
use std::str::{
|
||||||
FromStr,
|
FromStr,
|
||||||
from_utf8,
|
from_utf8,
|
||||||
|
@ -20,6 +25,34 @@ use hyper::header::{AUTHORIZATION};
|
||||||
use hyper_router::{Route, RouterBuilder, RouterService};
|
use hyper_router::{Route, RouterBuilder, RouterService};
|
||||||
use base64::decode;
|
use base64::decode;
|
||||||
|
|
||||||
|
use ring::signature::RsaKeyPair;
|
||||||
|
use biscuit::{
|
||||||
|
ClaimsSet,
|
||||||
|
Empty,
|
||||||
|
JWT,
|
||||||
|
RegisteredClaims,
|
||||||
|
SingleOrMultiple,
|
||||||
|
};
|
||||||
|
use biscuit::jwa::{
|
||||||
|
SignatureAlgorithm,
|
||||||
|
Algorithm,
|
||||||
|
};
|
||||||
|
use biscuit::jwk::{
|
||||||
|
RSAKeyParameters,
|
||||||
|
CommonParameters,
|
||||||
|
AlgorithmParameters,
|
||||||
|
JWK,
|
||||||
|
JWKSet,
|
||||||
|
};
|
||||||
|
use biscuit::jws::{
|
||||||
|
Secret,
|
||||||
|
RegisteredHeader,
|
||||||
|
};
|
||||||
|
use num::BigUint;
|
||||||
|
use openssl::bn::BigNum;
|
||||||
|
use openssl::rsa::Rsa;
|
||||||
|
use openssl::rsa::RsaPrivateKeyBuilder;
|
||||||
|
|
||||||
use ldap3::{ LdapConn, Scope, SearchEntry };
|
use ldap3::{ LdapConn, Scope, SearchEntry };
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -152,30 +185,48 @@ fn auth_handler(req: Request<Body>) -> Response<Body> {
|
||||||
Response::new(Body::from(format!("BasicAuthentication {:?}", user)))
|
Response::new(Body::from(format!("BasicAuthentication {:?}", user)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
fn jwk_from_pem(file_path: &Path) -> Result<JWK<Empty>, io::Error> {
|
||||||
struct Key {
|
let key_bytes = fs::read(file_path)?;
|
||||||
pub e: String,
|
let rsa = Rsa::private_key_from_pem(key_bytes.as_slice()).unwrap();
|
||||||
}
|
Ok(JWK {
|
||||||
|
common: CommonParameters {
|
||||||
#[derive(Debug, Serialize)]
|
algorithm: Some(Algorithm::Signature(SignatureAlgorithm::RS256)),
|
||||||
struct JwksResponse {
|
key_id: Some(file_path.file_name().unwrap().to_str().unwrap().to_string()),
|
||||||
pub keys: Vec<Key>,
|
..Default::default()
|
||||||
|
},
|
||||||
|
algorithm: AlgorithmParameters::RSA(RSAKeyParameters {
|
||||||
|
n: BigUint::from_bytes_be(&rsa.n().to_vec()),
|
||||||
|
e: BigUint::from_bytes_be(&rsa.e().to_vec()),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
additional: Default::default(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_keys(_req: Request<Body>) -> Response<Body> {
|
fn get_keys(_req: Request<Body>) -> Response<Body> {
|
||||||
let key = Key {
|
let jwks: Vec<JWK<Empty>> = fs::read_dir("./").unwrap()
|
||||||
e: "what".to_string(),
|
.filter_map(|dir_entry| {
|
||||||
|
let path = dir_entry.unwrap().path();
|
||||||
|
let filename = match path.file_name() {
|
||||||
|
Some(filename) => filename.to_str().unwrap().to_owned(),
|
||||||
|
None => return None,
|
||||||
};
|
};
|
||||||
let mut response = JwksResponse {
|
let ext = match path.extension() {
|
||||||
keys: Vec::new(),
|
Some(ext) => ext.to_str().unwrap().to_owned(),
|
||||||
|
None => return None,
|
||||||
};
|
};
|
||||||
response.keys.push(key);
|
match ext.as_ref() {
|
||||||
|
"pem" => Some(jwk_from_pem(path.as_path()).unwrap()),
|
||||||
let json_str = serde_json::to_string(&response).unwrap();
|
_ => None,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let jwks = JWKSet { keys: jwks };
|
||||||
|
let jwks_json = serde_json::to_string(&jwks).unwrap();
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(StatusCode::OK)
|
.status(StatusCode::OK)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.body(Body::from(json_str))
|
.body(Body::from(jwks_json))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue