diff --git a/api/jwt.go b/api/jwt.go index a810c76..700c9c9 100644 --- a/api/jwt.go +++ b/api/jwt.go @@ -13,14 +13,13 @@ var( ErrMalformedJWT = errors.New("Malformed JWT") ) +// UnwrapJWT returns the JSON payload element of a JWT func UnwrapJWT(jwt []byte) (server.Session, error) { var sess server.Session - elements := strings.Split(string(jwt), ".") if len(elements) < 3 { return sess, ErrMalformedJWT } - payload := elements[1] jsonObj := make([]byte, base64.URLEncoding.DecodedLen(len(payload))) diff --git a/api/requests.go b/api/requests.go index 3a561aa..4a6f829 100644 --- a/api/requests.go +++ b/api/requests.go @@ -26,12 +26,15 @@ var( } ) +// Message represents Mercury's internal representation +// of a message type Message struct { Username string Timestamp string Message crypto.EncryptedMessage } +// MessageFetch checks for messages from peer through the Mercury Server func MessageFetch(jwt []byte, peer, since string) ([]Message, error) { uri := host + "/get?peer=" + url.QueryEscape(peer) @@ -68,6 +71,7 @@ func MessageFetch(jwt []byte, peer, since string) ([]Message, error) { return messages, err } +// MessageSend sends message to peer using the Mercrury server func MessageSend(jwt []byte, peer, message string) error { uri := host + "/send?to=" + url.QueryEscape(peer) request, err := http.NewRequest("POST", uri, bytes.NewBuffer([]byte(message))) @@ -93,10 +97,12 @@ func MessageSend(jwt []byte, peer, message string) error { return nil } +// SetHost changes the host server that will be used by Quicksilver func SetHost(newHost string) { host = newHost } +// LookupUser checks if a user exists in Mercury's database func LookupUser(user string) error { res, err := client.Get(host + "/lookup?user=" + user) if err != nil { @@ -110,6 +116,7 @@ func LookupUser(user string) error { return nil } +// Register registers a user with the Mercury server func Register(user, passwd string) error { creds := map[string]string{ "Username": user, @@ -132,6 +139,8 @@ func Register(user, passwd string) error { return nil } +// Login attempts to login to the Mercury Server. +// If it is successful, it returns the JWT. func Login(user, passwd string) ([]byte, error) { creds := map[string]string{ "Username": user, diff --git a/crypto/eecdh.go b/crypto/eecdh.go index 0c87aa1..7881f68 100644 --- a/crypto/eecdh.go +++ b/crypto/eecdh.go @@ -20,9 +20,7 @@ const( var( secureHash = sha256.New - Curve = elliptic.P521() - ErrUnexpectedMAC = errors.New("Computed and expected MAC tags do not match.") ) @@ -41,6 +39,8 @@ func DeriveKey(mother []byte, keysize int) []byte { return pbkdf2.Key(mother, nil, 4096, keysize, secureHash) } +// ECDH Performs combines public and private ECDH parameters and derives an +// AES key from the shared secret. func ECDH(priv []byte, x, y *big.Int) []byte { // Create shared secret xp from peer's public key and our private key xp, _ := Curve.ScalarMult(x, y, priv) @@ -49,12 +49,9 @@ func ECDH(priv []byte, x, y *big.Int) []byte { return DeriveKey(xp.Bytes(), aesKeySize) } -// Encrypt encrypts clearText using a shared secret acquired through an -// elliptic-curve diffie-hellman key exchange. -// -// Your private diffie-hellman information, priv, is used with the peer's -// public diffie-hellman information (bx, by), to create a shared AES session -// key to encrypt clearText with. Returns an EncryptedMessage and an error. +// Encrypt encrypts clearText aesKey, and advertises the next key nxt in the +// resulting message structure. sid and rid indicate to the receiver which keys +// should be used to decrypt the message. func EncryptMessage(clearText, aesKey, nxt []byte, sid, rid int) (msg *EncryptedMessage, err error) { // Create a random HMAC key hmacKey := make([]byte, hmacKeySize) @@ -121,6 +118,9 @@ func EncryptMessage(clearText, aesKey, nxt []byte, sid, rid int) (msg *Encrypted return msg, err } +// Decrypt decrypts a message that was encrypted with EncryptMessage. +// It returns the original encrypted message, along with public key that was +// advertised in the message. func (message *EncryptedMessage) Decrypt(aesKey []byte) (clearText, nextKey []byte, err error) { // Create AES block cipher aesCipher, err := aes.NewCipher(aesKey) @@ -157,6 +157,7 @@ func (message *EncryptedMessage) Decrypt(aesKey []byte) (clearText, nextKey []by return msg, nxt, err } +// CheckMAC verifies computes a MAC for message and compares it against messageMAC func CheckMAC(message, messageMAC, key []byte) bool { mac := hmac.New(sha256.New, key) mac.Write(message)