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