Skip to content

Instantly share code, notes, and snippets.

@et4te
Created March 28, 2017 17:19
Show Gist options
  • Save et4te/780a37b8dcd67d98a181e4860b47cbf6 to your computer and use it in GitHub Desktop.
Save et4te/780a37b8dcd67d98a181e4860b47cbf6 to your computer and use it in GitHub Desktop.
JWK Rust Simple RSA
#[macro_use] extern crate serde_derive;
extern crate rustc_serialize;
extern crate openssl;
extern crate dotenv;
extern crate serde;
extern crate serde_json;
use rustc_serialize::base64::{self, ToBase64};
use std::path::Path;
use openssl::rsa::Rsa;
use openssl::bn::BigNumRef;
use openssl::types::{OpenSslType, OpenSslTypeRef};
use dotenv::dotenv;
use std::env;
// Utility to convert BigNumRefs to base64
fn bn_to_base64(bn: &BigNumRef) -> String {
bn.to_vec().to_base64(base64::URL_SAFE)
}
#[derive(Serialize, Deserialize)]
struct SecretKey {
pub kty: String,
pub n: String,
pub e: String,
pub d: String,
pub p: String,
pub q: String,
pub dp: String,
pub dq: String,
pub qi: String,
}
#[derive(Serialize, Deserialize)]
struct PublicKey {
pub kid: String,
pub kty: String,
pub n: String,
pub e: String,
}
// Using a path from the config generates JWKs
fn main() {
dotenv().ok();
let public_key_path: String = env::var("PUBLIC_KEY_PATH")
.expect("PUBLIC_KEY_PATH required");
let secret_key_path: String = env::var("SECRET_KEY_PATH")
.expect("SECRET_KEY_PATH required");
let public_key_path = Path::new(public_key_path.as_str()).join("public-key.json");
let secret_key_path = Path::new(secret_key_path.as_str()).join("secret-key.json");
println!("Running generate_keys ...");
println!("PUBLIC_KEY_PATH = {:?}", public_key_path.clone());
println!("SECRET_KEY_PATH = {:?}", secret_key_path.clone());
if secret_key_path.exists() {
println!("A secret key has already been generated for this service.")
} else {
let rsa = Rsa::generate(2048).unwrap();
let n = rsa.n().unwrap();
let d = rsa.d().unwrap();
let e = rsa.e().unwrap();
let p = rsa.p().unwrap();
let q = rsa.q().unwrap();
// get (dp, dq, qi)
unsafe {
let rsa_ptr = rsa.as_ptr();
if rsa_ptr.is_null() {
println!("Error, RSA pointer was null");
} else {
let dp = BigNumRef::from_ptr((*rsa_ptr).dmp1);
let dq = BigNumRef::from_ptr((*rsa_ptr).dmq1);
let qi = BigNumRef::from_ptr((*rsa_ptr).iqmp);
let secret_key = SecretKey {
kty: "RSA".to_string(),
n: bn_to_base64(n.clone()),
d: bn_to_base64(d),
e: bn_to_base64(e.clone()),
p: bn_to_base64(p),
q: bn_to_base64(q),
dp: bn_to_base64(dp),
dq: bn_to_base64(dq),
qi: bn_to_base64(qi),
};
let public_key = PublicKey {
kid: "dev-1".to_string(),
kty: "RSA".to_string(),
n: bn_to_base64(n),
e: bn_to_base64(e),
};
let secret_key_json = serde_json::to_string(&secret_key).unwrap();
let public_key_json = serde_json::to_string(&public_key).unwrap();
println!("Generated secret key = {}", secret_key_json);
println!("Generated public key = {}", public_key_json);
println!("Success");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment