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

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

	"dfss/auth"
Axel's avatar
Axel committed
11
12
13
)

const (
14
	// PkeyFileName is the private key file default name
15
	PkeyFileName = "dfssp_pkey.pem"
16
	// RootCAFileName is the root certificate file default name
17
	RootCAFileName = "dfssp_rootCA.pem"
Axel's avatar
Axel committed
18
19
)

20
// PlatformID contains platform private key and root certificate
Axel's avatar
Axel committed
21
type PlatformID struct {
22
23
	Pkey   *rsa.PrivateKey
	RootCA *x509.Certificate
Axel's avatar
Axel committed
24
25
}

26
27
28
29
30
31
// 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.
// The files are saved at the specified path.
func Initialize(bits, days int, country, organization, unit, cn, path string, ca *x509.Certificate, rKey *rsa.PrivateKey) error {
	// Generate the private key.
	key, err := auth.GeneratePrivateKey(bits)
Axel's avatar
Axel committed
32
33

	if err != nil {
34
		return err
Axel's avatar
Axel committed
35
36
	}

37
38
39
	var cert []byte
	certPath := filepath.Join(path, RootCAFileName)
	keyPath := filepath.Join(path, PkeyFileName)
Axel's avatar
Axel committed
40

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

	if err != nil {
		return err
	}

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

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

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

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

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

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

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

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

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

	return res, nil
}