blob: 92489aaa59f4c1a680c29c4f7cea0a981e27a6b0 [file]
// Copyright 2016 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package machinetoken
import (
"crypto/x509/pkix"
"math/big"
"testing"
"time"
"github.com/luci/luci-go/common/clock"
"github.com/luci/luci-go/common/clock/testclock"
tokenserver "github.com/luci/luci-go/tokenserver/api"
admin "github.com/luci/luci-go/tokenserver/api/admin/v1"
"github.com/luci/luci-go/tokenserver/appengine/impl/certconfig"
. "github.com/smartystreets/goconvey/convey"
)
func TestInspectMachineTokenRPC(t *testing.T) {
Convey("with mocked context", t, func() {
ctx := testingContext(testingCA)
impl := InspectMachineTokenRPC{
Signer: testingSigner(),
}
tok := expectedLuciMachineToken
Convey("Good token", func() {
reply, err := impl.InspectMachineToken(ctx, &admin.InspectMachineTokenRequest{
TokenType: tokenserver.MachineTokenType_LUCI_MACHINE_TOKEN,
Token: tok,
})
So(err, ShouldBeNil)
So(reply, ShouldResemble, &admin.InspectMachineTokenResponse{
Valid: true,
Signed: true,
NonExpired: true,
NonRevoked: true,
SigningKeyId: "f9da5a0d0903bda58c6d664e3852a89c283d7fe9",
CertCaName: "Fake CA: fake.ca",
TokenType: &admin.InspectMachineTokenResponse_LuciMachineToken{
LuciMachineToken: &tokenserver.MachineTokenBody{
MachineFqdn: "luci-token-server-test-1.fake.domain",
IssuedBy: "signer@testing.host",
IssuedAt: 1422936306,
Lifetime: 3600,
CaId: 123,
CertSn: 4096,
},
},
})
})
Convey("Broken signature", func() {
reply, err := impl.InspectMachineToken(ctx, &admin.InspectMachineTokenRequest{
TokenType: tokenserver.MachineTokenType_LUCI_MACHINE_TOKEN,
Token: tok[:len(tok)-11] + "0" + tok[len(tok)-10:],
})
So(err, ShouldBeNil)
So(reply, ShouldResemble, &admin.InspectMachineTokenResponse{
Valid: false,
InvalidityReason: "bad signature - crypto/rsa: verification error",
Signed: false,
NonExpired: true,
NonRevoked: true,
CertCaName: "Fake CA: fake.ca",
SigningKeyId: "f9da5a0d0903bda58c6d664e3852a89c283d7fe9",
TokenType: &admin.InspectMachineTokenResponse_LuciMachineToken{
LuciMachineToken: &tokenserver.MachineTokenBody{
MachineFqdn: "luci-token-server-test-1.fake.domain",
IssuedBy: "signer@testing.host",
IssuedAt: 1422936306,
Lifetime: 3600,
CaId: 123,
CertSn: 4096,
},
},
})
})
Convey("Expired", func() {
clock.Get(ctx).(testclock.TestClock).Add(time.Hour + 11*time.Minute)
reply, err := impl.InspectMachineToken(ctx, &admin.InspectMachineTokenRequest{
TokenType: tokenserver.MachineTokenType_LUCI_MACHINE_TOKEN,
Token: tok,
})
So(err, ShouldBeNil)
So(reply, ShouldResemble, &admin.InspectMachineTokenResponse{
Valid: false,
InvalidityReason: "expired",
Signed: true,
NonExpired: false,
NonRevoked: true,
SigningKeyId: "f9da5a0d0903bda58c6d664e3852a89c283d7fe9",
CertCaName: "Fake CA: fake.ca",
TokenType: &admin.InspectMachineTokenResponse_LuciMachineToken{
LuciMachineToken: &tokenserver.MachineTokenBody{
MachineFqdn: "luci-token-server-test-1.fake.domain",
IssuedBy: "signer@testing.host",
IssuedAt: 1422936306,
Lifetime: 3600,
CaId: 123,
CertSn: 4096,
},
},
})
})
Convey("Revoked cert", func() {
// "Revoke" the certificate.
certconfig.UpdateCRLSet(ctx, "Fake CA: fake.ca", certconfig.CRLShardCount,
&pkix.CertificateList{
TBSCertList: pkix.TBSCertificateList{
RevokedCertificates: []pkix.RevokedCertificate{
{SerialNumber: big.NewInt(4096)},
},
},
})
// This makes the token expired too.
clock.Get(ctx).(testclock.TestClock).Add(time.Hour + 11*time.Minute)
reply, err := impl.InspectMachineToken(ctx, &admin.InspectMachineTokenRequest{
TokenType: tokenserver.MachineTokenType_LUCI_MACHINE_TOKEN,
Token: tok,
})
So(err, ShouldBeNil)
So(reply, ShouldResemble, &admin.InspectMachineTokenResponse{
Valid: false,
InvalidityReason: "expired", // "expired" 'beats' revocation
Signed: true,
NonExpired: false,
NonRevoked: false, // revoked now!
SigningKeyId: "f9da5a0d0903bda58c6d664e3852a89c283d7fe9",
CertCaName: "Fake CA: fake.ca",
TokenType: &admin.InspectMachineTokenResponse_LuciMachineToken{
LuciMachineToken: &tokenserver.MachineTokenBody{
MachineFqdn: "luci-token-server-test-1.fake.domain",
IssuedBy: "signer@testing.host",
IssuedAt: 1422936306,
Lifetime: 3600,
CaId: 123,
CertSn: 4096,
},
},
})
})
})
}