gitee.com/hyperledger/fabric-ca@v2.0.0-alpha+incompatible/util/util_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 17 package util 18 19 import ( 20 "bytes" 21 "crypto/ecdsa" 22 "crypto/elliptic" 23 "crypto/rand" 24 "crypto/rsa" 25 "crypto/x509" 26 "encoding/pem" 27 "fmt" 28 "io" 29 "io/ioutil" 30 "math/big" 31 "net/http" 32 "os" 33 "path" 34 "path/filepath" 35 "strings" 36 "testing" 37 38 "github.com/hyperledger/fabric/bccsp/factory" 39 _ "github.com/mattn/go-sqlite3" 40 "github.com/spf13/viper" 41 "github.com/stretchr/testify/assert" 42 ) 43 44 func TestMain(m *testing.M) { 45 factory.InitFactories(nil) 46 os.Exit(m.Run()) 47 } 48 49 func TestGetEnrollmentIDFromPEM(t *testing.T) { 50 cert, err := ioutil.ReadFile(getPath("ec.pem")) 51 if err != nil { 52 t.Fatalf("TestGetEnrollmentIDFromPEM.ReadFile failed: %s", err) 53 } 54 _, err = GetEnrollmentIDFromPEM(cert) 55 if err != nil { 56 t.Fatalf("Failed to get enrollment ID from PEM: %s", err) 57 } 58 } 59 60 func TestECCreateToken(t *testing.T) { 61 cert, _ := ioutil.ReadFile(getPath("ec.pem")) 62 bccsp := GetDefaultBCCSP() 63 privKey, err := ImportBCCSPKeyFromPEM(getPath("ec-key.pem"), bccsp, true) 64 if err != nil { 65 t.Logf("Failed importing key %s", err) 66 } 67 body := []byte("request byte array") 68 69 ECtoken, err := CreateToken(bccsp, cert, privKey, "GET", "/enroll", body) 70 if err != nil { 71 t.Fatalf("CreatToken failed: %s", err) 72 } 73 74 os.Setenv("FABRIC_CA_SERVER_COMPATIBILITY_MODE_V1_3", "false") // Test new token 75 _, err = VerifyToken(bccsp, ECtoken, "GET", "/enroll", body, false) 76 if err != nil { 77 t.Fatalf("VerifyToken failed: %s", err) 78 } 79 80 _, err = VerifyToken(nil, ECtoken, "GET", "/enroll", body, false) 81 if err == nil { 82 t.Fatal("VerifyToken should have failed as no instance of csp is passed") 83 } 84 85 _, err = VerifyToken(bccsp, "", "GET", "/enroll", body, false) 86 if err == nil { 87 t.Fatal("VerifyToken should have failed as no EC Token is passed") 88 } 89 90 _, err = VerifyToken(bccsp, ECtoken, "GET", "/enroll", nil, false) 91 if err == nil { 92 t.Fatal("VerifyToken should have failed as no body is passed") 93 } 94 95 _, err = VerifyToken(bccsp, ECtoken, "POST", "/enroll", nil, false) 96 if err == nil { 97 t.Fatal("VerifyToken should have failed as method was tampered") 98 } 99 100 _, err = VerifyToken(bccsp, ECtoken, "GET", "/affiliations", nil, false) 101 if err == nil { 102 t.Fatal("VerifyToken should have failed as path was tampered") 103 } 104 105 verifiedByte := []byte("TEST") 106 body = append(body, verifiedByte[0]) 107 _, err = VerifyToken(bccsp, ECtoken, "GET", "/enroll", body, false) 108 if err == nil { 109 t.Fatal("VerifyToken should have failed as body was tampered") 110 } 111 112 ski, skierror := ioutil.ReadFile(getPath("ec-key.ski")) 113 if skierror != nil { 114 t.Fatalf("SKI File Read failed with error : %s", skierror) 115 } 116 ECtoken, err = CreateToken(bccsp, ski, privKey, "GET", "/enroll", body) 117 if (err == nil) || (ECtoken != "") { 118 t.Fatal("CreatToken should have failed as certificate passed is not correct") 119 } 120 121 // With comptability mode disabled, using old token should fail 122 b64Cert := B64Encode(cert) 123 payload := B64Encode(body) + "." + b64Cert 124 oldToken, err := genECDSAToken(bccsp, privKey, b64Cert, payload) 125 FatalError(t, err, "Failed to create token") 126 _, err = VerifyToken(bccsp, oldToken, "GET", "/enroll", body, false) 127 assert.Error(t, err) 128 129 // Test that by default with no environment variable set, the old token is considered valid 130 os.Unsetenv("FABRIC_CA_SERVER_COMPATIBILITY_MODE_V1_3") 131 _, err = VerifyToken(bccsp, oldToken, "GET", "/enroll", body, true) 132 assert.NoError(t, err, "Failed to verify token using old token type") 133 } 134 135 func TestDecodeToken(t *testing.T) { 136 token := "x.y.z" 137 _, _, _, err := DecodeToken(token) 138 assert.Error(t, err, "Decode should fail if the token has more than two parts") 139 140 token = "x" 141 _, _, _, err = DecodeToken(token) 142 assert.Error(t, err, "Decode should fail if the token has less than two parts") 143 144 token = "x.y" 145 _, _, _, err = DecodeToken(token) 146 assert.Error(t, err, "Decode should fail if the 1st part of the token is not in base64 encoded format") 147 148 fakecert := B64Encode([]byte("hello")) 149 token = fakecert + ".y" 150 _, _, _, err = DecodeToken(token) 151 assert.Error(t, err, "Decode should fail if the 1st part of the token is not base64 bytes of a X509 cert") 152 } 153 func TestGetX509CertFromPem(t *testing.T) { 154 155 certBuffer, error := ioutil.ReadFile(getPath("ec.pem")) 156 if error != nil { 157 t.Fatalf("Certificate File Read from file failed with error : %s", error) 158 } 159 certificate, err := GetX509CertificateFromPEM(certBuffer) 160 if err != nil { 161 t.Fatalf("GetX509CertificateFromPEM failed with error : %s", err) 162 } 163 if certificate == nil { 164 t.Fatal("Certificate cannot be nil") 165 } 166 167 skiBuffer, skiError := ioutil.ReadFile(getPath("ec-key.ski")) 168 if skiError != nil { 169 t.Fatalf("SKI File read failed with error : %s", skiError) 170 } 171 172 certificate, err = GetX509CertificateFromPEM(skiBuffer) 173 if err == nil { 174 t.Fatal("GetX509CertificateFromPEM should have failed as bytes passed was not in correct format") 175 } 176 if certificate != nil { 177 t.Fatalf("GetX509CertificateFromPEM should have failed as bytes passed was not in correct format") 178 } 179 } 180 181 func TestGetX509CertsFromPem(t *testing.T) { 182 certBuffer, error := ioutil.ReadFile(getPath("ec.pem")) 183 if error != nil { 184 t.Fatalf("Certificate File Read from file failed with error : %s", error) 185 } 186 certificates, err := GetX509CertificatesFromPEM(certBuffer) 187 assert.NoError(t, err, "GetX509CertificatesFromPEM failed") 188 assert.NotNil(t, certificates) 189 assert.Equal(t, 1, len(certificates), "GetX509CertificatesFromPEM should have returned 1 certificate") 190 191 skiBuffer, skiError := ioutil.ReadFile(getPath("ec-key.ski")) 192 if skiError != nil { 193 t.Fatalf("SKI File read failed with error : %s", skiError) 194 } 195 196 certificates, err = GetX509CertificatesFromPEM(skiBuffer) 197 if err == nil { 198 t.Fatal("GetX509CertificatesFromPEM should have failed as bytes passed was not in correct format") 199 } 200 if certificates != nil { 201 t.Fatalf("GetX509CertificatesFromPEM should have failed as bytes passed was not in correct format") 202 } 203 } 204 205 // This test case has been removed temporarily 206 // as BCCSP does not have support for RSA private key import 207 /* 208 func TestRSACreateToken(t *testing.T) { 209 cert, _ := ioutil.ReadFile(getPath("rsa.pem")) 210 privKey, _ := ioutil.ReadFile(getPath("rsa-key.pem")) 211 body := []byte("request byte array") 212 213 csp := factory.GetDefault() 214 RSAtoken, err := CreateToken(csp, cert, privKey, body) 215 if err != nil { 216 t.Fatalf("CreatToken failed with error : %s", err) 217 } 218 219 _, err = VerifyToken(csp, RSAtoken, body) 220 if err != nil { 221 t.Fatalf("VerifyToken failed with error : %s", err) 222 } 223 } 224 */ 225 226 func TestCreateTokenDiffKey(t *testing.T) { 227 cert, _ := ioutil.ReadFile(getPath("ec.pem")) 228 bccsp := GetDefaultBCCSP() 229 privKey, _ := ImportBCCSPKeyFromPEM(getPath("rsa-key.pem"), bccsp, true) 230 body := []byte("request byte array") 231 _, err := CreateToken(bccsp, cert, privKey, "POST", "/enroll", body) 232 if err == nil { 233 t.Fatalf("TestCreateTokenDiffKey passed but should have failed") 234 } 235 } 236 237 // TestCreateTokenDiffKey2 has been commeted out right now 238 // As there BCCSP does not have support fot RSA private Key 239 // import. This will be uncommented when the support is in. 240 /* 241 func TestCreateTokenDiffKey2(t *testing.T) { 242 cert, _ := ioutil.ReadFile(getPath("rsa.pem")) 243 privKey, _ := ioutil.ReadFile(getPath("ec-key.pem")) 244 body := []byte("request byte array") 245 246 csp := factory.GetDefault() 247 _, err := CreateToken(csp, cert, privKey, body) 248 if err == nil { 249 t.Fatalf("TestCreateTokenDiffKey2 passed but should have failed") 250 } 251 } 252 */ 253 254 func TestEmptyToken(t *testing.T) { 255 body := []byte("request byte array") 256 257 csp := factory.GetDefault() 258 _, err := VerifyToken(csp, "", "POST", "/enroll", body, true) 259 if err == nil { 260 t.Fatalf("TestEmptyToken passed but should have failed") 261 } 262 } 263 264 func TestEmptyCert(t *testing.T) { 265 cert, _ := ioutil.ReadFile(getPath("ec.pem")) 266 body := []byte("request byte array") 267 268 csp := factory.GetDefault() 269 _, err := CreateToken(csp, cert, nil, "POST", "/enroll", body) 270 if err == nil { 271 t.Fatalf("TestEmptyCert passed but should have failed") 272 } 273 } 274 275 func TestEmptyKey(t *testing.T) { 276 bccsp := GetDefaultBCCSP() 277 privKey, _ := ImportBCCSPKeyFromPEM(getPath("ec-key.pem"), bccsp, true) 278 body := []byte("request byte array") 279 _, err := CreateToken(bccsp, []byte(""), privKey, "POST", "/enroll", body) 280 if err == nil { 281 t.Fatalf("TestEmptyKey passed but should have failed") 282 } 283 } 284 285 func TestEmptyBody(t *testing.T) { 286 bccsp := GetDefaultBCCSP() 287 privKey, _ := ImportBCCSPKeyFromPEM(getPath("ec-key.pem"), bccsp, true) 288 cert, _ := ioutil.ReadFile(getPath("ec.pem")) 289 _, err := CreateToken(bccsp, cert, privKey, "POST", "/enroll", []byte("")) 290 if err != nil { 291 t.Fatalf("CreateToken failed: %s", err) 292 } 293 } 294 295 func TestRandomString(t *testing.T) { 296 str := RandomString(10) 297 if str == "" { 298 t.Fatalf("RandomString failure") 299 } 300 } 301 302 func TestRemoveQuotes(t *testing.T) { 303 str := RemoveQuotes(`"a"`) 304 if str != "a" { 305 t.Fatalf("TestRemoveQuotes failed") 306 } 307 } 308 309 func TestRemoveQuotesNone(t *testing.T) { 310 str := RemoveQuotes(`a`) 311 if str != "a" { 312 t.Fatalf("TestRemoveQuotesNone failed") 313 } 314 } 315 316 func TestCreateHome(t *testing.T) { 317 t.Log("Test Creating Home Directory") 318 os.Unsetenv("COP_HOME") 319 tempDir, err := ioutil.TempDir("", "test") 320 if err != nil { 321 t.Errorf("Failed to create temp directory [error: %s]", err) 322 } 323 os.Setenv("HOME", tempDir) 324 325 dir, err := CreateClientHome() 326 if err != nil { 327 t.Errorf("Failed to create home directory, error: %s", err) 328 } 329 330 if _, err = os.Stat(dir); err != nil { 331 if os.IsNotExist(err) { 332 t.Error("Failed to create home directory") 333 } 334 } 335 336 os.RemoveAll(dir) 337 } 338 339 func TestGetDefaultConfigFile(t *testing.T) { 340 os.Unsetenv("FABRIC_CA_HOME") 341 os.Unsetenv("FABRIC_CA_CLIENT_HOME") 342 os.Unsetenv("FABRIC_CA_SERVER_HOME") 343 os.Unsetenv("CA_CFG_PATH") 344 345 const clientConfig = "fabric-ca-client-config.yaml" 346 const serverConfig = "fabric-ca-server-config.yaml" 347 348 os.Setenv("HOME", "/tmp") 349 350 expected := filepath.Join("/tmp/.fabric-ca-client/", clientConfig) 351 real := GetDefaultConfigFile("fabric-ca-client") 352 if real != expected { 353 t.Errorf("Incorrect default config path retrieved; expected %s but found %s", 354 expected, real) 355 } 356 357 os.Setenv("FABRIC_CA_HOME", "/tmp") 358 expected = filepath.Join("/tmp", clientConfig) 359 real = GetDefaultConfigFile("fabric-ca-client") 360 if real != expected { 361 t.Errorf("Incorrect default config path retrieved; expected %s but found %s", 362 expected, real) 363 } 364 365 expected = filepath.Join("/tmp", serverConfig) 366 real = GetDefaultConfigFile("fabric-ca-server") 367 if real != expected { 368 t.Errorf("Incorrect default config path retrieved; expected %s but found %s", 369 expected, real) 370 } 371 372 os.Setenv("FABRIC_CA_CLIENT_HOME", "/tmp/client") 373 expected = filepath.Join("/tmp/client", clientConfig) 374 real = GetDefaultConfigFile("fabric-ca-client") 375 if real != expected { 376 t.Errorf("Incorrect default config path retrieved; expected %s but found %s", 377 expected, real) 378 } 379 380 os.Setenv("FABRIC_CA_SERVER_HOME", "/tmp/server") 381 expected = filepath.Join("/tmp/server", serverConfig) 382 real = GetDefaultConfigFile("fabric-ca-server") 383 if real != expected { 384 t.Errorf("Incorrect default config path retrieved; expected %s but found %s", 385 expected, real) 386 } 387 } 388 389 func TestUnmarshal(t *testing.T) { 390 byteArray := []byte(`{"text":"foo"}`) 391 type test struct { 392 text string 393 } 394 var Test test 395 err := Unmarshal(byteArray, &Test, "testing unmarshal") 396 if err != nil { 397 t.Error("Failed to unmarshal, error: ", err) 398 } 399 } 400 401 func TestMarshal(t *testing.T) { 402 var x interface{} 403 _, err := Marshal(x, "testing marshal") 404 if err != nil { 405 t.Error("Failed to marshal, error: ", err) 406 } 407 } 408 409 func TestReadFile(t *testing.T) { 410 _, err := ReadFile("../testdata/csr.json") 411 if err != nil { 412 t.Error("Failed to read file, error: ", err) 413 } 414 } 415 416 func TestWriteFile(t *testing.T) { 417 testdir, err := ioutil.TempDir(".", "writefiletest") 418 if err != nil { 419 t.Fatalf("Failed to create temp directory: %s", err.Error()) 420 } 421 defer os.RemoveAll(testdir) 422 testData := []byte("foo") 423 err = WriteFile(path.Join(testdir, "test.txt"), testData, 0777) 424 assert.NoError(t, err) 425 readOnlyDir := path.Join(testdir, "readonlydir") 426 err = os.MkdirAll(readOnlyDir, 4444) 427 if err != nil { 428 t.Fatalf("Failed to create directory: %s", err.Error()) 429 } 430 err = WriteFile(path.Join(readOnlyDir, "test/test.txt"), testData, 0777) 431 assert.Error(t, err, "Should fail to create 'test' directory as the parent directory is read only") 432 } 433 434 func getPath(file string) string { 435 return "../testdata/" + file 436 } 437 438 func TestStrContained(t *testing.T) { 439 strs := []string{"one", "two", "three"} 440 str := "one" 441 result := StrContained(str, strs) 442 if result != true { 443 t.Error("Should have result in true") 444 } 445 } 446 447 func TestFileExists(t *testing.T) { 448 name := "../testdata/csr.json" 449 exists := FileExists(name) 450 if exists == false { 451 t.Error("File does not exist") 452 } 453 name = "better-not-exist" 454 exists = FileExists(name) 455 if exists == true { 456 t.Error("File 'better-not-exist' should not exist") 457 } 458 } 459 460 func TestMakeFileAbs(t *testing.T) { 461 testMakeFileAbs(t, "", "", "") 462 testMakeFileAbs(t, "/a/b/c", "", "/a/b/c") 463 testMakeFileAbs(t, "c", "/a/b", "/a/b/c") 464 testMakeFileAbs(t, "../c", "/a/b", "/a/c") 465 } 466 467 func TestMakeFilesAbs(t *testing.T) { 468 file1 := "a" 469 file2 := "a/b" 470 file3 := "/a/b" 471 files := []*string{&file1, &file2, &file3} 472 err := MakeFileNamesAbsolute(files, "/tmp") 473 if err != nil { 474 t.Fatalf("MakeFilesAbsolute failed: %s", err) 475 } 476 if file1 != "/tmp/a" { 477 t.Errorf("TestMakeFilesAbs failure: expecting /tmp/a but found %s", file1) 478 } 479 if file2 != "/tmp/a/b" { 480 t.Errorf("TestMakeFilesAbs failure: expecting /tmp/a/b but found %s", file2) 481 } 482 if file3 != "/a/b" { 483 t.Errorf("TestMakeFilesAbs failure: expecting /a/b but found %s", file3) 484 } 485 } 486 487 func TestB64(t *testing.T) { 488 buf := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 489 str := B64Encode(buf) 490 buf2, err := B64Decode(str) 491 if err != nil { 492 t.Errorf("Failed base64 decoding standard: %s", err) 493 } 494 if !bytes.Equal(buf, buf2) { 495 t.Error("Failed base64 decoding standard bytes aren't equal") 496 } 497 } 498 499 func TestGetUser(t *testing.T) { 500 os.Unsetenv("FABRIC_CA_CLIENT_URL") 501 viper.BindEnv("url", "FABRIC_CA_CLIENT_URL") 502 os.Setenv("FABRIC_CA_CLIENT_URL", "http://localhost:7054") 503 _, _, err := GetUser(viper.GetViper()) 504 assert.Error(t, err, "Should have failed no username and password provided") 505 506 os.Setenv("FABRIC_CA_CLIENT_URL", "http://:pass@localhost:7054") 507 _, _, err = GetUser(viper.GetViper()) 508 assert.Error(t, err, "Should have failed no username provided") 509 510 os.Setenv("FABRIC_CA_CLIENT_URL", "http://user:@localhost:7054") 511 _, _, err = GetUser(viper.GetViper()) 512 assert.Error(t, err, "Should have failed no password provided") 513 514 os.Setenv("FABRIC_CA_CLIENT_URL", "http://foo:bar@localhost:7054") 515 516 user, pass, err := GetUser(viper.GetViper()) 517 assert.NoError(t, err) 518 519 if user != "foo" { 520 t.Error("Failed to retrieve correct username") 521 } 522 523 if pass != "bar" { 524 t.Error("Failed to retrieve correct password") 525 } 526 } 527 528 type configID struct { 529 Name string `mask:"username"` 530 Addr string `json:"address"` 531 Pass string `mask:"password"` 532 URL string `mask:"url"` 533 ID int `mask:"url"` 534 } 535 536 func (cc configID) String() string { 537 return StructToString(&cc) 538 } 539 540 func TestStructToString(t *testing.T) { 541 var obj configID 542 obj.Name = "foo" 543 addr := "101, penn ave" 544 obj.Addr = addr 545 obj.Pass = "bar" 546 str := StructToString(&obj) 547 if strings.Index(str, "bar") > 0 { 548 t.Errorf("Password is not masked by the StructToString function: %s", str) 549 } 550 if strings.Index(str, "foo") > 0 { 551 t.Errorf("Name is not masked by the StructToString function: %s", str) 552 } 553 if strings.Index(str, addr) < 0 { 554 t.Errorf("Addr is masked by the StructToString function: %s", str) 555 } 556 557 type registry struct { 558 MaxEnrollments int 559 Identities []configID 560 } 561 type config struct { 562 Registry registry 563 Affiliations map[string]interface{} 564 } 565 affiliations := map[string]interface{}{"org1": nil} 566 caConfig := config{ 567 Affiliations: affiliations, 568 Registry: registry{ 569 MaxEnrollments: -1, 570 Identities: []configID{ 571 configID{ 572 Name: "foo", 573 Pass: "foopwd", 574 Addr: "user", 575 URL: "http://foo:foopwd@localhost:7054", 576 ID: 2, 577 }, 578 configID{ 579 Name: "bar", 580 Pass: "barpwd", 581 Addr: "user", 582 URL: "ldap://foo:foopwd@localhost:7054", 583 ID: 3, 584 }, 585 }, 586 }, 587 } 588 caConfigStr := fmt.Sprintf("caConfig=%+v", caConfig) 589 assert.NotContains(t, caConfigStr, "foopwd", "Identity password is not masked in the output") 590 assert.NotContains(t, caConfigStr, "barpwd", "Identity password is not masked in the output") 591 idStr := fmt.Sprintf("Identity[0]=%+v", caConfig.Registry.Identities[0]) 592 assert.NotContains(t, idStr, "foopwd", "Identity password is not masked in the output") 593 idStr = fmt.Sprintf("Identity[1]=%+v", &caConfig.Registry.Identities[1]) 594 assert.NotContains(t, idStr, "barpwd", "Identity password is not masked in the output") 595 } 596 597 func TestNormalizeStringSlice(t *testing.T) { 598 var tests = []struct { 599 slice []string 600 expected []string 601 }{ 602 { 603 slice: []string{"string1"}, 604 expected: []string{"string1"}, 605 }, 606 { 607 slice: []string{" string1"}, 608 expected: []string{"string1"}, 609 }, 610 { 611 slice: []string{" string1 "}, 612 expected: []string{"string1"}, 613 }, 614 { 615 slice: []string{" string1 "}, 616 expected: []string{"string1"}, 617 }, 618 { 619 slice: []string{"string1", "string2"}, 620 expected: []string{"string1", "string2"}, 621 }, 622 { 623 slice: []string{"string1", " string2"}, 624 expected: []string{"string1", "string2"}, 625 }, 626 } 627 628 for _, test := range tests { 629 actual := NormalizeStringSlice(test.slice) 630 assert.Equal(t, test.expected, actual) 631 } 632 } 633 634 // Test file list with multiple and single entries both with and without brackets 635 func TestNormalizeFileList(t *testing.T) { 636 slice := []string{"[file0,file1]", "file2,file3", "file4", "[file5]"} 637 slice, err := NormalizeFileList(slice, "../testdata") 638 if err != nil { 639 t.Fatalf("Failed to normalize files list, error: %s", err) 640 } 641 assert.Equal(t, 6, len(slice), "Invalid slice length") 642 for i := range slice { 643 if !strings.HasSuffix(slice[i], fmt.Sprintf("file%d", i)) { 644 t.Errorf("Failed to normalize files list for element %d; found '%s'", i, slice[i]) 645 } 646 } 647 } 648 649 func testMakeFileAbs(t *testing.T, file, dir, expect string) { 650 path, err := MakeFileAbs(file, dir) 651 if err != nil { 652 t.Errorf("Failed to make %s absolute: %s", file, err) 653 } 654 // make expected path platform specific to work on Windows 655 if expect != "" { 656 expect, _ = filepath.Abs(expect) 657 } 658 if path != expect { 659 t.Errorf("Absolute of file=%s with dir=%s expected %s but was %s", file, dir, expect, path) 660 } 661 } 662 663 func TestRemoveQuotesInvalidArgs(t *testing.T) { 664 res := RemoveQuotes("") 665 assert.Equal(t, "", res) 666 } 667 668 func TestUnmarshalInvalidArgs(t *testing.T) { 669 err := Unmarshal(nil, nil, "") 670 assert.Error(t, err) 671 assert.Contains(t, err.Error(), "Failed to unmarshal ") 672 } 673 674 func TestStrContainedInvalidArgs(t *testing.T) { 675 res := StrContained("Hello World", nil) 676 assert.False(t, res) 677 } 678 679 func TestGetSerialAsHex(t *testing.T) { 680 res := GetSerialAsHex(big.NewInt(101)) 681 assert.Equal(t, "65", res) 682 } 683 684 func TestECPrivateKey(t *testing.T) { 685 _, err := GetECPrivateKey(getPEM("../testdata/ec-key.pem", t)) 686 assert.NoError(t, err) 687 688 rsaKey, err := rsa.GenerateKey(rand.Reader, 256) 689 if err != nil { 690 t.Fatalf("Failed to create rsa key: %s", err.Error()) 691 } 692 encodedPK, err := x509.MarshalPKCS8PrivateKey(rsaKey) 693 if err != nil { 694 t.Fatalf("Failed to marshal RSA private key: %s", err.Error()) 695 } 696 697 pemEncodedPK := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: encodedPK}) 698 _, err = GetECPrivateKey(pemEncodedPK) 699 assert.Error(t, err) 700 701 _, err = GetECPrivateKey([]byte("hello")) 702 assert.Error(t, err) 703 704 _, err = GetECPrivateKey(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte("hello")})) 705 assert.Error(t, err) 706 } 707 708 func TestPKCS8WrappedECPrivateKey(t *testing.T) { 709 _, err := GetECPrivateKey(getPEM("../testdata/pkcs8eckey.pem", t)) 710 assert.NoError(t, err) 711 } 712 713 func TestRSAPrivateKey(t *testing.T) { 714 _, err := GetRSAPrivateKey([]byte("hello")) 715 assert.Error(t, err) 716 717 _, err = GetRSAPrivateKey(getPEM("../testdata/rsa-key.pem", t)) 718 assert.NoError(t, err) 719 720 rsaKey, err := rsa.GenerateKey(rand.Reader, 256) 721 if err != nil { 722 t.Fatalf("Failed to create rsa key: %s", err.Error()) 723 } 724 encodedPK, err := x509.MarshalPKCS8PrivateKey(rsaKey) 725 if err != nil { 726 t.Fatalf("Failed to marshal RSA private key: %s", err.Error()) 727 } 728 729 pemEncodedPK := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: encodedPK}) 730 _, err = GetRSAPrivateKey(pemEncodedPK) 731 assert.NoError(t, err) 732 733 _, err = GetRSAPrivateKey(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte("hello")})) 734 assert.Error(t, err) 735 736 ecdsaKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 737 if err != nil { 738 t.Fatalf("Failed to create rsa key: %s", err.Error()) 739 } 740 encodedPK, err = x509.MarshalPKCS8PrivateKey(ecdsaKey) 741 if err != nil { 742 t.Fatalf("Failed to marshal RSA private key: %s", err.Error()) 743 } 744 745 pemEncodedPK = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: encodedPK}) 746 _, err = GetRSAPrivateKey(pemEncodedPK) 747 assert.Error(t, err) 748 } 749 750 func TestCheckHostsInCert(t *testing.T) { 751 err := CheckHostsInCert("../testdata/doesnotexist.pem", "") 752 assert.Error(t, err) 753 754 err = CheckHostsInCert("../testdata/tls_server-cert.pem", "localhost") 755 assert.NoError(t, err, fmt.Sprintf("Failed to find 'localhost' for host in certificate: %s", err)) 756 757 err = CheckHostsInCert("../testdata/tls_server-cert.pem", "localhost", "fakehost") 758 assert.Error(t, err, "Certificate does not contain 'fakehost', should have failed") 759 760 err = CheckHostsInCert("../testdata/root.pem", "x") 761 assert.Error(t, err, "Certificate contained no host, should have failed") 762 } 763 764 func TestCertDuration(t *testing.T) { 765 d, err := GetCertificateDurationFromFile("../testdata/ec.pem") 766 assert.NoError(t, err) 767 assert.True(t, d.Hours() == 43800, "Expected certificate duration of 43800h in ec.pem") 768 _, err = GetCertificateDurationFromFile("bogus.pem") 769 assert.Error(t, err) 770 } 771 772 type MyReader struct { 773 buf []byte 774 maxPerRead, bytesRead int 775 } 776 777 func (r *MyReader) Read(data []byte) (int, error) { 778 if r.bytesRead >= len(r.buf) { 779 return 0, io.EOF 780 } 781 buf := r.buf[r.bytesRead:] 782 count := 0 783 for i, v := range buf { 784 if i >= len(data) || count > r.maxPerRead { 785 break 786 } 787 data[i] = v 788 count++ 789 } 790 r.bytesRead = r.bytesRead + count 791 return count, nil 792 } 793 794 func TestRead(t *testing.T) { 795 myReader := MyReader{ 796 buf: []byte("123456789012345"), 797 maxPerRead: 6, 798 } 799 800 // Test with a buffer that is too small to fit data 801 buf := make([]byte, 10) 802 data, err := Read(&myReader, buf) 803 assert.Error(t, err, "Should have errored, the data passed is bigger than the buffer") 804 805 // Test with a buffer that is big enough to fit data 806 buf = make([]byte, 25) 807 myReader.bytesRead = 0 808 data, err = Read(&myReader, buf) 809 if assert.NoError(t, err, fmt.Sprintf("Error occured during read: %s", err)) { 810 if string(data) != string(myReader.buf) { 811 t.Error("The data returned does not match") 812 } 813 } 814 815 // Test with a buffer with exact size of data 816 buf = make([]byte, len(myReader.buf)) 817 myReader.bytesRead = 0 818 data, err = Read(&myReader, buf) 819 if assert.NoError(t, err, fmt.Sprintf("Error occured during exact size read: %s", err)) { 820 if string(data) != string(myReader.buf) { 821 t.Error("The data returned does not match") 822 } 823 } 824 } 825 826 func getPEM(file string, t *testing.T) []byte { 827 buf, err := ioutil.ReadFile(file) 828 assert.NoError(t, err) 829 return buf 830 } 831 832 func TestIsSubsetOf(t *testing.T) { 833 testIsSubsetOf(t, "a,b", "b,a,c", true) 834 testIsSubsetOf(t, "a,b", "b,a", true) 835 testIsSubsetOf(t, "a,b,c", "a,b", false) 836 testIsSubsetOf(t, "a,b,c", "", false) 837 } 838 839 func testIsSubsetOf(t *testing.T, small, large string, expectToPass bool) { 840 err := IsSubsetOf(small, large) 841 if expectToPass { 842 if err != nil { 843 t.Errorf("IsSubsetOf('%s','%s') failed: %s", small, large, err) 844 } 845 } else { 846 if err == nil { 847 t.Errorf("IsSubsetOf('%s','%s') expected error but passed", small, large) 848 } 849 } 850 } 851 852 func TestHostname(t *testing.T) { 853 host := Hostname() 854 assert.NotEqual(t, "", host, "Hostname should not be empty") 855 } 856 857 func TestHTTPRequestToString(t *testing.T) { 858 url := "http://localhost:7054" 859 reqBody := "Hello" 860 req, err := http.NewRequest("POST", url, strings.NewReader(reqBody)) 861 if err != nil { 862 t.Errorf("Failed to create a request: %s", err) 863 } else { 864 reqStr := HTTPRequestToString(req) 865 assert.Contains(t, reqStr, url) 866 assert.Contains(t, reqStr, "POST") 867 assert.Contains(t, reqStr, reqBody) 868 } 869 } 870 871 func TestValidateAndReturnAbsConf(t *testing.T) { 872 var err error 873 var filename, homeDir string 874 875 filename, _, err = ValidateAndReturnAbsConf("/tmp/test.yaml", "/tmp/homeDir", "fabric-ca-client") 876 assert.NoError(t, err, "Should not have errored out, this is a valid configuration") 877 878 if filename != "/tmp/test.yaml" { 879 t.Error("Failed to get correct path for configuration file") 880 } 881 882 filename, homeDir, err = ValidateAndReturnAbsConf("", "../testdata/tmp", "fabric-ca-client") 883 assert.NoError(t, err, "Should not have errored out, this is a valid configuration") 884 885 homeDirAbs, err := filepath.Abs("../testdata/tmp") 886 if err != nil { 887 t.Fatal("Error occured getting absolute path: ", err) 888 } 889 890 if homeDir != homeDirAbs { 891 t.Error("Failed to get correct path for home directory") 892 } 893 894 if filename != filepath.Join(homeDirAbs, "fabric-ca-client-config.yaml") { 895 t.Error("Failed to get correct path for configuration file") 896 } 897 898 // Test with no home directory set 899 filename, _, err = ValidateAndReturnAbsConf("/tmp/test.yaml", "", "fabric-ca-client") 900 assert.NoError(t, err, "Should not have errored out, this is a valid configuration") 901 902 if filename != "/tmp/test.yaml" { 903 t.Error("Failed to get correct path for configuration file") 904 } 905 906 filename, homeDir, err = ValidateAndReturnAbsConf("../testdata/tmp/test.yaml", "", "fabric-ca-client") 907 assert.NoError(t, err, "Should not have errored out, this is a valid configuration") 908 909 homeDirAbs, err = filepath.Abs("../testdata/tmp") 910 if err != nil { 911 t.Fatal("Error occured getting absolute path: ", err) 912 } 913 914 if homeDir != homeDirAbs { 915 t.Error("Failed to get correct path for home directory") 916 } 917 918 if filename != filepath.Join(homeDirAbs, "test.yaml") { 919 t.Error("Failed to get correct path for configuration file") 920 } 921 } 922 923 func TestListContains(t *testing.T) { 924 list := "peer, client,orderer, *" 925 found := ListContains(list, "*") 926 assert.Equal(t, found, true) 927 928 list = "peer, client,orderer" 929 found = ListContains(list, "*") 930 assert.Equal(t, found, false) 931 }