google.golang.org/grpc@v1.72.2/internal/credentials/spiffe/spiffe_test.go (about) 1 /* 2 * 3 * Copyright 2025 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package spiffe 20 21 import ( 22 "crypto/x509" 23 "encoding/pem" 24 "io" 25 "os" 26 "testing" 27 28 "github.com/spiffe/go-spiffe/v2/bundle/spiffebundle" 29 "google.golang.org/grpc/testdata" 30 ) 31 32 // loadSPIFFEBundleMap loads a SPIFFE Bundle Map from a file. See the SPIFFE 33 // Bundle Map spec for more detail - 34 // https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Trust_Domain_and_Bundle.md#4-spiffe-bundle-format 35 // If duplicate keys are encountered in the JSON parsing, Go's default unmarshal 36 // behavior occurs which causes the last processed entry to be the entry in the 37 // parsed map. 38 func loadSPIFFEBundleMap(filePath string) (map[string]*spiffebundle.Bundle, error) { 39 bundleMapRaw, err := os.ReadFile(filePath) 40 if err != nil { 41 return nil, err 42 } 43 return BundleMapFromBytes(bundleMapRaw) 44 } 45 46 func TestKnownSPIFFEBundle(t *testing.T) { 47 spiffeBundleFile := testdata.Path("spiffe/spiffebundle.json") 48 bundles, err := loadSPIFFEBundleMap(spiffeBundleFile) 49 if err != nil { 50 t.Fatalf("LoadSPIFFEBundleMap(%v) Error during parsing: %v", spiffeBundleFile, err) 51 } 52 wantBundleSize := 2 53 if len(bundles) != wantBundleSize { 54 t.Fatalf("LoadSPIFFEBundleMap(%v) did not parse correct bundle length. got %v want %v", spiffeBundleFile, len(bundles), wantBundleSize) 55 } 56 if bundles["example.com"] == nil { 57 t.Fatalf("LoadSPIFFEBundleMap(%v) got no bundle for example.com", spiffeBundleFile) 58 } 59 if bundles["test.example.com"] == nil { 60 t.Fatalf("LoadSPIFFEBundleMap(%v) got no bundle for test.example.com", spiffeBundleFile) 61 } 62 63 expectedExampleComCert := loadX509Cert(t, testdata.Path("spiffe/spiffe_cert.pem")) 64 expectedTestExampleComCert := loadX509Cert(t, testdata.Path("spiffe/server1_spiffe.pem")) 65 if !bundles["example.com"].X509Authorities()[0].Equal(expectedExampleComCert) { 66 t.Fatalf("LoadSPIFFEBundleMap(%v) parsed wrong cert for example.com.", spiffeBundleFile) 67 } 68 if !bundles["test.example.com"].X509Authorities()[0].Equal(expectedTestExampleComCert) { 69 t.Fatalf("LoadSPIFFEBundleMap(%v) parsed wrong cert for test.example.com", spiffeBundleFile) 70 } 71 72 } 73 74 func loadX509Cert(t *testing.T, filePath string) *x509.Certificate { 75 t.Helper() 76 certFile, _ := os.Open(filePath) 77 certRaw, _ := io.ReadAll(certFile) 78 block, _ := pem.Decode([]byte(certRaw)) 79 if block == nil { 80 t.Fatalf("pem.Decode(%v) = nil. Want a value.", certRaw) 81 } 82 cert, err := x509.ParseCertificate(block.Bytes) 83 if err != nil { 84 t.Fatalf("x509.ParseCertificate(%v) failed %v", block.Bytes, err.Error()) 85 } 86 return cert 87 } 88 89 func TestLoadSPIFFEBundleMapFailures(t *testing.T) { 90 filePaths := []string{ 91 testdata.Path("spiffe/spiffebundle_corrupted_cert.json"), 92 testdata.Path("spiffe/spiffebundle_malformed.json"), 93 testdata.Path("spiffe/spiffebundle_wrong_kid.json"), 94 testdata.Path("spiffe/spiffebundle_wrong_kty.json"), 95 testdata.Path("spiffe/spiffebundle_wrong_multi_certs.json"), 96 testdata.Path("spiffe/spiffebundle_wrong_root.json"), 97 testdata.Path("spiffe/spiffebundle_wrong_seq_type.json"), 98 testdata.Path("NOT_A_REAL_FILE"), 99 testdata.Path("spiffe/spiffebundle_invalid_trustdomain.json"), 100 } 101 for _, path := range filePaths { 102 t.Run(path, func(t *testing.T) { 103 if _, err := loadSPIFFEBundleMap(path); err == nil { 104 t.Fatalf("LoadSPIFFEBundleMap(%v) did not fail but should have.", path) 105 } 106 }) 107 } 108 } 109 110 func TestLoadSPIFFEBundleMapX509Failures(t *testing.T) { 111 // SPIFFE Bundles only support a use of x509-svid and jwt-svid. If a 112 // use other than this is specified, the parser does not fail, it 113 // just doesn't add an x509 authority or jwt authority to the bundle 114 filePath := testdata.Path("spiffe/spiffebundle_wrong_use.json") 115 bundle, err := loadSPIFFEBundleMap(filePath) 116 if err != nil { 117 t.Fatalf("LoadSPIFFEBundleMap(%v) failed with error: %v", filePath, err) 118 } 119 if len(bundle["example.com"].X509Authorities()) != 0 { 120 t.Fatalf("LoadSPIFFEBundleMap(%v) did not have empty bundle but should have.", filePath) 121 } 122 }