master
Jordan Orelli 10 years ago
commit c724d4d224

@ -0,0 +1,44 @@
package main
import (
"crypto/rsa"
"encoding/json"
"fmt"
"net"
"os"
)
type Auth struct {
Nick string
Key rsa.PublicKey
}
func (a *Auth) Kind() string {
return "auth"
}
func connect() {
f, err := os.Open(options.key)
if err != nil {
exit(1, "unable to open private key file at %s: %v", options.key, err)
}
defer f.Close()
d1 := json.NewDecoder(f)
var key rsa.PrivateKey
if err := d1.Decode(&key); err != nil {
exit(1, "unable to decode key: %v", err)
}
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", options.host, options.port))
if err != nil {
exit(1, "unable to connect to server at %s:%d: %v", options.host, options.port, err)
}
auth := Auth{
Nick: options.nick,
Key: key.PublicKey,
}
encodeRequest(conn, &auth)
fmt.Println(conn)
}

10
cm.go

@ -0,0 +1,10 @@
package main
import (
"sync"
)
// connection manager
type CM struct {
mu sync.Mutex
}

@ -0,0 +1,96 @@
package main
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
func generate() {
priv, err := rsa.GenerateKey(rand.Reader, keyLength)
if err != nil {
exit(1, "couldn't generate private key: %v", err)
}
json.NewEncoder(os.Stdout).Encode(priv)
}
func encrypt() {
key, err := readKey()
if err != nil {
exit(1, "couldn't setup key: %v", err)
}
msg, err := ioutil.ReadAll(os.Stdin)
if err != nil {
exit(1, "error reading input message: %v", err)
}
ctxt, err := rsa.EncryptPKCS1v15(rand.Reader, &key.PublicKey, msg)
if err != nil {
exit(1, "error encrypting message: %v", err)
}
var buf bytes.Buffer
enc := base64.NewEncoder(base64.StdEncoding, &buf)
if _, err := enc.Write(ctxt); err != nil {
exit(1, "error b64 encoding ciphertext: %v", err)
}
enc.Close()
b64 := buf.Bytes()
os.Stdout.Write(b64)
os.Stdout.Close()
}
func decrypt() {
key, err := readKey()
if err != nil {
exit(1, "couldn't setup key: %v", err)
}
raw, err := ioutil.ReadAll(os.Stdin)
if err != nil {
exit(1, "error reading input message: %v", err)
}
buf := bytes.NewBuffer(raw)
decoder := base64.NewDecoder(base64.StdEncoding, buf)
ctxt, err := ioutil.ReadAll(decoder)
if err != nil {
exit(1, "error reading b64 buffer %v", err)
}
msg, err := rsa.DecryptPKCS1v15(rand.Reader, key, ctxt)
if err != nil {
exit(1, "error decrypting message: %v", err)
}
fmt.Printf("%s", msg)
}
func readKey() (*rsa.PrivateKey, error) {
f, err := os.Open(options.key)
if err != nil {
return nil, fmt.Errorf("unable to open private key file at %s: %v", options.key, err)
}
defer f.Close()
d1 := json.NewDecoder(f)
var key rsa.PrivateKey
if err := d1.Decode(&key); err != nil {
return nil, fmt.Errorf("unable to decode key from file %s: %v", options.key, err)
}
return &key, nil
}
func getPublic() {
priv, err := readKey()
if err != nil {
exit(1, "unable to read private key file: %v", err)
}
if err := json.NewEncoder(os.Stdout).Encode(priv.PublicKey); err != nil {
exit(1, "unable to marshal key: %v", err)
}
}

@ -0,0 +1,48 @@
package main
import (
"encoding/json"
"fmt"
"net"
)
type Envelope struct {
Kind string
Body json.RawMessage
}
type request interface {
Kind() string
}
func encodeRequest(conn net.Conn, r request) {
b, err := json.Marshal(r)
if err != nil {
exit(1, "unable to encode client request body: %v", err)
}
e := Envelope{
Kind: r.Kind(),
Body: b,
}
if err := json.NewEncoder(conn).Encode(e); err != nil {
exit(1, "unable to encode client request: %v", err)
}
}
func decodeRequest(conn net.Conn) (request, error) {
d := json.NewDecoder(conn)
var env Envelope
if err := d.Decode(&env); err != nil {
return nil, fmt.Errorf("unable to decode client request: %v", err)
}
switch env.Kind {
case "auth":
var auth Auth
if err := json.Unmarshal(env.Body, &auth); err != nil {
return nil, fmt.Errorf("unable to unmarshal auth request: %v", err)
}
return &auth, nil
default:
return nil, fmt.Errorf("unknown request type: %s", env.Kind)
}
}

@ -0,0 +1,49 @@
package main
import (
// "crypto/rsa"
"encoding/json"
"fmt"
"net"
)
func handleConnection(conn net.Conn) {
defer conn.Close()
d := json.NewDecoder(conn)
// var nick string
// var key rsa.PublicKey
var env Envelope
for {
if err := d.Decode(&env); err != nil {
error_log.Printf("unable to decode client request: %v", err)
return
}
switch env.Kind {
case "auth":
var auth Auth
if err := json.Unmarshal(env.Body, &auth); err != nil {
error_log.Printf("unable to decode auth body: %v", err)
break
}
// nick = auth.Nick
// key = auth.Key
}
}
}
func serve() {
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", options.port))
if err != nil {
exit(1, "couldn't open tcp port for listening: %v", err)
}
for {
conn, err := listener.Accept()
if err != nil {
error_log.Printf("error accepting new connection: %v", err)
continue
}
go handleConnection(conn)
}
}

@ -0,0 +1,70 @@
package main
import (
"flag"
"fmt"
"log"
// "net"
"os"
)
const keyLength = 4096
var (
info_log *log.Logger
error_log *log.Logger
)
var options struct {
port int
host string
key string
nick string
}
func exit(status int, template string, args ...interface{}) {
if status == 0 {
info_log.Printf(template, args...)
} else {
error_log.Printf(template, args...)
}
os.Exit(status)
}
func usage(template string, args ...interface{}) {
fmt.Fprintf(os.Stdout, template, args...)
os.Exit(1)
}
func main() {
flag.Parse()
info_log, error_log = log.New(os.Stdout, "", 0), log.New(os.Stderr, "", 0)
if flag.NArg() < 1 {
usage("client or server?")
}
switch flag.Arg(0) {
case "dial":
connect()
case "listen":
serve()
case "generate":
generate()
case "encrypt":
encrypt()
case "decrypt":
decrypt()
case "get-public":
getPublic()
default:
usage("i dunno what you mean with %v", flag.Arg(0))
}
}
func init() {
flag.IntVar(&options.port, "port", 9000, "port number")
flag.StringVar(&options.host, "host", "localhost", "host to connect to")
flag.StringVar(&options.key, "key", "whisper_key", "rsa key to use")
flag.StringVar(&options.nick, "nick", "", "nick to use in chat")
}
Loading…
Cancel
Save