From 3de0e0af3521f826e60468b2d6d19717fa0a53d7 Mon Sep 17 00:00:00 2001
From: Magnus Ahltorp <map@kth.se>
Date: Wed, 10 Jun 2015 16:36:54 +0200
Subject: Don't answer public requests if STH is too old or nonexistent

---
 src/v1.erl | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

(limited to 'src')

diff --git a/src/v1.erl b/src/v1.erl
index ad312e7..e066cdd 100644
--- a/src/v1.erl
+++ b/src/v1.erl
@@ -7,14 +7,37 @@
 %% API (URL)
 -export([request/3]).
 
+check_valid_sth() ->
+    case plop:sth() of
+        noentry ->
+            lager:error("No valid STH found"),
+            exit({internalerror, "No valid STH found"});
+        {struct, PropList} ->
+            Now = plop:generate_timestamp(),
+            Timestamp = proplists:get_value(<<"timestamp">>, PropList),
+            MMD = application:get_env(catlfish, mmd, 86400) * 1000,
+            if
+                Now - Timestamp > MMD ->
+                    lager:error("Old STH found, " ++
+                                    "now: ~p, STH timestamp: ~p, diff: ~p",
+                                [Now, Timestamp, Now - Timestamp]),
+                    exit({internalerror, "No valid STH found"});
+                true ->
+                    ok
+            end
+    end.
+
 %% Public functions, i.e. part of URL.
 request(post, "ct/v1/add-chain", Input) ->
+    check_valid_sth(),
     add_chain(Input, normal);
 
 request(post, "ct/v1/add-pre-chain", Input) ->
+    check_valid_sth(),
     add_chain(Input, precert);
 
 request(get, "ct/v1/get-sth", _Query) ->
+    check_valid_sth(),
     case plop:sth() of
         noentry ->
             lager:error("No valid STH found"),
@@ -24,6 +47,7 @@ request(get, "ct/v1/get-sth", _Query) ->
     end;
 
 request(get, "ct/v1/get-sth-consistency", Query) ->
+    check_valid_sth(),
     case lists:sort(Query) of
         [{"first", FirstInput}, {"second", SecondInput}] ->
             {First, _} = string:to_integer(FirstInput),
@@ -42,6 +66,7 @@ request(get, "ct/v1/get-sth-consistency", Query) ->
     end;
 
 request(get, "ct/v1/get-proof-by-hash", Query) ->
+    check_valid_sth(),
     case lists:sort(Query) of
         [{"hash", HashInput}, {"tree_size", TreeSizeInput}] ->
             Hash = case (catch base64:decode(HashInput)) of
@@ -67,6 +92,7 @@ request(get, "ct/v1/get-proof-by-hash", Query) ->
     end;
 
 request(get, "ct/v1/get-entries", Query) ->
+    check_valid_sth(),
     case lists:sort(Query) of
         [{"end", EndInput}, {"start", StartInput}] ->
             {Start, _} = string:to_integer(StartInput),
@@ -80,6 +106,7 @@ request(get, "ct/v1/get-entries", Query) ->
     end;
 
 request(get, "ct/v1/get-entry-and-proof", Query) ->
+    check_valid_sth(),
     case lists:sort(Query) of
         [{"leaf_index", IndexInput}, {"tree_size", TreeSizeInput}] ->
             {Index, _} = string:to_integer(IndexInput),
@@ -94,6 +121,7 @@ request(get, "ct/v1/get-entry-and-proof", Query) ->
     end;
 
 request(get, "ct/v1/get-roots", _Query) ->
+    check_valid_sth(),
     R = [{certificates,
           [base64:encode(Der) ||
               Der <- catlfish:update_known_roots()]}],
-- 
cgit v1.1