github.com/hyperledger-labs/bdls@v2.1.1+incompatible/msp/cert_test.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package msp 18 19 import ( 20 "crypto/ecdsa" 21 "crypto/elliptic" 22 "crypto/rand" 23 "crypto/x509" 24 "crypto/x509/pkix" 25 "encoding/asn1" 26 "math/big" 27 "net" 28 "testing" 29 "time" 30 31 "github.com/hyperledger/fabric/bccsp/sw" 32 "github.com/hyperledger/fabric/bccsp/utils" 33 "github.com/stretchr/testify/assert" 34 ) 35 36 func TestSanitizeCertWithRSA(t *testing.T) { 37 cert := &x509.Certificate{} 38 cert.SignatureAlgorithm = x509.MD2WithRSA 39 result := isECDSASignedCert(cert) 40 assert.False(t, result) 41 42 cert.SignatureAlgorithm = x509.ECDSAWithSHA512 43 result = isECDSASignedCert(cert) 44 assert.True(t, result) 45 } 46 47 func TestSanitizeCertInvalidInput(t *testing.T) { 48 _, err := sanitizeECDSASignedCert(nil, nil) 49 assert.Error(t, err) 50 assert.Contains(t, err.Error(), "certificate must be different from nil") 51 52 _, err = sanitizeECDSASignedCert(&x509.Certificate{}, nil) 53 assert.Error(t, err) 54 assert.Contains(t, err.Error(), "parent certificate must be different from nil") 55 56 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 57 assert.NoError(t, err) 58 cert := &x509.Certificate{} 59 cert.PublicKey = &k.PublicKey 60 sigma, err := utils.MarshalECDSASignature(big.NewInt(1), elliptic.P256().Params().N) 61 assert.NoError(t, err) 62 cert.Signature = sigma 63 cert.PublicKeyAlgorithm = x509.ECDSA 64 cert.Raw = []byte{0, 1} 65 _, err = sanitizeECDSASignedCert(cert, cert) 66 assert.Error(t, err) 67 assert.Contains(t, err.Error(), "asn1: structure error: tags don't match") 68 } 69 70 func TestSanitizeCert(t *testing.T) { 71 var k *ecdsa.PrivateKey 72 var cert *x509.Certificate 73 for { 74 k, cert = generateSelfSignedCert(t, time.Now()) 75 76 _, s, err := utils.UnmarshalECDSASignature(cert.Signature) 77 assert.NoError(t, err) 78 79 lowS, err := utils.IsLowS(&k.PublicKey, s) 80 assert.NoError(t, err) 81 82 if !lowS { 83 break 84 } 85 } 86 87 sanitizedCert, err := sanitizeECDSASignedCert(cert, cert) 88 assert.NoError(t, err) 89 assert.NotEqual(t, cert.Signature, sanitizedCert.Signature) 90 91 _, s, err := utils.UnmarshalECDSASignature(sanitizedCert.Signature) 92 assert.NoError(t, err) 93 94 lowS, err := utils.IsLowS(&k.PublicKey, s) 95 assert.NoError(t, err) 96 assert.True(t, lowS) 97 } 98 99 func TestCertExpiration(t *testing.T) { 100 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 101 assert.NoError(t, err) 102 msp := &bccspmsp{bccsp: cryptoProvider} 103 msp.opts = &x509.VerifyOptions{} 104 msp.opts.DNSName = "test.example.com" 105 106 // Certificate is in the future 107 _, cert := generateSelfSignedCert(t, time.Now().Add(24*time.Hour)) 108 msp.opts.Roots = x509.NewCertPool() 109 msp.opts.Roots.AddCert(cert) 110 _, err = msp.getUniqueValidationChain(cert, msp.getValidityOptsForCert(cert)) 111 assert.NoError(t, err) 112 113 // Certificate is in the past 114 _, cert = generateSelfSignedCert(t, time.Now().Add(-24*time.Hour)) 115 msp.opts.Roots = x509.NewCertPool() 116 msp.opts.Roots.AddCert(cert) 117 _, err = msp.getUniqueValidationChain(cert, msp.getValidityOptsForCert(cert)) 118 assert.NoError(t, err) 119 120 // Certificate is in the middle 121 _, cert = generateSelfSignedCert(t, time.Now()) 122 msp.opts.Roots = x509.NewCertPool() 123 msp.opts.Roots.AddCert(cert) 124 _, err = msp.getUniqueValidationChain(cert, msp.getValidityOptsForCert(cert)) 125 assert.NoError(t, err) 126 } 127 128 func generateSelfSignedCert(t *testing.T, now time.Time) (*ecdsa.PrivateKey, *x509.Certificate) { 129 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 130 assert.NoError(t, err) 131 132 // Generate a self-signed certificate 133 testExtKeyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth} 134 testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}} 135 extraExtensionData := []byte("extra extension") 136 commonName := "test.example.com" 137 template := x509.Certificate{ 138 SerialNumber: big.NewInt(1), 139 Subject: pkix.Name{ 140 CommonName: commonName, 141 Organization: []string{"Σ Acme Co"}, 142 Country: []string{"US"}, 143 ExtraNames: []pkix.AttributeTypeAndValue{ 144 { 145 Type: []int{2, 5, 4, 42}, 146 Value: "Gopher", 147 }, 148 // This should override the Country, above. 149 { 150 Type: []int{2, 5, 4, 6}, 151 Value: "NL", 152 }, 153 }, 154 }, 155 NotBefore: now.Add(-1 * time.Hour), 156 NotAfter: now.Add(1 * time.Hour), 157 SignatureAlgorithm: x509.ECDSAWithSHA256, 158 SubjectKeyId: []byte{1, 2, 3, 4}, 159 KeyUsage: x509.KeyUsageCertSign, 160 ExtKeyUsage: testExtKeyUsage, 161 UnknownExtKeyUsage: testUnknownExtKeyUsage, 162 BasicConstraintsValid: true, 163 IsCA: true, 164 OCSPServer: []string{"http://ocurrentBCCSP.example.com"}, 165 IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"}, 166 DNSNames: []string{"test.example.com"}, 167 EmailAddresses: []string{"gopher@golang.org"}, 168 IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")}, 169 PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}}, 170 PermittedDNSDomains: []string{".example.com", "example.com"}, 171 CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"}, 172 ExtraExtensions: []pkix.Extension{ 173 { 174 Id: []int{1, 2, 3, 4}, 175 Value: extraExtensionData, 176 }, 177 }, 178 } 179 certRaw, err := x509.CreateCertificate(rand.Reader, &template, &template, &k.PublicKey, k) 180 assert.NoError(t, err) 181 182 cert, err := x509.ParseCertificate(certRaw) 183 assert.NoError(t, err) 184 185 return k, cert 186 }