func TestReadWriter2Read(t *testing.T) { pubAlice, privAlice, errA := box.GenerateKey(rand.Reader) pubBob, privBob, errB := box.GenerateKey(rand.Reader) if errA != nil || errB != nil { t.Fatal(errA, errB) } r, w := io.Pipe() secureW := NewSecureWriter(w, privAlice, pubBob) secureR := NewSecureReader(r, privBob, pubAlice) // Encrypt hello world go func() { fmt.Fprintf(secureW, "h") fmt.Fprintf(secureW, "ello world\n") w.Close() }() // Decrypt message buf := make([]byte, len("hello world\n")) if _, err := io.ReadFull(secureR, buf[:len("hello")]); err != nil { t.Fatal(err) } if _, err := io.ReadFull(secureR, buf[len("hello"):]); err != nil { t.Fatal(err) } // Make sure we have hello world back if res := string(buf); res != "hello world\n" { t.Fatalf("Unexpected result: %s != %s", res, "hello world") } }
func TestEncryptDecrypt(t *testing.T) { peerPubKey, _, err := box.GenerateKey(rand.Reader) if err != nil { t.Errorf("failed key gen %s", err) return } _, ownPrivKey, err := box.GenerateKey(rand.Reader) if err != nil { t.Errorf("failed key gen %s", err) return } var sharedKey [32]byte box.Precompute(&sharedKey, peerPubKey, ownPrivKey) msg := []byte("|wtf am i doing|") cipher, err := node.Encrypt(msg, &sharedKey) if err != nil { t.Errorf("failed to encrypt %s", err) return } plain, err := node.Decrypt(cipher, &sharedKey) if err != nil { t.Errorf("failed to decrypt: %s", err) return } if !bytes.Equal(msg, plain) { t.Errorf("expected %s doesn't equal actual %s", string(msg), string(plain)) } }
func runHandshake(t *testing.T, haveClient bool) (c1 *Conn, c2 *Conn) { ch1, ch2 := make(chan struct{}), make(chan struct{}) p1, p2 := net.Pipe() pk1, sk1, err1 := box.GenerateKey(rand.Reader) pk2, sk2, err2 := box.GenerateKey(rand.Reader) if err1 != nil || err2 != nil { t.Fatal("key generation failed") } var pk2_1, pk1_2, expectedPK *[32]byte if haveClient { expectedPK = pk2 } go func() { c1, pk2_1, err1 = Handshake(p1, pk1, sk1, expectedPK, 1<<12); close(ch1) }() go func() { c2, pk1_2, err2 = Handshake(p2, pk2, sk2, nil, 1<<12); defer close(ch2) }() <-ch1 <-ch2 if err1 != nil { t.Fatal(err1) } if !bytes.Equal(pk2_1[:], pk2[:]) { t.Error("1 observed wrong pk") } if err2 != nil { t.Fatal(err2) } if !bytes.Equal(pk1_2[:], pk1[:]) { t.Error("2 observed wrong pk") } return c1, c2 }
func TestKeyUploadDownload(t *testing.T) { dir, err := ioutil.TempDir("", "testdb") handleError(err, t) defer os.RemoveAll(dir) db, err := leveldb.OpenFile(dir, nil) handleError(err, t) defer db.Close() server, conn, inBuf, outBuf, pkp := setUpServerTest(db, t) defer conn.Close() createAccount(conn, inBuf, outBuf, t) pk1, _, err := box.GenerateKey(rand.Reader) handleError(err, t) pk2, _, err := box.GenerateKey(rand.Reader) handleError(err, t) keyList := make([][]byte, 0, 64) //TODO: Make this a reasonable size keyList = append(keyList, pk1[:]) keyList = append(keyList, pk2[:]) uploadKeys(conn, inBuf, outBuf, t, keyList) numKeys := getNumKeys(conn, inBuf, outBuf, t, pkp) if numKeys != 2 { t.Error(fmt.Sprintf("Returned %d keys instead of 2.", numKeys)) } server.StopServer() }
func TestReadWriterPing(t *testing.T) { pub1, priv1, _ := box.GenerateKey(rand.Reader) pub2, priv2, _ := box.GenerateKey(rand.Reader) r, w := io.Pipe() secureR := NewSecureReader(r, priv1, pub2) secureW := NewSecureWriter(w, priv2, pub1) // Encrypt hello world go func() { fmt.Fprintf(secureW, "hello world\n") w.Close() }() // Decrypt message buf := make([]byte, 1024) n, err := secureR.Read(buf) if err != nil && err != io.EOF { t.Fatal(err) } buf = buf[:n] // Make sure we have hello world back if res := string(buf); res != "hello world\n" { t.Fatalf("Unexpected result: %s != %s", res, "hello world") } }
func TestReadWriterEOF(t *testing.T) { pubAlice, privAlice, errA := box.GenerateKey(rand.Reader) pubBob, privBob, errB := box.GenerateKey(rand.Reader) if errA != nil || errB != nil { t.Fatal(errA, errB) } r, w := io.Pipe() secureW := NewSecureWriter(w, privAlice, pubBob) secureR := NewSecureReader(r, privBob, pubAlice) // Encrypt hello world go func() { fmt.Fprintf(secureW, "hello world\n") w.Close() }() // Decrypt message buf := make([]byte, len("hello world\n")) if _, err := io.ReadFull(secureR, buf); err != nil { t.Fatal(err) } if n, err := secureR.Read(buf); err != io.EOF || n != 0 { t.Fatal(err) } }
func generateKeypair(sk *[kexPrvSize]byte, pk *[kexPubSize]byte) bool { if sk == nil || pk == nil { return false } pub, priv, err := box.GenerateKey(prng) if err != nil { return false } copy(sk[:], priv[:]) zero(priv[:], 0) copy(pk[:], pub[:]) pub, priv, err = box.GenerateKey(prng) if err != nil { zero(sk[:], 0) return false } copy(sk[32:], priv[:]) zero(priv[:], 0) copy(pk[32:], pub[:]) return true }
func TestAsymmetricalDecryption(t *testing.T) { cpub, cpriv, _ := box.GenerateKey(rand.Reader) spub, spriv, _ := box.GenerateKey(rand.Reader) r, w := io.Pipe() secureW := NewSecureWriter(w, cpriv, spub) secureR := NewSecureReader(r, spriv, cpub) go func() { fmt.Fprintf(secureW, "hello world\n") w.Close() }() // Decrypt message buf := make([]byte, 1024) n, err := secureR.Read(buf) if err != nil { t.Fatal(err) } buf = buf[:n] if res := string(buf); res != "hello world\n" { t.Fatalf("Unexpected result: %s != %s", res, "hello world") } }
func BenchmarkSeal(b *testing.B) { _, myPrivate, _ := box.GenerateKey(rand.Reader) theirPublic, _, _ := box.GenerateKey(rand.Reader) message := make([]byte, 256) nonce := new([24]byte) b.ResetTimer() for i := 0; i < b.N; i++ { box.Seal(nil, message, nonce, theirPublic, myPrivate) } }
func BenchmarkSealAfterPrecomputation(b *testing.B) { _, myPrivate, _ := box.GenerateKey(rand.Reader) theirPublic, _, _ := box.GenerateKey(rand.Reader) message := make([]byte, 256) nonce := new([24]byte) sharedKey := new([32]byte) box.Precompute(sharedKey, theirPublic, myPrivate) b.ResetTimer() for i := 0; i < b.N; i++ { box.SealAfterPrecomputation(nil, message, nonce, sharedKey) } }
func TestGenerateKeys(t *testing.T) { var err error alicePub, alicePriv, err = box.GenerateKey(rand.Reader) if err != nil { t.Fatalf("%v", err) } bobPub, bobPriv, err = box.GenerateKey(rand.Reader) if err != nil { t.Fatalf("%v", err) } }
// TestReplayAttack tries to perform an attack where messages from Alice to Bob // are sent back to Alice by an active MitM attacker. This would mean that // parties have no way to distinguish the other, like with even/odd sequence // numbers for high/low public keys. func TestReplayAttack(t *testing.T) { pubA, privA, err := box.GenerateKey(rand.Reader) if err != nil { t.Fatal(err) } pubB, privB, err := box.GenerateKey(rand.Reader) if err != nil { t.Fatal(err) } buf := &bytes.Buffer{} // Instantiate Alice's writer wr := NewSecureWriter(buf, privA, pubB) // Write and capture two messages if _, err := wr.Write([]byte("message1")); err != nil { t.Fatal(err) } message1 := buf.String() buf.Reset() if _, err := wr.Write([]byte("message2")); err != nil { t.Fatal(err) } message2 := buf.String() t.Log("\n" + hex.Dump([]byte(message1))) t.Log("\n" + hex.Dump([]byte(message2))) // Check that Bob's reader can read the messages correctly buf = bytes.NewBufferString(message1 + message2) rd := NewSecureReader(buf, privB, pubA) res, err := ioutil.ReadAll(rd) if err != nil { t.Fatal(err) } if !bytes.Equal(res, []byte("message1message2")) { t.Fatalf("Bob read the wrong message: %s", res) } // Check that Alice's reader refuses to read the messages buf = bytes.NewBufferString(message2 + message1) rd = NewSecureReader(buf, privA, pubB) res, err = ioutil.ReadAll(rd) if err == nil { t.Fatalf("Alice read the messages she sent: %s", res) } t.Logf("The replayed messages error is: %v", err) }
func TestAsymmetricalDecryptionWithBox(t *testing.T) { cpub, cpriv, _ := box.GenerateKey(rand.Reader) spub, spriv, _ := box.GenerateKey(rand.Reader) nonce := &[24]byte{'a'} message := []byte{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\n'} encrypted := box.Seal([]byte{}, message, nonce, spub, cpriv) buf, _ := box.Open([]byte{}, encrypted, nonce, cpub, spriv) if res := string(buf); res != "hello world\n" { t.Fatalf("Unexpected result: %s != %s", res, "hello world") } }
func TestGetNumberOfKeys(t *testing.T) { dir, err := ioutil.TempDir("", "testdb") handleError(err, t) defer os.RemoveAll(dir) db, err := leveldb.OpenFile(dir, nil) handleError(err, t) defer db.Close() server, conn, inBuf, outBuf, pkp := setUpServerTest(db, t) defer conn.Close() createAccount(conn, inBuf, outBuf, t) pk1, _, err := box.GenerateKey(rand.Reader) handleError(err, t) pk2, _, err := box.GenerateKey(rand.Reader) handleError(err, t) // NOTE: the keys are note signed here, but they will be in real use keyList := make([][]byte, 0, 64) //TODO: Make this a reasonable size keyList = append(keyList, pk1[:]) keyList = append(keyList, pk2[:]) uploadKeys(conn, inBuf, outBuf, t, keyList) newKey1 := getKey(conn, inBuf, outBuf, t, pkp) if newKey1 == nil { t.Error("No keys in server") } if !(containsByteSlice(keyList, newKey1)) { t.Error("Non-uploaded key returned") } newKey2 := getKey(conn, inBuf, outBuf, t, pkp) if newKey2 == nil { t.Fatal("No keys in server") } if !(containsByteSlice(keyList, newKey2)) { t.Error("Non-uploaded key returned") } if bytes.Equal(newKey1, newKey2) { t.Error("Key not deleted from server") } server.StopServer() }
func Seal(out, message []byte, peersPublicKey *[32]byte) []byte { otk_pub, otk_priv, err := box.GenerateKey(rand.Reader) if err != nil { panic(err) } return box.Seal(append(out, otk_pub[:]...), message, &n, peersPublicKey, otk_priv) }
// NewSecureConn performs the key exchange over the passed net.Conn and then // returns a SecureConn wrapping it. func NewSecureConn(co net.Conn) (*SecureConn, error) { c := &SecureConn{co: co} // Generate a local keypair pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return nil, err } c.priv = priv // Send the public key to the other party if _, err := c.co.Write(pub[:]); err != nil { return nil, err } // Receive the other party's public key var key [32]byte if _, err := io.ReadFull(c.co, key[:]); err != nil { return nil, err } c.pub = &key // Initialize the SecureReader and SecureWriter c.wr = NewSecureWriter(c.co, c.priv, c.pub) c.rd = NewSecureReader(c.co, c.priv, c.pub) return c, nil }
// swapKeys generates a public/private key pair and swaps the public key with // a corresponding call to swapKeys over the given ReadWriter. // // swapKeys returns the private key generated locally and the public key of it's // counterpart. func swapKeys(rw io.ReadWriter) (priv, peer *[32]byte, err error) { // Always return nil for the keys if there is an error defer func() { if err != nil { priv, peer = nil, nil } }() pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return } // Write our public key werr := make(chan error) go func() { _, err := rw.Write(pub[:]) werr <- err }() defer func() { if err == nil { err = <-werr } }() // Read their public key peer = new([32]byte) _, err = io.ReadFull(rw, peer[:]) return }
// Serve starts a secure echo server on the given listener. Sending an empty // message will quit the server. func Serve(l net.Listener) error { for { conn, err := l.Accept() if err != nil { return err } defer conn.Close() pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return err } peer, err := exchangeKeys(conn, pub) if err != nil { return err } secure := NewSecureConn(conn, priv, peer) // If nothing is copied then the server will end. This allows the client to // send an empty message to kill the server. if n, err := io.Copy(secure, secure); n == 0 { if err != nil { return err } return fmt.Errorf("Server ending.") } } }
// Serve starts a secure echo server on the given listener. func Serve(l net.Listener) error { defer l.Close() pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return err } for { rawConn, err := l.Accept() if err != nil { return err } conn := &Conn{rawConn: rawConn, pub: pub, priv: priv} go func(c *Conn) { defer c.Close() buf := make([]byte, 1024*32) n, err := c.Read(buf) if err != nil { fmt.Println(err) } got := string(buf[:n]) log.Print(got) // echo the message n, err = c.Write([]byte(got)) if err != nil { fmt.Println(err) } }(conn) } }
// Dial generates a private/public key pair, // connects to the server, perform the handshake // and return a reader/writer. func Dial(addr string) (io.ReadWriteCloser, error) { pub, priv, err := box.GenerateKey(rand.Reader) if nil != err { return nil, err } conn, err := net.Dial("tcp", addr) if nil != err { return nil, err } // Send client public key pubSlice := pub[:] _, err = conn.Write(pubSlice) if nil != err { return nil, err } // Get server public key var serverKey [32]byte serverKeySlice := serverKey[:] _, err = conn.Read(serverKeySlice) if nil != err { return nil, err } rwc := readWriteCloser{ NewSecureReader(conn, priv, &serverKey), NewSecureWriter(conn, priv, &serverKey), conn, } return rwc, nil }
// Generates an NaCL key-pair func genkey(publicKeyFile string, privateKeyFile string) { publicKey, privateKey, err := box.GenerateKey(rand.Reader) check(err, "Failed to generate key pair") pemWrite(publicKey, publicKeyFile, "NACL PUBLIC KEY", 0644) pemWrite(privateKey, privateKeyFile, "NACL PRIVATE KEY", 0600) }
// handleAndEcho handles a client connection to the server and echos the message body back to the client func handleAndEcho(conn net.Conn) { priv, myPub, err := box.GenerateKey(rand.Reader) if err != nil { log.Fatal("Cannot Generate Key") } _, err = conn.Write(myPub[:]) if err != nil { log.Fatal(err) } var pub [32]byte _, err = conn.Read(pub[:]) if err != nil { log.Fatal("Handshake Failed") } s := &SecureReadWriteCloser{ NewSecureWriter(conn, priv, &pub), NewSecureReader(conn, priv, &pub), } var buf [2048]byte n, err := s.Read(buf[:]) if err != nil { log.Fatal(err) } _, err = s.Write(buf[:n]) if err != nil { log.Fatal(err) } }
// Dial generates a private/public key pair, // connects to the server, perform the handshake // and return a reader/writer. func Dial(addr string) (io.ReadWriteCloser, error) { pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return nil, err } conn, err := net.Dial("tcp", addr) if err != nil { return nil, err } // receive server public key var servPub [32]byte if n, err := conn.Read(servPub[:]); err != nil || n != 32 { return conn, err } // send public key if n, err := conn.Write(pub[:]); err != nil || n != 32 { return conn, err } sr := NewSecureReader(conn, priv, &servPub) sw := NewSecureWriter(conn, priv, &servPub) rwc := &secReadWriteCloser{Reader: sr, Writer: sw, Closer: conn} return rwc, nil }
// newClientConn wraps the provided connections and enables secured // duplex communication between the client and the server. func newClientConn(conn net.Conn) (*clientConn, error) { pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return nil, err } privK, pubK := (*key)(priv), (*key)(pub) v(2).Printf("client: generated private key %v, public key %v", privK, pubK) peersPub, err := exchange(conn, pubK) if err != nil { return nil, fmt.Errorf("key exchange failed with server %v: %v", conn.RemoteAddr(), err) } v(2).Printf("client: peer's public key is %v", peersPub) cc := &clientConn{ NewSecureReader(conn, privK, peersPub), NewSecureWriter(conn, privK, peersPub), conn, } return cc, nil }
// Dial generates a private/public key pair, // connects to the server, perform the handshake // and return a reader/writer. func Dial(addr string) (io.ReadWriteCloser, error) { conn, err := net.Dial("tcp", addr) if err != nil { return nil, err } //generate priv and pub keys pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return nil, err } //insecure communication to exchange public keys, handshake conn.Write(pub[:]) serverPubB := make([]byte, keySize) n, err := conn.Read(serverPubB) if err != nil { return nil, err } if n != keySize { return nil, errors.New("Server didn't send the public key") } var serverPub [keySize]byte copy(serverPub[:], serverPubB) secureR := NewSecureReader(conn, priv, &serverPub) secureW := NewSecureWriter(conn, priv, &serverPub) return secureReadWriteCloser{secureR, secureW, conn}, nil }
// Dial generates a private/public key pair, // connects to the server, perform the handshake // and return a reader/writer. func Dial(addr string) (io.ReadWriteCloser, error) { conn, err := net.Dial("tcp", addr) if err != nil { return nil, err } pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return nil, err } // wait for the server's public key var serverKey [32]byte _, err = io.ReadFull(conn, serverKey[:]) if err != nil { conn.Close() return nil, ErrKeyExchangeFailed } // then send our public key _, err = conn.Write(pub[:]) if err != nil { conn.Close() return nil, ErrKeyExchangeFailed } return readWriteCloser{ NewSecureReader(conn, priv, &serverKey), NewSecureWriter(conn, priv, &serverKey), conn, }, nil }
func serveConn(c net.Conn) error { defer c.Close() pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return fmt.Errorf("could not generate key: %s", err) } n, err := c.Write(pub[:]) if err != nil || n != 32 { return fmt.Errorf("handshake failed, could not send public key:%s", err) } var clientPub [32]byte if n, err := c.Read(clientPub[:]); n != 32 || err != nil { return fmt.Errorf("handshake failed, did not receive public key:%s", err) } sr := NewSecureReader(c, priv, &clientPub) sw := NewSecureWriter(c, priv, &clientPub) if _, err := io.Copy(sw, sr); err != nil { return fmt.Errorf("serve copy failed: %s", err) } return nil }
// Dial generates a private/public key pair, // connects to the server, perform the handshake // and return a reader/writer. func Dial(addr string) (io.ReadWriteCloser, error) { pub, priv, err := box.GenerateKey(rand.Reader) if err != nil { return nil, err } c, err := net.Dial("tcp", addr) if err != nil { return nil, err } n, err := c.Write(pub[:]) if err != nil || n != 32 { return nil, errors.New("Handshake failed: client key") } buf := make([]byte, 32) m, err := c.Read(buf) if (err != nil && err != io.EOF) || m != 32 { return nil, errors.New("Handshake failed: server key") } peer := &[32]byte{} copy(peer[:], buf[:]) s := &SecureConn{ r: NewSecureReader(c, priv, peer), w: NewSecureWriter(c, priv, peer), c: c, } return s, err }
// Dial generates a private/public key pair, // connects to the server, perform the handshake // and return a reader/writer. func Dial(addr string) (io.ReadWriteCloser, error) { // Generate key pair for client cpub, cpriv, _ := box.GenerateKey(rand.Reader) // Attempt to connect to server conn, err := net.Dial("tcp", addr) if err != nil { log.Println("Could not make connection with server...") log.Fatal(err) } // Get server's public key var spub [32]byte _, err = io.ReadAtLeast(conn, spub[:], 32) if err != nil { log.Println("Could not get server's public key...") log.Fatal(err) } // Send client's public key key := [32]byte(*cpub) _, err = conn.Write(key[:]) if err != nil { log.Println("Could not send public key to server...") log.Fatal(err) } // Return client a reader/writer r := NewSecureReader(conn, cpriv, &spub) w := NewSecureWriter(conn, cpriv, &spub) c := NewSecureCloser(conn) srwc := NewSecureReadWriteCloser(r, w, c) return srwc, err }
// Dial generates a private/public key pair, // connects to the server, perform the handshake // and return a reader/writer. func Dial(addr string) (io.ReadWriteCloser, error) { conn, err := net.Dial("tcp", addr) if err != nil { return nil, err } var pub [32]byte n, err := conn.Read(pub[:]) if n == 0 || err != nil { conn.Close() return nil, fmt.Errorf("Error retrieving public key from server, handshake failed") } priv, myPub, err := box.GenerateKey(rand.Reader) if err != nil { return nil, fmt.Errorf("Handshake failed") } _, err = conn.Write(myPub[:]) if err != nil { return nil, fmt.Errorf("Handshake failed") } return &SecureReadWriteCloser{ NewSecureWriter(conn, priv, &pub), NewSecureReader(conn, priv, &pub), }, nil }