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