diff options
author | David Barksdale <amatus.amongus@gmail.com> | 2010-10-30 20:29:44 -0700 |
---|---|---|
committer | David Barksdale <amatus.amongus@gmail.com> | 2010-10-30 20:29:44 -0700 |
commit | 8d14a8036807bb75b66d83dbc605ee8eaa8fd5f4 (patch) | |
tree | 9907c0d35029e53ce6c8641ca4292d832d4fca6a | |
parent | 16e5faba51de49ea00f394790c91f16999768ac6 (diff) |
First steps in handling CORE_ENCRYPTED_MESSAGE. Make date comparisons more
readable.
-rw-r--r-- | src/org/gnu/clojure/gnunet/core.clj | 92 | ||||
-rw-r--r-- | src/org/gnu/clojure/gnunet/crypto.clj | 6 | ||||
-rw-r--r-- | src/org/gnu/clojure/gnunet/peer.clj | 2 | ||||
-rw-r--r-- | src/org/gnu/clojure/gnunet/transport.clj | 4 |
4 files changed, 96 insertions, 8 deletions
diff --git a/src/org/gnu/clojure/gnunet/core.clj b/src/org/gnu/clojure/gnunet/core.clj index dbe5c33..10d61b2 100644 --- a/src/org/gnu/clojure/gnunet/core.clj +++ b/src/org/gnu/clojure/gnunet/core.clj @@ -1,7 +1,7 @@ (ns org.gnu.clojure.gnunet.core (:use (org.gnu.clojure.gnunet parser message peer crypto) clojure.contrib.monads) - (:import java.util.Date)) + (:import (java.util Date Calendar))) (def message-type-core-set-key 80) (def message-type-core-encrypted-message 81) @@ -15,6 +15,10 @@ (def peer-status-key-received 2) (def peer-status-key-confirmed 3) +(defn message-expiration + [] + (.getTime (doto (Calendar/getInstance) (.add Calendar/DAY_OF_YEAR -1)))) + (defn encode-set-key-signed-material [set-key] (encode-signed signature-purpose-set-key @@ -67,6 +71,15 @@ (encode-int32 challenge) (encode-utf8 "pong initialization vector")))) +(defn derive-auth-key + [aes-key seed aes-key-created] + (derive-hmac-key aes-key + (encode-int32 seed) + (concat + (.getEncoded aes-key) + (encode-date aes-key-created) + (encode-utf8 "authentication key")))) + (defn encode-core-ping [ping aes-key remote-peer-id] (let [iv (derive-iv aes-key (:iv-seed ping) remote-peer-id)] @@ -81,8 +94,8 @@ [aes-key peer-id] (domonad parser-m [iv-seed parse-int32 - :let [iv (derive-iv aes-key iv-seed peer-id)] ciphertext (none-or-more item) + :let [iv (derive-iv aes-key iv-seed peer-id)] :let [plaintext (aes-decrypt aes-key iv ciphertext)] :let [ping (first ((domonad parser-m [peer-id (items id-size) @@ -109,8 +122,8 @@ [aes-key ping-challenge peer-id] (domonad parser-m [iv-seed parse-int32 - :let [iv (derive-pong-iv aes-key iv-seed ping-challenge peer-id)] ciphertext (none-or-more item) + :let [iv (derive-pong-iv aes-key iv-seed ping-challenge peer-id)] :let [plaintext (aes-decrypt aes-key iv ciphertext)] :let [pong (first ((domonad parser-m [challenge parse-int32 @@ -123,6 +136,29 @@ :when pong] pong)) +(defn parse-core-encrypted-message + [aes-key aes-key-created peer-id] + (domonad parser-m + [iv-seed parse-int32 + hmac (items hash-size) + ciphertext (none-or-more item) + :let [auth-key (derive-auth-key aes-key iv-seed aes-key-created)] + :when (= hmac (seq (hmac-sha-512 auth-key ciphertext))) + :let [iv (derive-iv aes-key iv-seed peer-id)] + :let [plaintext (aes-decrypt aes-key iv ciphertext)] + :let [message (first ((domonad parser-m + [sequence-number parse-uint32 + inbound-bw-limit parse-uint32 + timestamp parse-date + message-bytes (none-or-more item)] + {:sequence-number sequence-number + :inbound-bw-limit inbound-bw-limit + :timestamp timestamp + :bytes message-bytes}) + plaintext))] + :when message] + message)) + (defn emit-messages! [peer remote-peer messages] (send (:state-agent remote-peer) @@ -207,7 +243,7 @@ state (if (= decrypt-key-created creation-time) state (conj state {:last-sequence-number-received 0 - :last-packets-bitmap 0 + :last-packets-bitmap (int 0) :decrypt-key-created creation-time})) status (:status state) sender-status (:sender-status set-key)] @@ -266,6 +302,51 @@ state) state)))) +(defn admit-core-message! + [peer remote-peer message] + (send (:state-agent remote-peer) + (fn [state] + ;; TODO: update bandwidth tracking + state + ))) + +(defn handle-core-encrypted-message! + [peer remote-peer message] + (send (:state-agent remote-peer) + (fn [state] + (if-let [decrypt-key (:decrypt-key state)] + (if-let [message (first ((parse-core-encrypted-message decrypt-key + (:decrypt-key-created state) (:id peer)) + (:bytes message)))] + (let [last-seqnum-received (:last-sequence-number-received state) + seqnum (:sequence-number message)] + (cond + (.before (:timestamp message) (message-expiration)) + state + (== last-seqnum-received seqnum) + state + (> last-seqnum-received (+ 32 seqnum)) + state + (> last-seqnum-received seqnum) + (let [bit (bit-set 0 (- last-seqnum-received seqnum 1)) + bitmap (:last-packets-bitmap state)] + (if (bit-test bitmap bit) + state + (do + (admit-core-message! peer remote-peer message) + (assoc state :last-packets-bitmap (bit-or bitmap bit))))) + (< last-seqnum-received seqnum) + (let [bitmap (.intValue + (bit-shift-left + (bigint (:last-packets-bitmap state)) + (- seqnum last-seqnum-received)))] + (admit-core-message! peer remote-peer message) + (conj state {:last-packets-bitmap bitmap + :last-sequence-number-received seqnum})) + :else state)) + state) + state)))) + (defn initialize-remote-peer-state [peer state] (conj state @@ -286,7 +367,8 @@ (initialize-remote-peer-state peer state))] (condp = (:message-type message) message-type-core-set-key (handle-set-key! peer remote-peer message) - message-type-core-encrypted-message nil + message-type-core-encrypted-message (handle-core-encrypted-message! + peer remote-peer message) message-type-core-ping (handle-core-ping! peer remote-peer message) message-type-core-pong (handle-core-pong! peer remote-peer message) nil) diff --git a/src/org/gnu/clojure/gnunet/crypto.clj b/src/org/gnu/clojure/gnunet/crypto.clj index 3fab82d..b9e7693 100644 --- a/src/org/gnu/clojure/gnunet/crypto.clj +++ b/src/org/gnu/clojure/gnunet/crypto.clj @@ -9,6 +9,7 @@ (javax.crypto Cipher KeyGenerator SecretKeyFactory Mac) (javax.crypto.spec SecretKeySpec IvParameterSpec))) +(def hash-size 64) (def signature-size 256) (def aes-key-size 32) (def aes-iv-size (/ aes-key-size 2)) @@ -60,6 +61,11 @@ (hkdf hmac-sha-256 hmac-sha-256 ikm salt info l)) (encode-int 0x8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8)))) +(defn derive-hmac-key + [aes-key salt context] + (hkdf hmac-sha-512 hmac-sha-256 + (.getEncoded aes-key) salt context hash-size)) + (defn make-aes-key [byte-seq] (.generateSecret (SecretKeyFactory/getInstance "AES") diff --git a/src/org/gnu/clojure/gnunet/peer.clj b/src/org/gnu/clojure/gnunet/peer.clj index aa51859..b9fff19 100644 --- a/src/org/gnu/clojure/gnunet/peer.clj +++ b/src/org/gnu/clojure/gnunet/peer.clj @@ -64,7 +64,7 @@ [public-key] (vec (sha-512 (encode-rsa-public-key public-key)))) -(def id-size (count (sha-512 ()))) +(def id-size hash-size) (defn selector-loop! [selector continuations] diff --git a/src/org/gnu/clojure/gnunet/transport.clj b/src/org/gnu/clojure/gnunet/transport.clj index 20bf5a0..8e368a8 100644 --- a/src/org/gnu/clojure/gnunet/transport.clj +++ b/src/org/gnu/clojure/gnunet/transport.clj @@ -125,7 +125,7 @@ (defn expire-transport-addresses [min-expiration addresses-list] - (filter #(>= 0 (compare min-expiration (:expiration %))) addresses-list)) + (filter #(not (.after min-expiration (:expiration %))) addresses-list)) (defn hello-for-peer-message [peer] @@ -283,7 +283,7 @@ (defn handle-pong! [peer message] (when-let [pong (first (parse-pong (:bytes message)))] - (if (>= 0 (.compareTo (Date.) (:expiration pong))) + (if (not (.after (Date.) (:expiration pong))) (when-let [remote-peer ((deref (:remote-peers-agent peer)) (:peer-id pong))] (send (:transport-addresses-agent remote-peer) check-pending-validation |