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