You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
3.0 KiB
Go

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 := publicKey()
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, 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 := privateKey()
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 publicKey() (*rsa.PublicKey, error) {
if options.publicKey == "" {
priv, err := privateKey()
if err != nil {
return nil, err
}
return &priv.PublicKey, nil
}
f, err := os.Open(options.publicKey)
if err != nil {
return nil, fmt.Errorf("unable to read public key from file %s: %v", options.publicKey, err)
}
defer f.Close()
d1 := json.NewDecoder(f)
var key rsa.PublicKey
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 privateKey() (*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 := privateKey()
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)
}
}
type KeyRequest string
func (k KeyRequest) Kind() string {
return "get-key"
}
func (k KeyRequest) Nick() string {
return string(k)
}
func init() { registerRequestType(func() request { return new(KeyRequest) }) }
type KeyResponse struct {
Nick string
Key rsa.PublicKey
}
func (k KeyResponse) Kind() string {
return "key-response"
}
func init() { registerRequestType(func() request { return new(KeyResponse) }) }