github.com/49746628/fabric-ca-gm@v2.0.0-alpha.0.20200822143404-8a07eefa7452+incompatible/lib/client_whitebox_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 package lib 7 8 import ( 9 "crypto/rand" 10 "crypto/x509" 11 "fmt" 12 "io/ioutil" 13 "net/http" 14 "os" 15 "path" 16 "testing" 17 18 "github.com/cloudflare/cfssl/csr" 19 "github.com/cloudflare/cfssl/log" 20 "github.com/cloudflare/cfssl/signer" 21 "github.com/hyperledger/fabric-ca/internal/pkg/api" 22 "github.com/hyperledger/fabric-ca/internal/pkg/util" 23 cax509 "github.com/hyperledger/fabric-ca/lib/client/credential/x509" 24 "github.com/hyperledger/fabric/bccsp" 25 "github.com/hyperledger/fabric/bccsp/factory" 26 cspsigner "github.com/hyperledger/fabric/bccsp/signer" 27 "github.com/hyperledger/fabric/bccsp/utils" 28 "github.com/stretchr/testify/assert" 29 ) 30 31 const ( 32 whitePort = 7058 33 username = "admin" 34 pass = "adminpw" 35 serversDir = "testservers" 36 testTLSClientAuthDir = "testTLSClientAuthDir" 37 ) 38 39 var clientConfig = path.Join(testdataDir, "client-config.json") 40 41 func TestCWBClient1(t *testing.T) { 42 server := getServer(whitePort, path.Join(serversDir, "c1"), "", 1, t) 43 if server == nil { 44 t.Fatal("Failed to get server") 45 } 46 err := server.Start() 47 if err != nil { 48 t.Fatalf("Failed to start server: %s", err) 49 } 50 defer func() { 51 err = server.Stop() 52 if err != nil { 53 t.Errorf("Server stop failed: %s", err) 54 } 55 err = os.RemoveAll(serversDir) 56 if err != nil { 57 t.Errorf("RemoveAll failed: %s", err) 58 } 59 }() 60 61 testInvalidAuthEnrollment(t) 62 } 63 64 // TestTLS performs 3 main steps: 65 // 1) Test over HTTP to get an standard ECert 66 // 2) Test over HTTPS with client auth disabled 67 // 3) Test over HTTPS with client auth enabled, using standard ECert from #1 68 func TestCWBTLSClientAuth(t *testing.T) { 69 cleanTestSlateCWB(t) 70 defer cleanTestSlateCWB(t) 71 // 72 // 1) Test over HTTP to get a standard ECert 73 // 74 // Start server 75 server := getServer(whitePort, path.Join(testTLSClientAuthDir, "server"), "", 2, t) 76 if server == nil { 77 return 78 } 79 server.CA.Config.CSR.CN = "localhost" 80 err := server.Start() 81 if err != nil { 82 t.Fatalf("Failed to start server: %s", err) 83 } 84 85 // Enroll over HTTP 86 client := &Client{ 87 Config: &ClientConfig{ 88 URL: fmt.Sprintf("http://localhost:%d", whitePort), 89 }, 90 HomeDir: path.Join(testTLSClientAuthDir, "client"), 91 } 92 93 eresp, err := client.Enroll(&api.EnrollmentRequest{Name: username, Secret: pass}) 94 if err != nil { 95 server.Stop() 96 t.Fatalf("Failed to enroll admin: %s", err) 97 } 98 id := eresp.Identity 99 testImpersonation(id, t) 100 testMasqueradeEnroll(t, client, id) 101 102 // Register and enroll user to test reenrolling while masquerading 103 name := "masqueradeUser2" 104 rr, err := id.Register(&api.RegistrationRequest{ 105 Name: name, 106 Type: "user", 107 Affiliation: "hyperledger.fabric.security", 108 MaxEnrollments: 2, 109 }) 110 if err != nil { 111 t.Fatalf("Failed to register maqueradeUser: %s", err) 112 } 113 114 eresp2, err := client.Enroll(&api.EnrollmentRequest{Name: name, Secret: rr.Secret}) 115 if err != nil { 116 t.Errorf("Failed to enroll") 117 } 118 119 id2 := eresp2.Identity 120 testMasqueradeReenroll(t, client, id2) 121 122 // Stop server 123 log.Debug("Stopping the server") 124 err = server.Stop() 125 if err != nil { 126 t.Fatalf("Failed to stop server: %s", err) 127 } 128 129 // 130 // 2) Test over HTTPS with client auth disabled 131 // 132 // Start server 133 log.Debug("Starting the server with TLS") 134 server.Config.TLS.Enabled = true 135 server.Config.TLS.CertFile = "ca-cert.pem" 136 err = server.Start() 137 if err != nil { 138 t.Fatalf("Failed to start server with HTTPS: %s", err) 139 } 140 141 // Close the idle connections that were established to the non-SSL 142 // server. client will create new connection for the next request 143 // There is no need to do this in real scenario where the Fabric CA 144 // server's transport can only be changed from ssl to non-ssl or vice-versa 145 // by restarting the server, in which case connections in the client's 146 // connection pool are invalidated and it is forced to create new connection. 147 client.httpClient.Transport.(*http.Transport).CloseIdleConnections() 148 149 // Try to reenroll over HTTP and it should fail because server is listening on HTTPS 150 _, err = id.Reenroll(&api.ReenrollmentRequest{}) 151 if err == nil { 152 t.Error("Client HTTP should have failed to reenroll with server HTTPS") 153 } 154 155 client.Config.URL = fmt.Sprintf("https://localhost:%d", whitePort) 156 client.Config.TLS.Enabled = true 157 client.Config.TLS.CertFiles = []string{"../server/ca-cert.pem"} 158 // Reinialize the http client with updated config and re-enroll over HTTPS 159 err = client.initHTTPClient() 160 resp, err := id.Reenroll(&api.ReenrollmentRequest{}) 161 if err != nil { 162 server.Stop() 163 t.Fatalf("Failed to reenroll over HTTPS: %s", err) 164 } 165 id = resp.Identity 166 // Store identity persistently 167 err = id.Store() 168 if err != nil { 169 server.Stop() 170 t.Fatalf("Failed to store identity: %s", err) 171 } 172 173 // Stop server 174 err = server.Stop() 175 if err != nil { 176 t.Fatalf("Failed to stop server: %s", err) 177 } 178 179 // 180 // 3) Test over HTTPS with client auth enabled 181 // 182 server.Config.TLS.ClientAuth.Type = "RequireAndVerifyClientCert" 183 server.Config.TLS.ClientAuth.CertFiles = []string{"ca-cert.pem"} 184 err = server.Start() 185 if err != nil { 186 t.Fatalf("Failed to start server with HTTPS and client auth: %s", err) 187 } 188 // Close all idle connections 189 client.httpClient.Transport.(*http.Transport).CloseIdleConnections() 190 191 // Try to reenroll and it should fail because client has no client cert 192 _, err = id.Reenroll(&api.ReenrollmentRequest{}) 193 if err == nil { 194 t.Error("Client reenroll without client cert should have failed") 195 } 196 197 client.Config.TLS.Client.CertFile = path.Join("msp", "signcerts", "cert.pem") 198 // Reinialize the http client with updated config and re-enroll over HTTPS with client auth 199 err = client.initHTTPClient() 200 _, err = id.Reenroll(&api.ReenrollmentRequest{}) 201 if err != nil { 202 t.Errorf("Client reenroll with client auth failed: %s", err) 203 } 204 // Stop server 205 err = server.Stop() 206 if err != nil { 207 t.Fatalf("Failed to stop server: %s", err) 208 } 209 } 210 211 func testInvalidAuthEnrollment(t *testing.T) { 212 c := getTestClient(whitePort) 213 err := c.Init() 214 if err != nil { 215 t.Fatalf("Failed to initialize client: %s", err) 216 } 217 body, err1 := getEnrollmentPayload(t, c) 218 if err1 != nil { 219 t.Fatalf("Failed to get enrollment payload: %s", err1) 220 } 221 222 enrollAndCheck(t, c, body, "Basic admin:adminpw") // Invalid auth header 223 enrollAndCheck(t, c, body, "Basicadmin:adminpw") // Invalid auth header 224 enrollAndCheck(t, c, body, "BasicYWRtaW46YWRtaW5wdw==") // Invalid auth header 225 enrollAndCheck(t, c, body, "Basic YWRtaW46YWRtaW4=") // Invalid password 226 enrollAndCheck(t, c, body, "Basic dXNlcjpwYXNz") // Invalid user 227 enrollAndCheck(t, c, body, "Bearer YWRtaW46YWRtaW5wdw==") // Invalid auth header 228 // Invalid auth header, it has to be Basic <base64 encoded user:pass> 229 enrollAndCheck(t, c, body, "Basic YWRtaW46YWRtaW5wdw==") 230 enrollAndCheck(t, c, body, "garbage") // Invalid auth header 231 enrollAndCheck(t, c, body, "") // No auth header 232 } 233 234 func enrollAndCheck(t *testing.T, c *Client, body []byte, authHeader string) { 235 // Send the CSR to the fabric-ca server with basic auth header 236 post, err := c.newPost("enroll", body) 237 if err != nil { 238 t.Fatalf("Failed to create post request: %s", err) 239 } 240 if authHeader != "" { 241 post.Header.Set("Authorization", authHeader) 242 } 243 var result api.EnrollmentResponseNet 244 err = c.SendReq(post, &result) 245 t.Logf("c.SendReq: %v", err) 246 if err == nil { 247 t.Errorf("Enrollment with bad basic auth header '%s' should have failed", 248 authHeader) 249 } 250 err = os.RemoveAll("../testdata/msp") 251 if err != nil { 252 t.Errorf("RemoveAll failed: %s", err) 253 } 254 } 255 256 // Try to impersonate 'id' identity by creating a self-signed certificate 257 // with the same serial and AKI as this identity. 258 func testImpersonation(id *Identity, t *testing.T) { 259 // test as a fake user trying to impersonate admin give only the cert 260 cert, err := BytesToX509Cert(id.GetECert().Cert()) 261 if err != nil { 262 t.Fatalf("Failed to convert admin's cert: %s", err) 263 } 264 bc := &factory.FactoryOpts{} 265 csp, err := util.InitBCCSP(&bc, "", path.Join(testTLSClientAuthDir, "client")) 266 if err != nil { 267 t.Fatalf("Failed to initialize BCCSP: %s", err) 268 } 269 var fm os.FileMode = 0777 270 os.MkdirAll("msp/keystore", os.FileMode(fm)) 271 defer func() { 272 err = os.RemoveAll("msp") 273 if err != nil { 274 t.Errorf("RemoveAll failed: %s", err) 275 } 276 }() 277 278 privateKey, err := csp.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false}) 279 if err != nil { 280 t.Fatalf("Failed generating ECDSA key [%s]", err) 281 } 282 cspSigner, err := cspsigner.New(csp, privateKey) 283 if err != nil { 284 t.Fatalf("Failed initializing signer: %s", err) 285 } 286 // Export the public key 287 publicKey, err := privateKey.PublicKey() 288 if err != nil { 289 t.Fatalf("Failed getting ECDSA public key: %s", err) 290 } 291 pkRaw, err := publicKey.Bytes() 292 if err != nil { 293 t.Fatalf("Failed getting ECDSA raw public key [%s]", err) 294 } 295 pub, err := utils.DERToPublicKey(pkRaw) 296 if err != nil { 297 t.Fatalf("Failed converting raw to ECDSA.PublicKey [%s]", err) 298 } 299 fakeCertBytes, err := x509.CreateCertificate(rand.Reader, cert, cert, pub, cspSigner) 300 if err != nil { 301 t.Fatalf("Failed to create self-signed fake cert: %s", err) 302 } 303 _, err = cax509.NewSigner(privateKey, fakeCertBytes) 304 if err == nil { 305 t.Fatalf("Should have failed to create signer with fake certificate") 306 } 307 } 308 309 func testMasqueradeEnroll(t *testing.T, c *Client, id *Identity) { 310 // Register masqueradeUser 311 log.Debug("Entering testMasqueradeEnroll") 312 name := "masqueradeUser" 313 rr, err := id.Register(&api.RegistrationRequest{ 314 Name: name, 315 Type: "user", 316 Affiliation: "hyperledger.fabric.security", 317 MaxEnrollments: 2, 318 }) 319 if err != nil { 320 t.Fatalf("Failed to register maqueradeUser: %s", err) 321 } 322 // Try to enroll masqueradeUser but masquerading as 'admin' 323 _, err = masqueradeEnroll(c, "admin", false, &api.EnrollmentRequest{ 324 Name: name, 325 Secret: rr.Secret, 326 }) 327 if err == nil { 328 t.Fatalf("%s masquerading as admin (false) should have failed", name) 329 } 330 log.Debugf("testMasqueradeEnroll (false) error: %s", err) 331 _, err = masqueradeEnroll(c, "admin", true, &api.EnrollmentRequest{ 332 Name: name, 333 Secret: rr.Secret, 334 }) 335 if err == nil { 336 t.Fatalf("%s masquerading as admin (true) should have failed", name) 337 } 338 log.Debugf("testMasqueradeEnroll (true) error: %s", err) 339 } 340 341 func testMasqueradeReenroll(t *testing.T, c *Client, id *Identity) { 342 log.Debug("Entering testMasqueradeReenroll") 343 // Try to reenroll but masquerading as 'admin' 344 _, err := masqueradeReenroll(c, "admin", id, false, &api.ReenrollmentRequest{}) 345 if assert.Error(t, err, fmt.Sprintf("%s masquerading as admin (false) should have failed", id.GetName())) { 346 assert.Contains(t, err.Error(), "The CSR subject common name must equal the enrollment ID", "Failed for other reason besides masquerading") 347 } 348 349 log.Debugf("testMasqueradeEnroll (false) error: %s", err) 350 _, err = masqueradeReenroll(c, "admin", id, true, &api.ReenrollmentRequest{}) 351 if assert.Error(t, err, fmt.Sprintf("%s masquerading as admin (false) should have failed", id.GetName())) { 352 assert.Contains(t, err.Error(), "The CSR subject common name must equal the enrollment ID", "Failed for other reason besides masquerading") 353 } 354 log.Debugf("testMasqueradeEnroll (true) error: %s", err) 355 } 356 357 func getEnrollmentPayload(t *testing.T, c *Client) ([]byte, error) { 358 req := &api.EnrollmentRequest{ 359 Name: username, 360 Secret: pass, 361 } 362 363 // Generate the CSR 364 csrPEM, _, err := c.GenCSR(req.CSR, req.Name) 365 if err != nil { 366 t.Logf("Enroll failure generating CSR: %s", err) 367 return nil, err 368 } 369 370 // Get the body of the request 371 sreq := signer.SignRequest{ 372 Request: string(csrPEM), 373 Profile: req.Profile, 374 Label: req.Label, 375 } 376 377 return util.Marshal(sreq, "SignRequest") 378 } 379 380 func getServer(port int, home, parentURL string, maxEnroll int, t *testing.T) *Server { 381 if home != testdataDir { 382 err := os.RemoveAll(home) 383 if err != nil { 384 t.Errorf("RemoveAll failed: %s", err) 385 } 386 } 387 srv, err := createServer(port, home, parentURL, maxEnroll) 388 if err != nil { 389 t.Errorf("failed to register bootstrap user: %s", err) 390 return nil 391 } 392 return srv 393 } 394 395 func getServerForBenchmark(port int, home, parentURL string, maxEnroll int, b *testing.B) *Server { 396 if home != testdataDir { 397 err := os.RemoveAll(home) 398 if err != nil { 399 b.Errorf("RemoveAll failed: %s", err) 400 } 401 } 402 srv, err := createServer(port, home, parentURL, maxEnroll) 403 if err != nil { 404 b.Errorf("failed to register bootstrap user: %s", err) 405 return nil 406 } 407 return srv 408 } 409 410 func createServer(port int, home, parentURL string, maxEnroll int) (*Server, error) { 411 affiliations := map[string]interface{}{ 412 "hyperledger": map[string]interface{}{ 413 "fabric": []string{"ledger", "orderer", "security"}, 414 "fabric-ca": nil, 415 "sdk": nil, 416 }, 417 "org2": nil, 418 } 419 affiliations[affiliationName] = map[string]interface{}{ 420 "department1": nil, 421 "department2": nil, 422 } 423 srv := &Server{ 424 Config: &ServerConfig{ 425 Port: port, 426 Debug: true, 427 }, 428 CA: CA{ 429 Config: &CAConfig{ 430 Intermediate: IntermediateCA{ 431 ParentServer: ParentServer{ 432 URL: parentURL, 433 }, 434 }, 435 Affiliations: affiliations, 436 Registry: CAConfigRegistry{ 437 MaxEnrollments: maxEnroll, 438 }, 439 }, 440 }, 441 HomeDir: home, 442 } 443 // The bootstrap user's affiliation is the empty string, which 444 // means the user is at the affiliation root 445 err := srv.RegisterBootstrapUser(username, pass, "") 446 if err != nil { 447 return nil, err 448 } 449 return srv, nil 450 } 451 452 func getTestClient(port int) *Client { 453 return &Client{ 454 Config: &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", port)}, 455 HomeDir: testdataDir, 456 } 457 } 458 459 func TestCWBCAConfig(t *testing.T) { 460 ca := &CA{ 461 server: &Server{}, 462 } 463 464 //Error cases 465 err := ca.fillCAInfo(nil) 466 t.Logf("fillCAInfo err: %v", err) 467 if err == nil { 468 t.Error("ca.fileCAInfo should have failed but passed") 469 } 470 _, err = ca.getCAChain() 471 t.Logf("getCAChain err: %v", err) 472 if err == nil { 473 t.Error("getCAChain:1 should have failed but passed") 474 } 475 ca.Config = &CAConfig{} 476 ca.Config.Intermediate.ParentServer.URL = "foo" 477 _, err = ca.getCAChain() 478 t.Logf("getCAChain err: %v", err) 479 if err == nil { 480 t.Error("getCAChain:2 should have failed but passed") 481 } 482 ca.Config.DB.Type = "postgres" 483 err = ca.initDB(nil) 484 t.Logf("initDB err: %v", err) 485 if err == nil { 486 t.Error("initDB postgres should have failed but passed") 487 } 488 ca.Config.DB.Type = "mysql" 489 err = ca.initDB(nil) 490 t.Logf("initDB err: %v", err) 491 if err == nil { 492 t.Error("initDB mysql should have failed but passed") 493 } 494 495 ca.Config.DB.Type = "unknown" 496 err = ca.initDB(nil) 497 t.Logf("initDB err: %v", err) 498 if err == nil { 499 t.Error("initDB unknown should have failed but passed") 500 } 501 502 ca.Config.LDAP.Enabled = true 503 ca.server = &Server{} 504 err = ca.initUserRegistry() 505 t.Logf("initUserRegistry err: %v", err) 506 if err == nil { 507 t.Error("initConfig LDAP passed but should have failed") 508 } 509 510 //Non error cases 511 err = GenerateECDSATestCert() 512 util.FatalError(t, err, "Failed to generate certificate for testing") 513 ca.Config.CA.Chainfile = "../testdata/ec.pem" 514 _, err = ca.getCAChain() 515 t.Logf("getCAChain err: %v", err) 516 if err != nil { 517 t.Errorf("Failed to getCAChain: %s", err) 518 } 519 err = ca.initConfig() 520 if err != nil { 521 t.Errorf("initConfig failed: %s", err) 522 } 523 ca = &CA{} 524 ca.server = &Server{} 525 err = ca.initConfig() 526 if err != nil { 527 t.Errorf("ca.initConfig default failed: %s", err) 528 } 529 ca.HomeDir = "" 530 err = ca.initConfig() 531 if err != nil { 532 t.Errorf("initConfig failed: %s", err) 533 } 534 ca.Config = new(CAConfig) 535 ca.server = &Server{} 536 ca.Config.CA.Certfile = "../testdata/ec_cert.pem" 537 ca.Config.CA.Keyfile = "../testdata/ec_key.pem" 538 err = ca.initConfig() 539 if err != nil { 540 t.Errorf("initConfig failed: %s", err) 541 } 542 s := &Server{} 543 s.CA.Config = &CAConfig{} 544 err = s.initConfig() 545 if err != nil { 546 t.Errorf("server.initConfig default failed: %s", err) 547 } 548 } 549 550 func TestCWBNewCertificateRequest(t *testing.T) { 551 c := &Client{} 552 req := &api.CSRInfo{ 553 Names: []csr.Name{}, 554 Hosts: []string{}, 555 KeyRequest: api.NewKeyRequest(), 556 } 557 if c.newCertificateRequest(req) == nil { 558 t.Error("newCertificateRequest failed") 559 } 560 } 561 562 func TestCWBCAConfigStat(t *testing.T) { 563 wd, err := os.Getwd() 564 if err != nil { 565 t.Fatalf("failed to get cwd: %s", err) 566 } 567 td, err := ioutil.TempDir("", "CAConfigStat") 568 if err != nil { 569 t.Fatalf("failed to get tmp dir: %s", err) 570 } 571 defer func() { 572 err = os.RemoveAll(td) 573 if err != nil { 574 t.Errorf("RemoveAll failed: %s", err) 575 } 576 }() 577 err = os.Chdir(td) 578 if err != nil { 579 t.Fatalf("failed to cd to %v: %s", td, err) 580 } 581 defer func() { 582 err = os.Chdir(wd) 583 if err != nil { 584 t.Fatalf("failed to cd to %v: %s", wd, err) 585 } 586 }() 587 588 ca := &CA{} 589 ca.Config = &CAConfig{} 590 ca.HomeDir = "." 591 fileInfo, err := os.Stat(".") 592 if err != nil { 593 t.Fatalf("os.Stat failed on current dir: %s", err) 594 } 595 oldmode := fileInfo.Mode() 596 err = os.Chmod(".", 0000) 597 if err != nil { 598 t.Fatalf("Chmod on %s failed: %s", fileInfo.Name(), err) 599 } 600 defer func() { 601 err = os.Chmod(td, oldmode) 602 if err != nil { 603 t.Fatalf("Chmod on %s failed: %s", td, err) 604 } 605 }() 606 607 ca.Config.DB.Type = "" 608 err = ca.initDB(nil) 609 t.Logf("initDB err: %v", err) 610 if err == nil { 611 t.Errorf("initDB should have failed (getcwd failure)") 612 } 613 ca.Config.DB.Datasource = "" 614 ca.HomeDir = "" 615 } 616 617 func cleanTestSlateCWB(t *testing.T) { 618 err := os.RemoveAll("msp") 619 if err != nil { 620 t.Errorf("RemoveAll failed: %s", err) 621 } 622 err = os.RemoveAll("../testdata/msp") 623 if err != nil { 624 t.Errorf("RemoveAll failed: %s", err) 625 } 626 err = os.RemoveAll(serversDir) 627 if err != nil { 628 t.Errorf("RemoveAll failed: %s", err) 629 } 630 err = os.RemoveAll(testTLSClientAuthDir) 631 if err != nil { 632 t.Errorf("RemoveAll failed: %s", err) 633 } 634 } 635 636 // masqueradeEnroll enrolls a new identity as a masquerader 637 func masqueradeEnroll(c *Client, id string, passInSubject bool, req *api.EnrollmentRequest) (*EnrollmentResponse, error) { 638 err := c.Init() 639 if err != nil { 640 return nil, err 641 } 642 csrPEM, key, err := c.GenCSR(req.CSR, id) 643 if err != nil { 644 log.Debugf("Enroll failure generating CSR: %s", err) 645 return nil, err 646 } 647 reqNet := &api.EnrollmentRequestNet{ 648 CAName: req.CAName, 649 } 650 if req.CSR != nil { 651 reqNet.SignRequest.Hosts = req.CSR.Hosts 652 } 653 reqNet.SignRequest.Request = string(csrPEM) 654 reqNet.SignRequest.Profile = req.Profile 655 reqNet.SignRequest.Label = req.Label 656 if passInSubject { 657 reqNet.SignRequest.Subject = &signer.Subject{CN: id} 658 } 659 body, err := util.Marshal(reqNet, "SignRequest") 660 if err != nil { 661 return nil, err 662 } 663 // Send the CSR to the fabric-ca server with basic auth header 664 post, err := c.newPost("enroll", body) 665 if err != nil { 666 return nil, err 667 } 668 post.SetBasicAuth(req.Name, req.Secret) 669 var result api.EnrollmentResponseNet 670 err = c.SendReq(post, &result) 671 if err != nil { 672 return nil, err 673 } 674 // Create the enrollment response 675 return c.newEnrollmentResponse(&result, req.Name, key) 676 } 677 678 // masqueradeReenroll reenrolls a new identity as a masquerader 679 func masqueradeReenroll(c *Client, id string, identity *Identity, passInSubject bool, req *api.ReenrollmentRequest) (*EnrollmentResponse, error) { 680 err := c.Init() 681 if err != nil { 682 return nil, err 683 } 684 csrPEM, key, err := c.GenCSR(req.CSR, id) 685 if err != nil { 686 log.Debugf("Enroll failure generating CSR: %s", err) 687 return nil, err 688 } 689 reqNet := &api.EnrollmentRequestNet{ 690 CAName: req.CAName, 691 } 692 if req.CSR != nil { 693 reqNet.SignRequest.Hosts = req.CSR.Hosts 694 } 695 reqNet.SignRequest.Request = string(csrPEM) 696 reqNet.SignRequest.Profile = req.Profile 697 reqNet.SignRequest.Label = req.Label 698 if passInSubject { 699 reqNet.SignRequest.Subject = &signer.Subject{CN: id} 700 } 701 body, err := util.Marshal(reqNet, "SignRequest") 702 if err != nil { 703 return nil, err 704 } 705 // Send the CSR to the fabric-ca server with basic auth header 706 var result api.EnrollmentResponseNet 707 err = identity.Post("reenroll", body, &result, nil) 708 if err != nil { 709 return nil, err 710 } 711 712 // Create the enrollment response 713 return c.newEnrollmentResponse(&result, identity.GetName(), key) 714 }