github.com/tw-bc-group/fabric-ca-gm@v0.0.0-20201218004200-3b690512bd5a/lib/client_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lib_test
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"io/ioutil"
    13  	"net/http"
    14  	"os"
    15  	"path"
    16  	"path/filepath"
    17  	"strings"
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/cloudflare/cfssl/csr"
    22  	"github.com/stretchr/testify/assert"
    23  	"github.com/tw-bc-group/fabric-ca-gm/api"
    24  	. "github.com/tw-bc-group/fabric-ca-gm/lib"
    25  	"github.com/tw-bc-group/fabric-ca-gm/lib/tls"
    26  	"github.com/tw-bc-group/fabric-ca-gm/util"
    27  	"github.com/tw-bc-group/fabric-gm/common/attrmgr"
    28  )
    29  
    30  var (
    31  	ctport1     = 7098
    32  	ctport2     = 7099
    33  	intCAPort   = 7080
    34  	tdDir       = "../testdata"
    35  	fcaDB       = path.Join(tdDir, "fabric-ca-server.db")
    36  	fcaDB2      = path.Join(tdDir, "fabric-ca.db")
    37  	cfgFile     = path.Join(tdDir, "config.json")
    38  	testCfgFile = "testconfig.json"
    39  	csrFile     = path.Join(tdDir, "csr.json")
    40  	serversDir  = "testservers"
    41  	adminID     *Identity
    42  )
    43  
    44  const (
    45  	DefaultCA = ""
    46  )
    47  
    48  func TestClientConfigStat(t *testing.T) {
    49  	wd, err := os.Getwd()
    50  	if err != nil {
    51  		t.Fatalf("failed to get cwd: %s", err)
    52  	}
    53  	td, err := ioutil.TempDir("", "ClientConfigStat")
    54  	if err != nil {
    55  		t.Fatalf("failed to get tmp dir: %s", err)
    56  	}
    57  	defer func() {
    58  		err = os.RemoveAll(td)
    59  		if err != nil {
    60  			t.Errorf("RemoveAll failed: %s", err)
    61  		}
    62  	}()
    63  	err = os.Chdir(td)
    64  	if err != nil {
    65  		t.Fatalf("failed to cd to %v: %s", td, err)
    66  	}
    67  	defer func() {
    68  		err = os.Chdir(wd)
    69  		if err != nil {
    70  			t.Fatalf("failed to cd to %v: %s", wd, err)
    71  		}
    72  	}()
    73  	fileInfo, err := os.Stat(".")
    74  	if err != nil {
    75  		t.Fatalf("os.Stat failed on current dir: %s", err)
    76  	}
    77  	oldmode := fileInfo.Mode()
    78  	err = os.Chmod(".", 0000)
    79  	if err != nil {
    80  		t.Fatalf("Chmod on %s failed: %s", td, err)
    81  	}
    82  	defer func() {
    83  		err = os.Chmod(td, oldmode)
    84  		if err != nil {
    85  			t.Fatalf("Chmod on %s failed: %s", td, err)
    86  		}
    87  	}()
    88  	c := new(Client)
    89  	c.Config = new(ClientConfig)
    90  	err = c.Init()
    91  	t.Logf("initDB err: %v", err)
    92  	if err == nil {
    93  		t.Errorf("initDB should have failed (getcwd failure)")
    94  	}
    95  }
    96  
    97  func TestClientInit(t *testing.T) {
    98  	client := new(Client)
    99  	client.Config = new(ClientConfig)
   100  	client.Config.MSPDir = string(make([]byte, 1))
   101  	err := client.Init()
   102  	t.Logf("Client Init() error %v", err)
   103  	if err == nil {
   104  		t.Errorf("Init should have failed to create keystoreDir")
   105  	}
   106  	defer func() {
   107  		err = os.RemoveAll(filepath.Join(os.TempDir(), "signcerts"))
   108  		if err != nil {
   109  			t.Errorf("RemoveAll failed: %s", err)
   110  		}
   111  		err = os.RemoveAll(filepath.Join(os.TempDir(), "cacerts"))
   112  		if err != nil {
   113  			t.Errorf("RemoveAll failed: %s", err)
   114  		}
   115  		err = os.RemoveAll(filepath.Join(os.TempDir(), "keystore"))
   116  		if err != nil {
   117  			t.Errorf("RemoveAll failed: %s", err)
   118  		}
   119  	}()
   120  
   121  	client.Config.MSPDir = strings.Repeat("a", 260)
   122  	err = client.CheckEnrollment()
   123  	t.Logf("Client CheckEnrollment() error %v", err)
   124  	if err == nil {
   125  		t.Errorf("CheckEnrollment should have failed: %s", err)
   126  	}
   127  	client.Config.MSPDir = os.TempDir()
   128  	_, err = os.Create(filepath.Join(os.TempDir(), "signcerts"))
   129  	if err != nil {
   130  		t.Fatalf("Failed to create cert file: %s", err)
   131  	}
   132  	err = client.Init()
   133  	t.Logf("Client Init() error %v", err)
   134  	if err == nil {
   135  		t.Fatalf("Init should have failed to create certDir")
   136  	}
   137  	err = os.Rename(filepath.Join(os.TempDir(), "signcerts"), filepath.Join(os.TempDir(), "cacerts"))
   138  	if err != nil {
   139  		t.Fatalf("Failed to rename cert dir: %s", err)
   140  	}
   141  	err = client.Init()
   142  	t.Logf("Client Init() error %v", err)
   143  	if err == nil {
   144  		t.Errorf("Init should have failed to create cacertsDir")
   145  	}
   146  }
   147  
   148  func TestIdemixEnroll(t *testing.T) {
   149  	srvHome, err := ioutil.TempDir(testdataDir, "idemixenrollsrv")
   150  	if err != nil {
   151  		t.Fatal("Failed to create server home directory")
   152  	}
   153  	clientHome, err := ioutil.TempDir(testdataDir, "idemixenrollclient")
   154  	if err != nil {
   155  		t.Fatal("Failed to create server home directory")
   156  	}
   157  
   158  	server := TestGetServer(ctport1, srvHome, "", 5, t)
   159  	if server == nil {
   160  		t.Fatal("Failed to create test server")
   161  	}
   162  	err = server.Start()
   163  	if err != nil {
   164  		t.Fatalf("Failed to start server: %s", err)
   165  	}
   166  	stopserver := true
   167  	defer func() {
   168  		if stopserver {
   169  			err = server.Stop()
   170  			if err != nil {
   171  				t.Errorf("Failed to stop server: %s", err)
   172  			}
   173  		}
   174  		os.RemoveAll(srvHome)
   175  		os.RemoveAll(clientHome)
   176  	}()
   177  
   178  	client := &Client{
   179  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", ctport1)},
   180  		HomeDir: clientHome,
   181  	}
   182  
   183  	cainfo, err := client.GetCAInfo(&api.GetCAInfoRequest{})
   184  	if err != nil {
   185  		t.Fatalf("Failed to get CA info: %s", err)
   186  	}
   187  	err = util.WriteFile(filepath.Join(clientHome, "msp/IssuerPublicKey"), cainfo.IssuerPublicKey, 0644)
   188  	if err != nil {
   189  		t.Fatalf("Failed to store CA's idemix public key: %s", err)
   190  	}
   191  
   192  	req := &api.EnrollmentRequest{
   193  		Type: "idemix",
   194  	}
   195  
   196  	_, err = client.Enroll(req)
   197  	assert.Error(t, err, "Idemix enroll should have failed as no user id and secret are not specified in the enrollment request")
   198  
   199  	req.Name = "admin"
   200  	req.Secret = "adminpw1"
   201  	assert.Error(t, err, "Idemix enroll should have failed as secret is incorrect in the enrollment request")
   202  
   203  	req.Secret = "adminpw"
   204  	idemixEnrollRes, err := client.Enroll(req)
   205  	assert.NoError(t, err, "Idemix enroll should not have failed with valid userid/password")
   206  	idemixCred := idemixEnrollRes.Identity.GetIdemixCredential()
   207  	err = idemixCred.Store()
   208  	if err != nil {
   209  		t.Fatalf("Failed to store idemix cred")
   210  	}
   211  
   212  	req.Type = "x509"
   213  	enrollRes, err := client.Enroll(req)
   214  	assert.NoError(t, err, "X509 enroll should not fail")
   215  
   216  	err = enrollRes.Identity.Store()
   217  	if err != nil {
   218  		t.Fatalf("Failed to store X509 credential: %s", err)
   219  	}
   220  
   221  	req.Type = "idemix"
   222  	req.Name = ""
   223  	req.Secret = ""
   224  	enrollRes, err = client.Enroll(req)
   225  	assert.NoError(t, err, "Idemix enroll should not have failed with valid x509 enrollment certificate")
   226  	err = enrollRes.Identity.Store()
   227  	if err != nil {
   228  		t.Fatalf("Failed to store idenditity: %s", err.Error())
   229  	}
   230  
   231  	_, err = client.LoadIdentity("", filepath.Join(clientHome, "msp/signcerts/cert.pem"), filepath.Join(clientHome, "msp/user/SignerConfig"))
   232  	assert.NoError(t, err, "Failed to load identity that has both X509 and Idemix credentials")
   233  
   234  	_, err = client.LoadIdentity("", "", filepath.Join(clientHome, "msp/user/SignerConfig"))
   235  	assert.NoError(t, err, "Failed to load identity that only has Idemix credential")
   236  
   237  	// Error case, invalid x509 and Idemix credential
   238  	_, err = client.LoadIdentity("fake-key.pem", "fake-cert.pem", "fakeIdemixCred")
   239  	util.ErrorContains(t, err, "Identity does not posses any enrollment credentials", "Should have failed to load identity that has no valid credentials")
   240  
   241  	err = client.CheckEnrollment()
   242  	assert.NoError(t, err, "CheckEnrollment should not return an error")
   243  
   244  	CopyFile("../testdata/ec256-1-cert.pem", filepath.Join(clientHome, "msp/signcerts/cert.pem"))
   245  	CopyFile("../testdata/ec256-1-key.pem", filepath.Join(clientHome, "msp/keystore/key.pem"))
   246  	_, err = client.Enroll(req)
   247  	assert.Error(t, err, "Idemix enroll should fail as the certificate is of unregistered user")
   248  }
   249  
   250  func TestGetCRIUsingIdemixToken(t *testing.T) {
   251  	srvHome, err := ioutil.TempDir(testdataDir, "idemixgetcrisrv")
   252  	if err != nil {
   253  		t.Fatal("Failed to create server home directory")
   254  	}
   255  	clientHome, err := ioutil.TempDir(testdataDir, "idemixgetcriclient")
   256  	if err != nil {
   257  		t.Fatal("Failed to create server home directory")
   258  	}
   259  
   260  	server := TestGetServer(ctport1, srvHome, "", 5, t)
   261  	if server == nil {
   262  		t.Fatal("Failed to create test server")
   263  	}
   264  	err = server.Start()
   265  	if err != nil {
   266  		t.Fatalf("Failed to start server: %s", err)
   267  	}
   268  	stopserver := true
   269  	defer func() {
   270  		if stopserver {
   271  			err = server.Stop()
   272  			if err != nil {
   273  				t.Errorf("Failed to stop server: %s", err)
   274  			}
   275  		}
   276  		os.RemoveAll(srvHome)
   277  		os.RemoveAll(clientHome)
   278  	}()
   279  
   280  	client := &Client{
   281  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", ctport1)},
   282  		HomeDir: clientHome,
   283  	}
   284  
   285  	cainfo, err := client.GetCAInfo(&api.GetCAInfoRequest{})
   286  	if err != nil {
   287  		t.Fatalf("Failed to get CA info: %s", err)
   288  	}
   289  	err = util.WriteFile(filepath.Join(clientHome, "msp/IssuerPublicKey"), cainfo.IssuerPublicKey, 0644)
   290  	if err != nil {
   291  		t.Fatalf("Failed to store CA's idemix public key: %s", err)
   292  	}
   293  
   294  	req := &api.EnrollmentRequest{
   295  		Type:   "idemix",
   296  		Name:   "admin",
   297  		Secret: "adminpw",
   298  	}
   299  
   300  	enrollRes, err := client.Enroll(req)
   301  	assert.NoError(t, err, "Idemix enroll should not have failed with valid userid/password")
   302  	err = enrollRes.Identity.Store()
   303  	if err != nil {
   304  		t.Fatalf("Failed to store idenditity: %s", err.Error())
   305  	}
   306  
   307  	criRes, err := enrollRes.Identity.GetCRI(&api.GetCRIRequest{CAName: ""})
   308  	assert.NoError(t, err)
   309  	assert.NotNil(t, criRes)
   310  }
   311  
   312  func TestGetCRIUsingX509Token(t *testing.T) {
   313  	srvHome, err := ioutil.TempDir(testdataDir, "idemixgetcrix509srv")
   314  	if err != nil {
   315  		t.Fatal("Failed to create server home directory")
   316  	}
   317  	clientHome, err := ioutil.TempDir(testdataDir, "idemixgetcrix509client")
   318  	if err != nil {
   319  		t.Fatal("Failed to create server home directory")
   320  	}
   321  
   322  	server := TestGetServer(ctport1, srvHome, "", 5, t)
   323  	if server == nil {
   324  		t.Fatal("Failed to create test server")
   325  	}
   326  	err = server.Start()
   327  	if err != nil {
   328  		t.Fatalf("Failed to start server: %s", err)
   329  	}
   330  	stopserver := true
   331  	defer func() {
   332  		if stopserver {
   333  			err = server.Stop()
   334  			if err != nil {
   335  				t.Errorf("Failed to stop server: %s", err)
   336  			}
   337  		}
   338  		os.RemoveAll(srvHome)
   339  		os.RemoveAll(clientHome)
   340  	}()
   341  
   342  	client := &Client{
   343  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", ctport1)},
   344  		HomeDir: clientHome,
   345  	}
   346  
   347  	cainfo, err := client.GetCAInfo(&api.GetCAInfoRequest{})
   348  	if err != nil {
   349  		t.Fatalf("Failed to get CA info: %s", err)
   350  	}
   351  	err = util.WriteFile(filepath.Join(clientHome, "msp/IssuerPublicKey"), cainfo.IssuerPublicKey, 0644)
   352  	if err != nil {
   353  		t.Fatalf("Failed to store CA's idemix public key: %s", err)
   354  	}
   355  
   356  	req := &api.EnrollmentRequest{
   357  		Type:   "x509",
   358  		Name:   "admin",
   359  		Secret: "adminpw",
   360  	}
   361  
   362  	enrollRes, err := client.Enroll(req)
   363  	assert.NoError(t, err, "Idemix enroll should not have failed with valid userid/password")
   364  
   365  	criRes, err := enrollRes.Identity.GetCRI(&api.GetCRIRequest{CAName: ""})
   366  	assert.NoError(t, err)
   367  	assert.NotNil(t, criRes)
   368  }
   369  
   370  func TestClient(t *testing.T) {
   371  	server := TestGetServer(ctport1, path.Join(serversDir, "c1"), "", 1, t)
   372  	if server == nil {
   373  		return
   374  	}
   375  	err := server.Start()
   376  	if err != nil {
   377  		t.Fatalf("Failed to start server: %s", err)
   378  	}
   379  	stopserver := true
   380  	defer func() {
   381  		if stopserver {
   382  			err = server.Stop()
   383  			if err != nil {
   384  				t.Errorf("Failed to stop server: %s", err)
   385  			}
   386  		}
   387  		err = os.RemoveAll(serversDir)
   388  		if err != nil {
   389  			t.Errorf("RemoveAll failed: %s", err)
   390  		}
   391  		err = os.RemoveAll("msp")
   392  		if err != nil {
   393  			t.Errorf("RemoveAll failed: %s", err)
   394  		}
   395  		err = os.RemoveAll("../testdata/msp")
   396  		if err != nil {
   397  			t.Errorf("RemoveAll failed: %s", err)
   398  		}
   399  	}()
   400  
   401  	c := getTestClient(ctport1)
   402  
   403  	testLoadIdentity(c, t)
   404  	testGetCAInfo(c, t)
   405  	testRegister(c, t)
   406  	testEnrollIncorrectPassword(c, t)
   407  	testDoubleEnroll(c, t)
   408  	testReenroll(c, t)
   409  	testRevocation(c, t, "revoker1", true, true)
   410  	testRevocation(c, t, "nonrevoker1", false, true)
   411  	testRevocation(c, t, "revoker2", true, false)
   412  	testRevocation(c, t, "nonrevoker2", false, false)
   413  	testRevocationErrors(c, t)
   414  	testLoadCSRInfo(c, t)
   415  	testLoadNoCSRInfo(c, t)
   416  	testLoadBadCSRInfo(c, t)
   417  	testEnrollMiscFailures(c, t)
   418  
   419  	stopserver = false
   420  	err = server.Stop()
   421  	if err != nil {
   422  		t.Errorf("Server stop failed: %s", err)
   423  	}
   424  
   425  	testWhenServerIsDown(c, t)
   426  }
   427  
   428  func testGetCAInfo(c *Client, t *testing.T) {
   429  	req := &api.GetCAInfoRequest{}
   430  	si, err := c.GetCAInfo(req)
   431  	if err != nil {
   432  		t.Fatalf("Failed to get server info: %s", err)
   433  	}
   434  	if si == nil {
   435  		t.Fatal("Server info is nil")
   436  	}
   437  
   438  	client2 := new(Client)
   439  	client2.Config = new(ClientConfig)
   440  	client2.Config.MSPDir = string(make([]byte, 1))
   441  	_, err = client2.GetCAInfo(req)
   442  	if err == nil {
   443  		t.Errorf("Should have failed to get server info")
   444  	}
   445  
   446  	client2.Config.MSPDir = ""
   447  	client2.Config.URL = "http://localhost:["
   448  	_, err = client2.GetCAInfo(req)
   449  	if err == nil {
   450  		t.Errorf("Should have failed due to invalid URL")
   451  	}
   452  
   453  	client2.Config.MSPDir = ""
   454  	client2.Config.URL = ""
   455  	client2.Config.TLS.Enabled = true
   456  	_, err = client2.GetCAInfo(req)
   457  	if err == nil {
   458  		t.Errorf("Should have failed due to invalid TLS config")
   459  	}
   460  }
   461  
   462  func testRegister(c *Client, t *testing.T) {
   463  
   464  	// Enroll admin
   465  	enrollReq := &api.EnrollmentRequest{
   466  		Name:   "admin",
   467  		Secret: "adminpw",
   468  	}
   469  
   470  	err := c.CheckEnrollment()
   471  	if err == nil {
   472  		t.Fatalf("testRegister check enrollment should have failed - client not enrolled")
   473  	}
   474  
   475  	eresp, err := c.Enroll(enrollReq)
   476  	if err != nil {
   477  		t.Fatalf("testRegister enroll of admin failed: %s", err)
   478  	}
   479  
   480  	adminID = eresp.Identity
   481  
   482  	err = adminID.Store()
   483  	if err != nil {
   484  		t.Fatalf("testRegister failed to store admin identity: %s", err)
   485  	}
   486  
   487  	// Verify that the duration of the newly created enrollment certificate is 1 year
   488  	d, err := util.GetCertificateDurationFromFile(c.GetCertFilePath())
   489  	if assert.NoError(t, err) {
   490  		assert.True(t, int(d.Hours()) == 8760, "Expecting 8760 but found %f", d.Hours())
   491  	}
   492  
   493  	err = c.CheckEnrollment()
   494  	if err != nil {
   495  		t.Fatalf("testRegister failed to check enrollment: %s", err)
   496  	}
   497  
   498  	// Register as admin
   499  	registerReq := &api.RegistrationRequest{
   500  		Name:           "MyTestUser",
   501  		Type:           "Client",
   502  		Affiliation:    "hyperledger",
   503  		MaxEnrollments: 1,
   504  	}
   505  
   506  	resp, err := adminID.Register(registerReq)
   507  	if err != nil {
   508  		t.Fatalf("Register failed: %s", err)
   509  	}
   510  
   511  	req := &api.EnrollmentRequest{
   512  		Name:   "MyTestUser",
   513  		Secret: resp.Secret,
   514  	}
   515  
   516  	eresp, err = c.Enroll(req)
   517  	if err != nil {
   518  		t.Fatalf("Enroll failed: %s", err)
   519  	}
   520  	id := eresp.Identity
   521  
   522  	if id.GetName() != "MyTestUser" {
   523  		t.Fatal("Incorrect name retrieved")
   524  	}
   525  
   526  	if id.GetECert() == nil {
   527  		t.Fatal("No ECert was returned")
   528  	}
   529  
   530  	_, err = id.GetTCertBatch(&api.GetTCertBatchRequest{Count: 1})
   531  	if err != nil {
   532  		t.Fatal("Failed to get batch of TCerts")
   533  	}
   534  
   535  	// Test registration and enrollment of an identity with attributes
   536  	userName := "MyTestUserWithAttrs"
   537  	registerReq = &api.RegistrationRequest{
   538  		Name:        userName,
   539  		Type:        "client",
   540  		Affiliation: "hyperledger",
   541  		Attributes: []api.Attribute{
   542  			api.Attribute{Name: "attr1", Value: "val1", ECert: true},
   543  			api.Attribute{Name: "attr2", Value: "val2"},
   544  		},
   545  	}
   546  	resp, err = adminID.Register(registerReq)
   547  	if err != nil {
   548  		t.Fatalf("Register of %s failed: %s", userName, err)
   549  	}
   550  
   551  	// Get an ECert with no explict attribute requested and make sure we get the defaults.
   552  	req = &api.EnrollmentRequest{
   553  		Name:   userName,
   554  		Secret: resp.Secret,
   555  	}
   556  	eresp, err = c.Enroll(req)
   557  	if err != nil {
   558  		t.Fatalf("Enroll with attributes failed: %s", err)
   559  	}
   560  	// Verify that the ECert has the correct attributes.
   561  	attrs, err := eresp.Identity.GetECert().Attributes()
   562  	if err != nil {
   563  		t.Fatalf("%s", err)
   564  	}
   565  	checkAttrResult(t, "hf.EnrollmentID", userName, attrs)
   566  	checkAttrResult(t, "hf.Type", "client", attrs)
   567  	checkAttrResult(t, "hf.Affiliation", "hyperledger", attrs)
   568  	checkAttrResult(t, "attr1", "val1", attrs)
   569  	checkAttrResult(t, "attr2", "", attrs)
   570  
   571  	// Another test of registration and enrollment of an identity with attributes
   572  	userName = "MyTestUserWithAttrs2"
   573  	registerReq = &api.RegistrationRequest{
   574  		Name:        userName,
   575  		Type:        "client",
   576  		Affiliation: "hyperledger",
   577  		Attributes: []api.Attribute{
   578  			api.Attribute{Name: "attr1", Value: "val1", ECert: true},
   579  			api.Attribute{Name: "attr2", Value: "val2"},
   580  		},
   581  	}
   582  	resp, err = adminID.Register(registerReq)
   583  	if err != nil {
   584  		t.Fatalf("Register of %s failed: %s", userName, err)
   585  	}
   586  
   587  	// Request an ECert with hf.EnrollmentID, hf.Type, hf.Affiliation, attr1 but without attr2.
   588  	req = &api.EnrollmentRequest{
   589  		Name:   userName,
   590  		Secret: resp.Secret,
   591  		AttrReqs: []*api.AttributeRequest{
   592  			&api.AttributeRequest{Name: "hf.Type"},
   593  			&api.AttributeRequest{Name: "hf.Affiliation"},
   594  			&api.AttributeRequest{Name: "attr1"},
   595  		},
   596  	}
   597  	eresp, err = c.Enroll(req)
   598  	if err != nil {
   599  		t.Fatalf("Enroll with attributes failed: %s", err)
   600  	}
   601  	// Verify that the ECert has the correct attributes
   602  	attrs, err = eresp.Identity.GetECert().Attributes()
   603  	if err != nil {
   604  		t.Fatalf("%s", err)
   605  	}
   606  	checkAttrResult(t, "hf.EnrollmentID", "", attrs)
   607  	checkAttrResult(t, "hf.Type", "client", attrs)
   608  	checkAttrResult(t, "hf.Affiliation", "hyperledger", attrs)
   609  	checkAttrResult(t, "attr1", "val1", attrs)
   610  	checkAttrResult(t, "attr2", "", attrs)
   611  
   612  	// Request an ECert with an attribute that the identity does not have (attr3)
   613  	// but we say that it is required.  This should result in an error.
   614  	req = &api.EnrollmentRequest{
   615  		Name:   userName,
   616  		Secret: resp.Secret,
   617  		AttrReqs: []*api.AttributeRequest{
   618  			&api.AttributeRequest{Name: "attr1", Optional: true},
   619  			&api.AttributeRequest{Name: "attr3"},
   620  		},
   621  	}
   622  	eresp, err = c.Enroll(req)
   623  	if err == nil {
   624  		t.Fatalf("Enroll should have failed because %s does not have attr3", userName)
   625  	}
   626  
   627  	// Register a user with no attributes.
   628  	userName = "MyTestUserWithNoAttrs"
   629  	registerReq = &api.RegistrationRequest{
   630  		Name:        userName,
   631  		Type:        "client",
   632  		Affiliation: "hyperledger",
   633  	}
   634  	resp, err = adminID.Register(registerReq)
   635  	if err != nil {
   636  		t.Fatalf("Register of %s failed: %s", userName, err)
   637  	}
   638  	// Try to enroll the user with no attributes with the "ca" profile.
   639  	// Since the identity doesn't have the "hf.IntermediateCA" attribute,
   640  	// this should fail.
   641  	req = &api.EnrollmentRequest{
   642  		Name:    userName,
   643  		Secret:  resp.Secret,
   644  		Profile: "ca",
   645  	}
   646  	_, err = c.Enroll(req)
   647  	if err == nil {
   648  		t.Fatalf("Enroll to 'ca' profile should have failed because %s does not have the hf.IntermediateCA attribute", userName)
   649  	}
   650  
   651  }
   652  
   653  func checkAttrResult(t *testing.T, name, val string, attrs *attrmgr.Attributes) {
   654  	v, ok, err := attrs.Value(name)
   655  	if assert.NoError(t, err) {
   656  		if val == "" {
   657  			assert.False(t, ok, "attribute '%s' was found", name)
   658  		} else if assert.True(t, ok, "attribute '%s' was not found", name) {
   659  			assert.True(t, v == val, "invalid value of attribute '%s'; expecting '%s' but found '%s'", name, val, v)
   660  		}
   661  	}
   662  }
   663  
   664  func testEnrollIncorrectPassword(c *Client, t *testing.T) {
   665  
   666  	req := &api.EnrollmentRequest{
   667  		Name:   "admin",
   668  		Secret: "incorrect",
   669  	}
   670  
   671  	_, err := c.Enroll(req)
   672  	if err == nil {
   673  		t.Error("Enroll with incorrect password passed but should have failed")
   674  	}
   675  }
   676  
   677  func testDoubleEnroll(c *Client, t *testing.T) {
   678  
   679  	req := &api.EnrollmentRequest{
   680  		Name:   "testUser",
   681  		Secret: "user1",
   682  	}
   683  
   684  	_, err := c.Enroll(req)
   685  	if err == nil {
   686  		t.Error("Double enroll should have failed but passed")
   687  	}
   688  
   689  }
   690  
   691  func testEnrollMiscFailures(c *Client, t *testing.T) {
   692  	req := &api.EnrollmentRequest{
   693  		Name:   "testUser",
   694  		Secret: "user1",
   695  	}
   696  
   697  	c.Config.URL = "http://localhost:["
   698  	_, err := c.Enroll(req)
   699  	t.Logf("Client Enroll error %v", err)
   700  	if err == nil {
   701  		t.Error("Enroll should have failed due to URL error")
   702  	}
   703  
   704  	c.Config.URL = ""
   705  	var r api.CSRInfo
   706  	var k api.BasicKeyRequest
   707  	var n csr.Name
   708  	k.Algo = "dsa"
   709  	k.Size = 256
   710  	n.C = "US"
   711  
   712  	r.KeyRequest = &k
   713  	r.Names = []csr.Name{n}
   714  	r.Hosts = []string{"host"}
   715  	r.KeyRequest = &k
   716  	req.CSR = &r
   717  	_, err = c.Enroll(req)
   718  	t.Logf("Client Enroll error %v", err)
   719  	if err == nil {
   720  		t.Error("Enroll should have failed due to invalid CSR algo")
   721  	}
   722  }
   723  
   724  func testReenroll(c *Client, t *testing.T) {
   725  	id, err := c.LoadMyIdentity()
   726  	if err != nil {
   727  		t.Errorf("testReenroll: failed LoadMyIdentity: %s", err)
   728  		return
   729  	}
   730  	eresp, err := id.Reenroll(&api.ReenrollmentRequest{})
   731  	if err != nil {
   732  		t.Errorf("testReenroll: failed reenroll: %s", err)
   733  		return
   734  	}
   735  	id = eresp.Identity
   736  	err = id.Store()
   737  	if err != nil {
   738  		t.Errorf("testReenroll: failed Store: %s", err)
   739  	}
   740  }
   741  
   742  func testRevocation(c *Client, t *testing.T, user string, withPriv, ecertOnly bool) {
   743  	rr := &api.RegistrationRequest{
   744  		Name:           user,
   745  		Type:           "user",
   746  		Affiliation:    "hyperledger",
   747  		MaxEnrollments: 1,
   748  	}
   749  	if withPriv {
   750  		rr.Attributes = []api.Attribute{api.Attribute{Name: "hf.Revoker", Value: "true"}}
   751  	}
   752  	resp, err := adminID.Register(rr)
   753  	if err != nil {
   754  		t.Fatalf("Failed to register %s: %s", user, err)
   755  	}
   756  	req := &api.EnrollmentRequest{
   757  		Name:   user,
   758  		Secret: resp.Secret,
   759  	}
   760  	eresp, err := c.Enroll(req)
   761  	if err != nil {
   762  		t.Errorf("enroll of user '%s' failed", user)
   763  		return
   764  	}
   765  	id := eresp.Identity
   766  	var revResp *api.RevocationResponse
   767  	if ecertOnly {
   768  		x509Cred := id.GetX509Credential()
   769  		revResp, err = x509Cred.RevokeSelf()
   770  	} else {
   771  		revResp, err = id.RevokeSelf()
   772  	}
   773  	// Assert that there is no error revoking user/Ecert
   774  	ar := assert.NoError(t, err, "Revocation failed for user %s", user)
   775  	if !ar {
   776  		return
   777  	}
   778  
   779  	// Assert that the cert serial in the revocation response is same as that of user certificate
   780  	cert := id.GetECert().GetX509Cert()
   781  	if cert == nil {
   782  		t.Fatalf("Failed to get certificate for the enrolled user %s: %s", user, err)
   783  	}
   784  	assert.Equal(t, 1, len(revResp.RevokedCerts), "Expected 1 certificate to be revoked")
   785  	assert.Equal(t, util.GetSerialAsHex(cert.SerialNumber), revResp.RevokedCerts[0].Serial,
   786  		"Cert serial in revocation response does match serial number of the cert that was revoked")
   787  
   788  	eresp, err = id.Reenroll(&api.ReenrollmentRequest{})
   789  	assert.Errorf(t, err, "Enrollment of a revoked user %s cert succeeded but should have failed", user)
   790  	if !ecertOnly {
   791  		eresp, err = c.Enroll(req)
   792  		assert.Errorf(t, err, "Enrollment of a revoked user %s succeeded but should have failed", user)
   793  	}
   794  }
   795  
   796  func testRevocationErrors(c *Client, t *testing.T) {
   797  	var revoker = "erroneous_revoker"
   798  	var revoker2 = "erroneous_revoker2"
   799  	var user = "etuser"
   800  
   801  	// register and enroll revoker
   802  	rr := &api.RegistrationRequest{
   803  		Name:           revoker,
   804  		Type:           "user",
   805  		Affiliation:    "org2",
   806  		MaxEnrollments: 1,
   807  		Attributes:     []api.Attribute{api.Attribute{Name: "hf.Revoker", Value: "true"}},
   808  	}
   809  	resp, err := adminID.Register(rr)
   810  	if err != nil {
   811  		t.Fatalf("Failed to register %s %s", revoker, err)
   812  	}
   813  	req := &api.EnrollmentRequest{
   814  		Name:   revoker,
   815  		Secret: resp.Secret,
   816  	}
   817  	eresp, err := c.Enroll(req)
   818  	if err != nil {
   819  		t.Errorf("enroll of user %s failed", revoker)
   820  		return
   821  	}
   822  	revokerId := eresp.Identity
   823  
   824  	// register and enroll revoker2
   825  	rr = &api.RegistrationRequest{
   826  		Name:           revoker2,
   827  		Type:           "user",
   828  		Affiliation:    "org2",
   829  		MaxEnrollments: 1,
   830  		Attributes:     []api.Attribute{api.Attribute{Name: "hf.Revoker", Value: "faux"}},
   831  	}
   832  	_, err = adminID.Register(rr)
   833  	assert.Error(t, err, "Invalid value 'faux' provided for a boolean type attribute")
   834  	// register and enroll revoker2
   835  	rr = &api.RegistrationRequest{
   836  		Name:           revoker2,
   837  		Type:           "user",
   838  		Affiliation:    "org2",
   839  		MaxEnrollments: 1,
   840  		Attributes:     []api.Attribute{api.Attribute{Name: "hf.Revoker", Value: "false"}},
   841  	}
   842  	resp, err = adminID.Register(rr)
   843  	if err != nil {
   844  		t.Fatalf("Failed to register %s %s", revoker2, err)
   845  	}
   846  	req = &api.EnrollmentRequest{
   847  		Name:   revoker2,
   848  		Secret: resp.Secret,
   849  	}
   850  	eresp, err = c.Enroll(req)
   851  	if err != nil {
   852  		t.Errorf("enroll of user %s failed", revoker2)
   853  		return
   854  	}
   855  	revoker2Id := eresp.Identity
   856  
   857  	// register and enroll test user
   858  	rr = &api.RegistrationRequest{
   859  		Name:           user,
   860  		Type:           "user",
   861  		Affiliation:    "hyperledger",
   862  		MaxEnrollments: 1,
   863  		Attributes:     []api.Attribute{api.Attribute{}},
   864  	}
   865  	resp, err = adminID.Register(rr)
   866  	if err != nil {
   867  		t.Fatalf("Failed to register %s: %s", user, err)
   868  	}
   869  	req = &api.EnrollmentRequest{
   870  		Name:   user,
   871  		Secret: resp.Secret,
   872  	}
   873  	eresp, err = c.Enroll(req)
   874  	if err != nil {
   875  		t.Errorf("enroll of user '%s' failed: %v", user, err)
   876  		return
   877  	}
   878  
   879  	// Revoke cert that doesn't exist
   880  	user = "etuser"
   881  	revreq := &api.RevocationRequest{
   882  		Name:   user,
   883  		Serial: "1",
   884  		AKI:    "1",
   885  		Reason: "privilegeWithdrawn",
   886  	}
   887  
   888  	id := eresp.Identity
   889  	_, err = revokerId.Revoke(revreq)
   890  	t.Logf("testRevocationErrors revoke error %v", err)
   891  	if err == nil {
   892  		t.Errorf("Revocation should have failed")
   893  	}
   894  	_, err = revoker2Id.Revoke(revreq)
   895  	t.Logf("testRevocationErrors revoke error %v", err)
   896  	if err == nil {
   897  		t.Errorf("Revocation should have failed")
   898  	}
   899  	eresp, err = id.Reenroll(&api.ReenrollmentRequest{})
   900  	t.Logf("testRevocationErrors reenroll error %v", err)
   901  	if err != nil {
   902  		t.Errorf("%s renroll failed and ecert should not be revoked", user)
   903  	}
   904  
   905  	// Revoke cert that exists, but doesn't belong to user
   906  	revreq.Name = "fake"
   907  	revreq.Serial, revreq.AKI, err = GetCertID(eresp.Identity.GetECert().Cert())
   908  	t.Logf("Name: %s, Serial: %s, AKI: %s. err, %v", revreq.Name, revreq.Serial, revreq.AKI, err)
   909  	_, err = revokerId.Revoke(revreq)
   910  	t.Logf("testRevocationErrors revoke error %v", err)
   911  	if err == nil {
   912  		t.Errorf("Revocation should have failed")
   913  	}
   914  	eresp, err = id.Reenroll(&api.ReenrollmentRequest{})
   915  	t.Logf("testRevocationErrors reenroll error %v", err)
   916  	if err != nil {
   917  		t.Errorf("%s renroll failed and ecert should not be revoked", user)
   918  	}
   919  
   920  	// Cannot revoke across affiliations
   921  	revreq.Name = "etuser"
   922  	revreq.Serial, revreq.AKI, err = GetCertID(eresp.Identity.GetECert().Cert())
   923  	t.Logf("Name: %s, Serial: %s, AKI: %s. err, %v", revreq.Name, revreq.Serial, revreq.AKI, err)
   924  	_, err = revokerId.Revoke(revreq)
   925  	t.Logf("testRevocationErrors revoke error %v", err)
   926  	if err == nil {
   927  		t.Errorf("Revocation should have failed")
   928  	}
   929  	eresp, err = id.Reenroll(&api.ReenrollmentRequest{})
   930  	t.Logf("testRevocationErrors reenroll error %v", err)
   931  	if err != nil {
   932  		t.Errorf("%s renroll failed and ecert should not be revoked", user)
   933  	}
   934  }
   935  
   936  func testLoadCSRInfo(c *Client, t *testing.T) {
   937  	_, err := c.LoadCSRInfo(csrFile)
   938  	if err != nil {
   939  		t.Errorf("testLoadCSRInfo failed: %s", err)
   940  	}
   941  }
   942  
   943  func testLoadNoCSRInfo(c *Client, t *testing.T) {
   944  	_, err := c.LoadCSRInfo("nofile")
   945  	if err == nil {
   946  		t.Error("testLoadNoCSRInfo passed but should have failed")
   947  	}
   948  }
   949  
   950  func testLoadBadCSRInfo(c *Client, t *testing.T) {
   951  	_, err := c.LoadCSRInfo(cfgFile)
   952  	if err == nil {
   953  		t.Error("testLoadBadCSRInfo passed but should have failed")
   954  	}
   955  }
   956  
   957  func testLoadIdentity(c *Client, t *testing.T) {
   958  	_, err := c.LoadIdentity("foo", "bar", "rab")
   959  	if err == nil {
   960  		t.Error("testLoadIdentity foo/bar/rab passed but should have failed")
   961  	}
   962  	_, err = c.LoadIdentity("foo", "../testdata/ec.pem", "bar")
   963  	if err == nil {
   964  		t.Error("testLoadIdentity foo passed but should have failed")
   965  	}
   966  	_, err = c.LoadIdentity("../testdata/ec-key.pem", "../testdata/ec.pem", "bar")
   967  	if err != nil {
   968  		t.Errorf("testLoadIdentity failed: %s", err)
   969  	}
   970  }
   971  
   972  func TestCustomizableMaxEnroll(t *testing.T) {
   973  	srv := TestGetServer(ctport2, path.Join(serversDir, "c2"), "", 3, t)
   974  	if srv == nil {
   975  		return
   976  	}
   977  
   978  	srv.CA.Config.Registry.MaxEnrollments = 3
   979  	srv.Config.Debug = true
   980  
   981  	err := srv.Start()
   982  	if err != nil {
   983  		t.Errorf("Server start failed: %s", err)
   984  	}
   985  	defer func() {
   986  		err = os.RemoveAll("../testdata/fabric-ca-server.db")
   987  		if err != nil {
   988  			t.Errorf("RemoveAll failed: %s", err)
   989  		}
   990  		err = os.RemoveAll(serversDir)
   991  		if err != nil {
   992  			t.Errorf("RemoveAll failed: %s", err)
   993  		}
   994  		err = os.RemoveAll("../testdata/msp")
   995  		if err != nil {
   996  			t.Errorf("RemoveAll failed: %s", err)
   997  		}
   998  	}()
   999  
  1000  	testTooManyEnrollments(t)
  1001  	testIncorrectEnrollment(t)
  1002  
  1003  	err = srv.Stop()
  1004  	if err != nil {
  1005  		t.Errorf("Server stop failed: %s", err)
  1006  	}
  1007  }
  1008  
  1009  func testTooManyEnrollments(t *testing.T) {
  1010  	clientConfig := &ClientConfig{
  1011  		URL: fmt.Sprintf("http://localhost:%d", ctport2),
  1012  	}
  1013  
  1014  	rawURL := fmt.Sprintf("http://admin:adminpw@localhost:%d", ctport2)
  1015  
  1016  	_, err := clientConfig.Enroll(rawURL, testdataDir)
  1017  	if err != nil {
  1018  		t.Errorf("Failed to enroll: %s", err)
  1019  	}
  1020  
  1021  	_, err = clientConfig.Enroll(rawURL, testdataDir)
  1022  	if err != nil {
  1023  		t.Errorf("Failed to enroll: %s", err)
  1024  	}
  1025  
  1026  	eresp, err := clientConfig.Enroll(rawURL, testdataDir)
  1027  	if err != nil {
  1028  		t.Errorf("Failed to enroll: %s", err)
  1029  	}
  1030  	id := eresp.Identity
  1031  
  1032  	_, err = clientConfig.Enroll(rawURL, testdataDir)
  1033  	if err == nil {
  1034  		t.Errorf("Enroll should have failed, no more enrollments left")
  1035  	}
  1036  
  1037  	id.Store()
  1038  }
  1039  
  1040  func testIncorrectEnrollment(t *testing.T) {
  1041  	c := getTestClient(ctport1)
  1042  
  1043  	id, err := c.LoadMyIdentity()
  1044  	if err != nil {
  1045  		t.Fatalf("Failed to load identity: %s", err)
  1046  	}
  1047  
  1048  	req := &api.RegistrationRequest{
  1049  		Name:           "TestUser",
  1050  		Type:           "Client",
  1051  		Affiliation:    "hyperledger",
  1052  		MaxEnrollments: 4,
  1053  	}
  1054  
  1055  	_, err = id.Register(req)
  1056  	if err == nil {
  1057  		t.Error("Registration should have failed, can't register user with max enrollment greater than server max enrollment setting")
  1058  	}
  1059  }
  1060  
  1061  // Test cases for gencrl command
  1062  func TestGenCRL(t *testing.T) {
  1063  	t.Log("Testing genCRL")
  1064  
  1065  	serverHome := path.Join(serversDir, "gencrlserver")
  1066  	clientHome := path.Join(tdDir, "gencrlclient")
  1067  	err := os.RemoveAll(serverHome)
  1068  	if err != nil {
  1069  		t.Fatalf("Failed to remove directory %s", serverHome)
  1070  	}
  1071  	err = os.RemoveAll(clientHome)
  1072  	if err != nil {
  1073  		t.Fatalf("Failed to remove directory %s", clientHome)
  1074  	}
  1075  	defer os.RemoveAll(serverHome)
  1076  	defer os.RemoveAll(clientHome)
  1077  
  1078  	srv, adminID := setupGenCRLTest(t, serverHome, clientHome)
  1079  	defer func() {
  1080  		if srv != nil {
  1081  			srv.Stop()
  1082  		}
  1083  	}()
  1084  
  1085  	_, err = adminID.GenCRL(&api.GenCRLRequest{CAName: ""})
  1086  	assert.NoError(t, err, "failed to generate CRL")
  1087  
  1088  	// error cases
  1089  	// Error case 1: revokedafter is greater than revokedbefore
  1090  	gencrlReq := &api.GenCRLRequest{
  1091  		CAName:        "",
  1092  		RevokedBefore: time.Now().UTC().AddDate(0, 1, 0),
  1093  		RevokedAfter:  time.Now().UTC().AddDate(0, 2, 0),
  1094  	}
  1095  	_, err = adminID.GenCRL(gencrlReq)
  1096  	assert.Error(t, err, "genCRL should have failed as revokedafter timestamp is after revokedbefore timestamp")
  1097  	assert.Contains(t, err.Error(), "Invalid 'revokedafter' value", "Not expected error message")
  1098  
  1099  	// Error case 2: expireafter is greater than expirebefore
  1100  	gencrlReq = &api.GenCRLRequest{
  1101  		CAName:       "",
  1102  		ExpireBefore: time.Now().UTC().AddDate(0, 1, 0),
  1103  		ExpireAfter:  time.Now().UTC().AddDate(0, 2, 0),
  1104  	}
  1105  	_, err = adminID.GenCRL(gencrlReq)
  1106  	assert.Error(t, err, "genCRL should have failed as expireafter timestamp is after expirebefore timestamp")
  1107  	assert.Contains(t, err.Error(), "Invalid 'expireafter' value", "Not expected error message")
  1108  
  1109  	// Error case 3: gencrl request by an user without hf.GenCRL authority should fail
  1110  	gencrluser := "gencrluser1"
  1111  	rr := &api.RegistrationRequest{
  1112  		Name:           gencrluser,
  1113  		Type:           "user",
  1114  		Affiliation:    "org2",
  1115  		MaxEnrollments: 1,
  1116  	}
  1117  	resp, err := adminID.Register(rr)
  1118  	if err != nil {
  1119  		t.Fatalf("Failed to register %s: %s", gencrluser, err)
  1120  	}
  1121  
  1122  	eresp, err := adminID.GetClient().Enroll(&api.EnrollmentRequest{
  1123  		Name:   gencrluser,
  1124  		Secret: resp.Secret,
  1125  	})
  1126  	if err != nil {
  1127  		t.Fatalf("Failed to enroll user %s: %s", gencrluser, err)
  1128  	}
  1129  
  1130  	user1 := eresp.Identity
  1131  	_, err = user1.GenCRL(gencrlReq)
  1132  	assert.Error(t, err, "genCRL should have failed as invoker does not have hf.GenCRL attribute")
  1133  }
  1134  
  1135  func TestGenCRLWithIntServer(t *testing.T) {
  1136  	t.Log("Testing genCRL against intermediate CA server")
  1137  
  1138  	rootCAHome := path.Join(serversDir, "gencrlrootserver")
  1139  	intCAHome := path.Join(serversDir, "gencrlintserver")
  1140  	clientHome := path.Join(tdDir, "gencrlclient")
  1141  	err := os.RemoveAll(rootCAHome)
  1142  	if err != nil {
  1143  		t.Fatalf("Failed to remove directory %s", rootCAHome)
  1144  	}
  1145  	err = os.RemoveAll(intCAHome)
  1146  	if err != nil {
  1147  		t.Fatalf("Failed to remove directory %s", intCAHome)
  1148  	}
  1149  	err = os.RemoveAll(clientHome)
  1150  	if err != nil {
  1151  		t.Fatalf("Failed to remove directory %s", clientHome)
  1152  	}
  1153  
  1154  	removeDirs := func() {
  1155  		os.RemoveAll(rootCAHome)
  1156  		os.RemoveAll(intCAHome)
  1157  		os.RemoveAll(clientHome)
  1158  	}
  1159  	defer removeDirs()
  1160  
  1161  	rootCASrv, intCASrv, adminID := setupGenCRLWithIntServerTest(t, rootCAHome, intCAHome, clientHome, false)
  1162  	stopServers := func() {
  1163  		if rootCASrv != nil {
  1164  			rootCASrv.Stop()
  1165  		}
  1166  		if intCASrv != nil {
  1167  			intCASrv.Stop()
  1168  		}
  1169  	}
  1170  	defer stopServers()
  1171  
  1172  	_, err = adminID.GenCRL(&api.GenCRLRequest{CAName: ""})
  1173  	assert.NoError(t, err, "failed to generate CRL")
  1174  
  1175  	stopServers()
  1176  	removeDirs()
  1177  
  1178  	// Error case: Do not give 'crl sign' usage to the intermediate CA certificate and try generating a CRL
  1179  	// It should return an error
  1180  	rootCASrv, intCASrv, adminID = setupGenCRLWithIntServerTest(t, rootCAHome, intCAHome, clientHome, true)
  1181  	_, err = adminID.GenCRL(&api.GenCRLRequest{CAName: ""})
  1182  	assert.Error(t, err, "gen CRL should have failed because intermediate CA does not have 'crl sign' usage")
  1183  }
  1184  
  1185  func setupGenCRLWithIntServerTest(t *testing.T, rootCAHome, intCAHome, clientHome string, noCrlSign bool) (*Server, *Server, *Identity) {
  1186  	// Start the root CA server
  1187  	rootCASrv := TestGetServer(ctport1, rootCAHome, "", 1, t)
  1188  	if rootCASrv == nil {
  1189  		t.Fatalf("Failed to get server")
  1190  	}
  1191  	// If noCrlSign is true, remove 'crl sign' usage from the ca profile
  1192  	if noCrlSign {
  1193  		caProfile := rootCASrv.CA.Config.Signing.Profiles["ca"]
  1194  		caProfile.Usage = caProfile.Usage[0:1]
  1195  	}
  1196  	err := rootCASrv.Start()
  1197  	if err != nil {
  1198  		t.Fatalf("Failed to start server: %s", err)
  1199  	}
  1200  
  1201  	// Start the intermediate CA server
  1202  	intCASrv := TestGetServer(intCAPort, intCAHome,
  1203  		fmt.Sprintf("http://admin:adminpw@localhost:%d", ctport1),
  1204  		-1, t)
  1205  	if intCASrv == nil {
  1206  		t.Fatalf("Failed to get server")
  1207  	}
  1208  
  1209  	d, _ := time.ParseDuration("2h")
  1210  	intCASrv.CA.Config.Signing.Default.Expiry = d
  1211  
  1212  	err = intCASrv.Start()
  1213  	if err != nil {
  1214  		t.Fatalf("Failed to start server: %s", err)
  1215  	}
  1216  
  1217  	// Enroll admin
  1218  	c := &Client{
  1219  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", intCAPort)},
  1220  		HomeDir: clientHome,
  1221  	}
  1222  	eresp, err := c.Enroll(&api.EnrollmentRequest{Name: "admin", Secret: "adminpw"})
  1223  	if err != nil {
  1224  		t.Fatalf("Failed to enroll admin: %s", err)
  1225  	}
  1226  	adminID := eresp.Identity
  1227  
  1228  	// Register and revoker a user using admin identity
  1229  	user := "gencrluser"
  1230  	rr := &api.RegistrationRequest{
  1231  		Name:           user,
  1232  		Type:           "user",
  1233  		Affiliation:    "hyperledger",
  1234  		MaxEnrollments: 1,
  1235  	}
  1236  	resp, err := adminID.Register(rr)
  1237  	if err != nil {
  1238  		t.Fatalf("Failed to register user '%s': %s", user, err)
  1239  	}
  1240  	req := &api.EnrollmentRequest{
  1241  		Name:   user,
  1242  		Secret: resp.Secret,
  1243  	}
  1244  	eresp, err = c.Enroll(req)
  1245  	if err != nil {
  1246  		t.Fatalf("Failed to enroll user '%s': %s", user, err)
  1247  	}
  1248  	_, err = adminID.Revoke(&api.RevocationRequest{Name: user})
  1249  	if err != nil {
  1250  		t.Fatalf("Failed to revoke user '%s': %s", user, err)
  1251  	}
  1252  	return rootCASrv, intCASrv, adminID
  1253  }
  1254  
  1255  func setupGenCRLTest(t *testing.T, serverHome, clientHome string) (*Server, *Identity) {
  1256  	server := TestGetServer(ctport1, serverHome, "", 1, t)
  1257  	if server == nil {
  1258  		t.Fatalf("Failed to get server")
  1259  	}
  1260  	d, _ := time.ParseDuration("2h")
  1261  	server.CA.Config.Signing.Default.Expiry = d
  1262  
  1263  	err := server.Start()
  1264  	if err != nil {
  1265  		t.Fatalf("Failed to start server: %s", err)
  1266  	}
  1267  
  1268  	c := &Client{
  1269  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", ctport1)},
  1270  		HomeDir: clientHome,
  1271  	}
  1272  
  1273  	// Enroll admin
  1274  	eresp, err := c.Enroll(&api.EnrollmentRequest{Name: "admin", Secret: "adminpw"})
  1275  	if err != nil {
  1276  		t.Fatalf("Failed to enroll admin: %s", err)
  1277  	}
  1278  	adminID := eresp.Identity
  1279  
  1280  	// Register and revoker a user
  1281  	user := "gencrluser"
  1282  	rr := &api.RegistrationRequest{
  1283  		Name:           user,
  1284  		Type:           "user",
  1285  		Affiliation:    "hyperledger",
  1286  		MaxEnrollments: 1,
  1287  	}
  1288  	resp, err := adminID.Register(rr)
  1289  	if err != nil {
  1290  		t.Fatalf("Failed to register user '%s': %s", user, err)
  1291  	}
  1292  	req := &api.EnrollmentRequest{
  1293  		Name:   user,
  1294  		Secret: resp.Secret,
  1295  	}
  1296  	eresp, err = c.Enroll(req)
  1297  	if err != nil {
  1298  		t.Fatalf("Failed to enroll user '%s': %s", user, err)
  1299  	}
  1300  	_, err = adminID.Revoke(&api.RevocationRequest{Name: user})
  1301  	if err != nil {
  1302  		t.Fatalf("Failed to revoke user '%s': %s", user, err)
  1303  	}
  1304  	return server, adminID
  1305  }
  1306  
  1307  func TestNormalizeUrl(t *testing.T) {
  1308  	u, err := NormalizeURL("")
  1309  	if err != nil {
  1310  		t.Errorf("normalizeURL empty: %s", err)
  1311  	} else {
  1312  		t.Logf("URL %s, %s, %s", u.Scheme, u.Host, u.Path)
  1313  	}
  1314  	u, err = NormalizeURL("http://host:7054:x/path")
  1315  	if err != nil {
  1316  		t.Errorf("normalizeURL colons: %s", err)
  1317  	} else {
  1318  		t.Logf("URL %s, %s, %s", u.Scheme, u.Host, u.Path)
  1319  	}
  1320  	u, err = NormalizeURL("http://host:7054/path")
  1321  	if err != nil {
  1322  		t.Errorf("normalizeURL failed: %s", err)
  1323  	} else {
  1324  		t.Logf("URL %s, %s, %s", u.Scheme, u.Host, u.Path)
  1325  	}
  1326  	u, err = NormalizeURL("https://localhost:80/a%2Fb%2Fc")
  1327  	if err != nil {
  1328  		t.Errorf("NormalizeURL failed: %s", err)
  1329  	} else {
  1330  		t.Logf("URL %s, %s, %s", u.Scheme, u.Host, u.Path)
  1331  	}
  1332  	_, err = NormalizeURL("[")
  1333  	t.Logf("NormalizeURL() error %v", err)
  1334  	if err == nil {
  1335  		t.Errorf("NormalizeURL '[' should have failed")
  1336  	}
  1337  	_, err = NormalizeURL("http://[/path")
  1338  	t.Logf("NormalizeURL() error %v", err)
  1339  	if err == nil {
  1340  		t.Errorf("NormalizeURL 'http://[/path]' should have failed")
  1341  	}
  1342  	_, err = NormalizeURL("https:rootless/path")
  1343  	t.Logf("NormalizeURL() error %v", err)
  1344  	if err == nil {
  1345  		t.Errorf("NormalizeURL 'https:rootless/path' should have failed")
  1346  	}
  1347  }
  1348  
  1349  func TestSendBadPost(t *testing.T) {
  1350  	c := new(Client)
  1351  
  1352  	c.Config = new(ClientConfig)
  1353  
  1354  	curl := "fake"
  1355  	reqBody := []byte("")
  1356  	req, _ := http.NewRequest("POST", curl, bytes.NewReader(reqBody))
  1357  	err := c.SendReq(req, nil)
  1358  	if err == nil {
  1359  		t.Error("Sending post should have failed")
  1360  	}
  1361  }
  1362  
  1363  // Test to make sure that CSR is generated by GenCSR function
  1364  func TestGenCSR(t *testing.T) {
  1365  	config := new(ClientConfig)
  1366  
  1367  	homeDir := filepath.Join(testdataDir, "identity")
  1368  
  1369  	defer func() {
  1370  		err := os.RemoveAll(homeDir)
  1371  		if err != nil {
  1372  			t.Errorf("RemoveAll failed: %s", err)
  1373  		}
  1374  	}()
  1375  
  1376  	config.CSR.CN = "identity"
  1377  	err := config.GenCSR(homeDir)
  1378  	if err != nil {
  1379  		t.Fatalf("Failed to generate CSR: %s", err)
  1380  	}
  1381  	csrFile := filepath.Join(homeDir, "msp", "signcerts", "identity.csr")
  1382  	_, err = os.Stat(csrFile)
  1383  	if os.IsNotExist(err) {
  1384  		t.Fatalf("CSR file does not exist at %s", csrFile)
  1385  	}
  1386  	err = os.RemoveAll(homeDir)
  1387  	if err != nil {
  1388  		t.Errorf("RemoveAll failed: %s", err)
  1389  	}
  1390  
  1391  	// Error cases
  1392  	//CN is missing
  1393  	config.CSR.CN = ""
  1394  	err = config.GenCSR(homeDir)
  1395  	if err == nil {
  1396  		t.Fatalf("GenCSR should fail as CN is missing: %s", err)
  1397  	}
  1398  
  1399  	// Fail to write file
  1400  	config.CSR.CN = strings.Repeat("a", 260)
  1401  	err = config.GenCSR(homeDir)
  1402  	t.Logf("ClientConfig.GenCSR error %v", err)
  1403  	if err == nil {
  1404  		t.Error("ClientConfig.GenCSR should have failed due to invalid filename")
  1405  	}
  1406  
  1407  	// Fail to gen key
  1408  	config.CSR = api.CSRInfo{
  1409  		CN: "TestGenCSR",
  1410  		KeyRequest: &api.BasicKeyRequest{
  1411  			Algo: "dsa",
  1412  			Size: 256,
  1413  		},
  1414  	}
  1415  	err = config.GenCSR(homeDir)
  1416  	t.Logf("ClientConfig.GenCSR error %v", err)
  1417  	if err == nil {
  1418  		t.Error("ClientConfig.GenCSR should have failed due to unsupported algorithm")
  1419  	}
  1420  
  1421  	// Fail to init client
  1422  	config.MSPDir = string(make([]byte, 1))
  1423  	err = config.GenCSR(homeDir)
  1424  	t.Logf("ClientConfig.GenCSR error %v", err)
  1425  	if err == nil {
  1426  		t.Error("ClientConfig.GenCSR should have failed to init client")
  1427  	}
  1428  
  1429  }
  1430  
  1431  // Test to make sure that once an identity is revoked, all subsequent commands
  1432  // invoked by revoked user should be rejected by server for all its issued certificates
  1433  func TestRevokedIdentity(t *testing.T) {
  1434  	testHome, err := ioutil.TempDir(".", "revoketesthome")
  1435  	if err != nil {
  1436  		t.Fatalf("Failed to create temp directory: %s", err.Error())
  1437  	}
  1438  	serverdir := filepath.Join(testdataDir, "server")
  1439  
  1440  	srv := TestGetServer(ctport1, serverdir, "", -1, t)
  1441  	err = srv.Start()
  1442  	if err != nil {
  1443  		t.Fatalf("Failed to start server: %s", err)
  1444  	}
  1445  	defer func() {
  1446  		err := srv.Stop()
  1447  		if err != nil {
  1448  			t.Errorf("Server stop failed: %s", err)
  1449  		}
  1450  		err = os.RemoveAll(serverdir)
  1451  		if err != nil {
  1452  			t.Errorf("RemoveAll failed: %s", err)
  1453  		}
  1454  		err = os.RemoveAll(testHome)
  1455  		if err != nil {
  1456  			t.Errorf("RemoveAll failed: %s", err)
  1457  		}
  1458  	}()
  1459  
  1460  	// Enroll admin
  1461  	c := &Client{
  1462  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", ctport1)},
  1463  		HomeDir: filepath.Join(testHome, "admin"),
  1464  	}
  1465  
  1466  	enrollReq := &api.EnrollmentRequest{
  1467  		Name:   "admin",
  1468  		Secret: "adminpw",
  1469  	}
  1470  
  1471  	eresp, err := c.Enroll(enrollReq)
  1472  	if err != nil {
  1473  		t.Fatalf("Enrollment of admin failed: %s", err)
  1474  	}
  1475  
  1476  	admin_id := eresp.Identity
  1477  
  1478  	// 'admin' registers 'TestUser' user
  1479  	registerReq := &api.RegistrationRequest{
  1480  		Name:           "TestUser",
  1481  		Type:           "user",
  1482  		Affiliation:    "hyperledger",
  1483  		MaxEnrollments: 2,
  1484  	}
  1485  
  1486  	resp, err := admin_id.Register(registerReq)
  1487  	if err != nil {
  1488  		t.Fatalf("Register failed: %s", err)
  1489  	}
  1490  
  1491  	// Enroll 'TestUser'
  1492  	TestUserClient := &Client{
  1493  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", ctport1)},
  1494  		HomeDir: filepath.Join(testHome, "TestUserClient"),
  1495  	}
  1496  
  1497  	enrollReq = &api.EnrollmentRequest{
  1498  		Name:   "TestUser",
  1499  		Secret: resp.Secret,
  1500  	}
  1501  
  1502  	eresp2, err := TestUserClient.Enroll(enrollReq)
  1503  	if err != nil {
  1504  		t.Fatalf("Enrollment of TestUser failed: %s", err)
  1505  	}
  1506  
  1507  	testuserid := eresp2.Identity
  1508  
  1509  	// Enroll 'TestUser' again with a different home/msp directory
  1510  	TestUserClient2 := &Client{
  1511  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", ctport1)},
  1512  		HomeDir: filepath.Join(testHome, "TestUserClient2"),
  1513  	}
  1514  
  1515  	enrollReq = &api.EnrollmentRequest{
  1516  		Name:   "TestUser",
  1517  		Secret: resp.Secret,
  1518  	}
  1519  
  1520  	eresp3, err := TestUserClient2.Enroll(enrollReq)
  1521  	if err != nil {
  1522  		t.Fatalf("Enrollment of TestUser failed: %s", err)
  1523  	}
  1524  
  1525  	testuserid2 := eresp3.Identity
  1526  
  1527  	// 'admin' revokes user 'TestUser'
  1528  	revReq := &api.RevocationRequest{
  1529  		Name:   "TestUser",
  1530  		GenCRL: true,
  1531  	}
  1532  
  1533  	_, err = admin_id.Revoke(revReq)
  1534  	if err != nil {
  1535  		t.Fatalf("Failed to revoke TestUser identity: %s", err)
  1536  	}
  1537  
  1538  	// After an identity has been revoked, all subsequent commands invoked by revoked user should be rejected by server
  1539  	// for all its issued certificates
  1540  	_, err = TestUserClient2.Enroll(enrollReq)
  1541  	if err == nil {
  1542  		t.Fatalf("Enrollment of TestUser should have failed: %s", err)
  1543  	}
  1544  
  1545  	_, err = testuserid.Reenroll(&api.ReenrollmentRequest{})
  1546  	if err == nil {
  1547  		t.Fatalf("Reenrollment of TestUser identity should have failed: %s", err)
  1548  	}
  1549  
  1550  	_, err = testuserid2.Reenroll(&api.ReenrollmentRequest{})
  1551  	if err == nil {
  1552  		t.Fatalf("Reenrollment of TestUser identity should have failed: %s", err)
  1553  	}
  1554  
  1555  	_, err = testuserid.Register(registerReq)
  1556  	if err == nil {
  1557  		t.Fatalf("Registeration of TestUser identity should have failed: %s", err)
  1558  	}
  1559  
  1560  	_, err = testuserid2.Register(registerReq)
  1561  	if err == nil {
  1562  		t.Fatalf("Registeration of TestUser identity should have failed: %s", err)
  1563  	}
  1564  
  1565  	_, err = testuserid.Revoke(&api.RevocationRequest{
  1566  		Name: "admin",
  1567  	})
  1568  	if err == nil {
  1569  		t.Fatalf("Revocation of 'admin' identity should have failed: %s", err)
  1570  	}
  1571  
  1572  	_, err = testuserid2.Revoke(&api.RevocationRequest{
  1573  		Name: "admin",
  1574  	})
  1575  	if err == nil {
  1576  		t.Fatalf("Revocation of 'admin' identity should have failed: %s", err)
  1577  	}
  1578  
  1579  	c = new(Client)
  1580  	c.Config = new(ClientConfig)
  1581  	c.Config.URL = fmt.Sprintf("http://localhost:%d", ctport1)
  1582  
  1583  	// Bad TLS
  1584  	c.Config.MSPDir = "msp"
  1585  	var kc tls.KeyCertFiles
  1586  	kc.KeyFile = "../testdata/ec_key.pem"
  1587  	kc.CertFile = "../testdata/expiredcert.pem"
  1588  	c.Config.MSPDir = ""
  1589  	c.Config.URL = ""
  1590  	c.Config.TLS.Enabled = true
  1591  	c.Config.TLS.CertFiles = []string{"../testdata/ec.pem"}
  1592  	c.Config.TLS.Client = kc
  1593  	curl := fmt.Sprintf("http://localhost:%d/api/v1/register", ctport1)
  1594  	reqBody := []byte("")
  1595  	req, _ := http.NewRequest("POST", curl, bytes.NewReader(reqBody))
  1596  	err = c.SendReq(req, nil)
  1597  	t.Logf("Client SendReq() error %v", err)
  1598  	if err == nil {
  1599  		t.Error("Sending post with bad TLS config should have failed")
  1600  	}
  1601  
  1602  	err = GenerateECDSATestCert()
  1603  	util.FatalError(t, err, "Failed to generate certificate for testing")
  1604  	kc.CertFile = "../testdata/ec_cert.pem"
  1605  	c.Config.TLS.Client = kc
  1606  	req, _ = http.NewRequest("POST", curl, bytes.NewReader(reqBody))
  1607  	err = c.SendReq(req, nil)
  1608  	t.Logf("Client SendReq() error %v", err)
  1609  	if err == nil {
  1610  		t.Error("Sending post with bad TLS config should have failed")
  1611  	}
  1612  
  1613  	// Bad URL
  1614  	curl = fmt.Sprintf("http://localhost:%d/fake", ctport1)
  1615  	reqBody = []byte("")
  1616  	req, _ = http.NewRequest("POST", curl, bytes.NewReader(reqBody))
  1617  	err = c.SendReq(req, nil)
  1618  	t.Logf("Client SendReq() error %v", err)
  1619  	if err == nil {
  1620  		t.Error("Sending post with bad URL should have failed")
  1621  	}
  1622  
  1623  	// No authorization header
  1624  	curl = fmt.Sprintf("http://localhost:%d/api/v1/revoke", ctport1)
  1625  	reqBody = []byte("")
  1626  	req, _ = http.NewRequest("POST", curl, bytes.NewReader(reqBody))
  1627  	err = c.SendReq(req, nil)
  1628  	t.Logf("Client SendReq() error %v", err)
  1629  	if err == nil {
  1630  		t.Error("Sending register with no authorization header should have failed")
  1631  	}
  1632  
  1633  	// Bad authorization header
  1634  	curl = fmt.Sprintf("http://localhost:%d/api/v1/register", ctport1)
  1635  	reqBody = []byte("")
  1636  	req, _ = http.NewRequest("POST", curl, bytes.NewReader(reqBody))
  1637  	req.Header.Add("Authorization", "bad-auth")
  1638  	err = c.SendReq(req, nil)
  1639  	t.Logf("Client SendReq() error %v", err)
  1640  	if err == nil {
  1641  		t.Error("Sending register with bad authorization header should have failed")
  1642  	}
  1643  
  1644  	// Bad Init
  1645  	c2 := new(Client)
  1646  	c2.Config = new(ClientConfig)
  1647  	c2.Config.URL = fmt.Sprintf("http://localhost:%d", ctport1)
  1648  	c2.Config.MSPDir = string(make([]byte, 1))
  1649  	curl = fmt.Sprintf("http://localhost:%d/api/v1/register", ctport1)
  1650  	reqBody = []byte("")
  1651  	req, _ = http.NewRequest("POST", curl, bytes.NewReader(reqBody))
  1652  	err = c2.SendReq(req, nil)
  1653  	t.Logf("Client SendReq() error %v", err)
  1654  	if err == nil {
  1655  		t.Error("Sending post with bad Init should have failed")
  1656  	}
  1657  }
  1658  
  1659  func TestGetCertificatesClient(t *testing.T) {
  1660  	serverHome := path.Join(serversDir, "gencrlserver")
  1661  	clientHome := path.Join(tdDir, "gencrlclient")
  1662  
  1663  	err := os.RemoveAll(serverHome)
  1664  	assert.NoError(t, err, "Failed to remove directory: %s", serverHome)
  1665  	err = os.RemoveAll(clientHome)
  1666  	assert.NoError(t, err, "Failed to remove directory: %s", clientHome)
  1667  	defer os.RemoveAll(serverHome)
  1668  	defer os.RemoveAll(clientHome)
  1669  
  1670  	srv, adminID := setupGetCertTest(t, serverHome, clientHome)
  1671  	defer func() {
  1672  		if srv != nil {
  1673  			srv.Stop()
  1674  		}
  1675  	}()
  1676  
  1677  	cd := NewCertificateDecoder(filepath.Join(clientHome, "getCert"))
  1678  	err = adminID.GetCertificates(&api.GetCertificatesRequest{}, cd.CertificateDecoder)
  1679  	assert.NoError(t, err)
  1680  
  1681  	_, err = os.Stat(filepath.Join(clientHome, "getCert", "admin.pem"))
  1682  	if err != nil {
  1683  		t.Error("Failed to store certificate in correct location")
  1684  	}
  1685  }
  1686  
  1687  func setupGetCertTest(t *testing.T, serverHome, clientHome string) (*Server, *Identity) {
  1688  	server := TestGetServer(ctport1, serverHome, "", 1, t)
  1689  	if server == nil {
  1690  		t.Fatalf("Failed to get server")
  1691  	}
  1692  	d, _ := time.ParseDuration("2h")
  1693  	server.CA.Config.Signing.Default.Expiry = d
  1694  
  1695  	err := server.Start()
  1696  	if err != nil {
  1697  		t.Fatalf("Failed to start server: %s", err)
  1698  	}
  1699  
  1700  	c := &Client{
  1701  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", ctport1)},
  1702  		HomeDir: clientHome,
  1703  	}
  1704  
  1705  	// Enroll admin
  1706  	eresp, err := c.Enroll(&api.EnrollmentRequest{Name: "admin", Secret: "adminpw"})
  1707  	if err != nil {
  1708  		t.Fatalf("Failed to enroll admin: %s", err)
  1709  	}
  1710  	adminID := eresp.Identity
  1711  	return server, adminID
  1712  }
  1713  
  1714  func testWhenServerIsDown(c *Client, t *testing.T) {
  1715  	enrollReq := &api.EnrollmentRequest{
  1716  		Name:   "admin",
  1717  		Secret: "adminpw",
  1718  	}
  1719  	_, err := c.Enroll(enrollReq)
  1720  	if err == nil {
  1721  		t.Error("Enroll while server is down should have failed")
  1722  	}
  1723  	id, err := c.LoadMyIdentity()
  1724  	if err != nil {
  1725  		t.Fatalf("LoadMyIdentity failed: %s", err)
  1726  	}
  1727  	_, err = id.Reenroll(&api.ReenrollmentRequest{})
  1728  	if err == nil {
  1729  		t.Error("Reenroll while server is down should have failed")
  1730  	}
  1731  	registration := &api.RegistrationRequest{
  1732  		Name:        "TestUser",
  1733  		Type:        "Client",
  1734  		Affiliation: "hyperledger",
  1735  	}
  1736  	_, err = id.Register(registration)
  1737  	if err == nil {
  1738  		t.Error("Register while server is down should have failed")
  1739  	}
  1740  	_, err = id.GetTCertBatch(&api.GetTCertBatchRequest{Count: 1})
  1741  	if err == nil {
  1742  		t.Error("GetTCertBatch while server is down should have failed")
  1743  	}
  1744  }