github.com/llimllib/devd@v0.0.0-20230426145215-4d29fc25f909/certgen.go (about) 1 package devd 2 3 import ( 4 "crypto/rand" 5 "crypto/rsa" 6 "crypto/x509" 7 "crypto/x509/pkix" 8 "encoding/pem" 9 "fmt" 10 "math/big" 11 "os" 12 "time" 13 ) 14 15 // GenerateCert generates a self-signed certificate bundle for devd 16 func GenerateCert(dst string) error { 17 priv, err := rsa.GenerateKey(rand.Reader, 2048) 18 if err != nil { 19 return err 20 } 21 notBefore := time.Now() 22 notAfter := notBefore.Add(365 * 24 * time.Hour * 3) 23 24 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 25 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 26 if err != nil { 27 return err 28 } 29 30 template := x509.Certificate{ 31 SerialNumber: serialNumber, 32 Subject: pkix.Name{ 33 Organization: []string{"Acme Co"}, 34 }, 35 NotBefore: notBefore, 36 NotAfter: notAfter, 37 38 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 39 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 40 BasicConstraintsValid: true, 41 } 42 template.DNSNames = append(template.DNSNames, "devd.io") 43 template.DNSNames = append(template.DNSNames, "*.devd.io") 44 45 derBytes, err := x509.CreateCertificate( 46 rand.Reader, 47 &template, 48 &template, 49 &priv.PublicKey, 50 priv, 51 ) 52 if err != nil { 53 return fmt.Errorf("could not create cert: %s", err) 54 } 55 56 certOut, err := os.Create(dst) 57 if err != nil { 58 return fmt.Errorf("could not open %s for writing: %s", dst, err) 59 } 60 err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) 61 if err != nil { 62 return err 63 } 64 65 err = certOut.Close() 66 if err != nil { 67 return err 68 } 69 70 keyOut, err := os.OpenFile(dst, os.O_WRONLY|os.O_APPEND, 0600) 71 if err != nil { 72 return fmt.Errorf("could not open %s for writing: %s", dst, err) 73 } 74 err = pem.Encode( 75 keyOut, 76 &pem.Block{ 77 Type: "RSA PRIVATE KEY", 78 Bytes: x509.MarshalPKCS1PrivateKey(priv), 79 }, 80 ) 81 if err != nil { 82 return err 83 } 84 85 err = keyOut.Close() 86 if err != nil { 87 return err 88 } 89 return nil 90 }