Skip to content

Commit 669c51c

Browse files
committed
[FAB-4884] Restrict KeyUsage for signing keys
FAB-4626 introduces a change to restrict the KeyUsage for signing certificates to x509.KeyUsageDigitalSignature and restricts ExtendedKeyUsage as well. cryptogen currently uses the same certs for signing and TLS and therefore the the generated certs will no longer be valid signing identities. This CR does the following: - generates signing certs with the proper KeyUsage - generates separate TLS certs with the appropriate KeyUsage and ExtendedKeyUsage Change-Id: I9112d47d2635370489fec3ff07f09118dc021318 Signed-off-by: Gari Singh <[email protected]>
1 parent 1ee6eed commit 669c51c

File tree

4 files changed

+78
-37
lines changed

4 files changed

+78
-37
lines changed

common/tools/cryptogen/ca/ca_test.go

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

74-
_, err = rootCA.SignCertificate(certDir, testName, nil, ecPubKey)
74+
cert, err := rootCA.SignCertificate(certDir, testName, nil, ecPubKey,
75+
x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment,
76+
[]x509.ExtKeyUsage{x509.ExtKeyUsageAny})
7577
assert.NoError(t, err, "Failed to generate signed certificate")
78+
// KeyUsage should be x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment
79+
assert.Equal(t, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment,
80+
cert.KeyUsage)
81+
assert.Contains(t, cert.ExtKeyUsage, x509.ExtKeyUsageAny)
82+
83+
cert, err = rootCA.SignCertificate(certDir, testName, nil, ecPubKey,
84+
x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{})
85+
assert.NoError(t, err, "Failed to generate signed certificate")
86+
assert.Equal(t, 0, len(cert.ExtKeyUsage))
7687

7788
// check to make sure the signed public key was stored
7889
pemFile := filepath.Join(certDir, testName+"-cert.pem")
7990
assert.Equal(t, true, checkForFile(pemFile),
8091
"Expected to find file "+pemFile)
8192

82-
_, err = rootCA.SignCertificate(certDir, "empty/CA", nil, ecPubKey)
93+
_, err = rootCA.SignCertificate(certDir, "empty/CA", nil, ecPubKey,
94+
x509.KeyUsageKeyEncipherment, []x509.ExtKeyUsage{x509.ExtKeyUsageAny})
8395
assert.Error(t, err, "Bad name should fail")
8496

8597
// use an empty CA to test error path
8698
badCA := &ca.CA{
8799
Name: "badCA",
88100
SignCert: &x509.Certificate{},
89101
}
90-
_, err = badCA.SignCertificate(certDir, testName, nil, &ecdsa.PublicKey{})
102+
_, err = badCA.SignCertificate(certDir, testName, nil, &ecdsa.PublicKey{},
103+
x509.KeyUsageKeyEncipherment, []x509.ExtKeyUsage{x509.ExtKeyUsageAny})
91104
assert.Error(t, err, "Empty CA should not be able to sign")
92105
cleanup(testDir)
93106

common/tools/cryptogen/ca/generator.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ func NewCA(baseDir, org, name string) (*CA, error) {
5757
template := x509Template()
5858
//this is a CA
5959
template.IsCA = true
60-
template.KeyUsage |= x509.KeyUsageCertSign | x509.KeyUsageCRLSign
61-
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny, x509.ExtKeyUsageServerAuth}
60+
template.KeyUsage |= x509.KeyUsageDigitalSignature |
61+
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
62+
x509.KeyUsageCRLSign
63+
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
6264

6365
//set the organization for the subject
6466
subject := subjectTemplate()
@@ -86,10 +88,12 @@ func NewCA(baseDir, org, name string) (*CA, error) {
8688

8789
// SignCertificate creates a signed certificate based on a built-in template
8890
// and saves it in baseDir/name
89-
func (ca *CA) SignCertificate(baseDir, name string, sans []string, pub *ecdsa.PublicKey) (*x509.Certificate, error) {
91+
func (ca *CA) SignCertificate(baseDir, name string, sans []string, pub *ecdsa.PublicKey,
92+
ku x509.KeyUsage, eku []x509.ExtKeyUsage) (*x509.Certificate, error) {
9093

9194
template := x509Template()
92-
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
95+
template.KeyUsage = ku
96+
template.ExtKeyUsage = eku
9397

9498
//set the organization for the subject
9599
subject := subjectTemplate()
@@ -130,7 +134,6 @@ func x509Template() x509.Certificate {
130134
SerialNumber: serialNumber,
131135
NotBefore: now,
132136
NotAfter: now.Add(3650 * 24 * time.Hour), //~ten years
133-
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
134137
BasicConstraintsValid: true,
135138
}
136139
return x509

common/tools/cryptogen/msp/generator.go

+53-27
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error
3636
mspDir := filepath.Join(baseDir, "msp")
3737
tlsDir := filepath.Join(baseDir, "tls")
3838

39-
err := createFolderStructure(mspDir)
39+
err := createFolderStructure(mspDir, true)
4040
if err != nil {
4141
return err
4242
}
@@ -46,6 +46,9 @@ func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error
4646
return err
4747
}
4848

49+
/*
50+
Create the MSP identity artifacts
51+
*/
4952
// get keystore path
5053
keystore := filepath.Join(mspDir, "keystore")
5154

@@ -55,26 +58,24 @@ func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error
5558
return err
5659
}
5760

58-
// get public signing certificate
61+
// get public key
5962
ecPubKey, err := csp.GetECPublicKey(priv)
6063
if err != nil {
6164
return err
6265
}
63-
64-
cert, err := rootCA.SignCertificate(filepath.Join(mspDir, "signcerts"), name, sans, ecPubKey)
66+
// generate X509 certificate
67+
cert, err := rootCA.SignCertificate(filepath.Join(mspDir, "signcerts"),
68+
name, []string{}, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{})
6569
if err != nil {
6670
return err
6771
}
6872

6973
// write artifacts to MSP folders
7074

7175
// the CA certificate goes into cacerts
72-
folders := []string{"cacerts"}
73-
for _, folder := range folders {
74-
err = x509Export(filepath.Join(mspDir, folder, x509Filename(rootCA.Name)), rootCA.SignCert)
75-
if err != nil {
76-
return err
77-
}
76+
err = x509Export(filepath.Join(mspDir, "cacerts", x509Filename(rootCA.Name)), rootCA.SignCert)
77+
if err != nil {
78+
return err
7879
}
7980

8081
// the signing identity goes into admincerts.
@@ -84,26 +85,46 @@ func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error
8485
// cleared up anyway by copyAdminCert, but
8586
// we leave a valid admin for now for the sake
8687
// of unit tests
87-
folders = []string{"admincerts"}
88-
for _, folder := range folders {
89-
err = x509Export(filepath.Join(mspDir, folder, x509Filename(rootCA.Name)), cert)
90-
if err != nil {
91-
return err
92-
}
88+
err = x509Export(filepath.Join(mspDir, "admincerts", x509Filename(name)), cert)
89+
if err != nil {
90+
return err
9391
}
9492

95-
// write artifacts to TLS folder
93+
/*
94+
Generate the TLS artifacts in the TLS folder
95+
*/
96+
97+
// generate private key
98+
tlsPrivKey, _, err := csp.GeneratePrivateKey(tlsDir)
99+
if err != nil {
100+
return err
101+
}
102+
// get public key
103+
tlsPubKey, err := csp.GetECPublicKey(tlsPrivKey)
104+
if err != nil {
105+
return err
106+
}
107+
// generate X509 certificate
108+
_, err = rootCA.SignCertificate(filepath.Join(tlsDir),
109+
name, sans, tlsPubKey, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment,
110+
[]x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth})
111+
if err != nil {
112+
return err
113+
}
96114
err = x509Export(filepath.Join(tlsDir, "ca.crt"), rootCA.SignCert)
97115
if err != nil {
98116
return err
99117
}
100118

101-
err = x509Export(filepath.Join(tlsDir, "server.crt"), cert)
119+
// rename the generated TLS X509 cert
120+
err = os.Rename(filepath.Join(tlsDir, x509Filename(name)),
121+
filepath.Join(tlsDir, "server.crt"))
122+
//err = x509Export(filepath.Join(tlsDir, "server.crt"), tlsCert)
102123
if err != nil {
103124
return err
104125
}
105126

106-
err = keyExport(keystore, filepath.Join(tlsDir, "server.key"), priv)
127+
err = keyExport(tlsDir, filepath.Join(tlsDir, "server.key"), tlsPrivKey)
107128
if err != nil {
108129
return err
109130
}
@@ -114,10 +135,11 @@ func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error
114135
func GenerateVerifyingMSP(baseDir string, rootCA *ca.CA) error {
115136

116137
// create folder structure
117-
err := createFolderStructure(baseDir)
138+
err := createFolderStructure(baseDir, false)
118139
if err == nil {
119140
// write MSP cert to appropriate folders
120-
folders := []string{"cacerts", "signcerts"}
141+
//folders := []string{"cacerts", "signcerts"}
142+
folders := []string{"cacerts"}
121143
for _, folder := range folders {
122144
err = x509Export(filepath.Join(baseDir, folder, x509Filename(rootCA.Name)), rootCA.SignCert)
123145
if err != nil {
@@ -137,22 +159,26 @@ func GenerateVerifyingMSP(baseDir string, rootCA *ca.CA) error {
137159
if err != nil {
138160
return err
139161
}
140-
_, err = rootCA.SignCertificate(filepath.Join(baseDir, "admincerts"), rootCA.Name, []string{""}, ecPubKey)
162+
_, err = rootCA.SignCertificate(filepath.Join(baseDir, "admincerts"), rootCA.Name,
163+
[]string{""}, ecPubKey, x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{})
141164
if err != nil {
142165
return err
143166
}
144167

145168
return nil
146169
}
147170

148-
func createFolderStructure(rootDir string) error {
171+
func createFolderStructure(rootDir string, local bool) error {
149172

173+
var folders []string
150174
// create admincerts, cacerts, keystore and signcerts folders
151-
folders := []string{
175+
folders = []string{
152176
filepath.Join(rootDir, "admincerts"),
153177
filepath.Join(rootDir, "cacerts"),
154-
filepath.Join(rootDir, "keystore"),
155-
filepath.Join(rootDir, "signcerts"),
178+
}
179+
if local {
180+
folders = append(folders, filepath.Join(rootDir, "keystore"),
181+
filepath.Join(rootDir, "signcerts"))
156182
}
157183

158184
for _, folder := range folders {
@@ -195,7 +221,7 @@ func copyFile(src, dst string) error {
195221
func keyExport(keystore, output string, key bccsp.Key) error {
196222
id := hex.EncodeToString(key.SKI())
197223

198-
return copyFile(filepath.Join(keystore, id+"_sk"), output)
224+
return os.Rename(filepath.Join(keystore, id+"_sk"), output)
199225
}
200226

201227
func pemExport(path, pemType string, bytes []byte) error {

common/tools/cryptogen/msp/msp_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func TestGenerateLocalMSP(t *testing.T) {
5050

5151
// check to see that the right files were generated/saved
5252
files := []string{
53-
filepath.Join(mspDir, "admincerts", testCAName+"-cert.pem"),
53+
filepath.Join(mspDir, "admincerts", testName+"-cert.pem"),
5454
filepath.Join(mspDir, "cacerts", testCAName+"-cert.pem"),
5555
filepath.Join(mspDir, "keystore"),
5656
filepath.Join(mspDir, "signcerts", testName+"-cert.pem"),
@@ -91,7 +91,6 @@ func TestGenerateVerifyingMSP(t *testing.T) {
9191
files := []string{
9292
filepath.Join(mspDir, "admincerts", testCAName+"-cert.pem"),
9393
filepath.Join(mspDir, "cacerts", testCAName+"-cert.pem"),
94-
filepath.Join(mspDir, "signcerts", testCAName+"-cert.pem"),
9594
}
9695

9796
for _, file := range files {

0 commit comments

Comments
 (0)