selfcert.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package missinggo
  2. import (
  3. "crypto/ecdsa"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/tls"
  7. "crypto/x509"
  8. "crypto/x509/pkix"
  9. "log"
  10. "math/big"
  11. "time"
  12. )
  13. func publicKey(priv interface{}) interface{} {
  14. switch k := priv.(type) {
  15. case *rsa.PrivateKey:
  16. return &k.PublicKey
  17. case *ecdsa.PrivateKey:
  18. return &k.PublicKey
  19. default:
  20. return nil
  21. }
  22. }
  23. // Creates a self-signed certificate in memory for use with tls.Config.
  24. func NewSelfSignedCertificate() (cert tls.Certificate, err error) {
  25. cert.PrivateKey, err = rsa.GenerateKey(rand.Reader, 2048)
  26. if err != nil {
  27. return
  28. }
  29. notBefore := time.Now()
  30. notAfter := notBefore.Add(365 * 24 * time.Hour)
  31. serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
  32. serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
  33. if err != nil {
  34. log.Fatalf("failed to generate serial number: %s", err)
  35. }
  36. template := x509.Certificate{
  37. SerialNumber: serialNumber,
  38. Subject: pkix.Name{
  39. Organization: []string{"Acme Co"},
  40. },
  41. NotBefore: notBefore,
  42. NotAfter: notAfter,
  43. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  44. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
  45. BasicConstraintsValid: true,
  46. }
  47. derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(cert.PrivateKey), cert.PrivateKey)
  48. if err != nil {
  49. log.Fatalf("Failed to create certificate: %s", err)
  50. }
  51. cert.Certificate = [][]byte{derBytes}
  52. return
  53. }