Skip to content

Instantly share code, notes, and snippets.

Created January 9, 2010 01:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/272648 to your computer and use it in GitHub Desktop.
Save anonymous/272648 to your computer and use it in GitHub Desktop.
(ns com.bebop.gate (:gen-class)
(:import [java.security KeyPair KeyPairGenerator]
[org.jasypt.util.password StrongPasswordEncryptor]
[org.apache.commons.codec.binary Base64])
(:use dk.bestinclass.clojureql)
(:require [dk.bestinclass.clojureql.backend.derby :as derby]))
(def *conn-info* (make-connection-info "derby" ".gate/db;create=true"))
(defmacro dosql [& forms] `(run *conn-info* ~@forms))
(defn setup
[]
(try (dosql
(create-table
users
[id int
username "varchar(64)"
password "varchar(64)"
public_key "varchar(1024)"
private_key "varchar(1024)"]
:primary-key id
:auto-inc id
:unique username
:not-nulls [id username password public_key private_key])
)
(catch java.sql.SQLException e
(when (empty? (re-seq #"exists" (.getMessage e))) (throw e)))
))
(defn generate-keys
"Generates RSA Keys of a given bit length."
([algo length]
(let [gen (doto (KeyPairGenerator/getInstance algo) (.initialize 1024))
keypair (.generateKeyPair gen)
ders (doall (map #(.encode %1) [(.getPublic keypair) (.getPrivate keypair)]))
b64ders (doall (map #(Base64/encodeBase64 %1) ders))
surround #(str "-----BEGIN " %1 " KEY-----\n" %2 "-----END " %1 " KEY-----\n")]
[(surround "PUBLIC" (String. (first b64ders)))
(surround "PRIVATE" (String. (second b64ders)))]
))
([length] (generate-keys "rsa" length))
([] (generate-keys 1024)))
(def *password-encryptor* (new StrongPasswordEncryptor))
(def password-encryptor (constantly *password-encryptor*))
(defn hash-password
"Strongly hash password"
[pword]
(-> (password-encryptor) (.encryptPassword pword)))
(defn lookup
"Retrieves login record optionally with public private keys"
([username withpublic withprivate]
(dosql
(cond
(and withpublic withprivate) (query [username password] users (= username ~username))
withpublic (query users [username password public_key] (= username ~username))
withprivate (query users [username password withprivate] (= username ~username))
:else (query users * (= username ~username))
)))
([username withpublic] (lookup username withpublic false))
([username] (lookup username false false)))
(defn insert
"Write user to the Database"
[username password publickey privatekey]
(let [hpword (hash-password password)]
(dosql (insert-into users
[username ~username
password ~hpword
public_key ~publickey
private_key ~privatekey]))))
(defn register
"Registers a new username and password."
[username password]
(when-not (lookup username false false)
(let [[pub priv] (generate-keys)]
(dosql (insert username password pub priv)))
))
(defn check-password
"Checks supplied password against hashed password in database."
[supplied hashed]
(-> (password-encryptor) (.checkPassword supplied hashed)))
(defn login
"Check username against password. Returns the public and private key."
[username password]
(when-let [user (lookup username)]
(if (check-password password (user :password))
user
false)))
(defn reset-keys
[username password]
(when (login username)
(let [[pub priv] (generate-keys)]
(dosql (update users [public_key ~pub private_key ~priv] (= username ~username)))
)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment