Skip to content

Commit 0d8c255

Browse files
committed
[FAB-3453] cryptogen: generate tls artifacts
This patch structures the cryptogen output in a way that makes it more directly consumable. The output for each node looks like: └── peer4.org1 ├── msp │   ├── admincerts │   │   └── [email protected] │   ├── cacerts │   │   └── org1-cert.pem │   ├── keystore │   │   └── 0aa7a89070ce8322a4dc3fac2206fa8313b88fb625c70963934714d4129d2897_sk │   └── signcerts │   └── peer4.org1-cert.pem └── tls ├── ca.crt ├── server.crt └── server.key The notable differences are that we push the msp content down under ./msp, and we add the ./tls directory. The crypto material under tls is simply duplicated content from the MSP, as appropriate, to present a consistent layout for consumption by the TLS layer. We also update the default paths in the config to be consistent with this layout. Fixes FAB-3453 Change-Id: I8e149035b92a4758d6c87c03306c08b82687683f Signed-off-by: Gregory Haskins <[email protected]>
1 parent f825608 commit 0d8c255

File tree

7 files changed

+122
-60
lines changed

7 files changed

+122
-60
lines changed

common/tools/cryptogen/ca/ca_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -71,23 +71,23 @@ func TestGenerateSignCertificate(t *testing.T) {
7171
rootCA, err := ca.NewCA(caDir, testCA2Name)
7272
assert.NoError(t, err, "Error generating CA")
7373

74-
err = rootCA.SignCertificate(certDir, testName, ecPubKey)
74+
_, err = rootCA.SignCertificate(certDir, testName, ecPubKey)
7575
assert.NoError(t, err, "Failed to generate signed certificate")
7676

7777
// check to make sure the signed public key was stored
7878
pemFile := filepath.Join(certDir, testName+"-cert.pem")
7979
assert.Equal(t, true, checkForFile(pemFile),
8080
"Expected to find file "+pemFile)
8181

82-
err = rootCA.SignCertificate(certDir, "empty/CA", ecPubKey)
82+
_, err = rootCA.SignCertificate(certDir, "empty/CA", ecPubKey)
8383
assert.Error(t, err, "Bad name should fail")
8484

8585
// use an empty CA to test error path
8686
badCA := &ca.CA{
8787
Name: "badCA",
8888
SignCert: &x509.Certificate{},
8989
}
90-
err = badCA.SignCertificate(certDir, testName, &ecdsa.PublicKey{})
90+
_, err = badCA.SignCertificate(certDir, testName, &ecdsa.PublicKey{})
9191
assert.Error(t, err, "Empty CA should not be able to sign")
9292
cleanup(testDir)
9393

common/tools/cryptogen/ca/generator.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func NewCA(baseDir, name string) (*CA, error) {
8686

8787
// SignCertificate creates a signed certificate based on a built-in template
8888
// and saves it in baseDir/name
89-
func (ca *CA) SignCertificate(baseDir, name string, pub *ecdsa.PublicKey) error {
89+
func (ca *CA) SignCertificate(baseDir, name string, pub *ecdsa.PublicKey) (*x509.Certificate, error) {
9090

9191
template := x509Template()
9292
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
@@ -97,14 +97,14 @@ func (ca *CA) SignCertificate(baseDir, name string, pub *ecdsa.PublicKey) error
9797

9898
template.Subject = subject
9999

100-
_, err := genCertificateECDSA(baseDir, name, &template, ca.SignCert,
100+
cert, err := genCertificateECDSA(baseDir, name, &template, ca.SignCert,
101101
pub, ca.Signer)
102102

103103
if err != nil {
104-
return err
104+
return nil, err
105105
}
106106

107-
return nil
107+
return cert, nil
108108
}
109109

110110
// default template for X509 subject

common/tools/cryptogen/main.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,9 @@ func generatePeerOrg(baseDir string, orgSpec OrgSpec) {
351351

352352
// copy the admin cert to each of the org's peer's MSP admincerts
353353
for _, peerName := range peerNames {
354-
err = copyAdminCert(usersDir, filepath.Join(peersDir, peerName,
355-
"admincerts"), adminUserName)
354+
err = copyAdminCert(usersDir,
355+
filepath.Join(peersDir, peerName, "msp", "admincerts"),
356+
adminUserName)
356357
if err != nil {
357358
fmt.Printf("Error copying admin cert for org %s peer %s:\n%v\n",
358359
orgName, peerName, err)
@@ -372,7 +373,7 @@ func copyAdminCert(usersDir, adminCertsDir, adminUserName string) error {
372373
if err != nil {
373374
return err
374375
}
375-
err = copyFile(filepath.Join(usersDir, adminUserName, "signcerts",
376+
err = copyFile(filepath.Join(usersDir, adminUserName, "msp", "signcerts",
376377
adminUserName+"-cert.pem"), filepath.Join(adminCertsDir,
377378
adminUserName+"-cert.pem"))
378379
if err != nil {
@@ -444,8 +445,8 @@ func generateOrdererOrg(baseDir string, orgSpec OrgSpec) {
444445

445446
// copy the admin cert to each of the org's orderers's MSP admincerts
446447
for _, ordererName := range ordererNames {
447-
err = copyAdminCert(usersDir, filepath.Join(orderersDir, ordererName,
448-
"admincerts"), adminUserName)
448+
err = copyAdminCert(usersDir,
449+
filepath.Join(orderersDir, ordererName, "msp", "admincerts"), adminUserName)
449450
if err != nil {
450451
fmt.Printf("Error copying admin cert for org %s orderer %s:\n%v\n",
451452
orgName, ordererName, err)

common/tools/cryptogen/msp/generator.go

+102-38
Original file line numberDiff line numberDiff line change
@@ -21,59 +21,94 @@ import (
2121
"os"
2222
"path/filepath"
2323

24+
"encoding/hex"
25+
"io"
26+
27+
"github.com/hyperledger/fabric/bccsp"
2428
"github.com/hyperledger/fabric/common/tools/cryptogen/ca"
2529
"github.com/hyperledger/fabric/common/tools/cryptogen/csp"
2630
)
2731

2832
func GenerateLocalMSP(baseDir, name string, rootCA *ca.CA) error {
2933

30-
var response error
3134
// create folder structure
32-
err := createFolderStructure(baseDir)
33-
response = err
34-
if err == nil {
35-
// generate private key
36-
priv, _, err := csp.GeneratePrivateKey(filepath.Join(baseDir, "keystore"))
37-
response = err
38-
if err == nil {
39-
// get public signing certificate
40-
ecPubKey, err := csp.GetECPublicKey(priv)
41-
response = err
42-
if err == nil {
43-
err = rootCA.SignCertificate(filepath.Join(baseDir, "signcerts"),
44-
name, ecPubKey)
45-
response = err
46-
if err == nil {
47-
// write root cert to folders
48-
folders := []string{"admincerts", "cacerts"}
49-
for _, folder := range folders {
50-
err = x509ToFile(filepath.Join(baseDir, folder), rootCA.Name, rootCA.SignCert)
51-
if err != nil {
52-
return err
53-
}
54-
}
55-
}
56-
}
35+
mspDir := filepath.Join(baseDir, "msp")
36+
tlsDir := filepath.Join(baseDir, "tls")
37+
38+
err := createFolderStructure(mspDir)
39+
if err != nil {
40+
return err
41+
}
42+
43+
err = os.MkdirAll(tlsDir, 0755)
44+
if err != nil {
45+
return err
46+
}
47+
48+
// get keystore path
49+
keystore := filepath.Join(mspDir, "keystore")
50+
51+
// generate private key
52+
priv, _, err := csp.GeneratePrivateKey(keystore)
53+
if err != nil {
54+
return err
55+
}
56+
57+
// get public signing certificate
58+
ecPubKey, err := csp.GetECPublicKey(priv)
59+
if err != nil {
60+
return err
61+
}
62+
63+
cert, err := rootCA.SignCertificate(filepath.Join(mspDir, "signcerts"), name, ecPubKey)
64+
if err != nil {
65+
return err
66+
}
67+
68+
// write artifacts to MSP folders
69+
folders := []string{"admincerts", "cacerts"}
70+
for _, folder := range folders {
71+
err = x509Export(filepath.Join(mspDir, folder, x509Filename(rootCA.Name)), rootCA.SignCert)
72+
if err != nil {
73+
return err
5774
}
5875
}
59-
return response
76+
77+
// write artifacts to TLS folder
78+
err = x509Export(filepath.Join(tlsDir, "ca.crt"), rootCA.SignCert)
79+
if err != nil {
80+
return err
81+
}
82+
83+
err = x509Export(filepath.Join(tlsDir, "server.crt"), cert)
84+
if err != nil {
85+
return err
86+
}
87+
88+
err = keyExport(keystore, filepath.Join(tlsDir, "server.key"), priv)
89+
if err != nil {
90+
return err
91+
}
92+
93+
return nil
6094
}
6195

6296
func GenerateVerifyingMSP(baseDir string, rootCA *ca.CA) error {
6397

6498
// create folder structure
6599
err := createFolderStructure(baseDir)
66100
if err == nil {
67-
// write public cert to appropriate folders
101+
// write MSP cert to appropriate folders
68102
folders := []string{"admincerts", "cacerts", "signcerts"}
69103
for _, folder := range folders {
70-
err = x509ToFile(filepath.Join(baseDir, folder), rootCA.Name, rootCA.SignCert)
104+
err = x509Export(filepath.Join(baseDir, folder, x509Filename(rootCA.Name)), rootCA.SignCert)
71105
if err != nil {
72106
return err
73107
}
74108
}
75109
}
76-
return err
110+
111+
return nil
77112
}
78113

79114
func createFolderStructure(rootDir string) error {
@@ -92,21 +127,50 @@ func createFolderStructure(rootDir string) error {
92127
return err
93128
}
94129
}
130+
95131
return nil
96132
}
97133

98-
func x509ToFile(baseDir, name string, cert *x509.Certificate) error {
134+
func x509Filename(name string) string {
135+
return name + "-cert.pem"
136+
}
99137

100-
//write cert out to file
101-
fileName := filepath.Join(baseDir, name+"-cert.pem")
102-
certFile, err := os.Create(fileName)
138+
func x509Export(path string, cert *x509.Certificate) error {
139+
return pemExport(path, "CERTIFICATE", cert.Raw)
140+
}
141+
142+
func copyFile(src, dst string) error {
143+
in, err := os.Open(src)
144+
if err != nil {
145+
return err
146+
}
147+
defer in.Close()
148+
out, err := os.Create(dst)
149+
if err != nil {
150+
return err
151+
}
152+
defer out.Close()
153+
_, err = io.Copy(out, in)
154+
cerr := out.Close()
103155
if err != nil {
104156
return err
105157
}
106-
//pem encode the cert
107-
err = pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
108-
certFile.Close()
158+
return cerr
159+
}
160+
161+
func keyExport(keystore, output string, key bccsp.Key) error {
162+
id := hex.EncodeToString(key.SKI())
163+
164+
return copyFile(filepath.Join(keystore, id+"_sk"), output)
165+
}
109166

110-
return err
167+
func pemExport(path, pemType string, bytes []byte) error {
168+
//write pem out to file
169+
file, err := os.Create(path)
170+
if err != nil {
171+
return err
172+
}
173+
defer file.Close()
111174

175+
return pem.Encode(file, &pem.Block{Type: pemType, Bytes: bytes})
112176
}

common/tools/cryptogen/msp/msp_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func TestGenerateLocalMSP(t *testing.T) {
4444
mspDir := filepath.Join(testDir, "msp")
4545
rootCA, err := ca.NewCA(caDir, testCAName)
4646
assert.NoError(t, err, "Error generating CA")
47-
err = msp.GenerateLocalMSP(mspDir, testName, rootCA)
47+
err = msp.GenerateLocalMSP(testDir, testName, rootCA)
4848
assert.NoError(t, err, "Failed to generate local MSP")
4949

5050
// check to see that the right files were generated/saved

sampleconfig/core.yaml

+3-7
Original file line numberDiff line numberDiff line change
@@ -193,15 +193,11 @@ peer:
193193
tls:
194194
enabled: false
195195
cert:
196-
file: peer/tls.crt
196+
file: tls/server.crt
197197
key:
198-
file: peer/tls.key
199-
# Root cert file for selfsigned certificates
200-
# This represents a self-signed x509 cert that was used to sign the cert.file,
201-
# this is sent to client to validate the recived certificate from server when
202-
# establishing TLS connection
198+
file: tls/server.key
203199
rootcert:
204-
file: peer/tls.crt
200+
file: tls/ca.crt
205201

206202
# The server name use to verify the hostname returned by TLS handshake
207203
serverhostoverride:

sampleconfig/orderer.yaml

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ General:
2525
# TLS: TLS settings for the GRPC server.
2626
TLS:
2727
Enabled: false
28-
PrivateKey:
29-
Certificate:
28+
PrivateKey: tls/server.key
29+
Certificate: tls/server.crt
3030
RootCAs:
31+
- tls/ca.crt
3132
ClientAuthEnabled: false
3233
ClientRootCAs:
3334

0 commit comments

Comments
 (0)