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