github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/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/stretchr/testify/assert" 33 ) 34 35 func TestSanitizeCertWithRSA(t *testing.T) { 36 cert := &x509.Certificate{} 37 cert.SignatureAlgorithm = x509.MD2WithRSA 38 result := isECDSASignedCert(cert) 39 assert.False(t, result) 40 41 cert.SignatureAlgorithm = x509.ECDSAWithSHA512 42 result = isECDSASignedCert(cert) 43 assert.True(t, result) 44 } 45 46 func TestSanitizeCertInvalidInput(t *testing.T) { 47 _, err := sanitizeECDSASignedCert(nil, nil) 48 assert.Error(t, err) 49 assert.Contains(t, err.Error(), "Certificate must be different from nil.") 50 51 _, err = sanitizeECDSASignedCert(&x509.Certificate{}, nil) 52 assert.Error(t, err) 53 assert.Contains(t, err.Error(), "Parent certificate must be different from nil") 54 55 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 56 assert.NoError(t, err) 57 cert := &x509.Certificate{} 58 cert.PublicKey = &k.PublicKey 59 sigma, err := sw.MarshalECDSASignature(big.NewInt(1), elliptic.P256().Params().N) 60 assert.NoError(t, err) 61 cert.Signature = sigma 62 cert.PublicKeyAlgorithm = x509.ECDSA 63 cert.Raw = []byte{0, 1} 64 _, err = sanitizeECDSASignedCert(cert, cert) 65 assert.Error(t, err) 66 assert.Contains(t, err.Error(), "asn1: structure error: tags don't match") 67 } 68 69 func TestSanitizeCert(t *testing.T) { 70 var k *ecdsa.PrivateKey 71 var cert *x509.Certificate 72 for { 73 k, cert = generateSelfSignedCert(t, time.Now()) 74 75 _, s, err := sw.UnmarshalECDSASignature(cert.Signature) 76 assert.NoError(t, err) 77 78 lowS, err := sw.IsLowS(&k.PublicKey, s) 79 assert.NoError(t, err) 80 81 if !lowS { 82 break 83 } 84 } 85 86 sanitizedCert, err := sanitizeECDSASignedCert(cert, cert) 87 assert.NoError(t, err) 88 assert.NotEqual(t, cert.Signature, sanitizedCert.Signature) 89 90 _, s, err := sw.UnmarshalECDSASignature(sanitizedCert.Signature) 91 assert.NoError(t, err) 92 93 lowS, err := sw.IsLowS(&k.PublicKey, s) 94 assert.NoError(t, err) 95 assert.True(t, lowS) 96 } 97 98 func TestCertExpiration(t *testing.T) { 99 msp := &bccspmsp{} 100 msp.opts = &x509.VerifyOptions{} 101 msp.opts.DNSName = "test.example.com" 102 103 // Certificate is in the future 104 _, cert := generateSelfSignedCert(t, time.Now().Add(24*time.Hour)) 105 msp.opts.Roots = x509.NewCertPool() 106 msp.opts.Roots.AddCert(cert) 107 _, err := msp.getUniqueValidationChain(cert) 108 assert.NoError(t, err) 109 110 // Certificate is in the past 111 _, cert = generateSelfSignedCert(t, time.Now().Add(-24*time.Hour)) 112 msp.opts.Roots = x509.NewCertPool() 113 msp.opts.Roots.AddCert(cert) 114 _, err = msp.getUniqueValidationChain(cert) 115 assert.NoError(t, err) 116 117 // Certificate is in the middle 118 _, cert = generateSelfSignedCert(t, time.Now()) 119 msp.opts.Roots = x509.NewCertPool() 120 msp.opts.Roots.AddCert(cert) 121 _, err = msp.getUniqueValidationChain(cert) 122 assert.NoError(t, err) 123 } 124 125 func generateSelfSignedCert(t *testing.T, now time.Time) (*ecdsa.PrivateKey, *x509.Certificate) { 126 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 127 assert.NoError(t, err) 128 129 // Generate a self-signed certificate 130 testExtKeyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth} 131 testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}} 132 extraExtensionData := []byte("extra extension") 133 commonName := "test.example.com" 134 template := x509.Certificate{ 135 SerialNumber: big.NewInt(1), 136 Subject: pkix.Name{ 137 CommonName: commonName, 138 Organization: []string{"Σ Acme Co"}, 139 Country: []string{"US"}, 140 ExtraNames: []pkix.AttributeTypeAndValue{ 141 { 142 Type: []int{2, 5, 4, 42}, 143 Value: "Gopher", 144 }, 145 // This should override the Country, above. 146 { 147 Type: []int{2, 5, 4, 6}, 148 Value: "NL", 149 }, 150 }, 151 }, 152 NotBefore: now.Add(-1 * time.Hour), 153 NotAfter: now.Add(1 * time.Hour), 154 SignatureAlgorithm: x509.ECDSAWithSHA256, 155 SubjectKeyId: []byte{1, 2, 3, 4}, 156 KeyUsage: x509.KeyUsageCertSign, 157 ExtKeyUsage: testExtKeyUsage, 158 UnknownExtKeyUsage: testUnknownExtKeyUsage, 159 BasicConstraintsValid: true, 160 IsCA: true, 161 OCSPServer: []string{"http://ocurrentBCCSP.example.com"}, 162 IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"}, 163 DNSNames: []string{"test.example.com"}, 164 EmailAddresses: []string{"gopher@golang.org"}, 165 IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")}, 166 PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}}, 167 PermittedDNSDomains: []string{".example.com", "example.com"}, 168 CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"}, 169 ExtraExtensions: []pkix.Extension{ 170 { 171 Id: []int{1, 2, 3, 4}, 172 Value: extraExtensionData, 173 }, 174 }, 175 } 176 certRaw, err := x509.CreateCertificate(rand.Reader, &template, &template, &k.PublicKey, k) 177 assert.NoError(t, err) 178 179 cert, err := x509.ParseCertificate(certRaw) 180 assert.NoError(t, err) 181 182 return k, cert 183 }