gitee.com/zhaochuninhefei/fabric-ca-gm@v0.0.2/lib/ca_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lib
     8  
     9  import (
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os"
    13  	"path"
    14  	"path/filepath"
    15  	"testing"
    16  
    17  	"gitee.com/zhaochuninhefei/gmgo/x509"
    18  
    19  	"gitee.com/zhaochuninhefei/cfssl-gm/csr"
    20  	"gitee.com/zhaochuninhefei/fabric-ca-gm/internal/pkg/api"
    21  	"gitee.com/zhaochuninhefei/fabric-ca-gm/internal/pkg/util"
    22  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/mocks"
    23  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/db/sqlite"
    24  	dbutil "gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/db/util"
    25  	"gitee.com/zhaochuninhefei/fabric-gm/common/metrics/metricsfakes"
    26  	"github.com/stretchr/testify/assert"
    27  )
    28  
    29  const (
    30  	testdir               = "../testdata/"
    31  	dbname                = "fabric-ca-server.db"
    32  	badcert               = "../testdata/expiredcert.pem"
    33  	dsacert               = "../testdata/dsa-cert.pem"
    34  	lowbitcert            = "../testdata/lowbitcert.pem"
    35  	ecPrivKeyNotMatching  = "../testdata/ec-key.pem"
    36  	ecCert                = "../testdata/ec_cert.pem"
    37  	ecPrivKeyMatching     = "../testdata/ec_key.pem"
    38  	rsacert               = "../testdata/rsa.pem"
    39  	rsaPrivKeyNotMatching = "../testdata/rsa2048-1-key.pem"
    40  	backDated             = "../testdata/unRipeCaEc256-cert.pem"
    41  	badUsageCert          = "../testdata/tls_client-cert.pem"
    42  	badUsageKey           = "../testdata/tls_client-key.pem"
    43  	noUsageCert           = "../testdata/noKeyUsage.cert.pem"
    44  	noCACert              = "../testdata/caFalse.cert.pem"
    45  	noCAkey               = "../testdata/caFalse.key.pem"
    46  	caCert                = "ca-cert.pem"
    47  	caKey                 = "ca-key.pem"
    48  	caPort                = "7054"
    49  )
    50  
    51  var (
    52  	configFile = serverCfgFile(testdir)
    53  )
    54  
    55  var cfg CAConfig
    56  var srv Server
    57  
    58  func TestCABadCACertificates(t *testing.T) {
    59  	srv.levels = &dbutil.Levels{
    60  		Identity:    1,
    61  		Affiliation: 1,
    62  		Certificate: 1,
    63  	}
    64  	mockOperationsServer := &mocks.OperationsServer{}
    65  	fakeCounter := &metricsfakes.Counter{}
    66  	fakeCounter.WithReturns(fakeCounter)
    67  	mockOperationsServer.NewCounterReturns(fakeCounter)
    68  	fakeHistogram := &metricsfakes.Histogram{}
    69  	fakeHistogram.WithReturns(fakeHistogram)
    70  	mockOperationsServer.NewHistogramReturns(fakeHistogram)
    71  
    72  	srv.Operations = mockOperationsServer
    73  	testDirClean(t)
    74  	ca, err := newCA(configFile, &CAConfig{}, &srv, false)
    75  	if err != nil {
    76  		t.Fatal("newCA failed ", err)
    77  	}
    78  	err = ca.validateCertAndKey(noCACert, noCAkey)
    79  	t.Log("validateCertAndKey Error: ", err)
    80  	if err == nil {
    81  		t.Error("Should have failed, non-CA certificate provided")
    82  	}
    83  	err = ca.validateCertAndKey(badUsageCert, badUsageKey)
    84  	t.Log("validateCertAndKey Error: ", err)
    85  	if err == nil {
    86  		t.Error("Should have failed, incorrect keyusage")
    87  	}
    88  
    89  	cert, err := getCertFromFile(noCACert)
    90  	if err != nil {
    91  		t.Fatal(err)
    92  	}
    93  	testValidCA(cert, t)
    94  
    95  	cert, err = getCertFromFile(backDated)
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	testValidDates(cert, t)
   100  
   101  	cert, err = getCertFromFile(badcert)
   102  	if err != nil {
   103  		t.Fatal(err)
   104  	}
   105  	testValidDates(cert, t)
   106  	testValidKeyType(cert, t)
   107  	testValidKeySize(cert, t)
   108  	testValidMatchingKeys(t)
   109  	testValidUsages(cert, t)
   110  	CAclean(ca, t)
   111  }
   112  
   113  func testValidDates(cert *x509.Certificate, t *testing.T) {
   114  	err := validateDates(cert)
   115  	t.Log("validateDates Error: ", err)
   116  	if err == nil {
   117  		t.Error("Should have failed, expired CA certificate provided")
   118  	}
   119  }
   120  
   121  func testValidUsages(cert *x509.Certificate, t *testing.T) {
   122  	err := validateUsage(cert, "")
   123  	t.Log("validateUsage Error: ", err)
   124  	if err == nil {
   125  		t.Error("Should have failed, incorrect usage specified for certificate")
   126  	}
   127  
   128  	cert, err = getCertFromFile(badUsageCert)
   129  	if err != nil {
   130  		t.Fatal(err)
   131  	}
   132  
   133  	err = validateUsage(cert, "")
   134  	t.Log("validateUsage Error: ", err)
   135  	if assert.Error(t, err, "Should have failed, missing 'Cert Sign' key usage") {
   136  		assert.Contains(t, err.Error(), "'cert sign' key usage is required")
   137  	}
   138  }
   139  
   140  func testValidCA(cert *x509.Certificate, t *testing.T) {
   141  	cert.IsCA = false
   142  	err := validateIsCA(cert)
   143  	t.Log("validateIsCA Error: ", err)
   144  	if err == nil {
   145  		t.Error("Should have failed, invalid value for IsCA")
   146  	}
   147  }
   148  
   149  func testValidKeyType(cert *x509.Certificate, t *testing.T) {
   150  	err := validateKeyType(cert)
   151  	if err != nil {
   152  		t.Error("Error occurred during validation of a supported key type: ", err)
   153  	}
   154  
   155  	cert, err = getCertFromFile(dsacert)
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  
   160  	err = validateKeyType(cert)
   161  	t.Log("validateKeyType-Bad Error: ", err)
   162  	if err == nil {
   163  		t.Error("Should have failed, unsupported key type DSA")
   164  	}
   165  }
   166  
   167  func testValidKeySize(cert *x509.Certificate, t *testing.T) {
   168  	err := validateKeySize(cert)
   169  	if err != nil {
   170  		t.Error("Failed to pass a certificate with valid key size: ", err)
   171  	}
   172  
   173  	cert, err = getCertFromFile(lowbitcert)
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  
   178  	err = validateKeySize(cert)
   179  	t.Log("validateKeySize Error: ", err)
   180  	if err == nil {
   181  		t.Error("Should have failed, bit size is too low (1024) for certificate")
   182  	}
   183  }
   184  
   185  func testValidMatchingKeys(t *testing.T) {
   186  	err := GenerateECDSATestCert()
   187  	util.FatalError(t, err, "Failed to generate certificate for testing")
   188  	cert, err := getCertFromFile(ecCert)
   189  	if err != nil {
   190  		t.Fatal(err)
   191  	}
   192  	err = validateMatchingKeys(cert, ecPrivKeyNotMatching)
   193  	t.Log("validateMatchingKeys Error: ", err)
   194  	if err == nil {
   195  		t.Error("Should have failed, public key and private key do not match")
   196  	}
   197  
   198  	err = validateMatchingKeys(cert, ecPrivKeyMatching)
   199  	if err != nil {
   200  		t.Error("Failed to validate a matching key pair, error: ", err)
   201  	}
   202  
   203  	cert, err = getCertFromFile(rsacert)
   204  	if err != nil {
   205  		t.Fatal(err)
   206  	}
   207  
   208  	err = validateMatchingKeys(cert, rsaPrivKeyNotMatching)
   209  	t.Log("validateMatchingKeys Error: ", err)
   210  	if err == nil {
   211  		t.Error("Should have failed, public key and private key do not match")
   212  	}
   213  
   214  	err = validateMatchingKeys(cert, ecPrivKeyNotMatching)
   215  	t.Log("validateMatchingKeys Error: ", err)
   216  	if err == nil {
   217  		t.Error("Should have failed, public key and private key do not match")
   218  	}
   219  
   220  	err = validateMatchingKeys(cert, "/does-not-exist")
   221  	t.Log("validateMatchingKeys Error: ", err)
   222  	if err == nil {
   223  		t.Error("Should have failed to read bad file")
   224  	}
   225  
   226  }
   227  
   228  // Tests String method of CAConfigDB
   229  func TestCAConfigDBStringer(t *testing.T) {
   230  	dbconfig := CAConfigDB{
   231  		Type:       "postgres",
   232  		Datasource: "dbname=mypostgres host=127.0.0.1 port=8888 user=admin password=admin sslmode=disable",
   233  	}
   234  	str := fmt.Sprintf("%+v", dbconfig) // String method of CAConfigDB is called here
   235  	t.Logf("Stringified postgres CAConfigDB: %s", str)
   236  	assert.Contains(t, str, "user=****", "Username is not masked in the datasource URL")
   237  	assert.Contains(t, str, "password=****", "Password is not masked in the datasource URL")
   238  
   239  	dbconfig.Datasource = "dbname=mypostgres host=127.0.0.1 port=8888 password=admin sslmode=disable user=admin"
   240  	str = fmt.Sprintf("%+v", dbconfig) // String method of CAConfigDB is called here
   241  	t.Logf("Stringified postgres CAConfigDB: %s", str)
   242  	assert.Contains(t, str, "user=****", "Username is not masked in the datasource URL")
   243  	assert.Contains(t, str, "password=****", "Password is not masked in the datasource URL")
   244  
   245  	dbconfig.Datasource = "dbname=cadb password=adminpwd host=127.0.0.1 port=8888 user=cadb sslmode=disable"
   246  	str = fmt.Sprintf("%+v", dbconfig) // String method of CAConfigDB is called here
   247  	t.Logf("Stringified postgres CAConfigDB: %s", str)
   248  	assert.Contains(t, str, "user=****", "Username is not masked in the datasource URL")
   249  	assert.Contains(t, str, "password=****", "Password is not masked in the datasource URL")
   250  
   251  	dbconfig = CAConfigDB{
   252  		Type:       "mysql",
   253  		Datasource: "root:rootpw@tcp(localhost:8888)/mysqldb?parseTime=true",
   254  	}
   255  	str = fmt.Sprintf("%+v", dbconfig)
   256  	t.Logf("Stringified mysql CAConfigDB: %s", str)
   257  	assert.NotContains(t, str, "root", "Username is not masked in the datasource URL")
   258  	assert.NotContains(t, str, "rootpw", "Password is not masked in the datasource URL")
   259  }
   260  
   261  func getTestDir(d string) (string, error) {
   262  	td, err := ioutil.TempDir(".", d)
   263  	if err != nil {
   264  		return string(""), err
   265  	}
   266  	_, d2 := filepath.Split(td)
   267  	return d2, nil
   268  }
   269  
   270  func cdTmpTestDir(name string) (string, error) {
   271  	os.Chdir(testdir)
   272  	tmpDir, err := getTestDir(name)
   273  	if err != nil {
   274  		return "", err
   275  	}
   276  	os.Chdir(tmpDir)
   277  	return tmpDir, nil
   278  }
   279  
   280  func TestCAParseDuration(t *testing.T) {
   281  	defer func() {
   282  		if r := recover(); r != nil {
   283  			t.Log("Successfully recovered ", r)
   284  		} else {
   285  			t.Error("parseDuration should have failed")
   286  		}
   287  	}()
   288  
   289  	parseDuration("9999999999999999999")
   290  }
   291  
   292  func TestCAwriteFile(t *testing.T) {
   293  	err := writeFile("/invalid/", make([]byte, 1), 0777)
   294  	assert.Error(t, err)
   295  }
   296  
   297  func TestCAloadCNFromEnrollmentInfo(t *testing.T) {
   298  	ca, err := newCA(serverCfgFile(os.TempDir()), &CAConfig{}, &srv, true)
   299  	assert.NoError(t, err, "failed to create new CA")
   300  	_, err = ca.loadCNFromEnrollmentInfo("does-not-exist")
   301  	t.Log("loadCNFromEnrollmentInfo err: ", err)
   302  	if err == nil {
   303  		t.Error("Should have failed: ")
   304  	}
   305  	_, err = ca.loadCNFromEnrollmentInfo(ecPrivKeyMatching)
   306  	t.Log("loadCNFromEnrollmentInfo err: ", err)
   307  	if err == nil {
   308  		t.Error("Should have failed: ")
   309  	}
   310  	CAclean(ca, t)
   311  }
   312  
   313  func TestCAgetUserAffiliation(t *testing.T) {
   314  	testDirClean(t)
   315  	ca, err := newCA(configFile, &CAConfig{}, &srv, false)
   316  	if err != nil {
   317  		t.Fatal("newCA failed ", err)
   318  	}
   319  	_, err = ca.getUserAffiliation("does-not-exist")
   320  	t.Log("getUserAffiliation err: ", err)
   321  	if err == nil {
   322  		t.Error("getUserAffiliation should have failed: bad parameter")
   323  	}
   324  	CAclean(ca, t)
   325  }
   326  
   327  func TestCAuserHasAttribute(t *testing.T) {
   328  	testDirClean(t)
   329  	ca, err := newCA(configFile, &CAConfig{}, &srv, false)
   330  	if err != nil {
   331  		t.Fatal("newCA failed ", err)
   332  	}
   333  	_, err = ca.userHasAttribute("does-not-exist", "does-not-exist")
   334  	t.Log("userHasAttribute err: ", err)
   335  	if err == nil {
   336  		t.Error("userHasAttribute should have failed: bad parameter")
   337  	}
   338  	CAclean(ca, t)
   339  }
   340  
   341  func TestCAgetUserAttrValue(t *testing.T) {
   342  	testDirClean(t)
   343  	ca, err := newCA(configFile, &CAConfig{}, &srv, false)
   344  	if err != nil {
   345  		t.Fatal("newCA failed: ", err)
   346  	}
   347  	_, err = ca.getUserAttrValue("maryjokopechne", "delmont")
   348  	t.Log("getUserAttrValue err: ", err)
   349  	if err == nil {
   350  		t.Error("getUserAttrValue should have failed: no such user")
   351  	}
   352  	CAclean(ca, t)
   353  }
   354  
   355  func TestCAaddIdentity(t *testing.T) {
   356  	testDirClean(t)
   357  	id := &CAConfigIdentity{
   358  		Name: "admin",
   359  		Pass: "adminpw",
   360  	}
   361  
   362  	cfg = CAConfig{}
   363  	cfg.Registry = CAConfigRegistry{MaxEnrollments: 10}
   364  	ca, err := newCA(configFile, &cfg, &srv, false)
   365  	if err != nil {
   366  		t.Fatal("newCA failed: ", err)
   367  	}
   368  	err = ca.addIdentity(id, true)
   369  	t.Log("ca.addIdentity err: ", err)
   370  	if err != nil {
   371  		t.Error("ca.addIdentity failed: ", err)
   372  	}
   373  	err = ca.addIdentity(id, true)
   374  	t.Log("ca.addIdentity err: ", err)
   375  	if err == nil {
   376  		t.Error("getUserAttrValue should have failed: duplicate id")
   377  	}
   378  	CAclean(ca, t)
   379  }
   380  
   381  func TestCAinitUserRegistry(t *testing.T) {
   382  	testDirClean(t)
   383  	cfg = CAConfig{}
   384  	cfg.LDAP.Enabled = true
   385  	cfg.LDAP.URL = "ldap://CN=admin,dc=example,dc=com:adminpw@localhost:389/dc=example,dc=com"
   386  	ca, err := newCA(configFile, &cfg, &srv, false)
   387  	if err != nil {
   388  		t.Fatal("newCA FAILED", err)
   389  	}
   390  	CAclean(ca, t)
   391  }
   392  
   393  func TestCAgetCaCert(t *testing.T) {
   394  	testDirClean(t)
   395  	os.Remove(configFile)
   396  	cfg = CAConfig{}
   397  
   398  	cfg.CSR = api.CSRInfo{CA: &csr.CAConfig{}}
   399  	cfg.CSR.CA.Expiry = "not-a-date"
   400  	_, err := newCA(configFile, &cfg, &srv, false)
   401  	t.Log("getCaCert error: ", err)
   402  	if err == nil {
   403  		t.Error("newCA should have failed")
   404  	}
   405  
   406  	cfg.CSR.CA.Expiry = ""
   407  	ca, err := newCA(configFile, &cfg, &srv, false)
   408  	if err != nil {
   409  		t.Fatal("newCA failed ", err)
   410  	}
   411  	cfg.CSR.CA.Expiry = ""
   412  	_, err = ca.getCACert()
   413  	if err != nil {
   414  		t.Error("getCaCert failed ", err)
   415  	}
   416  
   417  	ca.Config.CA.Keyfile = ecPrivKeyMatching
   418  	ca.Config.CA.Certfile = "/"
   419  	ca, err = newCA(configFile, &cfg, &srv, true)
   420  	t.Log("getCaCert error: ", err)
   421  	if err == nil {
   422  		t.Fatal("newCA should have failed")
   423  	}
   424  
   425  	CAclean(ca, t)
   426  	err = os.RemoveAll(configFile)
   427  	if err != nil {
   428  		t.Errorf("RemoveAll failed: %s", err)
   429  	}
   430  }
   431  
   432  func TestCAinitEnrollmentSigner(t *testing.T) {
   433  	testDirClean(t)
   434  	cfg = CAConfig{}
   435  	ca, err := newCA(configFile, &cfg, &srv, true)
   436  	if err != nil {
   437  		t.Fatal("newCA FAILED", err)
   438  	}
   439  
   440  	cfg.Intermediate.ParentServer.URL = "1"
   441  	ca, err = newCA(configFile, &cfg, &srv, false)
   442  	if err != nil {
   443  		t.Fatal("newCA FAILED", err)
   444  	}
   445  
   446  	//Rely on default policy
   447  	cfg.Signing = nil
   448  	ca.csp = nil
   449  	err = ca.initEnrollmentSigner()
   450  	t.Log("ca.initEnrollmentSigner error: ", err)
   451  	if err == nil {
   452  		t.Error("initEnrollmentSigner should have failed")
   453  	}
   454  	CAclean(ca, t)
   455  }
   456  
   457  func TestCADBinit(t *testing.T) {
   458  	orgwd, err := os.Getwd()
   459  	if err != nil {
   460  		t.Fatal("failed to get cwd")
   461  	}
   462  	confDir, err := cdTmpTestDir("TestCADBinit")
   463  	t.Logf("Conf dir: %s", confDir)
   464  	defer func() {
   465  		err = os.Chdir(orgwd)
   466  		if err != nil {
   467  			t.Fatalf("failed to cd to %v: %s", orgwd, err)
   468  		}
   469  	}()
   470  	wd, err := os.Getwd()
   471  	defer cleanupTmpfiles(t, wd)
   472  
   473  	cfg = CAConfig{}
   474  	cfg.DB = CAConfigDB{Datasource: "root:mysql@" + util.RandomString(237)}
   475  	t.Logf("serverCfgFile(confDir): %s", serverCfgFile(confDir))
   476  	ca, err := newCA(serverCfgFile(confDir), &cfg, &srv, false)
   477  	if ca.db != nil {
   478  		t.Error("Create DB should have failed")
   479  	}
   480  }
   481  
   482  func TestCAloadAffiliationsTableR(t *testing.T) {
   483  	testDirClean(t)
   484  	cfg = CAConfig{}
   485  	ca, err := newCA(configFile, &cfg, &srv, true)
   486  	if err != nil {
   487  		t.Fatal("newCA FAILED", err)
   488  	}
   489  
   490  	//Failure to write to DB; non-valid accessor
   491  	dbAccessor := &Accessor{}
   492  	ca.registry = dbAccessor
   493  
   494  	i := make([]interface{}, 3)
   495  	i[1] = []string{"", "root", "root"}
   496  	ca.Config.Affiliations = make(map[string]interface{}, 3)
   497  	ca.Config.Affiliations["a"] = i
   498  	err = ca.loadAffiliationsTable()
   499  	t.Log("ca.loadAffiliationsTable error: ", err)
   500  	if err == nil {
   501  		t.Error("ca.loadAffiliationsTableR should have failed ", err)
   502  	}
   503  	err = ca.loadAffiliationsTableR(i[1], "")
   504  	t.Log("ca.loadAffiliationsTableR error: ", err)
   505  	if err == nil {
   506  		t.Error("ca.loadAffiliationsTableR should have failed ", err)
   507  	}
   508  	err = ca.loadAffiliationsTableR(i, "root")
   509  	t.Log("ca.loadAffiliationsTableR error: ", err)
   510  	if err == nil {
   511  		t.Error("ca.loadAffiliationsTableR should have failed ", err)
   512  	}
   513  	CAclean(ca, t)
   514  }
   515  
   516  func TestCAloadUsersTable(t *testing.T) {
   517  	testDirClean(t)
   518  	cfg = CAConfig{}
   519  	u := &CAConfigIdentity{Name: "a", MaxEnrollments: -10}
   520  	cfg.Registry = CAConfigRegistry{Identities: []CAConfigIdentity{*u}, MaxEnrollments: 10}
   521  	ca, err := newCA(configFile, &cfg, &srv, false)
   522  	t.Log("ca.newCA error: ", err)
   523  	if err == nil {
   524  		t.Error("ca.newCA should have failed")
   525  	}
   526  
   527  	// Chase down all error paths using duplicate entries
   528  	i := make([]interface{}, 3)
   529  	i[1] = []string{"", "root", "root"}
   530  	cfg.Affiliations = make(map[string]interface{}, 3)
   531  	cfg.Affiliations["a"] = i
   532  
   533  	// Valid registration
   534  	err = os.Remove(testdir + dbname)
   535  	if err != nil {
   536  		t.Fatalf("Remove failed: %s", err)
   537  	}
   538  	u = &CAConfigIdentity{Name: "a", MaxEnrollments: 10}
   539  	cfg.Registry = CAConfigRegistry{Identities: []CAConfigIdentity{*u}, MaxEnrollments: 10}
   540  	ca, err = newCA(configFile, &cfg, &srv, false)
   541  	if err != nil {
   542  		t.Fatal("newCA FAILED", err)
   543  	}
   544  
   545  	u = &CAConfigIdentity{Name: "a", MaxEnrollments: 10}
   546  	ca.Config.Registry = CAConfigRegistry{Identities: []CAConfigIdentity{*u}, MaxEnrollments: 10}
   547  	err = ca.loadUsersTable()
   548  	if err != nil {
   549  		t.Error("ca.loadUsersTable failed ", err)
   550  	}
   551  
   552  	// Duplicate resgistration, non-error
   553  	u = &CAConfigIdentity{Name: "a", MaxEnrollments: 10}
   554  	ca.Config.Registry = CAConfigRegistry{Identities: []CAConfigIdentity{*u}, MaxEnrollments: 10}
   555  	err = ca.loadUsersTable()
   556  	if err != nil {
   557  		t.Error("ca.loadUsersTable error path should have succeeded: ", err)
   558  	}
   559  
   560  	// Database error (db is closed)
   561  	u = &CAConfigIdentity{Name: "b", MaxEnrollments: 10}
   562  	ca.Config.Registry = CAConfigRegistry{Identities: []CAConfigIdentity{*u}, MaxEnrollments: 10}
   563  	err = ca.closeDB()
   564  	if err != nil {
   565  		t.Fatalf("CloseDB failed: %s", err)
   566  	}
   567  	err = os.Remove(testdir + dbname)
   568  	if err != nil {
   569  		t.Fatalf("Remove failed: %s", err)
   570  	}
   571  	err = ca.loadUsersTable()
   572  	t.Log("ca.loadUsersTable error: ", err)
   573  	if err == nil {
   574  		t.Error("ca.loadUsersTable should have failed due to DB error ", err)
   575  	}
   576  	CAclean(ca, t)
   577  }
   578  
   579  func TestCAVerifyCertificate(t *testing.T) {
   580  	testDirClean(t)
   581  	cfg = CAConfig{}
   582  	ca, err := newCA(configFile, &cfg, &srv, false)
   583  	if err != nil {
   584  		t.Fatal("newCA FAILED", err)
   585  	}
   586  
   587  	cert, err := getCertFromFile(noCACert)
   588  	if err != nil {
   589  		t.Fatal(err)
   590  	}
   591  
   592  	ca.Config.CA.Keyfile = caKey
   593  	ca.Config.CA.Certfile = caCert
   594  	ca.Config.CA.Chainfile = "../testdata/empty.json"
   595  	err = ca.VerifyCertificate(cert, false)
   596  	t.Log("ca.VerifyCertificate error: ", err)
   597  	if err == nil {
   598  		t.Error("VerifyCertificate should have failed")
   599  	}
   600  
   601  	ca.Config.CA.Chainfile = "../testdata/crl.pem"
   602  	err = ca.VerifyCertificate(cert, false)
   603  	t.Log("ca.VerifyCertificate error: ", err)
   604  	if err == nil {
   605  		t.Error("VerifyCertificate should have failed")
   606  	}
   607  
   608  	err = GenerateECDSATestCert()
   609  	util.FatalError(t, err, "Failed to generate certificate for testing")
   610  	caCert1, err := ioutil.ReadFile("../testdata/ec_cert.pem")
   611  	assert.NoError(t, err, "failed to read ec_cert.pem")
   612  	caCert2 := append(caCert1, util.RandomString(128)...)
   613  	err = ioutil.WriteFile(filepath.Join(os.TempDir(), "ca-chainfile.pem"), caCert2, 0644)
   614  	assert.NoError(t, err, "failed to write ca-chainfile.pem")
   615  	ca.Config.CA.Chainfile = filepath.Join(os.TempDir(), "ca-chainfile.pem")
   616  	err = ca.VerifyCertificate(cert, false)
   617  	t.Log("ca.VerifyCertificate error: ", err)
   618  	if err == nil {
   619  		t.Error("VerifyCertificate should have failed")
   620  	}
   621  	err = os.Remove(filepath.Join(os.TempDir(), "ca-chainfile.pem"))
   622  	if err != nil {
   623  		t.Errorf("Remove failed: %s", err)
   624  	}
   625  
   626  	ca.Config.CA.Chainfile = "doesNotExist"
   627  	ca.Config.CA.Certfile = "doesNotExist"
   628  	ca.Config.Intermediate.ParentServer.URL = "http://127.0.0.1:" + caPort
   629  	err = ca.VerifyCertificate(cert, false)
   630  	t.Log("ca.VerifyCertificate error: ", err)
   631  	if err == nil {
   632  		t.Error("VerifyCertificate should have failed")
   633  	}
   634  	ca.Config.CA.Chainfile = noUsageCert
   635  	err = ca.VerifyCertificate(cert, false)
   636  	t.Log("ca.VerifyCertificate error: ", err)
   637  	if err == nil {
   638  		t.Error("VerifyCertificate should have failed")
   639  	}
   640  	CAclean(ca, t)
   641  }
   642  
   643  // Loads a registrar user and a non-registrar user into database. Server is started using an existing database
   644  // with users. This test verifies that the registrar is given the new attribute "hf.Registrar.Attribute" but
   645  // the non-registrar user is not.
   646  func TestServerMigration(t *testing.T) {
   647  	dir := "migrationTest"
   648  	os.RemoveAll(dir)
   649  	defer os.RemoveAll(dir)
   650  	err := os.Mkdir(dir, 0777)
   651  	if err != nil {
   652  		t.Fatalf("Failed to create directory: %s", err.Error())
   653  	}
   654  
   655  	sqliteDB := sqlite.NewDB(filepath.Join(dir, "fabric-ca-server.db"), "", nil)
   656  	err = sqliteDB.Connect()
   657  	assert.NoError(t, err, "failed to connect to database")
   658  	db, err := sqliteDB.Create()
   659  	assert.NoError(t, err, "failed to create database")
   660  
   661  	util.FatalError(t, err, "Failed to create db")
   662  	_, err = db.Exec("", "INSERT INTO users (id, token, type, affiliation, attributes, state, max_enrollments, level) VALUES ('registrar', '', 'user', 'org2', '[{\"name\":\"hf.Registrar.Roles\",\"value\":\"user,peer,client\"}]', '0', '-1', '0')")
   663  	assert.NoError(t, err, "Failed to insert user 'registrar' into database")
   664  	_, err = db.Exec("", "INSERT INTO users (id, token, type, affiliation, attributes, state, max_enrollments, level) VALUES ('notregistrar', '', 'user', 'org2', '[{\"name\":\"hf.Revoker\",\"value\":\"true\"}]', '0', '-1', '0')")
   665  	assert.NoError(t, err, "Failed to insert user 'notregistrar' into database")
   666  
   667  	server := TestGetServer2(false, rootPort, dir, "", -1, t)
   668  	if server == nil {
   669  		return
   670  	}
   671  	err = server.Start()
   672  	util.FatalError(t, err, "Server start failed")
   673  	defer func() {
   674  		err = server.Stop()
   675  		if err != nil {
   676  			t.Errorf("Failed to stop server: %s", err)
   677  		}
   678  	}()
   679  
   680  	registrar, err := server.CA.registry.GetUser("registrar", nil)
   681  	assert.NoError(t, err, "Failed to get user")
   682  	registrarAttr, err := registrar.GetAttribute("hf.Registrar.Attributes")
   683  	assert.NoError(t, err, "Failed to get attribute")
   684  	t.Logf("registrarAttr: '%+v'", registrarAttr)
   685  	if registrarAttr.Value == "" {
   686  		t.Error("Failed to correctly migrate user 'registrar'")
   687  	}
   688  
   689  	notregistrar, err := server.CA.registry.GetUser("notregistrar", nil)
   690  	assert.NoError(t, err, "Failed to get user")
   691  	_, err = notregistrar.GetAttribute("hf.Registrar.Attributes")
   692  	assert.Error(t, err, "Non-registrar user should not have this attribute, failed to correctly migrate user")
   693  }
   694  
   695  func getCertFromFile(f string) (*x509.Certificate, error) {
   696  	p, err := ioutil.ReadFile(f)
   697  	if err != nil {
   698  		return nil, fmt.Errorf("read of %s failed", f)
   699  	}
   700  	c, err := util.GetX509CertificateFromPEM(p)
   701  	if err != nil {
   702  		return nil, fmt.Errorf("decode of %s failed", f)
   703  	}
   704  	return c, nil
   705  }
   706  
   707  func serverCfgFile(dir string) string {
   708  	return path.Join(dir, "fabric-ca-server-config.yaml")
   709  }
   710  
   711  func cleanupTmpfiles(t *testing.T, d string) {
   712  	err := os.RemoveAll(d) // clean up
   713  	if err != nil {
   714  		t.Fatal("Remove failed: ", err)
   715  	} else {
   716  		t.Log("Removed: ", d)
   717  	}
   718  }
   719  
   720  func CAclean(ca *CA, t *testing.T) {
   721  	if ca != nil {
   722  		err := ca.closeDB()
   723  		if err != nil {
   724  			t.Error("CloseDB failed: ", err)
   725  		}
   726  	}
   727  	testDirClean(t)
   728  }
   729  
   730  func testDirClean(t *testing.T) {
   731  	err := os.RemoveAll(testdir + "msp")
   732  	if err != nil {
   733  		t.Fatal("RemoveAll failed: ", err)
   734  	}
   735  	err = os.RemoveAll(testdir + "ca-cert.pem")
   736  	if err != nil {
   737  		t.Fatal("RemoveAll failed: ", err)
   738  	}
   739  	err = os.RemoveAll(testdir + "ca-key.pem")
   740  	if err != nil {
   741  		t.Fatal("RemoveAll failed: ", err)
   742  	}
   743  	err = os.RemoveAll(testdir + dbname)
   744  	if err != nil {
   745  		t.Fatal("RemoveAll failed: ", err)
   746  	}
   747  	os.Remove(configFile)
   748  }