Core components of the web application. https://write.as
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 rivejä
1.9 KiB

  1. package activitypub
  2. import (
  3. "bytes"
  4. "crypto"
  5. "crypto/rsa"
  6. "crypto/x509"
  7. "encoding/pem"
  8. "fmt"
  9. "log"
  10. "os/exec"
  11. )
  12. const keyBitSize = 2048
  13. func openssl(stdin []byte, args ...string) ([]byte, error) {
  14. cmd := exec.Command("openssl", args...)
  15. in := bytes.NewReader(stdin)
  16. out := &bytes.Buffer{}
  17. errs := &bytes.Buffer{}
  18. cmd.Stdin, cmd.Stdout, cmd.Stderr = in, out, errs
  19. if err := cmd.Run(); err != nil {
  20. if len(errs.Bytes()) > 0 {
  21. return nil, fmt.Errorf("error running %s (%s):\n %v", cmd.Args, err, errs.String())
  22. }
  23. return nil, err
  24. }
  25. return out.Bytes(), nil
  26. }
  27. // GenerateKeys creates an RSA keypair and returns the public and private key,
  28. // in that order.
  29. func GenerateKeys() (pubPEM []byte, privPEM []byte) {
  30. var err error
  31. privPEM, err = openssl(nil, "genrsa", fmt.Sprintf("%d", keyBitSize))
  32. if err != nil {
  33. log.Printf("Unable to generate private key: %v", err)
  34. return nil, nil
  35. }
  36. pubPEM, err = openssl(privPEM, "rsa", "-in", "/dev/stdin", "-pubout")
  37. if err != nil {
  38. log.Printf("Unable to get public key: %v", err)
  39. return nil, nil
  40. }
  41. return
  42. }
  43. func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
  44. if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
  45. return key, nil
  46. }
  47. if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
  48. switch key := key.(type) {
  49. case *rsa.PrivateKey:
  50. return key, nil
  51. default:
  52. return nil, fmt.Errorf("found unknown private key type in PKCS#8 wrapping")
  53. }
  54. }
  55. if key, err := x509.ParseECPrivateKey(der); err == nil {
  56. return key, nil
  57. }
  58. return nil, fmt.Errorf("failed to parse private key")
  59. }
  60. // DecodePrivateKey encodes public and private key to PEM format, returning
  61. // them in that order.
  62. func DecodePrivateKey(k []byte) (crypto.PrivateKey, error) {
  63. block, _ := pem.Decode(k)
  64. if block == nil || block.Type != "RSA PRIVATE KEY" {
  65. return nil, fmt.Errorf("failed to decode PEM block containing private key")
  66. }
  67. return parsePrivateKey(block.Bytes)
  68. }