diff --git a/activitypub/keys.go b/activitypub/keys.go index 3f9d1ab..fee1b79 100644 --- a/activitypub/keys.go +++ b/activitypub/keys.go @@ -1,66 +1,81 @@ package activitypub import ( + "bytes" "crypto" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" - "github.com/spacemonkeygo/openssl" "log" + "os/exec" ) const keyBitSize = 2048 -// GenerateKey creates an RSA keypair. -func GenerateKey() (openssl.PrivateKey, error) { - return openssl.GenerateRSAKey(keyBitSize) +func openssl(stdin []byte, args ...string) ([]byte, error) { + cmd := exec.Command("openssl", args...) + + in := bytes.NewReader(stdin) + out := &bytes.Buffer{} + errs := &bytes.Buffer{} + + cmd.Stdin, cmd.Stdout, cmd.Stderr = in, out, errs + + if err := cmd.Run(); err != nil { + if len(errs.Bytes()) > 0 { + return nil, fmt.Errorf("error running %s (%s):\n %v", cmd.Args, err, errs.String()) + } + return nil, err + } + + return out.Bytes(), nil } -// EncodeKeysToPEM encodes public and private key to PEM format, returning -// them in that order. -func EncodeKeysToPEM(privKey openssl.PrivateKey) (pubPEM []byte, privPEM []byte) { +// GenerateKeys creates an RSA keypair and returns the public and private key, +// in that order. +func GenerateKeys() (pubPEM []byte, privPEM []byte) { var err error - privPEM, err = privKey.MarshalPKCS1PrivateKeyPEM() + privPEM, err = openssl(nil, "genrsa", fmt.Sprintf("%d", keyBitSize)) if err != nil { - log.Printf("Unable to marshal private key: %v", err) + log.Printf("Unable to generate private key: %v", err) return nil, nil } - pubPEM, err = privKey.MarshalPKIXPublicKeyPEM() + pubPEM, err = openssl(privPEM, "rsa", "-in", "/dev/stdin", "-pubout") if err != nil { - log.Printf("Unable to marshal public key: %v", err) + log.Printf("Unable to get public key: %v", err) return nil, nil } return } func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { return key, nil } if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { switch key := key.(type) { case *rsa.PrivateKey: return key, nil default: return nil, fmt.Errorf("found unknown private key type in PKCS#8 wrapping") } } if key, err := x509.ParseECPrivateKey(der); err == nil { return key, nil } return nil, fmt.Errorf("failed to parse private key") } // DecodePrivateKey encodes public and private key to PEM format, returning // them in that order. func DecodePrivateKey(k []byte) (crypto.PrivateKey, error) { block, _ := pem.Decode(k) if block == nil || block.Type != "RSA PRIVATE KEY" { return nil, fmt.Errorf("failed to decode PEM block containing private key") } return parsePrivateKey(block.Bytes) }