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