Skip to content

Commit

Permalink
Refactor interface to use records
Browse files Browse the repository at this point in the history
  • Loading branch information
Seth Falcon committed Aug 10, 2012
1 parent 9c7a50a commit ffcda21
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 28 deletions.
3 changes: 2 additions & 1 deletion AUTHORS
@@ -1 +1,2 @@
Christopher Brown <cb@opscode.com>
Christopher Brown <cb@opscode.com>
Seth Falcon <seth@opscode.com>
40 changes: 40 additions & 0 deletions include/chef_certgen.hrl
@@ -0,0 +1,40 @@
%%-------------------------------------------------------------------
%% @author Seth Falcon <seth@opscode.com>
%% @copyright 2012, Opscode, Inc.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%%-------------------------------------------------------------------

-record(rsa_key_pair, {
public_key :: binary(),
private_key :: binary()
}).

-record(x509_subject, {
'CN' :: string(),
'O' :: string(),
'OU' :: string(),
'C' :: string(),
'ST' :: string(),
'L' :: string()
}).

-record(x509_input, {
signing_key :: #rsa_key_pair{},
issuer_cert :: binary(),
newcert_public_key :: #rsa_key_pair{}, % FIXME: should just be pub key here
subject :: #x509_subject{},
serial :: non_neg_integer(),
expiry :: non_neg_integer()
}).
43 changes: 34 additions & 9 deletions src/chef_certgen.erl
Expand Up @@ -40,6 +40,8 @@

-on_load(on_load/0).

-include_lib("chef_certgen.hrl").

on_load() ->
%% FIXME: why do we need to start crypto here instead of relying
%% on the release or user?
Expand All @@ -60,17 +62,22 @@ manual_start() ->
manual_stop() ->
application:stop(chef_certgen).

-spec rsa_generate_keypair(non_neg_integer()) -> #rsa_key_pair{}.
rsa_generate_keypair(KeyLen) ->
{ok, PemPublicKey, PemPrivateKey} = rsa_generate_key_nif(KeyLen),
{keypair, [{public_key, PemPublicKey}, {private_key, PemPrivateKey}]}.

x509_make_cert([{signing_key, CaKeyPair}, {issuer_cert, CaCertPem},
{newcert_public_key, GeneratedKeypair},
Subject,
{serial, Serial}, {expiry, Expiry}])->
x509_make_cert_nif([{signing_key, CaKeyPair}, {issuer_cert, CaCertPem},
{newcert_public_key, GeneratedKeypair},
Subject,
#rsa_key_pair{public_key = PemPublicKey, private_key = PemPrivateKey}.

-spec x509_make_cert(#x509_input{}) -> {x509_cert, _}.
x509_make_cert(#x509_input{
signing_key = CaKeyPair,
issuer_cert = CaCertPem,
newcert_public_key = PublicKey,
subject = Subject,
serial = Serial,
expiry = Expiry}) ->
x509_make_cert_nif([{signing_key, convert_key_pair(CaKeyPair)}, {issuer_cert, CaCertPem},
{newcert_public_key, convert_single_key(PublicKey)},
convert_subject(Subject),
{serial, Serial}, {expiry, Expiry}]).

version() ->
Expand All @@ -80,6 +87,24 @@ version() ->
%% -----------------------------------------
%% internal functions
%% -----------------------------------------
convert_single_key(Public) ->
{keypair, [{public_key, Public}, {private_key, <<"">>}]}.

convert_key_pair(#rsa_key_pair{public_key = Public, private_key = Private}) ->
{keypair, [{public_key, Public}, {private_key, Private}]}.

convert_subject(#x509_subject{'CN' = CN,
'O' = O,
'OU' = OU,
'C' = C,
'ST' = ST,
'L' = L}) ->
{subject, [{'CN', CN},
{'O', O},
{'OU', OU},
{'C', C},
{'ST', ST},
{'L', L}]}.

rsa_generate_key_nif(_KeyLen) ->
?NIF_STUB.
Expand Down
40 changes: 22 additions & 18 deletions test/chef_certgen_tests.erl
Expand Up @@ -23,30 +23,34 @@
-module(chef_certgen_tests).

-include_lib("eunit/include/eunit.hrl").
-include_lib("chef_certgen/include/chef_certgen.hrl").

generate_keypair_test() ->
Keypair = chef_certgen:rsa_generate_keypair(2048),
?assertMatch({keypair, _}, Keypair).
?assertMatch(#rsa_key_pair{public_key = <<_Pub/binary>>,
private_key = <<_Priv/binary>>},
chef_certgen:rsa_generate_keypair(2048)).

create_x509_certificate_test() ->
CaDir = filename:join(["..", "test"]),
CaCertName = filename:join(CaDir, "server_cert.pem"),
CaKeypairName = filename:join(CaDir, "server_key.pem"),
{ok, CaCertPem} = file:read_file(CaCertName),
{ok, CaKeypairPem} = file:read_file(CaKeypairName),
CaKeypair = {keypair, [{public_key, list_to_binary("")}, {private_key, CaKeypairPem}]},
CommonName = "Bob",
Subject = {subject, [{'CN', CommonName},
{'O', "Opscode, Inc."},
{'OU', "Certificate Service"},
{'C', "US"},
{'ST', "Washington"}, {'L', "Seattle"}]},
GeneratedKeypair = chef_certgen:rsa_generate_keypair(2048),
?assertMatch({keypair, _}, GeneratedKeypair),
TestCertResult = chef_certgen:x509_make_cert([{signing_key, CaKeypair},
{issuer_cert, CaCertPem},
{newcert_public_key, GeneratedKeypair},
Subject,
{serial, 1},
{expiry, 10*365}]),
?assertMatch({x509_cert, _}, TestCertResult).
CaKeyPair = #rsa_key_pair{public_key = <<"">>,
private_key = CaKeypairPem},

Subject = #x509_subject{'CN' = "Bob",
'O' = "Opscode, Inc.",
'OU' = "Certificate Service",
'C' = "US",
'ST' = "Washington",
'L' = "Seattle"},
GeneratedKeyPair = chef_certgen:rsa_generate_keypair(2048),
X509In = #x509_input{signing_key = CaKeyPair,
issuer_cert = CaCertPem,
newcert_public_key = GeneratedKeyPair#rsa_key_pair.public_key,
subject = Subject,
serial = 1,
expiry = 10*365},
TestCertResult = chef_certgen:x509_make_cert(X509In),
?assertMatch({x509_cert, <<_/binary>>}, TestCertResult).

0 comments on commit ffcda21

Please sign in to comment.