github.com/canhui/fabric_ca2_2@v2.0.0-alpha+incompatible/lib/client/credential/x509/credential_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package x509_test 8 9 import ( 10 "bytes" 11 "crypto/x509" 12 "encoding/hex" 13 "fmt" 14 "io/ioutil" 15 "net/http" 16 "os" 17 "path/filepath" 18 "testing" 19 20 "github.com/hyperledger/fabric-ca/api" 21 "github.com/hyperledger/fabric-ca/lib" 22 "github.com/hyperledger/fabric-ca/lib/client/credential" 23 . "github.com/hyperledger/fabric-ca/lib/client/credential/x509" 24 "github.com/hyperledger/fabric-ca/lib/client/credential/x509/mocks" 25 "github.com/hyperledger/fabric-ca/util" 26 "github.com/hyperledger/fabric/bccsp/factory" 27 "github.com/stretchr/testify/assert" 28 ) 29 30 const ( 31 testDataDir = "../../../../testdata" 32 ) 33 34 func TestX509Credential(t *testing.T) { 35 clientHome, err := ioutil.TempDir(testDataDir, "x509credtest") 36 if err != nil { 37 t.Fatalf("Failed to create temp directory: %s", err.Error()) 38 } 39 defer os.RemoveAll(clientHome) 40 41 err = lib.CopyFile(filepath.Join(testDataDir, "ec256-1-cert.pem"), filepath.Join(clientHome, "ec256-1-cert.pem")) 42 if err != nil { 43 t.Fatalf("Failed to copy ec256-1-cert.pem to %s: %s", clientHome, err.Error()) 44 } 45 err = os.MkdirAll(filepath.Join(clientHome, "msp/keystore"), 0777) 46 if err != nil { 47 t.Fatalf("Failed to create msp/keystore directory: %s", err.Error()) 48 } 49 50 client := &lib.Client{ 51 Config: &lib.ClientConfig{ 52 URL: fmt.Sprintf("http://localhost:7054"), 53 CSP: &factory.FactoryOpts{ 54 SwOpts: &factory.SwOpts{ 55 HashFamily: "SHA2", 56 SecLevel: 256, 57 FileKeystore: &factory.FileKeystoreOpts{ 58 KeyStorePath: "msp/keystore", 59 }, 60 }, 61 }, 62 }, 63 HomeDir: clientHome, 64 } 65 certFile := filepath.Join(client.HomeDir, "fake-cert.pem") 66 keyFile := filepath.Join(client.HomeDir, "fake-key.pem") 67 x509Cred := NewCredential(certFile, keyFile, client) 68 69 assert.Equal(t, x509Cred.Type(), CredType, "Type for a X509Credential instance must be X509") 70 _, err = x509Cred.Val() 71 assert.Error(t, err, "Val should return error as credential has not been loaded from disk or set") 72 if err != nil { 73 assert.Equal(t, err.Error(), "X509 Credential value is not set") 74 } 75 _, err = x509Cred.EnrollmentID() 76 assert.Error(t, err, "EnrollmentID should return an error as credential has not been loaded from disk or set") 77 if err != nil { 78 assert.Equal(t, err.Error(), "X509 Credential value is not set") 79 } 80 81 err = x509Cred.Store() 82 assert.Error(t, err, "Store should return an error as credential has not been loaded from disk or set") 83 84 err = x509Cred.SetVal("hello") 85 assert.Error(t, err, "SetVal should fail as it expects an object of type *Signer") 86 87 _, err = x509Cred.RevokeSelf() 88 assert.Error(t, err, "RevokeSelf should return an error as credential has not been loaded from disk or set") 89 90 // Set valid value 91 certBytes, err := util.ReadFile(filepath.Join(testDataDir, "ec256-1-cert.pem")) 92 if err != nil { 93 t.Fatalf("Failed to read file: %s", err.Error()) 94 } 95 signer, err := NewSigner(nil, certBytes) 96 if err != nil { 97 t.Fatalf("Failed to create signer: %s", err.Error()) 98 } 99 err = x509Cred.SetVal(signer) 100 assert.NoError(t, err, "SetVal should not fail") 101 102 // Load the credential from client msp, which should fail as enrollment cert/key pair is not present 103 err = x509Cred.Load() 104 assert.Error(t, err, "Load should have failed to load non-existent certificate file") 105 106 certFile = filepath.Join(client.HomeDir, "ec256-1-cert.pem") 107 keyFile = filepath.Join(client.HomeDir, "ec256-1-key.pem") 108 109 err = client.Init() 110 if err != nil { 111 t.Fatalf("Failed to initialize client: %s", err.Error()) 112 } 113 x509Cred = NewCredential(certFile, keyFile, client) 114 err = x509Cred.Load() 115 assert.Error(t, err, "Load should have failed to load non-existent key file") 116 assert.Contains(t, err.Error(), "Could not find the private key in the BCCSP keystore nor in the keyfile") 117 118 err = lib.CopyFile(filepath.Join(testDataDir, "ec256-1-key.pem"), filepath.Join(client.HomeDir, "ec256-1-key.pem")) 119 if err != nil { 120 t.Fatalf("Failed to copy ec256-1-key.pem to %s: %s", clientHome, err.Error()) 121 } 122 err = x509Cred.Load() 123 assert.NoError(t, err, "Load should not fail as both cert and key files exist and are valid") 124 125 // Should error if it fails to write cert to the specified file 126 if err = os.Chmod(certFile, 0000); err != nil { 127 t.Fatalf("Failed to chmod certificate file %s: %s", certFile, err.Error()) 128 } 129 err = x509Cred.Store() 130 assert.Error(t, err, "Store should fail as %s is not writable", certFile) 131 if err = os.Chmod(certFile, 0644); err != nil { 132 t.Fatalf("Failed to chmod certificate file %s: %s", certFile, err.Error()) 133 } 134 135 // Success cases 136 err = x509Cred.Load() 137 assert.NoError(t, err, "Load should not fail as cert exists and key is in bccsp keystore") 138 139 _, err = x509Cred.Val() 140 assert.NoError(t, err, "Val should not return error as x509 credential has been loaded") 141 142 _, err = x509Cred.EnrollmentID() 143 assert.NoError(t, err, "EnrollmentID should not return error as credential has been loaded") 144 145 err = x509Cred.Store() 146 assert.NoError(t, err, "Store should not fail as x509 credential is set and cert file path is valid") 147 148 body := []byte("hello") 149 req, err := http.NewRequest("GET", "localhost:7054/enroll", bytes.NewReader(body)) 150 if err != nil { 151 t.Fatalf("Failed to create HTTP request: %s", err.Error()) 152 } 153 _, err = x509Cred.CreateToken(req, body) 154 assert.NoError(t, err, "CreateToken should not return error") 155 } 156 157 func TestRevokeSelf(t *testing.T) { 158 clientHome, err := ioutil.TempDir(testDataDir, "revokeselftest") 159 if err != nil { 160 t.Fatalf("Failed to create temp directory: %s", err.Error()) 161 } 162 defer os.RemoveAll(clientHome) 163 164 err = lib.CopyFile(filepath.Join(testDataDir, "ec256-1-cert.pem"), filepath.Join(clientHome, "ec256-1-cert.pem")) 165 if err != nil { 166 t.Fatalf("Failed to copy ec256-1-cert.pem to %s: %s", clientHome, err.Error()) 167 } 168 err = os.MkdirAll(filepath.Join(clientHome, "msp/keystore"), 0777) 169 if err != nil { 170 t.Fatalf("Failed to create msp/keystore directory: %s", err.Error()) 171 } 172 keystore := filepath.Join(clientHome, "msp/keystore/ec256-1-key.pem") 173 err = lib.CopyFile(filepath.Join(testDataDir, "ec256-1-key.pem"), keystore) 174 if err != nil { 175 t.Fatalf("Failed to copy ec256-1-key.pem to %s: %s", keystore, err.Error()) 176 } 177 178 id := new(mocks.Identity) 179 client := new(mocks.Client) 180 opts := &factory.FactoryOpts{ 181 SwOpts: &factory.SwOpts{ 182 HashFamily: "SHA2", 183 SecLevel: 256, 184 FileKeystore: &factory.FileKeystoreOpts{ 185 KeyStorePath: "msp/keystore", 186 }, 187 }, 188 } 189 bccsp, err := util.InitBCCSP(&opts, filepath.Join(clientHome, "msp/keystore"), clientHome) 190 if err != nil { 191 t.Fatalf("Failed initialize BCCSP: %s", err.Error()) 192 } 193 client.On("GetCSP").Return(bccsp) 194 client.On("GetCSP").Return(nil) 195 certFile := filepath.Join(clientHome, "ec256-1-cert.pem") 196 cert, err := readCert(certFile) 197 if err != nil { 198 t.Fatalf("Failed to read the cert: %s", err.Error()) 199 } 200 x509Cred := NewCredential(certFile, keystore, client) 201 err = x509Cred.Load() 202 if err != nil { 203 t.Fatalf("Should not fail to load x509 credential as cert exists and key is in bccsp keystore: %s", err.Error()) 204 } 205 name, err := x509Cred.EnrollmentID() 206 assert.NoError(t, err, "EnrollmentID() should not return an error") 207 client.On("NewX509Identity", name, []credential.Credential{x509Cred}).Return(id) 208 209 serial := util.GetSerialAsHex(cert.SerialNumber) 210 aki := hex.EncodeToString(cert.AuthorityKeyId) 211 req := &api.RevocationRequest{ 212 Serial: serial, 213 AKI: aki, 214 } 215 id.On("Revoke", req).Return(&api.RevocationResponse{}, nil) 216 217 _, err = x509Cred.RevokeSelf() 218 assert.NoError(t, err) 219 220 body := []byte{} 221 httpReq, err := http.NewRequest("GET", "localhost:7054/enroll", bytes.NewReader(body)) 222 if err != nil { 223 t.Fatalf("Failed to create HTTP request: %s", err.Error()) 224 } 225 _, err = x509Cred.CreateToken(httpReq, body) 226 assert.NoError(t, err) 227 } 228 229 func readCert(certFile string) (*x509.Certificate, error) { 230 certBytes, err := util.ReadFile(certFile) 231 if err != nil { 232 return nil, err 233 } 234 cert, err := util.GetX509CertificateFromPEM(certBytes) 235 if err != nil { 236 return nil, err 237 } 238 return cert, nil 239 }