summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Barksdale <amatus.amongus@gmail.com>2010-10-30 20:29:44 -0700
committerDavid Barksdale <amatus.amongus@gmail.com>2010-10-30 20:29:44 -0700
commit8d14a8036807bb75b66d83dbc605ee8eaa8fd5f4 (patch)
tree9907c0d35029e53ce6c8641ca4292d832d4fca6a
parent16e5faba51de49ea00f394790c91f16999768ac6 (diff)
First steps in handling CORE_ENCRYPTED_MESSAGE. Make date comparisons more
readable.
-rw-r--r--src/org/gnu/clojure/gnunet/core.clj92
-rw-r--r--src/org/gnu/clojure/gnunet/crypto.clj6
-rw-r--r--src/org/gnu/clojure/gnunet/peer.clj2
-rw-r--r--src/org/gnu/clojure/gnunet/transport.clj4
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