github.com/simranvc/fabric-ca@v0.0.0-20191030094829-acc364294dde/lib/test-util.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 lib
    18  
    19  import (
    20  	"crypto/rand"
    21  	"crypto/x509"
    22  	"crypto/x509/pkix"
    23  	"encoding/pem"
    24  	"errors"
    25  	"fmt"
    26  	"io"
    27  	"io/ioutil"
    28  	"math/big"
    29  	"os"
    30  	"path"
    31  	"strconv"
    32  	"testing"
    33  	"time"
    34  
    35  	"github.com/cloudflare/cfssl/config"
    36  )
    37  
    38  const (
    39  	rootPort         = 7075
    40  	rootDir          = "rootDir"
    41  	rootClientDir    = "rootClientDir"
    42  	intermediatePort = 7076
    43  	intermediateDir  = "intDir"
    44  	testdataDir      = "../testdata"
    45  )
    46  
    47  func getRootServerURL() string {
    48  	return fmt.Sprintf("http://admin:adminpw@localhost:%d", rootPort)
    49  }
    50  
    51  // TestGetRootServer creates a server with root configuration
    52  func TestGetRootServer(t *testing.T) *Server {
    53  	return TestGetServer(rootPort, rootDir, "", -1, t)
    54  }
    55  
    56  // TestGetIntermediateServer creates a server with intermediate server configuration
    57  func TestGetIntermediateServer(idx int, t *testing.T) *Server {
    58  	return TestGetServer(
    59  		intermediatePort,
    60  		path.Join(intermediateDir, strconv.Itoa(idx)),
    61  		getRootServerURL(),
    62  		-1,
    63  		t)
    64  }
    65  
    66  // TestGetServer creates and returns a pointer to a server struct
    67  func TestGetServer(port int, home, parentURL string, maxEnroll int, t *testing.T) *Server {
    68  	return TestGetServer2(home != testdataDir, port, home, parentURL, maxEnroll, t)
    69  }
    70  
    71  // TestGetServer2 creates and returns a pointer to a server struct, with an option of
    72  // whether or not to remove the home directory first
    73  func TestGetServer2(deleteHome bool, port int, home, parentURL string, maxEnroll int, t *testing.T) *Server {
    74  	if deleteHome {
    75  		os.RemoveAll(home)
    76  	}
    77  	affiliations := map[string]interface{}{
    78  		"hyperledger": map[string]interface{}{
    79  			"fabric":    []string{"ledger", "orderer", "security"},
    80  			"fabric-ca": nil,
    81  			"sdk":       nil,
    82  		},
    83  		"org2":      []string{"dept1"},
    84  		"org1":      nil,
    85  		"org2dept1": nil,
    86  	}
    87  	profiles := map[string]*config.SigningProfile{
    88  		"tls": &config.SigningProfile{
    89  			Usage:        []string{"signing", "key encipherment", "server auth", "client auth", "key agreement"},
    90  			ExpiryString: "8760h",
    91  		},
    92  		"ca": &config.SigningProfile{
    93  			Usage:        []string{"cert sign", "crl sign"},
    94  			ExpiryString: "8760h",
    95  			CAConstraint: config.CAConstraint{
    96  				IsCA:       true,
    97  				MaxPathLen: 0,
    98  			},
    99  		},
   100  	}
   101  	defaultProfile := &config.SigningProfile{
   102  		Usage:        []string{"cert sign"},
   103  		ExpiryString: "8760h",
   104  	}
   105  	srv := &Server{
   106  		Config: &ServerConfig{
   107  			Port:  port,
   108  			Debug: true,
   109  		},
   110  		CA: CA{
   111  			Config: &CAConfig{
   112  				Intermediate: IntermediateCA{
   113  					ParentServer: ParentServer{
   114  						URL: parentURL,
   115  					},
   116  				},
   117  				Affiliations: affiliations,
   118  				Registry: CAConfigRegistry{
   119  					MaxEnrollments: maxEnroll,
   120  				},
   121  				Signing: &config.Signing{
   122  					Profiles: profiles,
   123  					Default:  defaultProfile,
   124  				},
   125  				Version: "1.1.0", // The default test server/ca should use the latest version
   126  			},
   127  		},
   128  		HomeDir: home,
   129  	}
   130  	// The bootstrap user's affiliation is the empty string, which
   131  	// means the user is at the affiliation root
   132  	err := srv.RegisterBootstrapUser("admin", "adminpw", "")
   133  	if err != nil {
   134  		t.Errorf("Failed to register bootstrap user: %s", err)
   135  		return nil
   136  	}
   137  	return srv
   138  }
   139  
   140  // CopyFile copies a file
   141  func CopyFile(src, dst string) error {
   142  	srcFile, err := os.Open(src)
   143  	if err != nil {
   144  		return err
   145  	}
   146  
   147  	defer srcFile.Close()
   148  
   149  	destFile, err := os.Create(dst)
   150  	if err != nil {
   151  		return err
   152  	}
   153  
   154  	defer destFile.Close()
   155  
   156  	_, err = io.Copy(destFile, srcFile)
   157  	if err != nil {
   158  		return err
   159  	}
   160  
   161  	err = destFile.Sync()
   162  	if err != nil {
   163  		return err
   164  	}
   165  	return nil
   166  }
   167  
   168  // GenerateECDSATestCert generates EC based certificate for testing purposes
   169  func GenerateECDSATestCert() error {
   170  	template := &x509.Certificate{
   171  		IsCA:                  true,
   172  		BasicConstraintsValid: true,
   173  		SubjectKeyId:          []byte{1, 2, 3},
   174  		SerialNumber:          big.NewInt(1234),
   175  		Subject: pkix.Name{
   176  			Country:      []string{"US"},
   177  			Organization: []string{"IBM"},
   178  		},
   179  		NotBefore:   time.Now(),
   180  		NotAfter:    time.Now().AddDate(15, 0, 0),
   181  		ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
   182  		KeyUsage:    x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
   183  	}
   184  
   185  	privKey, err := ioutil.ReadFile("../testdata/ec_key.pem")
   186  	if err != nil {
   187  		return err
   188  	}
   189  
   190  	decoded, _ := pem.Decode(privKey)
   191  	if decoded == nil {
   192  		return errors.New("Failed to decode the PEM-encoded ECDSA key")
   193  	}
   194  	privateKey, err := x509.ParseECPrivateKey(decoded.Bytes)
   195  	if err != nil {
   196  		return err
   197  	}
   198  
   199  	publicKey := &privateKey.PublicKey
   200  
   201  	var parent = template
   202  	cert, err := x509.CreateCertificate(rand.Reader, template, parent, publicKey, privateKey)
   203  	if err != nil {
   204  		return err
   205  	}
   206  
   207  	certOut, err := os.Create("../testdata/ec_cert.pem")
   208  	if err != nil {
   209  		return err
   210  	}
   211  	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: cert})
   212  
   213  	return nil
   214  }
   215  
   216  // Currently not being used anywhere, commenting it out for right now
   217  // it was just bringing test coverage.
   218  
   219  // StopAndCleanupServer stops the server and removes the server's home directory
   220  // func StopAndCleanupServer(t *testing.T, srv *Server) {
   221  // 	if srv != nil {
   222  // 		defer os.RemoveAll(srv.HomeDir)
   223  // 		err := srv.Stop()
   224  // 		if err != nil {
   225  // 			t.Errorf("Server stop failed: %s", err)
   226  // 		}
   227  // 	}
   228  // }
   229  
   230  // TestGetRootClient returns a Fabric CA client that is meant for a root Fabric CA server
   231  func TestGetRootClient() *Client {
   232  	return TestGetClient(rootPort, rootClientDir)
   233  }
   234  
   235  // TestGetClient returns a Fabric CA client
   236  func TestGetClient(port int, home string) *Client {
   237  	return &Client{
   238  		Config:  &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", port)},
   239  		HomeDir: home,
   240  	}
   241  }