From 8c6269deba6adf240a5cccadeefc8540b04428d6 Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Tue, 15 Jan 2013 20:04:42 +0000 Subject: [PATCH] initial commit --- .gitignore | 7 ++ LICENSE.txt | 18 +++++ Makefile | 29 ++++++++ README.md | 46 ++++++++++++ rebar.config | 11 +++ src/termit.app.src | 10 +++ src/termit.erl | 162 ++++++++++++++++++++++++++++++++++++++++++ test/termit_SUITE.erl | 22 ++++++ 8 files changed, 305 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.txt create mode 100644 Makefile create mode 100644 README.md create mode 100644 rebar.config create mode 100644 src/termit.app.src create mode 100644 src/termit.erl create mode 100644 test/termit_SUITE.erl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bdd3840 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +ebin +deps +.eunit +.ct +logs +test/*.beam +erl_crash.dump diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..c3f0a46 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,18 @@ +Copyright (c) 2013 Vladimir Dronnikov + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..46c17c0 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +all: deps compile check test + +deps: + rebar get-deps + +compile: + rebar compile + +run: compile + sh start.sh + +clean: + rebar clean + rm -fr ebin .ct test/*.beam + +check: + rebar eunit skip_deps=true + +test: + #rebar ct + mkdir -p .ct + ct_run -dir test -logdir .ct -pa ebin + +dist: deps compile + echo TODO + +.PHONY: all deps compile check test run clean dist +.SILENT: + diff --git a/README.md b/README.md new file mode 100644 index 0000000..5b7250c --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +Termit +============== + +Library for serializing Erlang terms to signed encrypted binaries and reliably deserializing them back. + +Usage +-------------- + +A typical use case is to provide means to keep secrets put in public domain, e.g. secure cookies. + +```erlang +Term = {this, is, an, [erlang, <<"term">>]}. +Cookie = termit:encode_base64(Term, <<"cekpet">>). + +% time-to-live is 1000 seconds =:= secret valid no more than 1000 seconds +{ok, Term} = termit:decode_base64(Cookie, <<"cekpet">>, 1000). +% time-to-live is 0 seconds =:= expired +{error, expired} = termit:decode_base64(Cookie, <<"cekpet">>, 0). + +% check whether secret was not forged +{error, forged} = termit:decode_base64(<>, <<"cekpet">>, 1000). +{error, forged} = termit:decode_base64(Cookie, <<"secret">>, 1000). +{error, forged} = termit:decode_base64(undefined, <<"cekpet">>, 1000). +``` + +[License](termit/blob/master/LICENSE.txt) +------- + +Copyright (c) 2013 Vladimir Dronnikov + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/rebar.config b/rebar.config new file mode 100644 index 0000000..b3028a1 --- /dev/null +++ b/rebar.config @@ -0,0 +1,11 @@ +{lib_dirs, ["deps"]}. + +{erl_opts, [ + debug_info, + warn_format, + warn_export_vars, + warn_obsolete_guard, + warn_bif_clash +]}. + +{cover_enabled, true}. diff --git a/src/termit.app.src b/src/termit.app.src new file mode 100644 index 0000000..4e9bb6a --- /dev/null +++ b/src/termit.app.src @@ -0,0 +1,10 @@ +{application, termit, [ + {description, "Securely serialize/deserialize Erlang terms"}, + {vsn, "0.0.1"}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]}, + {env, []} +]}. diff --git a/src/termit.erl b/src/termit.erl new file mode 100644 index 0000000..d935f80 --- /dev/null +++ b/src/termit.erl @@ -0,0 +1,162 @@ +%% +%% @doc Serialize an Erlang term to signed encrypted binary and +%% deserialize it back ensuring it's not been forged. +%% + +-module(termit). +-author('Vladimir Dronnikov '). + +-export([ + encode/2, decode/3, + encode_base64/2, decode_base64/3 + ]). + +%% +%% ----------------------------------------------------------------------------- +%% @doc Serialize Term, encrypt and sign the result with Secret. +%% Return binary(). +%% ----------------------------------------------------------------------------- +%% + +-spec encode(Term :: any(), Secret :: binary()) -> Cipher :: binary(). + +encode(Term, Secret) -> + Bin = term_to_binary(Term), + Enc = encrypt(Bin, Secret), + {MegaSecs, Secs, _} = erlang:now(), + Time = list_to_binary(integer_to_list(MegaSecs * 1000000 + Secs)), + Sig = sign(<