github.com/defanghe/fabric@v2.1.1+incompatible/internal/cryptogen/ca/ca_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 package ca_test 7 8 import ( 9 "crypto/ecdsa" 10 "crypto/x509" 11 "io/ioutil" 12 "net" 13 "os" 14 "path/filepath" 15 "testing" 16 17 "github.com/hyperledger/fabric/internal/cryptogen/ca" 18 "github.com/hyperledger/fabric/internal/cryptogen/csp" 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/require" 21 ) 22 23 const ( 24 testCAName = "root0" 25 testCA2Name = "root1" 26 testCA3Name = "root2" 27 testName = "cert0" 28 testName2 = "cert1" 29 testName3 = "cert2" 30 testIP = "172.16.10.31" 31 testCountry = "US" 32 testProvince = "California" 33 testLocality = "San Francisco" 34 testOrganizationalUnit = "Hyperledger Fabric" 35 testStreetAddress = "testStreetAddress" 36 testPostalCode = "123456" 37 ) 38 39 func TestLoadCertificateECDSA(t *testing.T) { 40 testDir, err := ioutil.TempDir("", "ca-test") 41 if err != nil { 42 t.Fatalf("Failed to create test directory: %s", err) 43 } 44 defer os.RemoveAll(testDir) 45 46 // generate private key 47 certDir, err := ioutil.TempDir(testDir, "certs") 48 if err != nil { 49 t.Fatalf("Failed to create certs directory: %s", err) 50 } 51 priv, err := csp.GeneratePrivateKey(certDir) 52 assert.NoError(t, err, "Failed to generate signed certificate") 53 54 // create our CA 55 caDir := filepath.Join(testDir, "ca") 56 rootCA, err := ca.NewCA( 57 caDir, 58 testCA3Name, 59 testCA3Name, 60 testCountry, 61 testProvince, 62 testLocality, 63 testOrganizationalUnit, 64 testStreetAddress, 65 testPostalCode, 66 ) 67 assert.NoError(t, err, "Error generating CA") 68 69 cert, err := rootCA.SignCertificate( 70 certDir, 71 testName3, 72 nil, 73 nil, 74 &priv.PublicKey, 75 x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment, 76 []x509.ExtKeyUsage{x509.ExtKeyUsageAny}, 77 ) 78 assert.NoError(t, err, "Failed to generate signed certificate") 79 // KeyUsage should be x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment 80 assert.Equal(t, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment, 81 cert.KeyUsage) 82 assert.Contains(t, cert.ExtKeyUsage, x509.ExtKeyUsageAny) 83 84 loadedCert, err := ca.LoadCertificateECDSA(certDir) 85 assert.NoError(t, err) 86 assert.NotNil(t, loadedCert, "Should load cert") 87 assert.Equal(t, cert.SerialNumber, loadedCert.SerialNumber, "Should have same serial number") 88 assert.Equal(t, cert.Subject.CommonName, loadedCert.Subject.CommonName, "Should have same CN") 89 } 90 91 func TestLoadCertificateECDSA_wrongEncoding(t *testing.T) { 92 testDir, err := ioutil.TempDir("", "wrongEncoding") 93 require.NoError(t, err, "failed to create test directory") 94 defer os.RemoveAll(testDir) 95 96 filename := filepath.Join(testDir, "wrong_encoding.pem") 97 err = ioutil.WriteFile(filename, []byte("wrong_encoding"), 0644) // Wrong encoded cert 98 require.NoErrorf(t, err, "failed to create file %s", filename) 99 100 _, err = ca.LoadCertificateECDSA(testDir) 101 assert.NotNil(t, err) 102 assert.EqualError(t, err, filename+": wrong PEM encoding") 103 } 104 105 func TestLoadCertificateECDSA_empty_DER_cert(t *testing.T) { 106 testDir, err := ioutil.TempDir("", "ca-test") 107 require.NoError(t, err, "failed to create test directory") 108 defer os.RemoveAll(testDir) 109 110 filename := filepath.Join(testDir, "empty.pem") 111 empty_cert := "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----" 112 err = ioutil.WriteFile(filename, []byte(empty_cert), 0644) 113 require.NoErrorf(t, err, "failed to create file %s", filename) 114 115 cert, err := ca.LoadCertificateECDSA(testDir) 116 assert.Nil(t, cert) 117 assert.NotNil(t, err) 118 assert.EqualError(t, err, filename+": wrong DER encoding") 119 } 120 121 func TestNewCA(t *testing.T) { 122 testDir, err := ioutil.TempDir("", "ca-test") 123 if err != nil { 124 t.Fatalf("Failed to create test directory: %s", err) 125 } 126 defer os.RemoveAll(testDir) 127 128 caDir := filepath.Join(testDir, "ca") 129 rootCA, err := ca.NewCA( 130 caDir, 131 testCAName, 132 testCAName, 133 testCountry, 134 testProvince, 135 testLocality, 136 testOrganizationalUnit, 137 testStreetAddress, 138 testPostalCode, 139 ) 140 assert.NoError(t, err, "Error generating CA") 141 assert.NotNil(t, rootCA, "Failed to return CA") 142 assert.NotNil(t, rootCA.Signer, 143 "rootCA.Signer should not be empty") 144 assert.IsType(t, &x509.Certificate{}, rootCA.SignCert, 145 "rootCA.SignCert should be type x509.Certificate") 146 147 // check to make sure the root public key was stored 148 pemFile := filepath.Join(caDir, testCAName+"-cert.pem") 149 assert.Equal(t, true, checkForFile(pemFile), 150 "Expected to find file "+pemFile) 151 152 assert.NotEmpty(t, rootCA.SignCert.Subject.Country, "country cannot be empty.") 153 assert.Equal(t, testCountry, rootCA.SignCert.Subject.Country[0], "Failed to match country") 154 assert.NotEmpty(t, rootCA.SignCert.Subject.Province, "province cannot be empty.") 155 assert.Equal(t, testProvince, rootCA.SignCert.Subject.Province[0], "Failed to match province") 156 assert.NotEmpty(t, rootCA.SignCert.Subject.Locality, "locality cannot be empty.") 157 assert.Equal(t, testLocality, rootCA.SignCert.Subject.Locality[0], "Failed to match locality") 158 assert.NotEmpty(t, rootCA.SignCert.Subject.OrganizationalUnit, "organizationalUnit cannot be empty.") 159 assert.Equal(t, testOrganizationalUnit, rootCA.SignCert.Subject.OrganizationalUnit[0], "Failed to match organizationalUnit") 160 assert.NotEmpty(t, rootCA.SignCert.Subject.StreetAddress, "streetAddress cannot be empty.") 161 assert.Equal(t, testStreetAddress, rootCA.SignCert.Subject.StreetAddress[0], "Failed to match streetAddress") 162 assert.NotEmpty(t, rootCA.SignCert.Subject.PostalCode, "postalCode cannot be empty.") 163 assert.Equal(t, testPostalCode, rootCA.SignCert.Subject.PostalCode[0], "Failed to match postalCode") 164 } 165 166 func TestGenerateSignCertificate(t *testing.T) { 167 testDir, err := ioutil.TempDir("", "ca-test") 168 if err != nil { 169 t.Fatalf("Failed to create test directory: %s", err) 170 } 171 defer os.RemoveAll(testDir) 172 173 // generate private key 174 certDir, err := ioutil.TempDir(testDir, "certs") 175 if err != nil { 176 t.Fatalf("Failed to create certs directory: %s", err) 177 } 178 priv, err := csp.GeneratePrivateKey(certDir) 179 assert.NoError(t, err, "Failed to generate signed certificate") 180 181 // create our CA 182 caDir := filepath.Join(testDir, "ca") 183 rootCA, err := ca.NewCA( 184 caDir, 185 testCA2Name, 186 testCA2Name, 187 testCountry, 188 testProvince, 189 testLocality, 190 testOrganizationalUnit, 191 testStreetAddress, 192 testPostalCode, 193 ) 194 assert.NoError(t, err, "Error generating CA") 195 196 cert, err := rootCA.SignCertificate( 197 certDir, 198 testName, 199 nil, 200 nil, 201 &priv.PublicKey, 202 x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment, 203 []x509.ExtKeyUsage{x509.ExtKeyUsageAny}, 204 ) 205 assert.NoError(t, err, "Failed to generate signed certificate") 206 // KeyUsage should be x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment 207 assert.Equal(t, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment, 208 cert.KeyUsage) 209 assert.Contains(t, cert.ExtKeyUsage, x509.ExtKeyUsageAny) 210 211 cert, err = rootCA.SignCertificate( 212 certDir, 213 testName, 214 nil, 215 nil, 216 &priv.PublicKey, 217 x509.KeyUsageDigitalSignature, 218 []x509.ExtKeyUsage{}, 219 ) 220 assert.NoError(t, err, "Failed to generate signed certificate") 221 assert.Equal(t, 0, len(cert.ExtKeyUsage)) 222 223 // make sure ous are correctly set 224 ous := []string{"TestOU", "PeerOU"} 225 cert, err = rootCA.SignCertificate(certDir, testName, ous, nil, &priv.PublicKey, 226 x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) 227 assert.Contains(t, cert.Subject.OrganizationalUnit, ous[0]) 228 assert.Contains(t, cert.Subject.OrganizationalUnit, ous[1]) 229 230 // make sure sans are correctly set 231 sans := []string{testName2, testIP} 232 cert, err = rootCA.SignCertificate(certDir, testName, nil, sans, &priv.PublicKey, 233 x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) 234 assert.Contains(t, cert.DNSNames, testName2) 235 assert.Contains(t, cert.IPAddresses, net.ParseIP(testIP).To4()) 236 237 // check to make sure the signed public key was stored 238 pemFile := filepath.Join(certDir, testName+"-cert.pem") 239 assert.Equal(t, true, checkForFile(pemFile), 240 "Expected to find file "+pemFile) 241 242 _, err = rootCA.SignCertificate(certDir, "empty/CA", nil, nil, &priv.PublicKey, 243 x509.KeyUsageKeyEncipherment, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}) 244 assert.Error(t, err, "Bad name should fail") 245 246 // use an empty CA to test error path 247 badCA := &ca.CA{ 248 Name: "badCA", 249 SignCert: &x509.Certificate{}, 250 } 251 _, err = badCA.SignCertificate(certDir, testName, nil, nil, &ecdsa.PublicKey{}, 252 x509.KeyUsageKeyEncipherment, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}) 253 assert.Error(t, err, "Empty CA should not be able to sign") 254 255 } 256 257 func checkForFile(file string) bool { 258 if _, err := os.Stat(file); os.IsNotExist(err) { 259 return false 260 } 261 return true 262 }