go.chromium.org/luci@v0.0.0-20250314024836-d9a61d0730e6/tokenserver/appengine/impl/certconfig/crl_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 certconfig 16 17 import ( 18 "crypto/x509/pkix" 19 "math/big" 20 "testing" 21 "time" 22 23 "go.chromium.org/luci/appengine/gaetesting" 24 "go.chromium.org/luci/common/clock/testclock" 25 "go.chromium.org/luci/common/testing/ftt" 26 "go.chromium.org/luci/common/testing/truth/assert" 27 "go.chromium.org/luci/common/testing/truth/should" 28 29 "go.chromium.org/luci/tokenserver/appengine/impl/utils" 30 "go.chromium.org/luci/tokenserver/appengine/impl/utils/shards" 31 ) 32 33 func TestCRL(t *testing.T) { 34 ftt.Run("CRL storage works", t, func(t *ftt.Test) { 35 caName := "CA" 36 shardCount := 4 37 cachingTime := 10 * time.Second 38 39 ctx := gaetesting.TestingContext() 40 ctx, clk := testclock.UseTime(ctx, testclock.TestTimeUTC) 41 42 // Prepare a set of CRLs (with holes, to be more close to life) 43 crl := &pkix.CertificateList{} 44 for i := 1; i < 100; i++ { 45 crl.TBSCertList.RevokedCertificates = append(crl.TBSCertList.RevokedCertificates, pkix.RevokedCertificate{ 46 SerialNumber: big.NewInt(int64(i * 3)), 47 }) 48 } 49 50 // Upload it. 51 assert.Loosely(t, UpdateCRLSet(ctx, caName, shardCount, crl), should.BeNil) 52 53 // Use it. 54 checker := NewCRLChecker(caName, shardCount, cachingTime) 55 for i := 1; i < 300; i++ { 56 revoked, err := checker.IsRevokedSN(ctx, big.NewInt(int64(i))) 57 assert.Loosely(t, err, should.BeNil) 58 assert.Loosely(t, revoked, should.Equal((i%3) == 0)) 59 } 60 61 // Cert #1 is revoked now too. It will invalidate one cache shard. 62 crl.TBSCertList.RevokedCertificates = append(crl.TBSCertList.RevokedCertificates, pkix.RevokedCertificate{ 63 SerialNumber: big.NewInt(1), 64 }) 65 66 // Upload it. 67 assert.Loosely(t, UpdateCRLSet(ctx, caName, shardCount, crl), should.BeNil) 68 69 // Old cache is still used. 70 revoked, err := checker.IsRevokedSN(ctx, big.NewInt(1)) 71 assert.Loosely(t, err, should.BeNil) 72 assert.Loosely(t, revoked, should.BeFalse) 73 74 // Roll time to invalidate the cache. 75 clk.Add(cachingTime * 2) 76 77 // New shard version is fetched. 78 revoked, err = checker.IsRevokedSN(ctx, big.NewInt(1)) 79 assert.Loosely(t, err, should.BeNil) 80 assert.Loosely(t, revoked, should.BeTrue) 81 82 // Hit a code path for refetching of an unchanged shard. Pick a SN that 83 // doesn't belong to shard where '1' is. 84 shardIdx := func(sn int64) int { 85 blob, err := utils.SerializeSN(big.NewInt(sn)) 86 assert.Loosely(t, err, should.BeNil) 87 return shards.ShardIndex(blob, shardCount) 88 } 89 forbiddenIdx := shardIdx(1) 90 sn := int64(2) 91 for shardIdx(sn) == forbiddenIdx { 92 sn++ 93 } 94 95 // Hit this shard. 96 revoked, err = checker.IsRevokedSN(ctx, big.NewInt(sn)) 97 assert.Loosely(t, err, should.BeNil) 98 assert.Loosely(t, revoked, should.Equal((sn%3) == 0)) 99 }) 100 }