github.com/hxx258456/fabric-ca-gm@v0.0.3-0.20221111064038-a268ad7e3a37/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 "fmt" 11 "io/ioutil" 12 "os" 13 "path" 14 "testing" 15 16 log "gitee.com/zhaochuninhefei/zcgolog/zclog" 17 http "github.com/hxx258456/ccgo/gmhttp" 18 "github.com/hxx258456/ccgo/x509" 19 "github.com/hxx258456/cfssl-gm/csr" 20 "github.com/hxx258456/cfssl-gm/signer" 21 "github.com/hxx258456/fabric-ca-gm/internal/pkg/api" 22 "github.com/hxx258456/fabric-ca-gm/internal/pkg/util" 23 cax509 "github.com/hxx258456/fabric-ca-gm/lib/client/credential/x509" 24 "github.com/hxx258456/fabric-gm/bccsp" 25 "github.com/hxx258456/fabric-gm/bccsp/factory" 26 cspsigner "github.com/hxx258456/fabric-gm/bccsp/signer" 27 "github.com/hxx258456/fabric-gm/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 func TestCWBClient1(t *testing.T) { 40 server := getServer(whitePort, path.Join(serversDir, "c1"), "", 1, t) 41 if server == nil { 42 t.Fatal("Failed to get server") 43 } 44 err := server.Start() 45 if err != nil { 46 t.Fatalf("Failed to start server: %s", err) 47 } 48 defer func() { 49 err = server.Stop() 50 if err != nil { 51 t.Errorf("Server stop failed: %s", err) 52 } 53 err = os.RemoveAll(serversDir) 54 if err != nil { 55 t.Errorf("RemoveAll failed: %s", err) 56 } 57 }() 58 59 testInvalidAuthEnrollment(t) 60 } 61 62 // TestTLS performs 3 main steps: 63 // 1) Test over HTTP to get an standard ECert 64 // 2) Test over HTTPS with client auth disabled 65 // 3) Test over HTTPS with client auth enabled, using standard ECert from #1 66 func TestCWBTLSClientAuth(t *testing.T) { 67 cleanTestSlateCWB(t) 68 defer cleanTestSlateCWB(t) 69 // 70 // 1) Test over HTTP to get a standard ECert 71 // 72 // Start server 73 server := getServer(whitePort, path.Join(testTLSClientAuthDir, "server"), "", 2, t) 74 if server == nil { 75 return 76 } 77 server.CA.Config.CSR.CN = "localhost" 78 server.Config.CAcfg.CSR.Hosts = []string{"localhost"} 79 err := server.Start() 80 if err != nil { 81 t.Fatalf("Failed to start server: %s", err) 82 } 83 84 // Enroll over HTTP 85 client := &Client{ 86 Config: &ClientConfig{ 87 URL: fmt.Sprintf("http://localhost:%d", whitePort), 88 }, 89 HomeDir: path.Join(testTLSClientAuthDir, "client"), 90 } 91 92 eresp, err := client.Enroll(&api.EnrollmentRequest{Name: username, Secret: pass}) 93 if err != nil { 94 server.Stop() 95 t.Fatalf("Failed to enroll admin: %s", err) 96 } 97 id := eresp.Identity 98 testImpersonation(id, t) 99 testMasqueradeEnroll(t, client, id) 100 101 // Register and enroll user to test reenrolling while masquerading 102 name := "masqueradeUser2" 103 rr, err := id.Register(&api.RegistrationRequest{ 104 Name: name, 105 Type: "user", 106 Affiliation: "hyperledger.fabric.security", 107 MaxEnrollments: 2, 108 }) 109 if err != nil { 110 t.Fatalf("Failed to register maqueradeUser: %s", err) 111 } 112 113 eresp2, err := client.Enroll(&api.EnrollmentRequest{Name: name, Secret: rr.Secret}) 114 if err != nil { 115 t.Errorf("Failed to enroll") 116 } 117 118 id2 := eresp2.Identity 119 testMasqueradeReenroll(t, client, id2) 120 121 // Stop server 122 log.Debug("Stopping the server") 123 err = server.Stop() 124 if err != nil { 125 t.Fatalf("Failed to stop server: %s", err) 126 } 127 128 // 129 // 2) Test over HTTPS with client auth disabled 130 // 131 // Start server 132 log.Debug("Starting the server with TLS") 133 server.Config.TLS.Enabled = true 134 server.Config.TLS.CertFile = "tls-cert.pem" 135 err = server.Start() 136 if err != nil { 137 t.Fatalf("Failed to start server with HTTPS: %s", err) 138 } 139 140 // Close the idle connections that were established to the non-SSL 141 // server. client will create new connection for the next request 142 // There is no need to do this in real scenario where the Fabric CA 143 // server's transport can only be changed from ssl to non-ssl or vice-versa 144 // by restarting the server, in which case connections in the client's 145 // connection pool are invalidated and it is forced to create new connection. 146 client.httpClient.Transport.(*http.Transport).CloseIdleConnections() 147 148 // Try to reenroll over HTTP and it should fail because server is listening on HTTPS 149 _, err = id.Reenroll(&api.ReenrollmentRequest{}) 150 if err == nil { 151 t.Error("Client HTTP should have failed to reenroll with server HTTPS") 152 } 153 154 client.Config.URL = fmt.Sprintf("https://localhost:%d", whitePort) 155 client.Config.TLS.Enabled = true 156 client.Config.TLS.CertFiles = []string{"../server/ca-cert.pem"} 157 // Reinitialize the http client with updated config and re-enroll over HTTPS 158 err = client.initHTTPClient() 159 assert.NoError(t, err) 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 // Reinitialize the http client with updated config and re-enroll over HTTPS with client auth 199 err = client.initHTTPClient() 200 assert.NoError(t, err) 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 api.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.SM2KeyGenOpts{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(nil) 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(nil) 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(nil) 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.NewKeyRequest(), 557 } 558 if c.newCertificateRequest(req, "fake-id") == 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(nil) 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 api.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 api.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 }