oh hai
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)
|
||||
}
|
@ -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…
Reference in New Issue