gencert.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package api
  2. import (
  3. "crypto/ecdsa"
  4. "crypto/elliptic"
  5. "crypto/rand"
  6. "crypto/x509"
  7. "crypto/x509/pkix"
  8. "encoding/pem"
  9. "math/big"
  10. "net"
  11. "os"
  12. "path/filepath"
  13. "time"
  14. )
  15. func EnsureSelfSignedCert(certFile, keyFile string) error {
  16. if _, err := os.Stat(certFile); err == nil {
  17. if _, err := os.Stat(keyFile); err == nil {
  18. return nil
  19. }
  20. }
  21. priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  22. if err != nil {
  23. return err
  24. }
  25. serial, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
  26. if err != nil {
  27. return err
  28. }
  29. tmpl := &x509.Certificate{
  30. SerialNumber: serial,
  31. Subject: pkix.Name{
  32. Organization: []string{"AI-Status-Light"},
  33. CommonName: "localhost",
  34. },
  35. NotBefore: time.Now(),
  36. NotAfter: time.Now().Add(10 * 365 * 24 * time.Hour),
  37. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  38. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
  39. BasicConstraintsValid: true,
  40. DNSNames: []string{"localhost"},
  41. IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
  42. }
  43. certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &priv.PublicKey, priv)
  44. if err != nil {
  45. return err
  46. }
  47. if err := os.MkdirAll(filepath.Dir(certFile), 0700); err != nil {
  48. return err
  49. }
  50. certOut, err := os.Create(certFile)
  51. if err != nil {
  52. return err
  53. }
  54. if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certDER}); err != nil {
  55. certOut.Close()
  56. return err
  57. }
  58. certOut.Close()
  59. keyOut, err := os.Create(keyFile)
  60. if err != nil {
  61. return err
  62. }
  63. privBytes, err := x509.MarshalECPrivateKey(priv)
  64. if err != nil {
  65. keyOut.Close()
  66. return err
  67. }
  68. if err := pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: privBytes}); err != nil {
  69. keyOut.Close()
  70. return err
  71. }
  72. keyOut.Close()
  73. return nil
  74. }