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