rootCA.go 2.97 KB
Newer Older
1
package authority
Caro Axel's avatar
Caro Axel committed
2
3
4
5
6

import (
	"crypto/rsa"
	"crypto/x509"
	"io/ioutil"
7
	"os"
Caro Axel's avatar
Caro Axel committed
8
	"path/filepath"
9

ElyKar's avatar
ElyKar committed
10
	"github.com/spf13/viper"
Caro Axel's avatar
Caro Axel committed
11

ElyKar's avatar
ElyKar committed
12
	"dfss/auth"
Caro Axel's avatar
Caro Axel committed
13
14
)

15
// PlatformID contains platform private key and root certificate
Caro Axel's avatar
Caro Axel committed
16
type PlatformID struct {
17
18
	Pkey   *rsa.PrivateKey
	RootCA *x509.Certificate
Caro Axel's avatar
Caro Axel committed
19
20
}

21
22
// Initialize creates and saves the platform's private key and root certificate to a PEM format.
// If ca and rKey are not nil, they will be used as the root certificate and root private key instead of creating a ones.
ElyKar's avatar
ElyKar committed
23
24
// The files are saved at the specified path by viper.
func Initialize(v *viper.Viper, ca *x509.Certificate, rKey *rsa.PrivateKey) error {
25
	// Generate the private key.
ElyKar's avatar
ElyKar committed
26
	key, err := auth.GeneratePrivateKey(v.GetInt("key_size"))
Caro Axel's avatar
Caro Axel committed
27
28

	if err != nil {
29
		return err
Caro Axel's avatar
Caro Axel committed
30
31
	}

32
	var cert []byte
ElyKar's avatar
ElyKar committed
33
34
35
36
37
	path := v.GetString("path")
	// ca_filename and pkey_filename are part of the global conf of
	// the app, that's why we don't fetch them from the local viper
	certPath := filepath.Join(path, viper.GetString("ca_filename"))
	keyPath := filepath.Join(path, viper.GetString("pkey_filename"))
Caro Axel's avatar
Caro Axel committed
38

39
40
	if ca == nil {
		// Generate the root certificate, using the private key.
41
		cert, err = auth.GetSelfSignedCertificate(v.GetInt("validity"), auth.GenerateUID(), v.GetString("country"), v.GetString("organization"), v.GetString("unit"), v.GetString("cn"), key)
42
	} else {
ElyKar's avatar
ElyKar committed
43
		csr, _ := auth.GetCertificateRequest(v.GetString("country"), v.GetString("organization"), v.GetString("unit"), v.GetString("cn"), key)
44
		request, _ := auth.PEMToCertificateRequest(csr)
45
		cert, err = auth.GetCertificate(v.GetInt("validity"), auth.GenerateUID(), request, ca, rKey)
46
47
48
49
		// Override default path values
		certPath = filepath.Join(path, "cert.pem")
		keyPath = filepath.Join(path, "key.pem")
	}
Caro Axel's avatar
Caro Axel committed
50
51
52
53
54

	if err != nil {
		return err
	}

55
56
	// Create missing folders, if needed
	err = os.MkdirAll(path, os.ModeDir|0700)
Caro Axel's avatar
Caro Axel committed
57
58
59
60
	if err != nil {
		return err
	}

61
	// Convert the private key to a PEM format, and save it.
Caro Axel's avatar
Caro Axel committed
62
63
64
65
66
67
	keyPem := auth.PrivateKeyToPEM(key)
	err = ioutil.WriteFile(keyPath, keyPem, 0600)
	if err != nil {
		return err
	}

68
	// Save the root certificate.
69
	return ioutil.WriteFile(certPath, cert, 0600)
Caro Axel's avatar
Caro Axel committed
70
71
}

72
// Start fetches the platform's private rsa key and root certificate, and create a PlatformID accordingly.
Caro Axel's avatar
Caro Axel committed
73
74
75
76
77
//
// The specified path should not end by a separator.
//
// The files are fetched using their default name.
func Start(path string) (*PlatformID, error) {
ElyKar's avatar
ElyKar committed
78
79
	keyPath := filepath.Join(path, viper.GetString("pkey_filename"))
	certPath := filepath.Join(path, viper.GetString("ca_filename"))
Caro Axel's avatar
Caro Axel committed
80

81
	// Recover the private rsa key from file.
Caro Axel's avatar
Caro Axel committed
82
83
84
85
86
87
88
89
90
91
	keyBytes, err := ioutil.ReadFile(keyPath)
	if err != nil {
		return nil, err
	}

	key, err := auth.PEMToPrivateKey(keyBytes)
	if err != nil {
		return nil, err
	}

92
	// Recover the root certificate from file.
Caro Axel's avatar
Caro Axel committed
93
94
95
96
97
98
99
100
101
102
103
	certBytes, err := ioutil.ReadFile(certPath)
	if err != nil {
		return nil, err
	}

	cert, err := auth.PEMToCertificate(certBytes)
	if err != nil {
		return nil, err
	}

	res := &PlatformID{
104
105
106
		Pkey:   key,
		RootCA: cert,
	}
Caro Axel's avatar
Caro Axel committed
107
108
109

	return res, nil
}