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_json = "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)]
|
||||
extern crate biscuit;
|
||||
extern crate base64;
|
||||
extern crate hyper;
|
||||
extern crate ldap3;
|
||||
|
@ -8,6 +9,10 @@ extern crate tokio;
|
|||
extern crate serde_derive;
|
||||
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::str::{
|
||||
FromStr,
|
||||
from_utf8,
|
||||
|
@ -20,6 +25,34 @@ use hyper::header::{AUTHORIZATION};
|
|||
use hyper_router::{Route, RouterBuilder, RouterService};
|
||||
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 };
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -152,30 +185,48 @@ fn auth_handler(req: Request<Body>) -> Response<Body> {
|
|||
Response::new(Body::from(format!("BasicAuthentication {:?}", user)))
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct Key {
|
||||
pub e: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct JwksResponse {
|
||||
pub keys: Vec<Key>,
|
||||
fn jwk_from_pem(file_path: &Path) -> Result<JWK<Empty>, io::Error> {
|
||||
let key_bytes = fs::read(file_path)?;
|
||||
let rsa = Rsa::private_key_from_pem(key_bytes.as_slice()).unwrap();
|
||||
Ok(JWK {
|
||||
common: CommonParameters {
|
||||
algorithm: Some(Algorithm::Signature(SignatureAlgorithm::RS256)),
|
||||
key_id: Some(file_path.file_name().unwrap().to_str().unwrap().to_string()),
|
||||
..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> {
|
||||
let key = Key {
|
||||
e: "what".to_string(),
|
||||
let jwks: Vec<JWK<Empty>> = fs::read_dir("./").unwrap()
|
||||
.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 {
|
||||
keys: Vec::new(),
|
||||
let ext = match path.extension() {
|
||||
Some(ext) => ext.to_str().unwrap().to_owned(),
|
||||
None => return None,
|
||||
};
|
||||
response.keys.push(key);
|
||||
|
||||
let json_str = serde_json::to_string(&response).unwrap();
|
||||
match ext.as_ref() {
|
||||
"pem" => Some(jwk_from_pem(path.as_path()).unwrap()),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let jwks = JWKSet { keys: jwks };
|
||||
let jwks_json = serde_json::to_string(&jwks).unwrap();
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(Body::from(json_str))
|
||||
.body(Body::from(jwks_json))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue