github.com/Hnampk/my-fabric@v0.0.0-20201028083322-75069da399c0/common/crypto/expiration.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 "crypto/x509" 11 "encoding/pem" 12 "time" 13 14 "github.com/golang/protobuf/proto" 15 "github.com/hyperledger/fabric-protos-go/msp" 16 ) 17 18 // ExpiresAt returns when the given identity expires, or a zero time.Time 19 // in case we cannot determine that 20 func ExpiresAt(identityBytes []byte) time.Time { 21 sId := &msp.SerializedIdentity{} 22 // If protobuf parsing failed, we make no decisions about the expiration time 23 if err := proto.Unmarshal(identityBytes, sId); err != nil { 24 return time.Time{} 25 } 26 return certExpirationTime(sId.IdBytes) 27 } 28 29 func certExpirationTime(pemBytes []byte) time.Time { 30 bl, _ := pem.Decode(pemBytes) 31 if bl == nil { 32 // If the identity isn't a PEM block, we make no decisions about the expiration time 33 return time.Time{} 34 } 35 cert, err := x509.ParseCertificate(bl.Bytes) 36 if err != nil { 37 return time.Time{} 38 } 39 return cert.NotAfter 40 } 41 42 // MessageFunc notifies a message happened with the given format, and can be replaced with Warnf or Infof of a logger. 43 type MessageFunc func(format string, args ...interface{}) 44 45 // Scheduler invokes f after d time, and can be replaced with time.AfterFunc. 46 type Scheduler func(d time.Duration, f func()) *time.Timer 47 48 // TrackExpiration warns a week before one of the certificates expires 49 func TrackExpiration(tls bool, serverCert []byte, clientCertChain [][]byte, sIDBytes []byte, info MessageFunc, warn MessageFunc, now time.Time, s Scheduler) { 50 sID := &msp.SerializedIdentity{} 51 if err := proto.Unmarshal(sIDBytes, sID); err != nil { 52 return 53 } 54 55 trackCertExpiration(sID.IdBytes, "enrollment", info, warn, now, s) 56 57 if !tls { 58 return 59 } 60 61 trackCertExpiration(serverCert, "server TLS", info, warn, now, s) 62 63 if len(clientCertChain) == 0 || len(clientCertChain[0]) == 0 { 64 return 65 } 66 67 trackCertExpiration(clientCertChain[0], "client TLS", info, warn, now, s) 68 } 69 70 func trackCertExpiration(rawCert []byte, certRole string, info MessageFunc, warn MessageFunc, now time.Time, sched Scheduler) { 71 expirationTime := certExpirationTime(rawCert) 72 if expirationTime.IsZero() { 73 // If the certificate expiration time cannot be classified, return. 74 return 75 } 76 77 timeLeftUntilExpiration := expirationTime.Sub(now) 78 oneWeek := time.Hour * 24 * 7 79 80 if timeLeftUntilExpiration < 0 { 81 warn("The %s certificate has expired", certRole) 82 return 83 } 84 85 info("The %s certificate will expire on %s", certRole, expirationTime) 86 87 if timeLeftUntilExpiration < oneWeek { 88 days := timeLeftUntilExpiration / (time.Hour * 24) 89 hours := (timeLeftUntilExpiration - (days * time.Hour * 24)) / time.Hour 90 warn("The %s certificate expires within %d days and %d hours", certRole, days, hours) 91 return 92 } 93 94 timeLeftUntilOneWeekBeforeExpiration := timeLeftUntilExpiration - oneWeek 95 96 sched(timeLeftUntilOneWeekBeforeExpiration, func() { 97 warn("The %s certificate will expire within one week", certRole) 98 }) 99 100 }