summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorUlf Wiger <ulf@feuerlabs.com>2015-07-25 20:55:00 +0200
committerUlf Wiger <ulf@feuerlabs.com>2015-07-25 20:55:00 +0200
commit6b917d5a51f34acd4f48f00b965a0b487e34eca4 (patch)
tree20c9ae1257cb16d8ad43879e59856a149bb6560c /components
parent144501bdd0138306f36d3a2e3545bb10e059b56f (diff)
downloadrvi_core-6b917d5a51f34acd4f48f00b965a0b487e34eca4.tar.gz
Add functionality to author.erl
Diffstat (limited to 'components')
-rwxr-xr-xcomponents/authorize/authorbin392648 -> 397021 bytes
-rw-r--r--components/authorize/src/author.erl141
2 files changed, 120 insertions, 21 deletions
diff --git a/components/authorize/author b/components/authorize/author
index bbfc038..24e6154 100755
--- a/components/authorize/author
+++ b/components/authorize/author
Binary files differ
diff --git a/components/authorize/src/author.erl b/components/authorize/src/author.erl
index 530f074..9b869b1 100644
--- a/components/authorize/src/author.erl
+++ b/components/authorize/src/author.erl
@@ -17,18 +17,24 @@ main([]) ->
main(Args) ->
Opts = opts(Args),
check_verbose(Opts),
- {_, Cmd} = lists:keyfind(command, 1, Opts),
- ?verbose("Cmd = ~p; Options = ~p~n",
- [Cmd, lists:keydelete(command, 1, Opts)]),
- cmd(Cmd, Opts).
-
-opts(["-v" , "true" |T]) -> [{verbose, true}|opts(T)];
-opts(["-v" , "false" |T]) -> [{verbose, false}|opts(T)];
-opts(["-v" |T]) -> [{verbose, true}|opts(T)];
+ case lists:keyfind(command, 1, Opts) of
+ {_, Cmd} ->
+ ?verbose("Cmd = ~p; Options = ~p~n",
+ [Cmd, lists:keydelete(command, 1, Opts)]),
+ cmd(Cmd, Opts);
+ false ->
+ fail("No command given~n", [])
+ end.
+
+opts(["-v" , "true" |T]) -> [{v, true}|opts(T)];
+opts(["-v" , "false" |T]) -> [{v, false}|opts(T)];
+opts(["-v" |T]) -> [{v, true}|opts(T)];
opts(["-pub" , PubKey |T]) -> [{pub, PubKey}|opts(T)];
opts(["-root", RootKey |T]) -> [{root, RootKey}|opts(T)];
+opts(["-sig", SigFile |T]) -> [{sig, SigFile}|opts(T)];
opts(["-o" , OutF |T]) -> [{out, OutF}|opts(T)];
opts(["-c" , Cert |T]) -> [{cert, Cert}|opts(T)];
+opts(["-b" , Bits |T]) -> [{b, l2i(Bits)}|opts(T)];
opts(["-fmt" , Fmt |T]) -> [{fmt, Fmt}|opts(T)];
opts([Cmd]) ->
[{command, Cmd}];
@@ -36,7 +42,7 @@ opts([]) ->
[].
check_verbose(Opts) ->
- V = get_value(verbose, Opts, false),
+ V = get_value(v, Opts, false),
put({?MODULE, verbose}, V),
V.
@@ -50,19 +56,89 @@ cmd("make_auth", Opts) ->
{_Root, undefined, "jwt"} ->
fail("Cannot create JWT without pub key~n", []);
{Root, Pub, Fmt} ->
- case authorize_keys:get_key_pair_from_pem(openssl, Root) of
- {undefined, undefined} ->
- fail("Cannot read root key (~p)~n", [Root]);
- {RPriv, _RPub} ->
- case authorize_keys:get_pub_key(Pub) of
- undefined ->
- fail("Cannot read pub key (~p)~n", [Pub]);
- PubKey ->
- make_auth(RPriv, PubKey, Fmt, Opts)
- end
- end
+ {RPriv, _} = get_key_pair(Root),
+ PubKey = get_pub_key(Pub),
+ make_auth(RPriv, PubKey, Fmt, Opts)
+ end;
+cmd("make_root", Opts) ->
+ [Out] = mandatory([out], Opts),
+ Bits = bits(Opts),
+ make_root(Out, Bits, Opts);
+cmd("make_dev", Opts) ->
+ [Root, Out] = mandatory([root, out], Opts),
+ Bits = bits(Opts),
+ make_dev(Root, Out, Bits, Opts);
+cmd("read_sig", Opts) ->
+ [Root, Sig] = mandatory([root, sig], Opts),
+ {_, Pub} = get_key_pair(Root),
+ case file:read_file(Sig) of
+ {ok, JWT} ->
+ case authorize_sig:decode_jwt(JWT, Pub) of
+ invalid ->
+ fail("Cannot validate ~s~n", [Sig]);
+ {Header, Payload} ->
+ io:fwrite("Header: ~s~n"
+ "Payload: ~s~n",
+ [exo_json:encode(Header),
+ exo_json:encode(Payload)])
+ end;
+ {error, E} ->
+ fail("Cannot read ~s (~w)~n", [Sig, E])
+ end.
+
+make_root_msg(X) ->
+ {"~s_priv.pem - private root key~n"
+ "~s_pub.pem - public root key~n"
+ "~n"
+ "Use ./author -root ~s_priv.pem [-b <bits>] -o <device_key_file>"
+ " make_dev~n"
+ "to create a device key pair signed by the generated private root key.~n"
+ "~n"
+ "Use ./rvi_create_certificate.py ... --root_key=~s_priv.pem ...~n"
+ "to sign a created certificate with the generated private root key.~n",
+ [X, X, X, X]}.
+
+get_key_pair(Root) ->
+ case authorize_keys:get_key_pair_from_pem(openssl, Root) of
+ {undefined, undefined} ->
+ fail("Cannot read root key (~p)~n", [Root]);
+ {_RPriv, _RPub} = Pair ->
+ Pair
+ end.
+
+get_pub_key(Pub) ->
+ case authorize_keys:get_pub_key(Pub) of
+ undefined ->
+ fail("Cannot read pub key (~p)~n", [Pub]);
+ PubKey ->
+ PubKey
+ end.
+
+mandatory(Keys, Opts) ->
+ lists:map(
+ fun(K) ->
+ case lists:keyfind(K, 1, Opts) of
+ false ->
+ fail("Mandatory option: -~w~n", [K]);
+ {_, V} ->
+ V
+ end
+ end, Keys).
+
+bits(Opts) ->
+ get_value(b, Opts, 2048).
+
+l2i(Str) ->
+ try list_to_integer(Str)
+ catch
+ error:_ ->
+ fail("Invalid number argument, ~s~n", [Str])
end.
+i2l(I) ->
+ integer_to_list(I).
+
+
make_auth(RPriv, Pub, Fmt, Opts) ->
case Fmt of
"json" ->
@@ -74,6 +150,24 @@ make_auth(RPriv, Pub, Fmt, Opts) ->
out(JWT, Opts)
end.
+make_root(Out, Bits, _Opts) ->
+ make_key_pair(Out, Bits),
+ {Fmt, Args} = make_root_msg(Out),
+ io:fwrite(Fmt, Args).
+
+make_dev(Root, Out, Bits, Opts) ->
+ make_key_pair(Out, Bits),
+ {RPriv, _} = get_key_pair(Root),
+ Pub = get_pub_key(pub_f(Out)),
+ make_auth(RPriv, Pub, "jwt", [{out, Out ++ "_pub_sign.jwt"}|Opts]).
+
+make_key_pair(Out, Bits) ->
+ os:cmd(["openssl genrsa -out ", priv_f(Out), " ", i2l(Bits)]),
+ os:cmd(["openssl rsa -pubout -in ", priv_f(Out), " -out ", pub_f(Out)]).
+
+priv_f(Out) -> Out ++ "_priv.pem".
+pub_f (Out) -> Out ++ "_pub.pem".
+
out(Str, Opts) ->
case get_value(out, Opts, tty) of
tty ->
@@ -99,7 +193,12 @@ help() ->
" -fmt Format : Output format (json|jwt)~n"
" -o OutFile : Name of output (tty output, if not specified)~n"
"Command:~n"
- " make_auth : ~n", []).
+ " make_auth : Create an authorization JWT~n"
+ " Options: -root <RootKeyFile> -pub <PubKey> [-o <Outfile>]~n"
+ " make_root : Create a provisioning key pair~n"
+ " Options: [-b <Bits>] -o <Outfile>~n"
+ " read_sig : Validate and read a JWT~n"
+ " Options: -sig <SignatureFile> -root <RootKey>~n", []).
fail(Fmt, Args) ->
io:fwrite(Fmt, Args),