can read/write encrypted notes

master
Jordan Orelli 10 years ago
parent 2f5dd15c77
commit e501295e61

@ -10,6 +10,7 @@ import (
"io" "io"
"net" "net"
"os" "os"
"strconv"
"strings" "strings"
"sync" "sync"
"unicode" "unicode"
@ -82,6 +83,8 @@ func (c *Client) handleMessage(m Envelope) error {
switch m.Kind { switch m.Kind {
case "meta": case "meta":
return c.handleMeta(m.Body) return c.handleMeta(m.Body)
case "note":
return c.handleNote(m.Body)
default: default:
return fmt.Errorf("received message of unsupported type: %v", m.Kind) return fmt.Errorf("received message of unsupported type: %v", m.Kind)
} }
@ -97,6 +100,24 @@ func (c *Client) handleMeta(body json.RawMessage) error {
return nil return nil
} }
func (c *Client) handleNote(body json.RawMessage) error {
var ctxt []byte
if err := json.Unmarshal(body, &ctxt); err != nil {
return fmt.Errorf("unable to read note response: %v", err)
}
ptxt, err := rsa.DecryptPKCS1v15(rand.Reader, c.key, ctxt)
if err != nil {
return fmt.Errorf("unable to decrypt note response: %v", err)
}
var note NoteData
if err := json.Unmarshal(ptxt, &note); err != nil {
return fmt.Errorf("unable to unmarshal note response: %v", err)
}
c.info("title: %s", note.Title)
c.info("body: %s", string(note.Body))
return nil
}
func (c *Client) handshake() error { func (c *Client) handshake() error {
r := &Auth{Nick: c.nick, Key: c.key.PublicKey} r := &Auth{Nick: c.nick, Key: c.key.PublicKey}
c.info("authenticating as %s", c.nick) c.info("authenticating as %s", c.nick)
@ -198,6 +219,8 @@ func (c *Client) exec(line string) {
switch parts[0] { switch parts[0] {
case "notes/create": case "notes/create":
c.createNote(parts[1:]) c.createNote(parts[1:])
case "notes/get":
c.getNote(parts[1:])
default: default:
c.err("unrecognized client command: %s", parts[0]) c.err("unrecognized client command: %s", parts[0])
} }
@ -225,6 +248,22 @@ func (c *Client) createNote(args []string) {
} }
} }
func (c *Client) getNote(args []string) {
if len(args) != 1 {
c.err("ok notes/get takes exactly 1 argument")
return
}
id, err := strconv.Atoi(args[0])
if err != nil {
c.err("that doesn't look like an int: %v", err)
return
}
if err := c.sendRequest(GetNoteRequest(id)); err != nil {
c.err("couldn't request note: %v", err)
return
}
}
func (c *Client) encryptNote(title string, note []rune) (NoteRequest, error) { func (c *Client) encryptNote(title string, note []rune) (NoteRequest, error) {
obj := &NoteData{ obj := &NoteData{
Title: title, Title: title,

@ -8,6 +8,12 @@ func (n NoteRequest) Kind() string {
return "note" return "note"
} }
type GetNoteRequest int
func (g GetNoteRequest) Kind() string {
return "get-note"
}
type NoteData struct { type NoteData struct {
Title string Title string
Body []byte Body []byte

@ -53,6 +53,8 @@ func (s *serverConnection) handleRequest(request Envelope) error {
return s.handleAuthRequest(request.Body) return s.handleAuthRequest(request.Body)
case "note": case "note":
return s.handleNoteRequest(request.Body) return s.handleNoteRequest(request.Body)
case "get-note":
return s.handleGetNoteRequest(request.Body)
default: default:
return fmt.Errorf("no such request type: %v", request.Kind) return fmt.Errorf("no such request type: %v", request.Kind)
} }
@ -78,6 +80,11 @@ func (s *serverConnection) handleNoteRequest(body json.RawMessage) error {
it := s.db.NewIterator(r, nil) it := s.db.NewIterator(r, nil)
defer it.Release() defer it.Release()
var ctxt []byte
if err := json.Unmarshal(body, &ctxt); err != nil {
return fmt.Errorf("unable to unmarshal ciphertext: %v", err)
}
id := 0 id := 0
if it.Last() { if it.Last() {
k := it.Key() k := it.Key()
@ -89,13 +96,29 @@ func (s *serverConnection) handleNoteRequest(body json.RawMessage) error {
id = lastId + 1 id = lastId + 1
} }
key := fmt.Sprintf("notes/%d", id) key := fmt.Sprintf("notes/%d", id)
if err := s.db.Put([]byte(key), body, nil); err != nil { if err := s.db.Put([]byte(key), ctxt, nil); err != nil {
return fmt.Errorf("unable to write note to db: %v", err) return fmt.Errorf("unable to write note to db: %v", err)
} }
info_log.Printf("stored new note at %s", key) info_log.Printf("stored new note at %s", key)
return nil return nil
} }
func (s *serverConnection) handleGetNoteRequest(body json.RawMessage) error {
var req GetNoteRequest
if err := json.Unmarshal(body, &req); err != nil {
return fmt.Errorf("bad getnote request: %v", err)
}
key := fmt.Sprintf("notes/%d", req)
b, err := s.db.Get([]byte(key), nil)
if err != nil {
return fmt.Errorf("couldn't retrieve note: %v", err)
}
if err := s.sendRequest(NoteRequest(b)); err != nil {
return fmt.Errorf("couldn't send note back to client: %v", err)
}
return nil
}
func (s *serverConnection) openDB() error { func (s *serverConnection) openDB() error {
path := fmt.Sprintf("./%s.db", s.nick) path := fmt.Sprintf("./%s.db", s.nick)
db, err := leveldb.OpenFile(path, nil) db, err := leveldb.OpenFile(path, nil)

Loading…
Cancel
Save