github.com/cactusblossom/fabric-ca@v0.0.0-20200611062428-0082fc643826/lib/tls/tls_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 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 tls
    18  
    19  import (
    20  	"crypto/rand"
    21  	"crypto/rsa"
    22  	"crypto/x509"
    23  	"encoding/pem"
    24  	"errors"
    25  	"fmt"
    26  	"math/big"
    27  	"os"
    28  	"testing"
    29  	"time"
    30  
    31  	"github.com/stretchr/testify/assert"
    32  )
    33  
    34  const (
    35  	configDir   = "../../testdata"
    36  	caCert      = "root.pem"
    37  	certFile    = "tls_client-cert.pem"
    38  	keyFile     = "tls_client-key.pem"
    39  	expiredCert = "../../testdata/expiredcert.pem"
    40  )
    41  
    42  type testTLSConfig struct {
    43  	TLS *ClientTLSConfig
    44  }
    45  
    46  func TestGetClientTLSConfig(t *testing.T) {
    47  
    48  	cfg := &ClientTLSConfig{
    49  		CertFiles: []string{"root.pem"},
    50  		Client: KeyCertFiles{
    51  			KeyFile:  "tls_client-key.pem",
    52  			CertFile: "tls_client-cert.pem",
    53  		},
    54  	}
    55  
    56  	err := AbsTLSClient(cfg, configDir)
    57  	if err != nil {
    58  		t.Errorf("Failed to get absolute path for client TLS config: %s", err)
    59  	}
    60  
    61  	_, err = GetClientTLSConfig(cfg, nil)
    62  	if err != nil {
    63  		t.Errorf("Failed to get TLS Config: %s", err)
    64  	}
    65  
    66  }
    67  
    68  func TestGetClientTLSConfigInvalidArgs(t *testing.T) {
    69  	// 1.
    70  	cfg := &ClientTLSConfig{
    71  		CertFiles: []string{"root.pem"},
    72  		Client: KeyCertFiles{
    73  			KeyFile:  "no_tls_client-key.pem",
    74  			CertFile: "no_tls_client-cert.pem",
    75  		},
    76  	}
    77  	_, err := GetClientTLSConfig(cfg, nil)
    78  	assert.Error(t, err)
    79  	assert.Contains(t, err.Error(), "open no_tls_client-cert.pem: no such file or directory")
    80  
    81  	// 2.
    82  	cfg = &ClientTLSConfig{
    83  		CertFiles: nil,
    84  		Client: KeyCertFiles{
    85  			KeyFile:  "tls_client-key.pem",
    86  			CertFile: "tls_client-cert.pem",
    87  		},
    88  	}
    89  	AbsTLSClient(cfg, configDir)
    90  	_, err = GetClientTLSConfig(cfg, nil)
    91  	assert.Error(t, err)
    92  	assert.Contains(t, err.Error(), "No trusted root certificates for TLS were provided")
    93  
    94  	// 3.
    95  	cfg = &ClientTLSConfig{
    96  		CertFiles: nil,
    97  		Client: KeyCertFiles{
    98  			KeyFile:  "no-tls_client-key.pem",
    99  			CertFile: "tls_client-cert.pem",
   100  		},
   101  	}
   102  	AbsTLSClient(cfg, configDir)
   103  	_, err = GetClientTLSConfig(cfg, nil)
   104  	assert.Error(t, err)
   105  	assert.Contains(t, err.Error(), "no-tls_client-key.pem: no such file or directory")
   106  
   107  	// 4.
   108  	cfg = &ClientTLSConfig{
   109  		CertFiles: nil,
   110  		Client: KeyCertFiles{
   111  			KeyFile:  "",
   112  			CertFile: "",
   113  		},
   114  	}
   115  	_, err = GetClientTLSConfig(cfg, nil)
   116  	assert.Error(t, err)
   117  	assert.Contains(t, err.Error(), "No trusted root certificates for TLS were provided")
   118  
   119  	// 5.
   120  	cfg = &ClientTLSConfig{
   121  		CertFiles: []string{"no-root.pem"},
   122  		Client: KeyCertFiles{
   123  			KeyFile:  "tls_client-key.pem",
   124  			CertFile: "tls_client-cert.pem",
   125  		},
   126  	}
   127  	AbsTLSClient(cfg, configDir)
   128  	_, err = GetClientTLSConfig(cfg, nil)
   129  	assert.Error(t, err)
   130  	assert.Contains(t, err.Error(), "no-root.pem: no such file or directory")
   131  }
   132  
   133  func TestAbsServerTLSConfig(t *testing.T) {
   134  	cfg := &ServerTLSConfig{
   135  		KeyFile:  "tls_client-key.pem",
   136  		CertFile: "tls_client-cert.pem",
   137  		ClientAuth: ClientAuth{
   138  			CertFiles: []string{"root.pem"},
   139  		},
   140  	}
   141  
   142  	err := AbsTLSServer(cfg, configDir)
   143  	if err != nil {
   144  		t.Errorf("Failed to get absolute path for server TLS config: %s", err)
   145  	}
   146  }
   147  
   148  func TestCheckCertDates(t *testing.T) {
   149  	err := checkCertDates(expiredCert)
   150  	if err == nil {
   151  		assert.Error(t, errors.New("Expired certificate should have resulted in an error"))
   152  	}
   153  
   154  	err = createTestCertificate()
   155  	if err != nil {
   156  		assert.Error(t, err)
   157  	}
   158  
   159  	err = checkCertDates("notbefore.pem")
   160  	if err == nil {
   161  		assert.Error(t, errors.New("Future valid certificate should have resulted in an error"))
   162  	}
   163  	if err != nil {
   164  		assert.Contains(t, err.Error(), "Certificate provided not valid until later date")
   165  	}
   166  
   167  	os.Remove("notbefore.pem")
   168  }
   169  
   170  func createTestCertificate() error {
   171  	// Dynamically create a certificate with future valid date for testing purposes
   172  	certTemplate := &x509.Certificate{
   173  		IsCA:                  true,
   174  		BasicConstraintsValid: true,
   175  		SubjectKeyId:          []byte{1, 2, 3},
   176  		SerialNumber:          big.NewInt(1234),
   177  		NotBefore:             time.Now().Add(time.Hour * 24),
   178  		NotAfter:              time.Now().Add(time.Hour * 48),
   179  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
   180  		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
   181  	}
   182  	// generate private key
   183  	privatekey, err := rsa.GenerateKey(rand.Reader, 2048)
   184  	if err != nil {
   185  		return fmt.Errorf("Error occurred during key generation: %s", err)
   186  	}
   187  	publickey := &privatekey.PublicKey
   188  	// create a self-signed certificate. template = parent
   189  	var parent = certTemplate
   190  	cert, err := x509.CreateCertificate(rand.Reader, certTemplate, parent, publickey, privatekey)
   191  	if err != nil {
   192  		return fmt.Errorf("Error occurred during certificate creation: %s", err)
   193  	}
   194  
   195  	pemfile, _ := os.Create("notbefore.pem")
   196  	var pemkey = &pem.Block{
   197  		Type:  "CERTIFICATE",
   198  		Bytes: cert,
   199  	}
   200  	pem.Encode(pemfile, pemkey)
   201  	pemfile.Close()
   202  
   203  	return nil
   204  }