Skip to content

Commit ec94ba5

Browse files
committed
[FAB-4903] Use separate CA for TLS certs
FAB-4626 separates out the trusted roots for identity (signing) and for TLS. cryptogen currently uses the same CA for both. With this change, cryptogen will now create the updated MSP structure which includes tlscacerts folder and adds support for using separate CAs to generate identity and TLS certs. There is a TODO to actually leverage the tlsCA but we cannot enable that until we get FAB-4626 and this change merged Change-Id: I32de28e2489fd8554274b9379c2572945569fc63 Signed-off-by: Gari Singh <[email protected]>
1 parent 3bc937e commit ec94ba5

File tree

4 files changed

+110
-81
lines changed

4 files changed

+110
-81
lines changed

common/tools/cryptogen/csp/csp.go

+18-17
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,37 @@ import (
2323
"github.com/hyperledger/fabric/bccsp"
2424
"github.com/hyperledger/fabric/bccsp/factory"
2525
"github.com/hyperledger/fabric/bccsp/signer"
26-
"github.com/hyperledger/fabric/bccsp/sw"
2726
)
2827

2928
// GeneratePrivateKey creates a private key and stores it in keystorePath
3029
func GeneratePrivateKey(keystorePath string) (bccsp.Key,
3130
crypto.Signer, error) {
3231

33-
csp := factory.GetDefault()
34-
var response error
32+
var err error
3533
var priv bccsp.Key
3634
var s crypto.Signer
3735

38-
// generate a key
39-
priv, err := csp.KeyGen(&bccsp.ECDSAP256KeyGenOpts{Temporary: true})
40-
response = err
36+
opts := &factory.FactoryOpts{
37+
ProviderName: "SW",
38+
SwOpts: &factory.SwOpts{
39+
HashFamily: "SHA2",
40+
SecLevel: 256,
41+
42+
FileKeystore: &factory.FileKeystoreOpts{
43+
KeyStorePath: keystorePath,
44+
},
45+
},
46+
}
47+
csp, err := factory.GetBCCSPFromOpts(opts)
4148
if err == nil {
42-
// write it to the keystore
43-
ks, err := sw.NewFileBasedKeyStore(nil, keystorePath, false)
44-
response = err
49+
// generate a key
50+
priv, err = csp.KeyGen(&bccsp.ECDSAP256KeyGenOpts{Temporary: false})
4551
if err == nil {
46-
err = ks.StoreKey(priv)
47-
response = err
48-
if err == nil {
49-
// create a crypto.Signer
50-
s, response = signer.New(csp, priv)
51-
}
52+
// create a crypto.Signer
53+
s, err = signer.New(csp, priv)
5254
}
5355
}
54-
return priv, s, response
55-
56+
return priv, s, err
5657
}
5758

5859
func GetECPublicKey(priv bccsp.Key) (*ecdsa.PublicKey, error) {

common/tools/cryptogen/main.go

+34-14
Original file line numberDiff line numberDiff line change
@@ -381,25 +381,35 @@ func generatePeerOrg(baseDir string, orgSpec OrgSpec) {
381381
orgName := orgSpec.Domain
382382

383383
fmt.Println(orgName)
384-
// generate CA
384+
// generate CAs
385385
orgDir := filepath.Join(baseDir, "peerOrganizations", orgName)
386386
caDir := filepath.Join(orgDir, "ca")
387+
tlsCADir := filepath.Join(orgDir, "tlsca")
387388
mspDir := filepath.Join(orgDir, "msp")
388389
peersDir := filepath.Join(orgDir, "peers")
389390
usersDir := filepath.Join(orgDir, "users")
390391
adminCertsDir := filepath.Join(mspDir, "admincerts")
391-
rootCA, err := ca.NewCA(caDir, orgName, orgSpec.CA.CommonName)
392+
// generate signing CA
393+
signCA, err := ca.NewCA(caDir, orgName, orgSpec.CA.CommonName)
392394
if err != nil {
393-
fmt.Printf("Error generating CA for org %s:\n%v\n", orgName, err)
395+
fmt.Printf("Error generating signCA for org %s:\n%v\n", orgName, err)
394396
os.Exit(1)
395397
}
396-
err = msp.GenerateVerifyingMSP(mspDir, rootCA)
398+
// generate TLS CA
399+
tlsCA, err := ca.NewCA(tlsCADir, orgName, "tls"+orgSpec.CA.CommonName)
400+
if err != nil {
401+
fmt.Printf("Error generating tlsCA for org %s:\n%v\n", orgName, err)
402+
os.Exit(1)
403+
}
404+
// TODO remove the following line once MSP and peer changes are done
405+
tlsCA = signCA
406+
err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA)
397407
if err != nil {
398408
fmt.Printf("Error generating MSP for org %s:\n%v\n", orgName, err)
399409
os.Exit(1)
400410
}
401411

402-
generateNodes(peersDir, orgSpec.Specs, rootCA)
412+
generateNodes(peersDir, orgSpec.Specs, signCA, tlsCA)
403413

404414
// TODO: add ability to specify usernames
405415
users := []NodeSpec{}
@@ -416,7 +426,7 @@ func generatePeerOrg(baseDir string, orgSpec OrgSpec) {
416426
}
417427

418428
users = append(users, adminUser)
419-
generateNodes(usersDir, users, rootCA)
429+
generateNodes(usersDir, users, signCA, tlsCA)
420430

421431
// copy the admin cert to the org's MSP admincerts
422432
err = copyAdminCert(usersDir, adminCertsDir, adminUser.CommonName)
@@ -459,11 +469,11 @@ func copyAdminCert(usersDir, adminCertsDir, adminUserName string) error {
459469

460470
}
461471

462-
func generateNodes(baseDir string, nodes []NodeSpec, rootCA *ca.CA) {
472+
func generateNodes(baseDir string, nodes []NodeSpec, signCA *ca.CA, tlsCA *ca.CA) {
463473

464474
for _, node := range nodes {
465475
nodeDir := filepath.Join(baseDir, node.CommonName)
466-
err := msp.GenerateLocalMSP(nodeDir, node.CommonName, node.SANS, rootCA)
476+
err := msp.GenerateLocalMSP(nodeDir, node.CommonName, node.SANS, signCA, tlsCA)
467477
if err != nil {
468478
fmt.Printf("Error generating local MSP for %s:\n%v\n", node, err)
469479
os.Exit(1)
@@ -475,25 +485,35 @@ func generateOrdererOrg(baseDir string, orgSpec OrgSpec) {
475485

476486
orgName := orgSpec.Domain
477487

478-
// generate CA
488+
// generate CAs
479489
orgDir := filepath.Join(baseDir, "ordererOrganizations", orgName)
480490
caDir := filepath.Join(orgDir, "ca")
491+
tlsCADir := filepath.Join(orgDir, "tlsca")
481492
mspDir := filepath.Join(orgDir, "msp")
482493
orderersDir := filepath.Join(orgDir, "orderers")
483494
usersDir := filepath.Join(orgDir, "users")
484495
adminCertsDir := filepath.Join(mspDir, "admincerts")
485-
rootCA, err := ca.NewCA(caDir, orgName, orgSpec.CA.CommonName)
496+
// generate signing CA
497+
signCA, err := ca.NewCA(caDir, orgName, orgSpec.CA.CommonName)
498+
if err != nil {
499+
fmt.Printf("Error generating signCA for org %s:\n%v\n", orgName, err)
500+
os.Exit(1)
501+
}
502+
// generate TLS CA
503+
tlsCA, err := ca.NewCA(tlsCADir, orgName, "tls"+orgSpec.CA.CommonName)
486504
if err != nil {
487-
fmt.Printf("Error generating CA for org %s:\n%v\n", orgName, err)
505+
fmt.Printf("Error generating tlsCA for org %s:\n%v\n", orgName, err)
488506
os.Exit(1)
489507
}
490-
err = msp.GenerateVerifyingMSP(mspDir, rootCA)
508+
// TODO remove the following line once MSP and peer changes are done
509+
tlsCA = signCA
510+
err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA)
491511
if err != nil {
492512
fmt.Printf("Error generating MSP for org %s:\n%v\n", orgName, err)
493513
os.Exit(1)
494514
}
495515

496-
generateNodes(orderersDir, orgSpec.Specs, rootCA)
516+
generateNodes(orderersDir, orgSpec.Specs, signCA, tlsCA)
497517

498518
adminUser := NodeSpec{
499519
CommonName: fmt.Sprintf("%s@%s", adminBaseName, orgName),
@@ -503,7 +523,7 @@ func generateOrdererOrg(baseDir string, orgSpec OrgSpec) {
503523
users := []NodeSpec{}
504524
// add an admin user
505525
users = append(users, adminUser)
506-
generateNodes(usersDir, users, rootCA)
526+
generateNodes(usersDir, users, signCA, tlsCA)
507527

508528
// copy the admin cert to the org's MSP admincerts
509529
err = copyAdminCert(usersDir, adminCertsDir, adminUser.CommonName)

common/tools/cryptogen/msp/generator.go

+28-40
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ import (
2222
"path/filepath"
2323

2424
"encoding/hex"
25-
"io"
2625

2726
"github.com/hyperledger/fabric/bccsp"
2827
"github.com/hyperledger/fabric/bccsp/factory"
2928
"github.com/hyperledger/fabric/common/tools/cryptogen/ca"
3029
"github.com/hyperledger/fabric/common/tools/cryptogen/csp"
3130
)
3231

33-
func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error {
32+
func GenerateLocalMSP(baseDir, name string, sans []string, signCA *ca.CA,
33+
tlsCA *ca.CA) error {
3434

3535
// create folder structure
3636
mspDir := filepath.Join(baseDir, "msp")
@@ -63,17 +63,22 @@ func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error
6363
if err != nil {
6464
return err
6565
}
66-
// generate X509 certificate
67-
cert, err := rootCA.SignCertificate(filepath.Join(mspDir, "signcerts"),
66+
// generate X509 certificate using signing CA
67+
cert, err := signCA.SignCertificate(filepath.Join(mspDir, "signcerts"),
6868
name, []string{}, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{})
6969
if err != nil {
7070
return err
7171
}
7272

7373
// write artifacts to MSP folders
7474

75-
// the CA certificate goes into cacerts
76-
err = x509Export(filepath.Join(mspDir, "cacerts", x509Filename(rootCA.Name)), rootCA.SignCert)
75+
// the signing CA certificate goes into cacerts
76+
err = x509Export(filepath.Join(mspDir, "cacerts", x509Filename(signCA.Name)), signCA.SignCert)
77+
if err != nil {
78+
return err
79+
}
80+
// the TLS CA certificate goes into tlscacerts
81+
err = x509Export(filepath.Join(mspDir, "tlscacerts", x509Filename(tlsCA.Name)), tlsCA.SignCert)
7782
if err != nil {
7883
return err
7984
}
@@ -104,22 +109,21 @@ func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error
104109
if err != nil {
105110
return err
106111
}
107-
// generate X509 certificate
108-
_, err = rootCA.SignCertificate(filepath.Join(tlsDir),
112+
// generate X509 certificate using TLS CA
113+
_, err = tlsCA.SignCertificate(filepath.Join(tlsDir),
109114
name, sans, tlsPubKey, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment,
110115
[]x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth})
111116
if err != nil {
112117
return err
113118
}
114-
err = x509Export(filepath.Join(tlsDir, "ca.crt"), rootCA.SignCert)
119+
err = x509Export(filepath.Join(tlsDir, "ca.crt"), tlsCA.SignCert)
115120
if err != nil {
116121
return err
117122
}
118123

119124
// rename the generated TLS X509 cert
120125
err = os.Rename(filepath.Join(tlsDir, x509Filename(name)),
121126
filepath.Join(tlsDir, "server.crt"))
122-
//err = x509Export(filepath.Join(tlsDir, "server.crt"), tlsCert)
123127
if err != nil {
124128
return err
125129
}
@@ -132,19 +136,20 @@ func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error
132136
return nil
133137
}
134138

135-
func GenerateVerifyingMSP(baseDir string, rootCA *ca.CA) error {
139+
func GenerateVerifyingMSP(baseDir string, signCA *ca.CA, tlsCA *ca.CA) error {
136140

137-
// create folder structure
141+
// create folder structure and write artifacts to proper locations
138142
err := createFolderStructure(baseDir, false)
139143
if err == nil {
140-
// write MSP cert to appropriate folders
141-
//folders := []string{"cacerts", "signcerts"}
142-
folders := []string{"cacerts"}
143-
for _, folder := range folders {
144-
err = x509Export(filepath.Join(baseDir, folder, x509Filename(rootCA.Name)), rootCA.SignCert)
145-
if err != nil {
146-
return err
147-
}
144+
// the signing CA certificate goes into cacerts
145+
err = x509Export(filepath.Join(baseDir, "cacerts", x509Filename(signCA.Name)), signCA.SignCert)
146+
if err != nil {
147+
return err
148+
}
149+
// the TLS CA certificate goes into tlscacerts
150+
err = x509Export(filepath.Join(baseDir, "tlscacerts", x509Filename(tlsCA.Name)), tlsCA.SignCert)
151+
if err != nil {
152+
return err
148153
}
149154
}
150155

@@ -153,13 +158,14 @@ func GenerateVerifyingMSP(baseDir string, rootCA *ca.CA) error {
153158
// cleared up anyway by copyAdminCert, but
154159
// we leave a valid admin for now for the sake
155160
// of unit tests
161+
factory.InitFactories(nil)
156162
bcsp := factory.GetDefault()
157163
priv, err := bcsp.KeyGen(&bccsp.ECDSAP256KeyGenOpts{Temporary: true})
158164
ecPubKey, err := csp.GetECPublicKey(priv)
159165
if err != nil {
160166
return err
161167
}
162-
_, err = rootCA.SignCertificate(filepath.Join(baseDir, "admincerts"), rootCA.Name,
168+
_, err = signCA.SignCertificate(filepath.Join(baseDir, "admincerts"), signCA.Name,
163169
[]string{""}, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{})
164170
if err != nil {
165171
return err
@@ -175,6 +181,7 @@ func createFolderStructure(rootDir string, local bool) error {
175181
folders = []string{
176182
filepath.Join(rootDir, "admincerts"),
177183
filepath.Join(rootDir, "cacerts"),
184+
filepath.Join(rootDir, "tlscacerts"),
178185
}
179186
if local {
180187
folders = append(folders, filepath.Join(rootDir, "keystore"),
@@ -199,25 +206,6 @@ func x509Export(path string, cert *x509.Certificate) error {
199206
return pemExport(path, "CERTIFICATE", cert.Raw)
200207
}
201208

202-
func copyFile(src, dst string) error {
203-
in, err := os.Open(src)
204-
if err != nil {
205-
return err
206-
}
207-
defer in.Close()
208-
out, err := os.Create(dst)
209-
if err != nil {
210-
return err
211-
}
212-
defer out.Close()
213-
_, err = io.Copy(out, in)
214-
cerr := out.Close()
215-
if err != nil {
216-
return err
217-
}
218-
return cerr
219-
}
220-
221209
func keyExport(keystore, output string, key bccsp.Key) error {
222210
id := hex.EncodeToString(key.SKI())
223211

0 commit comments

Comments
 (0)