github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/common/crypto/expiration_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package crypto 8 9 import ( 10 "fmt" 11 "io/ioutil" 12 "path/filepath" 13 "testing" 14 "time" 15 16 "github.com/golang/protobuf/proto" 17 "github.com/hyperledger/fabric-protos-go/msp" 18 "github.com/hyperledger/fabric/common/crypto/tlsgen" 19 "github.com/hyperledger/fabric/protoutil" 20 "github.com/stretchr/testify/assert" 21 ) 22 23 func TestX509CertExpiresAt(t *testing.T) { 24 certBytes, err := ioutil.ReadFile(filepath.Join("testdata", "cert.pem")) 25 assert.NoError(t, err) 26 sId := &msp.SerializedIdentity{ 27 IdBytes: certBytes, 28 } 29 serializedIdentity, err := proto.Marshal(sId) 30 assert.NoError(t, err) 31 expirationTime := ExpiresAt(serializedIdentity) 32 assert.Equal(t, time.Date(2027, 8, 17, 12, 19, 48, 0, time.UTC), expirationTime) 33 } 34 35 func TestX509InvalidCertExpiresAt(t *testing.T) { 36 certBytes, err := ioutil.ReadFile(filepath.Join("testdata", "badCert.pem")) 37 assert.NoError(t, err) 38 sId := &msp.SerializedIdentity{ 39 IdBytes: certBytes, 40 } 41 serializedIdentity, err := proto.Marshal(sId) 42 assert.NoError(t, err) 43 expirationTime := ExpiresAt(serializedIdentity) 44 assert.True(t, expirationTime.IsZero()) 45 } 46 47 func TestIdemixIdentityExpiresAt(t *testing.T) { 48 idemixId := &msp.SerializedIdemixIdentity{ 49 NymX: []byte{1, 2, 3}, 50 NymY: []byte{1, 2, 3}, 51 Ou: []byte("OU1"), 52 } 53 idemixBytes, err := proto.Marshal(idemixId) 54 assert.NoError(t, err) 55 sId := &msp.SerializedIdentity{ 56 IdBytes: idemixBytes, 57 } 58 serializedIdentity, err := proto.Marshal(sId) 59 assert.NoError(t, err) 60 expirationTime := ExpiresAt(serializedIdentity) 61 assert.True(t, expirationTime.IsZero()) 62 } 63 64 func TestInvalidIdentityExpiresAt(t *testing.T) { 65 expirationTime := ExpiresAt([]byte{1, 2, 3}) 66 assert.True(t, expirationTime.IsZero()) 67 } 68 69 func TestTrackExpiration(t *testing.T) { 70 ca, err := tlsgen.NewCA() 71 assert.NoError(t, err) 72 73 now := time.Now() 74 expirationTime := certExpirationTime(ca.CertBytes()) 75 76 timeUntilExpiration := expirationTime.Sub(now) 77 timeUntilOneMonthBeforeExpiration := timeUntilExpiration - 28*24*time.Hour 78 timeUntil2DaysBeforeExpiration := timeUntilExpiration - 2*24*time.Hour - time.Hour*12 79 80 monthBeforeExpiration := now.Add(timeUntilOneMonthBeforeExpiration) 81 twoDaysBeforeExpiration := now.Add(timeUntil2DaysBeforeExpiration) 82 83 tlsCert, err := ca.NewServerCertKeyPair("127.0.0.1") 84 assert.NoError(t, err) 85 86 signingIdentity := protoutil.MarshalOrPanic(&msp.SerializedIdentity{ 87 IdBytes: tlsCert.Cert, 88 }) 89 90 shouldNotBeInvoked := func(format string, args ...interface{}) { 91 t.Fatalf(format, args...) 92 } 93 94 var formattedWarning string 95 shouldBeInvoked := func(format string, args ...interface{}) { 96 formattedWarning = fmt.Sprintf(format, args...) 97 } 98 99 for _, testCase := range []struct { 100 description string 101 tls bool 102 serverCert []byte 103 clientCertChain [][]byte 104 sIDBytes []byte 105 warn WarnFunc 106 now time.Time 107 expectedWarn string 108 }{ 109 { 110 description: "No TLS, enrollment cert isn't valid logs a warning", 111 warn: shouldNotBeInvoked, 112 sIDBytes: []byte{1, 2, 3}, 113 }, 114 { 115 description: "No TLS, enrollment cert expires soon", 116 sIDBytes: signingIdentity, 117 warn: shouldBeInvoked, 118 now: monthBeforeExpiration, 119 expectedWarn: "The enrollment certificate will expire within one week", 120 }, 121 { 122 description: "TLS, server cert expires soon", 123 warn: shouldBeInvoked, 124 now: monthBeforeExpiration, 125 tls: true, 126 serverCert: tlsCert.Cert, 127 expectedWarn: "The server TLS certificate will expire within one week", 128 }, 129 { 130 description: "TLS, server cert expires really soon", 131 warn: shouldBeInvoked, 132 now: twoDaysBeforeExpiration, 133 tls: true, 134 serverCert: tlsCert.Cert, 135 expectedWarn: "The server TLS certificate expires within 2 days and 12 hours", 136 }, 137 { 138 description: "TLS, server cert has expired", 139 warn: shouldBeInvoked, 140 now: expirationTime.Add(time.Hour), 141 tls: true, 142 serverCert: tlsCert.Cert, 143 expectedWarn: "The server TLS certificate has expired", 144 }, 145 { 146 description: "TLS, client cert expires soon", 147 warn: shouldBeInvoked, 148 now: monthBeforeExpiration, 149 tls: true, 150 clientCertChain: [][]byte{tlsCert.Cert}, 151 expectedWarn: "The client TLS certificate will expire within one week", 152 }, 153 } { 154 t.Run(testCase.description, func(t *testing.T) { 155 defer func() { 156 formattedWarning = "" 157 }() 158 159 fakeTimeAfter := func(duration time.Duration, f func()) *time.Timer { 160 assert.NotEmpty(t, testCase.expectedWarn) 161 threeWeeks := 3 * 7 * 24 * time.Hour 162 assert.Equal(t, threeWeeks, duration) 163 f() 164 return nil 165 } 166 167 TrackExpiration(testCase.tls, 168 testCase.serverCert, 169 testCase.clientCertChain, 170 testCase.sIDBytes, 171 testCase.warn, 172 testCase.now, 173 fakeTimeAfter) 174 175 if testCase.expectedWarn != "" { 176 assert.Equal(t, testCase.expectedWarn, formattedWarning) 177 } else { 178 assert.Empty(t, formattedWarning) 179 } 180 }) 181 } 182 }