Remove NewRawCertificate function
This commit is contained in:
		
							parent
							
								
									292fa7ee4f
								
							
						
					
					
						commit
						d99e3ed17c
					
				
							
								
								
									
										52
									
								
								cert.go
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								cert.go
									
									
									
									
									
								
							@ -1,12 +1,11 @@
 | 
			
		||||
package gmi
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"crypto"
 | 
			
		||||
	"crypto/ed25519"
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"encoding/pem"
 | 
			
		||||
	"math/big"
 | 
			
		||||
	"net"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
@ -73,37 +72,39 @@ func (c *CertificateStore) Load(path string) error {
 | 
			
		||||
 | 
			
		||||
// NewCertificate creates and returns a new parsed certificate.
 | 
			
		||||
func NewCertificate(host string, duration time.Duration) (tls.Certificate, error) {
 | 
			
		||||
	crt, key, err := NewRawCertificate(host, duration)
 | 
			
		||||
	crt, priv, err := newX509KeyPair(host, duration)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return tls.Certificate{}, err
 | 
			
		||||
	}
 | 
			
		||||
	return tls.X509KeyPair(crt, key)
 | 
			
		||||
	var cert tls.Certificate
 | 
			
		||||
	cert.Leaf = crt
 | 
			
		||||
	cert.Certificate = append(cert.Certificate, crt.Raw)
 | 
			
		||||
	cert.PrivateKey = priv
 | 
			
		||||
	return cert, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewRawCertificate creates and returns a raw certificate for the given host.
 | 
			
		||||
// It generates a self-signed TLS certificate and a ED25519 private key.
 | 
			
		||||
func NewRawCertificate(host string, duration time.Duration) (crt, key []byte, err error) {
 | 
			
		||||
	// Generate a ED25519 private key
 | 
			
		||||
// newX509KeyPair creates and returns a new certificate and private key.
 | 
			
		||||
func newX509KeyPair(host string, duration time.Duration) (*x509.Certificate, crypto.PrivateKey, error) {
 | 
			
		||||
	// Generate an ED25519 private key
 | 
			
		||||
	_, priv, err := ed25519.GenerateKey(rand.Reader)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	public := priv.Public().(ed25519.PublicKey)
 | 
			
		||||
	public := priv.Public()
 | 
			
		||||
 | 
			
		||||
	// ED25519 keys should have the DigitalSignature KeyUsage bits set
 | 
			
		||||
	// in the x509.Certificate template
 | 
			
		||||
	keyUsage := x509.KeyUsageDigitalSignature
 | 
			
		||||
 | 
			
		||||
	notBefore := time.Now()
 | 
			
		||||
	notAfter := notBefore.Add(duration)
 | 
			
		||||
 | 
			
		||||
	// Generate the serial number
 | 
			
		||||
	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
 | 
			
		||||
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	notBefore := time.Now()
 | 
			
		||||
	notAfter := notBefore.Add(duration)
 | 
			
		||||
 | 
			
		||||
	template := x509.Certificate{
 | 
			
		||||
		SerialNumber:          serialNumber,
 | 
			
		||||
		NotBefore:             notBefore,
 | 
			
		||||
@ -122,32 +123,13 @@ func NewRawCertificate(host string, duration time.Duration) (crt, key []byte, er
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create the certificate
 | 
			
		||||
	cert, err := x509.CreateCertificate(rand.Reader, &template, &template, public, priv)
 | 
			
		||||
	crt, err := x509.CreateCertificate(rand.Reader, &template, &template, public, priv)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Encode the certificate
 | 
			
		||||
	var b bytes.Buffer
 | 
			
		||||
	if err := pem.Encode(&b, &pem.Block{Type: "CERTIFICATE", Bytes: cert}); err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	crt = b.Bytes()
 | 
			
		||||
 | 
			
		||||
	// Encode the key
 | 
			
		||||
	b = bytes.Buffer{}
 | 
			
		||||
	cert, err := x509.ParseCertificate(crt)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := pem.Encode(&b, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	key = b.Bytes()
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
	return cert, priv, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,10 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"encoding/pem"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"time"
 | 
			
		||||
@ -13,19 +17,27 @@ import (
 | 
			
		||||
func main() {
 | 
			
		||||
	host := "localhost"
 | 
			
		||||
	duration := 365 * 24 * time.Hour
 | 
			
		||||
	crt, key, err := gmi.NewRawCertificate(host, duration)
 | 
			
		||||
	cert, err := gmi.NewCertificate(host, duration)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := writeX509KeyPair(host, crt, key); err != nil {
 | 
			
		||||
	if err := writeCertificate(host, cert); err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// writeX509KeyPair writes the provided certificate and private key
 | 
			
		||||
// writeCertificate writes the provided certificate and private key
 | 
			
		||||
// to path.crt and path.key respectively.
 | 
			
		||||
func writeX509KeyPair(path string, crt, key []byte) error {
 | 
			
		||||
func writeCertificate(path string, cert tls.Certificate) error {
 | 
			
		||||
	crt, err := marshalX509Certificate(cert.Leaf.Raw)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	key, err := marshalPrivateKey(cert.PrivateKey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Write the certificate
 | 
			
		||||
	crtPath := path + ".crt"
 | 
			
		||||
	crtOut, err := os.OpenFile(crtPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
 | 
			
		||||
@ -47,3 +59,25 @@ func writeX509KeyPair(path string, crt, key []byte) error {
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// marshalX509Certificate returns a PEM-encoded version of the given raw certificate.
 | 
			
		||||
func marshalX509Certificate(cert []byte) ([]byte, error) {
 | 
			
		||||
	var b bytes.Buffer
 | 
			
		||||
	if err := pem.Encode(&b, &pem.Block{Type: "CERTIFICATE", Bytes: cert}); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return b.Bytes(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// marshalPrivateKey returns PEM encoded versions of the given certificate and private key.
 | 
			
		||||
func marshalPrivateKey(priv interface{}) ([]byte, error) {
 | 
			
		||||
	var b bytes.Buffer
 | 
			
		||||
	privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := pem.Encode(&b, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return b.Bytes(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,12 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"encoding/pem"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"git.sr.ht/~adnano/gmi"
 | 
			
		||||
@ -22,22 +26,18 @@ func main() {
 | 
			
		||||
			case gmi.ErrCertificateExpired:
 | 
			
		||||
				log.Print("Old certificate expired, creating new one")
 | 
			
		||||
				// Generate a new certificate if the old one is expired.
 | 
			
		||||
				crt, key, err := gmi.NewRawCertificate(hostname, time.Minute)
 | 
			
		||||
				cert, err := gmi.NewCertificate(hostname, time.Minute)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					// Failed to generate new certificate, abort
 | 
			
		||||
					return nil
 | 
			
		||||
				}
 | 
			
		||||
				// Store and return the new certificate
 | 
			
		||||
				err = writeX509KeyPair("/var/lib/gemini/certs/"+hostname, crt, key)
 | 
			
		||||
				err = writeCertificate("/var/lib/gemini/certs/"+hostname, cert)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return nil
 | 
			
		||||
				}
 | 
			
		||||
				newCert, err := tls.X509KeyPair(crt, key)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return nil
 | 
			
		||||
				}
 | 
			
		||||
				store.Add(hostname, newCert)
 | 
			
		||||
				return &newCert
 | 
			
		||||
				store.Add(hostname, cert)
 | 
			
		||||
				return &cert
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return cert
 | 
			
		||||
@ -52,9 +52,18 @@ func main() {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// writeX509KeyPair writes the provided certificate and private key
 | 
			
		||||
// writeCertificate writes the provided certificate and private key
 | 
			
		||||
// to path.crt and path.key respectively.
 | 
			
		||||
func writeX509KeyPair(path string, crt, key []byte) error {
 | 
			
		||||
func writeCertificate(path string, cert tls.Certificate) error {
 | 
			
		||||
	crt, err := marshalX509Certificate(cert.Leaf.Raw)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	key, err := marshalPrivateKey(cert.PrivateKey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Write the certificate
 | 
			
		||||
	crtPath := path + ".crt"
 | 
			
		||||
	crtOut, err := os.OpenFile(crtPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
 | 
			
		||||
@ -76,3 +85,25 @@ func writeX509KeyPair(path string, crt, key []byte) error {
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// marshalX509Certificate returns a PEM-encoded version of the given raw certificate.
 | 
			
		||||
func marshalX509Certificate(cert []byte) ([]byte, error) {
 | 
			
		||||
	var b bytes.Buffer
 | 
			
		||||
	if err := pem.Encode(&b, &pem.Block{Type: "CERTIFICATE", Bytes: cert}); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return b.Bytes(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// marshalPrivateKey returns PEM encoded versions of the given certificate and private key.
 | 
			
		||||
func marshalPrivateKey(priv interface{}) ([]byte, error) {
 | 
			
		||||
	var b bytes.Buffer
 | 
			
		||||
	privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := pem.Encode(&b, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return b.Bytes(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user