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