Skip to content

Commit e86ea5b

Browse files
committed
[FAB-3350] Increase test coverage for cryptogen
As we start to package this tool, need to make sure the test coverage is adequate. This CR ups the current test coverage to >90%. It adds some logic to existing tests and modifies some functions to use nested if logic as independent checks for errors were not needed / efficient. Will need to add coverage for main.go in a follow-up change. Also addresses staticcheck errors from [FAB-3177] Change-Id: Ia7def11383e7c680ece59e5630cf9debaa6be2b0 Signed-off-by: Gari Singh <[email protected]>
1 parent 2dcac50 commit e86ea5b

File tree

6 files changed

+181
-131
lines changed

6 files changed

+181
-131
lines changed

common/tools/cryptogen/ca/ca_test.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ limitations under the License.
1616
package ca_test
1717

1818
import (
19+
"crypto/ecdsa"
1920
"crypto/x509"
2021
"os"
2122
"path/filepath"
@@ -53,7 +54,7 @@ func TestNewCA(t *testing.T) {
5354

5455
}
5556

56-
func TestGenerateSignedCertificate(t *testing.T) {
57+
func TestGenerateSignCertificate(t *testing.T) {
5758

5859
caDir := filepath.Join(testDir, "ca")
5960
certDir := filepath.Join(testDir, "certs")
@@ -77,6 +78,17 @@ func TestGenerateSignedCertificate(t *testing.T) {
7778
pemFile := filepath.Join(certDir, testName+"-cert.pem")
7879
assert.Equal(t, true, checkForFile(pemFile),
7980
"Expected to find file "+pemFile)
81+
82+
err = rootCA.SignCertificate(certDir, "empty/CA", ecPubKey)
83+
assert.Error(t, err, "Bad name should fail")
84+
85+
// use an empty CA to test error path
86+
badCA := &ca.CA{
87+
Name: "badCA",
88+
SignCert: &x509.Certificate{},
89+
}
90+
err = badCA.SignCertificate(certDir, testName, &ecdsa.PublicKey{})
91+
assert.Error(t, err, "Empty CA should not be able to sign")
8092
cleanup(testDir)
8193

8294
}

common/tools/cryptogen/ca/generator.go

+43-57
Original file line numberDiff line numberDiff line change
@@ -42,64 +42,53 @@ type CA struct {
4242
// baseDir/name
4343
func NewCA(baseDir, name string) (*CA, error) {
4444

45-
err := os.MkdirAll(baseDir, 0755)
46-
if err != nil {
47-
return nil, err
48-
}
49-
50-
//key, err := genKeyECDSA(caDir, name)
51-
priv, signer, err := csp.GeneratePrivateKey(baseDir)
52-
// get public signing certificate
53-
ecPubKey, err := csp.GetECPublicKey(priv)
54-
if err != nil {
55-
return nil, err
56-
}
57-
58-
template, err := x509Template()
59-
60-
if err != nil {
61-
return nil, err
62-
}
63-
64-
//this is a CA
65-
template.IsCA = true
66-
template.KeyUsage |= x509.KeyUsageCertSign | x509.KeyUsageCRLSign
67-
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny, x509.ExtKeyUsageServerAuth}
68-
69-
//set the organization for the subject
70-
subject := subjectTemplate()
71-
subject.Organization = []string{name}
72-
subject.CommonName = name
73-
74-
template.Subject = subject
75-
template.SubjectKeyId = priv.SKI()
45+
var response error
46+
var ca *CA
7647

77-
x509Cert, err := genCertificateECDSA(baseDir, name, &template, &template,
78-
ecPubKey, signer)
79-
80-
if err != nil {
81-
return nil, err
82-
}
83-
84-
ca := &CA{
85-
Name: name,
86-
Signer: signer,
87-
SignCert: x509Cert,
48+
err := os.MkdirAll(baseDir, 0755)
49+
if err == nil {
50+
priv, signer, err := csp.GeneratePrivateKey(baseDir)
51+
response = err
52+
if err == nil {
53+
// get public signing certificate
54+
ecPubKey, err := csp.GetECPublicKey(priv)
55+
response = err
56+
if err == nil {
57+
template := x509Template()
58+
//this is a CA
59+
template.IsCA = true
60+
template.KeyUsage |= x509.KeyUsageCertSign | x509.KeyUsageCRLSign
61+
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny, x509.ExtKeyUsageServerAuth}
62+
63+
//set the organization for the subject
64+
subject := subjectTemplate()
65+
subject.Organization = []string{name}
66+
subject.CommonName = name
67+
68+
template.Subject = subject
69+
template.SubjectKeyId = priv.SKI()
70+
71+
x509Cert, err := genCertificateECDSA(baseDir, name, &template, &template,
72+
ecPubKey, signer)
73+
response = err
74+
if err == nil {
75+
ca = &CA{
76+
Name: name,
77+
Signer: signer,
78+
SignCert: x509Cert,
79+
}
80+
}
81+
}
82+
}
8883
}
89-
90-
return ca, nil
84+
return ca, response
9185
}
9286

9387
// SignCertificate creates a signed certificate based on a built-in template
9488
// and saves it in baseDir/name
9589
func (ca *CA) SignCertificate(baseDir, name string, pub *ecdsa.PublicKey) error {
9690

97-
template, err := x509Template()
98-
99-
if err != nil {
100-
return err
101-
}
102-
91+
template := x509Template()
10392
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
10493

10594
//set the organization for the subject
@@ -108,7 +97,7 @@ func (ca *CA) SignCertificate(baseDir, name string, pub *ecdsa.PublicKey) error
10897

10998
template.Subject = subject
11099

111-
_, err = genCertificateECDSA(baseDir, name, &template, ca.SignCert,
100+
_, err := genCertificateECDSA(baseDir, name, &template, ca.SignCert,
112101
pub, ca.Signer)
113102

114103
if err != nil {
@@ -128,14 +117,11 @@ func subjectTemplate() pkix.Name {
128117
}
129118

130119
// default template for X509 certificates
131-
func x509Template() (x509.Certificate, error) {
120+
func x509Template() x509.Certificate {
132121

133122
//generate a serial number
134123
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
135-
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
136-
if err != nil {
137-
return x509.Certificate{}, err
138-
}
124+
serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)
139125

140126
now := time.Now()
141127
//basic template to use
@@ -146,7 +132,7 @@ func x509Template() (x509.Certificate, error) {
146132
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
147133
BasicConstraintsValid: true,
148134
}
149-
return x509, nil
135+
return x509
150136

151137
}
152138

common/tools/cryptogen/csp/csp.go

+17-20
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,27 @@ func GeneratePrivateKey(keystorePath string) (bccsp.Key,
3131
crypto.Signer, error) {
3232

3333
csp := factory.GetDefault()
34+
var response error
35+
var priv bccsp.Key
36+
signer := &signer.CryptoSigner{}
3437

3538
// generate a key
3639
priv, err := csp.KeyGen(&bccsp.ECDSAP256KeyGenOpts{Temporary: true})
37-
if err != nil {
38-
return nil, nil, err
39-
}
40-
// write it to the keystore
41-
ks, err := sw.NewFileBasedKeyStore(nil, keystorePath, false)
42-
if err != nil {
43-
return nil, nil, err
44-
}
45-
err = ks.StoreKey(priv)
46-
if err != nil {
47-
return nil, nil, err
40+
response = err
41+
if err == nil {
42+
// write it to the keystore
43+
ks, err := sw.NewFileBasedKeyStore(nil, keystorePath, false)
44+
response = err
45+
if err == nil {
46+
err = ks.StoreKey(priv)
47+
response = err
48+
if err == nil {
49+
// create a crypto.Signer
50+
err = signer.Init(csp, priv)
51+
}
52+
}
4853
}
49-
50-
// create a crypto.Signer
51-
signer := &signer.CryptoSigner{}
52-
err = signer.Init(csp, priv)
53-
if err != nil {
54-
return nil, nil, err
55-
}
56-
57-
return priv, signer, nil
54+
return priv, signer, response
5855

5956
}
6057

common/tools/cryptogen/csp/csp_test.go

+55
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,43 @@ package csp_test
1818
import (
1919
"crypto/ecdsa"
2020
"encoding/hex"
21+
"errors"
2122
"os"
2223
"path/filepath"
2324
"testing"
2425

26+
"github.com/hyperledger/fabric/bccsp"
2527
"github.com/hyperledger/fabric/common/tools/cryptogen/csp"
2628
"github.com/stretchr/testify/assert"
2729
)
2830

31+
// mock implementation of bccsp.Key interface
32+
type mockKey struct {
33+
pubKeyErr error
34+
bytesErr error
35+
pubKey bccsp.Key
36+
}
37+
38+
func (mk *mockKey) Bytes() ([]byte, error) {
39+
if mk.bytesErr != nil {
40+
return nil, mk.bytesErr
41+
}
42+
return []byte{1, 2, 3, 4}, nil
43+
}
44+
45+
func (mk *mockKey) PublicKey() (bccsp.Key, error) {
46+
if mk.pubKeyErr != nil {
47+
return nil, mk.pubKeyErr
48+
}
49+
return mk.pubKey, nil
50+
}
51+
52+
func (mk *mockKey) SKI() []byte { return []byte{1, 2, 3, 4} }
53+
54+
func (mk *mockKey) Symmetric() bool { return false }
55+
56+
func (mk *mockKey) Private() bool { return false }
57+
2958
var testDir = filepath.Join(os.TempDir(), "csp-test")
3059

3160
func TestGeneratePrivateKey(t *testing.T) {
@@ -52,6 +81,32 @@ func TestGetECPublicKey(t *testing.T) {
5281
assert.NoError(t, err, "Failed to get public key from private key")
5382
assert.IsType(t, &ecdsa.PublicKey{}, ecPubKey,
5483
"Failed to return an ecdsa.PublicKey")
84+
85+
// force errors using mockKey
86+
priv = &mockKey{
87+
pubKeyErr: nil,
88+
bytesErr: nil,
89+
pubKey: &mockKey{},
90+
}
91+
_, err = csp.GetECPublicKey(priv)
92+
assert.Error(t, err, "Expected an error with a invalid pubKey bytes")
93+
priv = &mockKey{
94+
pubKeyErr: nil,
95+
bytesErr: nil,
96+
pubKey: &mockKey{
97+
bytesErr: errors.New("bytesErr"),
98+
},
99+
}
100+
_, err = csp.GetECPublicKey(priv)
101+
assert.EqualError(t, err, "bytesErr", "Expected bytesErr")
102+
priv = &mockKey{
103+
pubKeyErr: errors.New("pubKeyErr"),
104+
bytesErr: nil,
105+
pubKey: &mockKey{},
106+
}
107+
_, err = csp.GetECPublicKey(priv)
108+
assert.EqualError(t, err, "pubKeyErr", "Expected pubKeyErr")
109+
55110
cleanup(testDir)
56111
}
57112

0 commit comments

Comments
 (0)