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