From c55606d47d98e96c955b1ff2c91d26a0bacf4d77 Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Sun, 24 Jun 2018 23:46:42 -0400 Subject: [PATCH] Add keypair generation funcs --- activitypub/keys.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 activitypub/keys.go diff --git a/activitypub/keys.go b/activitypub/keys.go new file mode 100644 index 0000000..8ab61ae --- /dev/null +++ b/activitypub/keys.go @@ -0,0 +1,68 @@ +package activitypub + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "fmt" + "log" +) + +const keyBitSize = 2048 + +// GenerateKey creates an RSA keypair. +func GenerateKey() (*rsa.PrivateKey, error) { + priv, err := rsa.GenerateKey(rand.Reader, keyBitSize) + if err != nil { + return nil, err + } + + err = priv.Validate() + if err != nil { + return nil, err + } + + return priv, nil +} + +// 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, + } + + // 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 + } + pubDER := x509.MarshalPKCS1PublicKey(pubKey) + pubBlock := pem.Block{ + Type: "PUBLIC KEY", + Bytes: pubDER, + } + pubPEM := pem.EncodeToMemory(&pubBlock) + + return pubPEM, privPEM +} + +// DecodePrivateKey encodes public and private key to PEM format, returning +// them in that order. +func DecodePrivateKey(k []byte) (*rsa.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) +}