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