go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/tokenserver/appengine/impl/machinetoken/rpc_inspect_machine_token_test.go (about) 1 // Copyright 2016 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package machinetoken 16 17 import ( 18 "crypto/x509/pkix" 19 "math/big" 20 "strings" 21 "testing" 22 "time" 23 24 "go.chromium.org/luci/common/clock" 25 "go.chromium.org/luci/common/clock/testclock" 26 27 tokenserver "go.chromium.org/luci/tokenserver/api" 28 admin "go.chromium.org/luci/tokenserver/api/admin/v1" 29 "go.chromium.org/luci/tokenserver/appengine/impl/certconfig" 30 31 . "github.com/smartystreets/goconvey/convey" 32 . "go.chromium.org/luci/common/testing/assertions" 33 ) 34 35 func TestInspectMachineTokenRPC(t *testing.T) { 36 Convey("with mocked context", t, func() { 37 ctx := testingContext(testingCA) 38 signer := testingSigner() 39 impl := InspectMachineTokenRPC{Signer: signer} 40 tok := testingMachineToken(ctx, signer) 41 42 Convey("Good token", func() { 43 reply, err := impl.InspectMachineToken(ctx, &admin.InspectMachineTokenRequest{ 44 TokenType: tokenserver.MachineTokenType_LUCI_MACHINE_TOKEN, 45 Token: tok, 46 }) 47 So(err, ShouldBeNil) 48 So(reply, ShouldResembleProto, &admin.InspectMachineTokenResponse{ 49 Valid: true, 50 Signed: true, 51 NonExpired: true, 52 NonRevoked: true, 53 SigningKeyId: signer.KeyNameForTest(), 54 CertCaName: "Fake CA: fake.ca", 55 TokenType: &admin.InspectMachineTokenResponse_LuciMachineToken{ 56 LuciMachineToken: &tokenserver.MachineTokenBody{ 57 MachineFqdn: "luci-token-server-test-1.fake.domain", 58 IssuedBy: "signer@testing.host", 59 IssuedAt: 1422936306, 60 Lifetime: 3600, 61 CaId: 123, 62 CertSn: big.NewInt(4096).Bytes(), 63 }, 64 }, 65 }) 66 }) 67 68 Convey("Broken signature", func() { 69 reply, err := impl.InspectMachineToken(ctx, &admin.InspectMachineTokenRequest{ 70 TokenType: tokenserver.MachineTokenType_LUCI_MACHINE_TOKEN, 71 Token: tok[:len(tok)-16] + strings.Repeat("0", 16), 72 }) 73 So(err, ShouldBeNil) 74 So(reply, ShouldResembleProto, &admin.InspectMachineTokenResponse{ 75 Valid: false, 76 InvalidityReason: "bad signature - crypto/rsa: verification error", 77 Signed: false, 78 NonExpired: true, 79 NonRevoked: true, 80 CertCaName: "Fake CA: fake.ca", 81 SigningKeyId: signer.KeyNameForTest(), 82 TokenType: &admin.InspectMachineTokenResponse_LuciMachineToken{ 83 LuciMachineToken: &tokenserver.MachineTokenBody{ 84 MachineFqdn: "luci-token-server-test-1.fake.domain", 85 IssuedBy: "signer@testing.host", 86 IssuedAt: 1422936306, 87 Lifetime: 3600, 88 CaId: 123, 89 CertSn: big.NewInt(4096).Bytes(), 90 }, 91 }, 92 }) 93 }) 94 95 Convey("Expired", func() { 96 clock.Get(ctx).(testclock.TestClock).Add(time.Hour + 11*time.Minute) 97 reply, err := impl.InspectMachineToken(ctx, &admin.InspectMachineTokenRequest{ 98 TokenType: tokenserver.MachineTokenType_LUCI_MACHINE_TOKEN, 99 Token: tok, 100 }) 101 So(err, ShouldBeNil) 102 So(reply, ShouldResembleProto, &admin.InspectMachineTokenResponse{ 103 Valid: false, 104 InvalidityReason: "expired", 105 Signed: true, 106 NonExpired: false, 107 NonRevoked: true, 108 SigningKeyId: signer.KeyNameForTest(), 109 CertCaName: "Fake CA: fake.ca", 110 TokenType: &admin.InspectMachineTokenResponse_LuciMachineToken{ 111 LuciMachineToken: &tokenserver.MachineTokenBody{ 112 MachineFqdn: "luci-token-server-test-1.fake.domain", 113 IssuedBy: "signer@testing.host", 114 IssuedAt: 1422936306, 115 Lifetime: 3600, 116 CaId: 123, 117 CertSn: big.NewInt(4096).Bytes(), 118 }, 119 }, 120 }) 121 }) 122 123 Convey("Revoked cert", func() { 124 // "Revoke" the certificate. 125 certconfig.UpdateCRLSet(ctx, "Fake CA: fake.ca", certconfig.CRLShardCount, 126 &pkix.CertificateList{ 127 TBSCertList: pkix.TBSCertificateList{ 128 RevokedCertificates: []pkix.RevokedCertificate{ 129 {SerialNumber: big.NewInt(4096)}, 130 }, 131 }, 132 }) 133 // This makes the token expired too. 134 clock.Get(ctx).(testclock.TestClock).Add(time.Hour + 11*time.Minute) 135 reply, err := impl.InspectMachineToken(ctx, &admin.InspectMachineTokenRequest{ 136 TokenType: tokenserver.MachineTokenType_LUCI_MACHINE_TOKEN, 137 Token: tok, 138 }) 139 So(err, ShouldBeNil) 140 So(reply, ShouldResembleProto, &admin.InspectMachineTokenResponse{ 141 Valid: false, 142 InvalidityReason: "expired", // "expired" 'beats' revocation 143 Signed: true, 144 NonExpired: false, 145 NonRevoked: false, // revoked now! 146 SigningKeyId: signer.KeyNameForTest(), 147 CertCaName: "Fake CA: fake.ca", 148 TokenType: &admin.InspectMachineTokenResponse_LuciMachineToken{ 149 LuciMachineToken: &tokenserver.MachineTokenBody{ 150 MachineFqdn: "luci-token-server-test-1.fake.domain", 151 IssuedBy: "signer@testing.host", 152 IssuedAt: 1422936306, 153 Lifetime: 3600, 154 CaId: 123, 155 CertSn: big.NewInt(4096).Bytes(), 156 }, 157 }, 158 }) 159 }) 160 }) 161 }