github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/security/x509_test.go (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package security_test 12 13 import ( 14 "crypto/rand" 15 "crypto/rsa" 16 "crypto/x509" 17 "testing" 18 "time" 19 20 "github.com/cockroachdb/cockroach/pkg/security" 21 "github.com/cockroachdb/cockroach/pkg/testutils" 22 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 23 "github.com/cockroachdb/cockroach/pkg/util/timeutil" 24 ) 25 26 const wiggle = time.Minute * 5 27 28 // Returns true if "|a-b| <= wiggle". 29 func timesFuzzyEqual(a, b time.Time) bool { 30 diff := a.Sub(b) 31 if diff < 0 { 32 diff = -diff 33 } 34 return diff <= wiggle 35 } 36 37 func TestGenerateCertLifetime(t *testing.T) { 38 defer leaktest.AfterTest(t)() 39 40 testKey, err := rsa.GenerateKey(rand.Reader, 512) 41 if err != nil { 42 t.Fatal(err) 43 } 44 45 // Create a CA that expires in 2 days. 46 caDuration := time.Hour * 48 47 now := timeutil.Now() 48 caBytes, err := security.GenerateCA(testKey, caDuration) 49 if err != nil { 50 t.Fatal(err) 51 } 52 53 caCert, err := x509.ParseCertificate(caBytes) 54 if err != nil { 55 t.Fatal(err) 56 } 57 58 if a, e := caCert.NotAfter, now.Add(caDuration); !timesFuzzyEqual(a, e) { 59 t.Fatalf("CA expiration differs from requested: %s vs %s", a, e) 60 } 61 62 // Create a Node certificate expiring in 4 days. Fails on shorter CA lifetime. 63 nodeDuration := time.Hour * 96 64 _, err = security.GenerateServerCert(caCert, testKey, 65 testKey.Public(), nodeDuration, security.NodeUser, []string{"localhost"}) 66 if !testutils.IsError(err, "CA lifetime is .*, shorter than the requested .*") { 67 t.Fatal(err) 68 } 69 70 // Try again, but expiring before the CA cert. 71 nodeDuration = time.Hour * 24 72 nodeBytes, err := security.GenerateServerCert(caCert, testKey, 73 testKey.Public(), nodeDuration, security.NodeUser, []string{"localhost"}) 74 if err != nil { 75 t.Fatal(err) 76 } 77 78 nodeCert, err := x509.ParseCertificate(nodeBytes) 79 if err != nil { 80 t.Fatal(err) 81 } 82 83 if a, e := nodeCert.NotAfter, now.Add(nodeDuration); !timesFuzzyEqual(a, e) { 84 t.Fatalf("node expiration differs from requested: %s vs %s", a, e) 85 } 86 87 // Create a Client certificate expiring in 4 days. Should get reduced to the CA lifetime. 88 clientDuration := time.Hour * 96 89 _, err = security.GenerateClientCert(caCert, testKey, testKey.Public(), clientDuration, "testuser") 90 if !testutils.IsError(err, "CA lifetime is .*, shorter than the requested .*") { 91 t.Fatal(err) 92 } 93 94 // Try again, but expiring before the CA cert. 95 clientDuration = time.Hour * 24 96 clientBytes, err := security.GenerateClientCert(caCert, testKey, testKey.Public(), clientDuration, "testuser") 97 if err != nil { 98 t.Fatal(err) 99 } 100 101 clientCert, err := x509.ParseCertificate(clientBytes) 102 if err != nil { 103 t.Fatal(err) 104 } 105 106 if a, e := clientCert.NotAfter, now.Add(clientDuration); !timesFuzzyEqual(a, e) { 107 t.Fatalf("client expiration differs from requested: %s vs %s", a, e) 108 } 109 110 }