1
0
Эх сурвалжийг харах

refactor: improve api wording and structure

Mustafa Arici 8 жил өмнө
parent
commit
a99c409694
3 өөрчлөгдсөн 60 нэмэгдсэн , 60 устгасан
  1. 32 46
      pki.go
  2. 5 5
      user.go
  3. 23 9
      vpn.go

+ 32 - 46
pki.go

@@ -14,21 +14,22 @@ import (
 	"time"
 )
 
-// CA represents x509 Certificate Authority.
-type CA struct {
+// CertHolder encapsulates a public certificate and the corresponding private key.
+type CertHolder struct {
 	Cert string
 	Key  string // Private Key
-	CSR  string
 }
 
-// Cert represents any certificate - key pair.
-type Cert struct {
-	Cert string
-	Key  string // Private Key
+// CA is a special type of CertHolder that also has a CSR in it.
+type CA struct {
+	CertHolder
+	CSR string
 }
 
-// CreateCA generates a certificate and a key-pair for the CA and returns them.
-func CreateCA() (*CA, error) {
+// NewCA returns a newly generated CA.
+//
+// This will generate a public/private RSA keypair and a authority certificate signed by itself.
+func NewCA() (*CA, error) {
 	key, err := rsa.GenerateKey(rand.Reader, CrtKeyLength)
 	if err != nil {
 		return nil, fmt.Errorf("private key cannot be created: %s", err)
@@ -96,37 +97,28 @@ func CreateCA() (*CA, error) {
 	}
 
 	return &CA{
-		Key:  privateKey.String(),
-		Cert: request.String(),
-		CSR:  string(csr),
+		CertHolder: CertHolder{
+			Key:  privateKey.String(),
+			Cert: request.String(),
+		},
+		CSR: string(csr),
 	}, nil
 
 }
 
-// CreateServerCert generates a x509 certificate and a key-pair for the server.
-func CreateServerCert(ca *CA) (*Cert, error) {
-	return createCert("localhost", ca, true)
-}
-
-// CreateClientCert generates a x509 certificate and a key-pair for the client.
-func CreateClientCert(username string, ca *CA) (*Cert, error) {
-	return createCert(username, ca, false)
+// NewServerCertHolder generates a x509 certificate and a key-pair for the server.
+func NewServerCertHolder(ca *CA) (*CertHolder, error) {
+	return newCert("localhost", ca, true)
 }
 
-func getCertFromPEM(pemCert string) (*x509.Certificate, error) {
-	block, _ := pem.Decode([]byte(pemCert))
-	var cert *x509.Certificate
-	cert, _ = x509.ParseCertificate(block.Bytes)
-	return cert, nil
+// NewClientCertHolder generates a x509 certificate and a key-pair for the client.
+func NewClientCertHolder(username string, ca *CA) (*CertHolder, error) {
+	return newCert(username, ca, false)
 }
 
-func MakeCRL(revokedCertificateSerials []*big.Int) (string, error) {
-	ca, err := getCA()
-	if err != nil {
-		return "", err
-	}
-
-	caCrt, err := getCertFromPEM(ca.Cert)
+// NewCRL takes in a list of certificate serial numbers and a CA then makes a PEM encoded CRL and returns it as a string.
+func NewCRL(revokedCertificateSerials []*big.Int, ca *CA) (string, error) {
+	caCrt, err := readCertFromPEM(ca.Cert)
 	if err != nil {
 		return "", err
 	}
@@ -162,7 +154,7 @@ func MakeCRL(revokedCertificateSerials []*big.Int) (string, error) {
 
 }
 
-func createCert(commonName string, ca *CA, server bool) (*Cert, error) {
+func newCert(commonName string, ca *CA, server bool) (*CertHolder, error) {
 	// Get CA private key
 	block, _ := pem.Decode([]byte(ca.Key))
 	if block == nil {
@@ -174,7 +166,7 @@ func createCert(commonName string, ca *CA, server bool) (*Cert, error) {
 		return nil, fmt.Errorf("failed to parse ca private key: %s", err)
 	}
 
-	caCert, err := getCertFromPEM(ca.Cert)
+	caCert, err := readCertFromPEM(ca.Cert)
 	if err != nil {
 		return nil, fmt.Errorf("failed to parse ca cert: %v", err)
 	}
@@ -222,7 +214,7 @@ func createCert(commonName string, ca *CA, server bool) (*Cert, error) {
 		Bytes: cert,
 	})
 
-	return &Cert{
+	return &CertHolder{
 		Key:  string(priKeyPem[:]),
 		Cert: string(certPem[:]),
 	}, nil
@@ -233,15 +225,9 @@ type basicConstraints struct {
 	MaxPathLen int  `asn1:"optional,default:-1"`
 }
 
-func getCA() (*CA, error) {
-	server := DBServer{}
-	db.First(&server)
-	if db.NewRecord(&server) {
-		return nil, fmt.Errorf("can not retrieve server from db")
-	}
-	return &CA{
-		Cert: server.CACert,
-		Key:  server.CAKey,
-	}, nil
-
+func readCertFromPEM(pemCert string) (*x509.Certificate, error) {
+	block, _ := pem.Decode([]byte(pemCert))
+	var cert *x509.Certificate
+	cert, _ = x509.ParseCertificate(block.Bytes)
+	return cert, nil
 }

+ 5 - 5
user.go

@@ -75,12 +75,12 @@ func CreateNewUser(username, password string) (*DBUser, error) {
 	if !govalidator.IsAlphanumeric(username) {
 		return nil, fmt.Errorf("validation error: `%s` can only contain letters and numbers", username)
 	}
-	ca, err := getCA()
+	ca, err := GetSystemCA()
 	if err != nil {
 		return nil, err
 	}
 
-	clientCert, err := CreateClientCert(username, ca)
+	clientCert, err := NewClientCertHolder(username, ca)
 	if err != nil {
 		return nil, fmt.Errorf("can not create client cert %s: %v", username, err)
 	}
@@ -118,7 +118,7 @@ func (u *DBUser) Delete() error {
 		// user is not found
 		return fmt.Errorf("user is not initialized: %s", u.Username)
 	}
-	crt, err := getCertFromPEM(u.Cert)
+	crt, err := readCertFromPEM(u.Cert)
 	if err != nil {
 		return fmt.Errorf("can not get user's certificate: %v", err)
 	}
@@ -154,12 +154,12 @@ func (u *DBUser) Sign() error {
 	if !CheckBootstrapped() {
 		return fmt.Errorf("you first need to create server")
 	}
-	ca, err := getCA()
+	ca, err := GetSystemCA()
 	if err != nil {
 		return err
 	}
 
-	clientCert, err := CreateClientCert(u.Username, ca)
+	clientCert, err := NewClientCertHolder(u.Username, ca)
 	if err != nil {
 		return fmt.Errorf("can not create client cert %s: %v", u.Username, err)
 	}

+ 23 - 9
vpn.go

@@ -76,22 +76,16 @@ func InitServer(serverName string, hostname string, port string) error {
 		return fmt.Errorf("validation error: hostname:`%s` should be either an ip address or a FQDN", hostname)
 	}
 
-	ca, err := CreateCA()
+	ca, err := NewCA()
 	if err != nil {
 		return fmt.Errorf("can not create ca creds: %s", err)
 	}
 
-	srv, err := CreateServerCert(ca)
+	srv, err := NewServerCertHolder(ca)
 	if err != nil {
 		return fmt.Errorf("can not create server cert creds: %s", err)
 	}
 	serialNumber := uuid.New().String()
-
-	// crl, err := MakeCRL([]*big.Int{})
-	// if err != nil {
-	// 	return fmt.Errorf("can not create server crl: %v", err)
-	// }
-
 	serverInstance := DBServer{
 		Name: serverName,
 
@@ -193,6 +187,22 @@ func DumpUserOVPNConf(username, outPath string) error {
 
 }
 
+// GetSystemCA returns the system CA from the database if available.
+func GetSystemCA() (*CA, error) {
+	server := DBServer{}
+	db.First(&server)
+	if db.NewRecord(&server) {
+		return nil, fmt.Errorf("server record does not exists in db")
+	}
+	return &CA{
+		CertHolder: CertHolder{
+			Cert: server.CACert,
+			Key:  server.CAKey,
+		},
+	}, nil
+
+}
+
 // Emit generates all needed files for the OpenVPN server and dumps them to their corresponding paths defined in the config.
 func Emit() error {
 	// Check dependencies
@@ -360,7 +370,11 @@ func emitCRL() error {
 		bi.SetString(item.SerialNumber, 16)
 		revokedCertSerials = append(revokedCertSerials, bi)
 	}
-	crl, err := MakeCRL(revokedCertSerials)
+	systemCA, err := GetSystemCA()
+	if err != nil {
+		return fmt.Errorf("can not emit CRL: %v", err)
+	}
+	crl, err := NewCRL(revokedCertSerials, systemCA)
 	if err != nil {
 		return fmt.Errorf("can not emit crl: %v", err)
 	}