diff --git a/activitypub/keys.go b/activitypub/keys.go index 8ab61ae..3f9d1ab 100644 --- a/activitypub/keys.go +++ b/activitypub/keys.go @@ -1,68 +1,66 @@ package activitypub import ( - "crypto/rand" + "crypto" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" + "github.com/spacemonkeygo/openssl" "log" ) const keyBitSize = 2048 // GenerateKey creates an RSA keypair. -func GenerateKey() (*rsa.PrivateKey, error) { - priv, err := rsa.GenerateKey(rand.Reader, keyBitSize) +func GenerateKey() (openssl.PrivateKey, error) { + return openssl.GenerateRSAKey(keyBitSize) +} + +// EncodeKeysToPEM encodes public and private key to PEM format, returning +// them in that order. +func EncodeKeysToPEM(privKey openssl.PrivateKey) (pubPEM []byte, privPEM []byte) { + var err error + privPEM, err = privKey.MarshalPKCS1PrivateKeyPEM() if err != nil { - return nil, err + log.Printf("Unable to marshal private key: %v", err) + return nil, nil } - err = priv.Validate() + pubPEM, err = privKey.MarshalPKIXPublicKeyPEM() if err != nil { - return nil, err + log.Printf("Unable to marshal public key: %v", err) + return nil, nil } - - return priv, nil + return } -// EncodeKeysToPEM encodes public and private key to PEM format, returning -// them in that order. -func EncodeKeysToPEM(privKey *rsa.PrivateKey) ([]byte, []byte) { - privDER := x509.MarshalPKCS1PrivateKey(privKey) - - // pem.Block - privBlock := pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: privDER, +func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { + if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { + return key, nil } - - // Private key in PEM format - privPEM := pem.EncodeToMemory(&privBlock) - - // Encode public key - pubKey, ok := privKey.Public().(*rsa.PublicKey) - if !ok { - log.Printf("Public key isn't RSA!") - return nil, 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") + } } - pubDER := x509.MarshalPKCS1PublicKey(pubKey) - pubBlock := pem.Block{ - Type: "PUBLIC KEY", - Bytes: pubDER, + if key, err := x509.ParseECPrivateKey(der); err == nil { + return key, nil } - pubPEM := pem.EncodeToMemory(&pubBlock) - return pubPEM, privPEM + 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) (*rsa.PrivateKey, error) { +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 x509.ParsePKCS1PrivateKey(block.Bytes) + return parsePrivateKey(block.Bytes) }