Skip to content

Instantly share code, notes, and snippets.

@zbroyar
Created December 28, 2010 02:33
Show Gist options
  • Save zbroyar/756823 to your computer and use it in GitHub Desktop.
Save zbroyar/756823 to your computer and use it in GitHub Desktop.
Converter of PEM RSA private key to OCaml Cryptokit
#!/usr/bin/env ocaml
(*
Prerequisites: Findlib, Pcre, Cryptokit
Usage: openssl rsa -in privkey.pem -text | ./pem2ck.ml > privkey.cryptokit
*)
#use "topfind" ;;
#require "pcre" ;;
#require "cryptokit" ;;
open Printf ;;
open Cryptokit ;;
open Cryptokit.RSA ;;
let empty_subst = Pcre.subst "" ;;
let repl_rex = Pcre.regexp "[[:space:]]|:" ;;
let data_rex = Pcre.regexp "^[[:space:]]{4}([[:alnum:]]+:?)" ;;
let if_match s rex = try ignore(Pcre.exec ~rex s); true with Not_found -> false ;;
let clean_string s = Pcre.replace ~rex:repl_rex ~itempl:empty_subst s ;;
let key = {
size = 0; n = ""; e = ""; d = "";
p = ""; q = ""; dp = ""; dq = "";
qinv = "";
} ;;
let set_size key subs = {key with size = int_of_string (Pcre.get_substring subs 1)} ;;
let set_e key subs = {key with e = Pcre.get_substring subs 1} ;;
let set_n key str = {key with n = key.n ^ (clean_string str)} ;;
let set_d key str = {key with d = key.d ^ (clean_string str)} ;;
let set_p key str = {key with p = key.p ^ (clean_string str)} ;;
let set_q key str = {key with q = key.q ^ (clean_string str)} ;;
let set_dp key str = {key with dp = key.dp ^ (clean_string str)} ;;
let set_dq key str = {key with dq = key.dq ^ (clean_string str)} ;;
let set_qinv key str = {key with qinv = key.qinv ^ (clean_string str)} ;;
let keys = [
Pcre.regexp "^Private-Key: \\(([[:digit:]]+) bit\\)$", None, Some set_size;
Pcre.regexp "^modulus:", Some set_n, None;
Pcre.regexp "^publicExponent: ([[:digit:]]+) .*$", None, Some set_e;
Pcre.regexp "^privateExponent:", Some set_d, None;
Pcre.regexp "^prime1:", Some set_p, None;
Pcre.regexp "^prime2:", Some set_q, None;
Pcre.regexp "^exponent1:", Some set_dp, None;
Pcre.regexp "^exponent2:", Some set_dq, None;
Pcre.regexp "^coefficient:", Some set_qinv, None;
Pcre.regexp "^-----BEGIN RSA PRIVATE KEY-----", None, None
] ;;
let rec loop ch key updater =
let matcher line (rex,_,_) = if_match line rex in
let line = input_line ch in
if (if_match line data_rex)
then loop ch (updater key line) updater
else begin
match (List.find (matcher line) keys) with
rex, None, Some once ->
let subs = Pcre.exec ~rex line in
loop ch (once key subs) updater
| rex, Some updater, None ->
loop ch key updater
| _ -> key
end
;;
let _ =
let from_string s =
transform_string (Hexa.decode()) s
and key = loop stdin key set_n in
output_value stdout {
key with
n = from_string key.n;
(*e = from_string key.e;*)
d = from_string key.d;
p = from_string key.p;
q = from_string key.q;
dp = from_string key.dp;
dq = from_string key.dq;
qinv = from_string key.qinv;
}
;;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment