github.com/hxx258456/fabric-ca-gm@v0.0.3-0.20221111064038-a268ad7e3a37/lib/ca.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lib
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/pem"
    12  	"fmt"
    13  	"io/ioutil"
    14  	"os"
    15  	"path"
    16  	"path/filepath"
    17  	"strconv"
    18  	"sync"
    19  	"time"
    20  
    21  	"gitee.com/zhaochuninhefei/zcgolog/zclog"
    22  	"github.com/hxx258456/ccgo/sm2"
    23  	"github.com/hxx258456/ccgo/x509"
    24  	"github.com/hxx258456/cfssl-gm/certdb"
    25  	"github.com/hxx258456/cfssl-gm/config"
    26  	cfcsr "github.com/hxx258456/cfssl-gm/csr"
    27  	"github.com/hxx258456/cfssl-gm/initca"
    28  	"github.com/hxx258456/cfssl-gm/signer"
    29  	cflocalsigner "github.com/hxx258456/cfssl-gm/signer/local"
    30  	"github.com/hxx258456/fabric-ca-gm/internal/pkg/api"
    31  	"github.com/hxx258456/fabric-ca-gm/internal/pkg/util"
    32  	"github.com/hxx258456/fabric-ca-gm/lib/attr"
    33  	"github.com/hxx258456/fabric-ca-gm/lib/attrmgr"
    34  	"github.com/hxx258456/fabric-ca-gm/lib/caerrors"
    35  	"github.com/hxx258456/fabric-ca-gm/lib/metadata"
    36  	"github.com/hxx258456/fabric-ca-gm/lib/server/db"
    37  	cadbfactory "github.com/hxx258456/fabric-ca-gm/lib/server/db/factory"
    38  	"github.com/hxx258456/fabric-ca-gm/lib/server/db/mysql"
    39  	"github.com/hxx258456/fabric-ca-gm/lib/server/db/postgres"
    40  	"github.com/hxx258456/fabric-ca-gm/lib/server/db/sqlite"
    41  	dbutil "github.com/hxx258456/fabric-ca-gm/lib/server/db/util"
    42  	idemix "github.com/hxx258456/fabric-ca-gm/lib/server/idemix"
    43  	"github.com/hxx258456/fabric-ca-gm/lib/server/ldap"
    44  	cadbuser "github.com/hxx258456/fabric-ca-gm/lib/server/user"
    45  	"github.com/hxx258456/fabric-ca-gm/lib/tls"
    46  	"github.com/hxx258456/fabric-gm/bccsp"
    47  	"github.com/pkg/errors"
    48  )
    49  
    50  const (
    51  	defaultDatabaseType = "sqlite3"
    52  	// CAChainParentFirstEnvVar is the name of the environment variable that needs to be set
    53  	// for server to return CA chain in parent-first order
    54  	CAChainParentFirstEnvVar = "CA_CHAIN_PARENT_FIRST"
    55  )
    56  
    57  var (
    58  	// Default root CA certificate expiration is 15 years (in hours). 改为100年
    59  	// defaultRootCACertificateExpiration = "131400h"
    60  	defaultRootCACertificateExpiration = "876000h"
    61  	// Default intermediate CA certificate expiration is 5 years (in hours). 改为80年
    62  	// defaultIntermediateCACertificateExpiration = parseDuration("43800h")
    63  	defaultIntermediateCACertificateExpiration = parseDuration("700800h")
    64  	// Default issued certificate expiration is 1 year (in hours). 改为50年
    65  	// defaultIssuedCertificateExpiration = parseDuration("8760h")
    66  	defaultIssuedCertificateExpiration = parseDuration("438000h")
    67  )
    68  
    69  // CA represents a certificate authority which signs, issues and revokes certificates
    70  type CA struct {
    71  	// The home directory for the CA
    72  	HomeDir string
    73  	// The CA's configuration
    74  	Config *CAConfig
    75  	// The file path of the config file
    76  	ConfigFilePath string
    77  	// The database handle used to store certificates and optionally
    78  	// the user registry information, unless LDAP it enabled for the
    79  	// user registry function.
    80  	db db.FabricCADB
    81  	// The crypto service provider (BCCSP)
    82  	csp bccsp.BCCSP
    83  	// The certificate DB accessor
    84  	certDBAccessor *CertDBAccessor
    85  	// The user registry
    86  	registry cadbuser.Registry
    87  	// The signer used for enrollment
    88  	enrollSigner signer.Signer
    89  	// Idemix issuer
    90  	issuer idemix.Issuer
    91  	// The options to use in verifying a signature in token-based authentication
    92  	verifyOptions *x509.VerifyOptions
    93  	// The attribute manager
    94  	attrMgr *attrmgr.Mgr
    95  	// The server hosting this CA
    96  	server *Server
    97  	// DB levels
    98  	levels *dbutil.Levels
    99  	// CA mutex
   100  	mutex sync.Mutex
   101  }
   102  
   103  const (
   104  	certificateError = "Invalid certificate in file"
   105  )
   106  
   107  // newCA creates a new CA with the specified
   108  // home directory, parent server URL, and config
   109  func newCA(caFile string, config *CAConfig, server *Server, renew bool) (*CA, error) {
   110  	ca := new(CA)
   111  	ca.ConfigFilePath = caFile
   112  	err := initCA(ca, filepath.Dir(caFile), config, server, renew)
   113  	if err != nil {
   114  		err2 := ca.closeDB()
   115  		if err2 != nil {
   116  			zclog.Errorf("Close DB failed: %s", err2)
   117  		}
   118  		return nil, err
   119  	}
   120  	return ca, nil
   121  }
   122  
   123  // initCA will initialize the passed in pointer to a CA struct
   124  func initCA(ca *CA, homeDir string, config *CAConfig, server *Server, renew bool) error {
   125  	ca.HomeDir = homeDir
   126  	ca.Config = config
   127  	ca.server = server
   128  
   129  	err := ca.init(renew)
   130  	if err != nil {
   131  		return err
   132  	}
   133  	zclog.Debug("Initializing Idemix issuer...")
   134  	ca.issuer = idemix.NewIssuer(ca.Config.CA.Name, ca.HomeDir,
   135  		&ca.Config.Idemix, ca.csp, idemix.NewLib())
   136  	err = ca.issuer.Init(renew, ca.db, ca.levels)
   137  	if err != nil {
   138  		return errors.WithMessage(err, fmt.Sprintf("Failed to initialize Idemix issuer for CA '%s'", err.Error()))
   139  	}
   140  	return nil
   141  }
   142  
   143  // Init initializes an instance of a CA
   144  func (ca *CA) init(renew bool) (err error) {
   145  	zclog.Debugf("Init CA with home %s and config %+v", ca.HomeDir, *ca.Config)
   146  
   147  	// Initialize the config, setting defaults, etc
   148  	// zclog.Info("===== ca.Config.CSP.ProviderName = ", ca.Config.CSP.ProviderName)
   149  	SetProviderName(ca.Config.CSP.ProviderName)
   150  	err = ca.initConfig()
   151  	if err != nil {
   152  		return err
   153  	}
   154  
   155  	// Initialize the crypto layer (BCCSP) for this CA
   156  	ca.csp, err = util.InitBCCSP(&ca.Config.CSP, "", ca.HomeDir)
   157  	if err != nil {
   158  		return err
   159  	}
   160  
   161  	// Initialize key materials
   162  	err = ca.initKeyMaterial(renew)
   163  	if err != nil {
   164  		return err
   165  	}
   166  
   167  	// Initialize the database
   168  	err = ca.initDB(ca.server.dbMetrics)
   169  	if err != nil {
   170  		zclog.Error("Error occurred initializing database: ", err)
   171  		// Return if a server configuration error encountered (e.g. Invalid max enrollment for a bootstrap user)
   172  		if caerrors.IsFatalError(err) {
   173  			return err
   174  		}
   175  	}
   176  	// Initialize the enrollment signer
   177  	err = ca.initEnrollmentSigner()
   178  	if err != nil {
   179  		return err
   180  	}
   181  	// Create the attribute manager
   182  	ca.attrMgr = attrmgr.New()
   183  	zclog.Debug("CA initialization successful")
   184  	// Successful initialization
   185  	return nil
   186  }
   187  
   188  // Initialize the CA's key material
   189  // 初始化 CA 的密钥材料
   190  func (ca *CA) initKeyMaterial(renew bool) error {
   191  	zclog.Debug("===== Initialize key material")
   192  
   193  	// Make the path names absolute in the config
   194  	err := ca.makeFileNamesAbsolute()
   195  	if err != nil {
   196  		return err
   197  	}
   198  
   199  	keyFile := ca.Config.CA.Keyfile
   200  	certFile := ca.Config.CA.Certfile
   201  
   202  	// If we aren't renewing and the key and cert files exist, do nothing
   203  	if !renew {
   204  		// If they both exist, the CA was already initialized
   205  		keyFileExists := util.FileExists(keyFile)
   206  		certFileExists := util.FileExists(certFile)
   207  		if keyFileExists && certFileExists {
   208  			zclog.Info("The CA key and certificate files already exist")
   209  			zclog.Infof("Key file location: %s", keyFile)
   210  			zclog.Infof("Certificate file location: %s", certFile)
   211  			err = ca.validateCertAndKey(certFile, keyFile)
   212  			if err != nil {
   213  				return errors.WithMessage(err, "Validation of certificate and key failed")
   214  			}
   215  			// Load CN from existing enrollment information and set CSR accordingly
   216  			// CN needs to be set, having a multi CA setup requires a unique CN and can't
   217  			// be left blank
   218  			ca.Config.CSR.CN, err = ca.loadCNFromEnrollmentInfo(certFile)
   219  			if err != nil {
   220  				return err
   221  			}
   222  			return nil
   223  		}
   224  
   225  		// If key file does not exist but certFile does, key file is probably
   226  		// stored by BCCSP, so check for that now.
   227  		if certFileExists {
   228  			_, _, _, err = util.GetSignerFromCertFile(certFile, ca.csp)
   229  			if err != nil {
   230  				return errors.WithMessage(err, fmt.Sprintf("Failed to find private key for certificate in '%s'", certFile))
   231  			}
   232  			// Yes, it is stored by BCCSP
   233  			zclog.Info("The CA key and certificate already exist")
   234  			zclog.Infof("The key is stored by BCCSP provider '%s'", ca.Config.CSP.ProviderName)
   235  			zclog.Infof("The certificate is at: %s", certFile)
   236  			// Load CN from existing enrollment information and set CSR accordingly
   237  			// CN needs to be set, having a multi CA setup requires a unique CN and can't
   238  			// be left blank
   239  			ca.Config.CSR.CN, err = ca.loadCNFromEnrollmentInfo(certFile)
   240  			if err != nil {
   241  				return errors.WithMessage(err, fmt.Sprintf("Failed to get CN for certificate in '%s'", certFile))
   242  			}
   243  			return nil
   244  		}
   245  		zclog.Warn(caerrors.NewServerError(caerrors.ErrCACertFileNotFound, "The specified CA certificate file %s does not exist", certFile))
   246  	}
   247  
   248  	// 获取CA根证书
   249  	cert, err := ca.getCACert()
   250  	if err != nil {
   251  		return err
   252  	}
   253  	// Store the certificate to file
   254  	err = writeFile(certFile, cert, 0644)
   255  	if err != nil {
   256  		return errors.Wrap(err, "Failed to store certificate")
   257  	}
   258  	zclog.Infof("===== The CA key and certificate were generated for CA %s", ca.Config.CA.Name)
   259  	zclog.Infof("===== The key was stored by BCCSP provider '%s'", ca.Config.CSP.ProviderName)
   260  	zclog.Infof("===== The certificate is at: %s", certFile)
   261  
   262  	return nil
   263  }
   264  
   265  // Get the CA certificate for this CA
   266  func (ca *CA) getCACert() (cert []byte, err error) {
   267  	if ca.Config.Intermediate.ParentServer.URL != "" {
   268  		// This is an intermediate CA, so call the parent fabric-ca-server
   269  		// to get the cert
   270  		zclog.Debugf("===== CA配置有父证书 parent server URL is %s", util.GetMaskedURL(ca.Config.Intermediate.ParentServer.URL))
   271  		clientCfg := ca.Config.Client
   272  		if clientCfg == nil {
   273  			clientCfg = &ClientConfig{}
   274  		}
   275  		// Copy over the intermediate configuration into client configuration
   276  		clientCfg.TLS = ca.Config.Intermediate.TLS
   277  		clientCfg.Enrollment = ca.Config.Intermediate.Enrollment
   278  		clientCfg.CAName = ca.Config.Intermediate.ParentServer.CAName
   279  		clientCfg.CSP = ca.Config.CSP
   280  		clientCfg.CSR = ca.Config.CSR
   281  		clientCfg.CSP = ca.Config.CSP
   282  		if ca.Config.CSR.CN != "" {
   283  			return nil, errors.Errorf("CN '%s' cannot be specified for an intermediate CA. Remove CN from CSR section for enrollment of intermediate CA to be successful", ca.Config.CSR.CN)
   284  		}
   285  		if clientCfg.Enrollment.Profile == "" {
   286  			clientCfg.Enrollment.Profile = "ca"
   287  		}
   288  		if clientCfg.Enrollment.CSR == nil {
   289  			clientCfg.Enrollment.CSR = &api.CSRInfo{}
   290  		}
   291  		if clientCfg.Enrollment.CSR.CA == nil {
   292  			clientCfg.Enrollment.CSR.CA = &cfcsr.CAConfig{PathLength: 0, PathLenZero: true}
   293  		}
   294  		zclog.Debugf("Intermediate enrollment request: %+v, CSR: %+v, CA: %+v",
   295  			clientCfg.Enrollment, clientCfg.Enrollment.CSR, clientCfg.Enrollment.CSR.CA)
   296  		var resp *EnrollmentResponse
   297  		resp, err = clientCfg.Enroll(ca.Config.Intermediate.ParentServer.URL, ca.HomeDir)
   298  		if err != nil {
   299  			return nil, err
   300  		}
   301  		// Set the CN for an intermediate server to be the ID used to enroll with root CA
   302  		ca.Config.CSR.CN = resp.Identity.GetName()
   303  		ecert := resp.Identity.GetECert()
   304  		if ecert == nil {
   305  			return nil, errors.New("No enrollment certificate returned by parent server")
   306  		}
   307  		cert = ecert.Cert()
   308  		// Store the chain file as the concatenation of the parent's chain plus the cert.
   309  		chainPath := ca.Config.CA.Chainfile
   310  		chain, err := ca.concatChain(resp.CAInfo.CAChain, cert)
   311  		if err != nil {
   312  			return nil, err
   313  		}
   314  		err = os.MkdirAll(path.Dir(chainPath), 0755)
   315  		if err != nil {
   316  			return nil, errors.Wrap(err, "Failed to create intermediate chain file directory")
   317  		}
   318  		err = util.WriteFile(chainPath, chain, 0644)
   319  		if err != nil {
   320  			return nil, errors.WithMessage(err, "Failed to create intermediate chain file")
   321  		}
   322  		zclog.Debugf("Stored intermediate certificate chain at %s", chainPath)
   323  	} else {
   324  		zclog.Debug("===== CA没有配置父证书 需要生成自签名的CA根证书")
   325  		// This is a root CA, so create a CSR (Certificate Signing Request)
   326  		if ca.Config.CSR.CN == "" {
   327  			ca.Config.CSR.CN = "fabric-ca-server"
   328  		}
   329  		csr := &ca.Config.CSR
   330  		if csr.CA == nil {
   331  			csr.CA = &cfcsr.CAConfig{}
   332  		}
   333  		if csr.CA.Expiry == "" {
   334  			csr.CA.Expiry = defaultRootCACertificateExpiration
   335  		}
   336  
   337  		if (csr.KeyRequest == nil) || (csr.KeyRequest.Algo == "" && csr.KeyRequest.Size == 0) {
   338  			// TODO 目前强制使用国密
   339  			// if IsGMConfig() {
   340  			// 	csr.KeyRequest = GetGMKeyRequest(ca.Config)
   341  			// } else {
   342  			// 	csr.KeyRequest = GetKeyRequest(ca.Config)
   343  			// }
   344  			csr.KeyRequest = GetGMKeyRequest(ca.Config)
   345  		}
   346  		req := cfcsr.CertificateRequest{
   347  			CN:           csr.CN,
   348  			Names:        csr.Names,
   349  			Hosts:        csr.Hosts,
   350  			KeyRequest:   &cfcsr.KeyRequest{A: csr.KeyRequest.Algo, S: csr.KeyRequest.Size},
   351  			CA:           csr.CA,
   352  			SerialNumber: csr.SerialNumber,
   353  		}
   354  		zclog.Debugf("Root CA certificate request: %+v", req)
   355  		// Generate the key/signer
   356  		_, cspSigner, err := util.BCCSPKeyRequestGenerate(&req, ca.csp)
   357  		if err != nil {
   358  			return nil, err
   359  		}
   360  		// 生成自签名的CA根证书
   361  		cert, _, err = initca.NewFromSigner(&req, cspSigner)
   362  		if err != nil {
   363  			return nil, errors.WithMessage(err, "Failed to create new CA certificate")
   364  		}
   365  	}
   366  	return cert, nil
   367  }
   368  
   369  // Return a certificate chain which is the concatenation of chain and cert
   370  func (ca *CA) concatChain(chain []byte, cert []byte) ([]byte, error) {
   371  	result := make([]byte, len(chain)+len(cert))
   372  	parentFirst, ok := os.LookupEnv(CAChainParentFirstEnvVar)
   373  	parentFirstBool := false
   374  	// If CA_CHAIN_PARENT_FIRST env variable is set then get the boolean
   375  	// value
   376  	if ok {
   377  		var err error
   378  		parentFirstBool, err = strconv.ParseBool(parentFirst)
   379  		if err != nil {
   380  			return nil, errors.Wrapf(err, "failed to parse the environment variable '%s'", CAChainParentFirstEnvVar)
   381  		}
   382  	}
   383  	if parentFirstBool {
   384  		copy(result[:len(chain)], chain)
   385  		copy(result[len(chain):], cert)
   386  	} else {
   387  		copy(result[:len(cert)], cert)
   388  		copy(result[len(cert):], chain)
   389  	}
   390  	return result, nil
   391  }
   392  
   393  // Get the certificate chain for the CA
   394  func (ca *CA) getCAChain() (chain []byte, err error) {
   395  	if ca.Config == nil {
   396  		return nil, errors.New("The server has no configuration")
   397  	}
   398  	certAuth := &ca.Config.CA
   399  	// If the chain file exists, we always return the chain from here
   400  	if util.FileExists(certAuth.Chainfile) {
   401  		return util.ReadFile(certAuth.Chainfile)
   402  	}
   403  	// Otherwise, if this is a root CA, we always return the contents of the CACertfile
   404  	if ca.Config.Intermediate.ParentServer.URL == "" {
   405  		return util.ReadFile(certAuth.Certfile)
   406  	}
   407  	// If this is an intermediate CA but the ca.Chainfile doesn't exist,
   408  	// it is an error.  It should have been created during intermediate CA enrollment.
   409  	return nil, errors.Errorf("Chain file does not exist at %s", certAuth.Chainfile)
   410  }
   411  
   412  // Initialize the configuration for the CA setting any defaults and making filenames absolute
   413  func (ca *CA) initConfig() (err error) {
   414  	// Init home directory if not set
   415  	if ca.HomeDir == "" {
   416  		ca.HomeDir, err = os.Getwd()
   417  		if err != nil {
   418  			return errors.Wrap(err, "Failed to initialize CA's home directory")
   419  		}
   420  	}
   421  	zclog.Debugf("CA Home Directory: %s", ca.HomeDir)
   422  	// Init config if not set
   423  	if ca.Config == nil {
   424  		ca.Config = new(CAConfig)
   425  		ca.Config.Registry.MaxEnrollments = -1
   426  	}
   427  	// Set config defaults
   428  	cfg := ca.Config
   429  	if cfg.Version == "" {
   430  		cfg.Version = "0"
   431  	}
   432  	if cfg.CA.Certfile == "" {
   433  		cfg.CA.Certfile = "ca-cert.pem"
   434  	}
   435  	if cfg.CA.Keyfile == "" {
   436  		cfg.CA.Keyfile = "ca-key.pem"
   437  	}
   438  	if cfg.CA.Chainfile == "" {
   439  		cfg.CA.Chainfile = "ca-chain.pem"
   440  	}
   441  	if cfg.CSR.CA == nil {
   442  		cfg.CSR.CA = &cfcsr.CAConfig{}
   443  	}
   444  	if cfg.CSR.CA.Expiry == "" {
   445  		cfg.CSR.CA.Expiry = defaultRootCACertificateExpiration
   446  	}
   447  	if cfg.Signing == nil {
   448  		cfg.Signing = &config.Signing{}
   449  	}
   450  	cs := cfg.Signing
   451  	if cs.Profiles == nil {
   452  		cs.Profiles = make(map[string]*config.SigningProfile)
   453  	}
   454  	caProfile := cs.Profiles["ca"]
   455  	initSigningProfile(&caProfile,
   456  		defaultIntermediateCACertificateExpiration,
   457  		true)
   458  	cs.Profiles["ca"] = caProfile
   459  	initSigningProfile(
   460  		&cs.Default,
   461  		defaultIssuedCertificateExpiration,
   462  		false)
   463  	tlsProfile := cs.Profiles["tls"]
   464  	initSigningProfile(&tlsProfile,
   465  		defaultIssuedCertificateExpiration,
   466  		false)
   467  	cs.Profiles["tls"] = tlsProfile
   468  	err = ca.checkConfigLevels()
   469  	if err != nil {
   470  		return err
   471  	}
   472  	// Set log level if debug is true
   473  	// if ca.server != nil && ca.server.Config != nil && ca.server.Config.Debug {
   474  	// 	log.Level = log.LevelDebug
   475  	// }
   476  	ca.normalizeStringSlices()
   477  
   478  	return nil
   479  }
   480  
   481  // 获取国密证书的检查配置
   482  func getVerifyOptions(ca *CA) (*x509.VerifyOptions, error) {
   483  	chain, err := ca.getCAChain()
   484  	if err != nil {
   485  		return nil, err
   486  	}
   487  	block, rest := pem.Decode(chain)
   488  	if block == nil {
   489  		return nil, errors.New("No root certificate was found")
   490  	}
   491  	rootCert, err := x509.ParseCertificate(block.Bytes)
   492  	if err != nil {
   493  		return nil, errors.Errorf("Failed to parse root certificate: %s", err)
   494  	}
   495  	rootPool := x509.NewCertPool()
   496  	rootPool.AddCert(rootCert)
   497  	var intPool *x509.CertPool
   498  	if len(rest) > 0 {
   499  		intPool = x509.NewCertPool()
   500  		if !intPool.AppendCertsFromPEM(rest) {
   501  			return nil, errors.New("Failed to add intermediate PEM certificates")
   502  		}
   503  	}
   504  	return &x509.VerifyOptions{
   505  		Roots:         rootPool,
   506  		Intermediates: intPool,
   507  		KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
   508  	}, nil
   509  }
   510  
   511  // 检查目标证书cert是否是由ca签署的。
   512  // VerifyCertificate verifies that 'cert' was issued by this CA
   513  // Return nil if successful; otherwise, return an error.
   514  // 'forceTime' if false, certificate expiry times will be checked based
   515  // on the current time.
   516  // if true, it will force the time to be used to check for expiry to be 30 seconds
   517  // after the certificate start time.  (this is to support reenrollIgnoreCertExpiry)
   518  func (ca *CA) VerifyCertificate(cert *x509.Certificate, forceTime bool) error {
   519  	// zclog.Debugf("===== Certicate Dates: NotAfter = %s NotBefore = %s \n", cert.NotAfter.Format(time.RFC3339), cert.NotBefore.Format(time.RFC3339))
   520  	// 从CA配置获取检查参数
   521  	opts, err := getVerifyOptions(ca)
   522  	// opts, err := ca.getVerifyOptions()
   523  	if err != nil {
   524  		return errors.WithMessage(err, "Failed to get verify options")
   525  	}
   526  	// force check time to be 30 seconds after certificate start time to ensure expiry doesn't get flagged
   527  	// this is one of the checks that is made on the certificate in Verify()
   528  	if forceTime {
   529  		opts.CurrentTime = cert.NotBefore.Add(time.Duration(time.Second * 30))
   530  	}
   531  	// 尝试从ca的根证书构建cert的信任链,成功则说明cert是由ca直接或间接签署的。
   532  	// 目前应该都是直接签署的。即证书信任链长度只有2。
   533  	_, err = cert.Verify(*opts)
   534  	if err != nil {
   535  		return errors.WithMessage(err, "Failed to verify certificate")
   536  	}
   537  	return nil
   538  }
   539  
   540  // Get the options to verify
   541  func (ca *CA) getVerifyOptions() (*x509.VerifyOptions, error) {
   542  	if ca.verifyOptions != nil {
   543  		return ca.verifyOptions, nil
   544  	}
   545  	chain, err := ca.getCAChain()
   546  	if err != nil {
   547  		return nil, err
   548  	}
   549  	var intPool *x509.CertPool
   550  	var rootPool *x509.CertPool
   551  
   552  	for len(chain) > 0 {
   553  		var block *pem.Block
   554  		block, chain = pem.Decode(chain)
   555  		if block == nil {
   556  			break
   557  		}
   558  		if block.Type != "CERTIFICATE" {
   559  			continue
   560  		}
   561  
   562  		cert, err := x509.ParseCertificate(block.Bytes)
   563  		if err != nil {
   564  			return nil, errors.Wrap(err, "Failed to parse CA chain certificate")
   565  		}
   566  
   567  		if !cert.IsCA {
   568  			return nil, errors.New("A certificate in the CA chain is not a CA certificate")
   569  		}
   570  
   571  		// If authority key id is not present or if it is present and equal to subject key id,
   572  		// then it is a root certificate
   573  		if len(cert.AuthorityKeyId) == 0 || bytes.Equal(cert.AuthorityKeyId, cert.SubjectKeyId) {
   574  			if rootPool == nil {
   575  				rootPool = x509.NewCertPool()
   576  			}
   577  			rootPool.AddCert(cert)
   578  		} else {
   579  			if intPool == nil {
   580  				intPool = x509.NewCertPool()
   581  			}
   582  			intPool.AddCert(cert)
   583  		}
   584  	}
   585  
   586  	ca.verifyOptions = &x509.VerifyOptions{
   587  		Roots:         rootPool,
   588  		Intermediates: intPool,
   589  		KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
   590  	}
   591  	return ca.verifyOptions, nil
   592  }
   593  
   594  // Initialize the database for the CA
   595  func (ca *CA) initDB(metrics *db.Metrics) error {
   596  	zclog.Debug("Initializing DB")
   597  
   598  	// If DB is initialized, don't need to proceed further
   599  	if ca.db != nil && ca.db.IsInitialized() {
   600  		return nil
   601  	}
   602  
   603  	ca.mutex.Lock()
   604  	defer ca.mutex.Unlock()
   605  
   606  	// After obtaining a lock, check again to see if DB got initialized by another process
   607  	if ca.db != nil && ca.db.IsInitialized() {
   608  		return nil
   609  	}
   610  
   611  	dbCfg := &ca.Config.DB
   612  	dbError := false
   613  	var err error
   614  
   615  	if dbCfg.Type == "" || dbCfg.Type == defaultDatabaseType {
   616  
   617  		dbCfg.Type = defaultDatabaseType
   618  
   619  		if dbCfg.Datasource == "" {
   620  			dbCfg.Datasource = "fabric-ca-server.db"
   621  		}
   622  
   623  		dbCfg.Datasource, err = util.MakeFileAbs(dbCfg.Datasource, ca.HomeDir)
   624  		if err != nil {
   625  			return err
   626  		}
   627  	}
   628  
   629  	// Strip out user:pass from datasource for logging
   630  	ds := dbCfg.Datasource
   631  	ds = dbutil.MaskDBCred(ds)
   632  
   633  	zclog.Debugf("Initializing '%s' database at '%s'", dbCfg.Type, ds)
   634  	caDB, err := cadbfactory.New(
   635  		dbCfg.Type,
   636  		dbCfg.Datasource,
   637  		ca.Config.CA.Name,
   638  		&dbCfg.TLS,
   639  		ca.csp,
   640  		metrics,
   641  	)
   642  	if err != nil {
   643  		return err
   644  	}
   645  	err = caDB.Connect()
   646  	if err != nil {
   647  		return err
   648  	}
   649  	sqlxdb, err := caDB.Create()
   650  	if err != nil {
   651  		return err
   652  	}
   653  
   654  	sqlxdb.Metrics = metrics
   655  
   656  	ca.db = sqlxdb
   657  	// Set the certificate DB accessor
   658  	ca.certDBAccessor = NewCertDBAccessor(ca.db, ca.levels.Certificate)
   659  
   660  	// If DB initialization fails and we need to reinitialize DB, need to make sure to set the DB accessor for the signer
   661  	if ca.enrollSigner != nil {
   662  		ca.enrollSigner.SetDBAccessor(ca.certDBAccessor)
   663  	}
   664  
   665  	// Initialize user registry to either use DB or LDAP
   666  	err = ca.initUserRegistry()
   667  	if err != nil {
   668  		return err
   669  	}
   670  
   671  	err = ca.checkDBLevels()
   672  	if err != nil {
   673  		return err
   674  	}
   675  
   676  	// Migrate the database
   677  	curLevels, err := db.CurrentDBLevels(ca.db)
   678  	if err != nil {
   679  		return errors.Wrap(err, "Failed to current ca levels")
   680  	}
   681  	migrator, err := getMigrator(ca.db.DriverName(), ca.db.BeginTx(), curLevels, ca.server.levels)
   682  	if err != nil {
   683  		return errors.Wrap(err, "Failed to get migrator")
   684  	}
   685  	err = db.Migrate(migrator, curLevels, ca.server.levels)
   686  	if err != nil {
   687  		return errors.Wrap(err, "Failed to migrate database")
   688  	}
   689  
   690  	// If not using LDAP, migrate database if needed to latest version and load the users and affiliations table
   691  	if !ca.Config.LDAP.Enabled {
   692  		err = ca.loadUsersTable()
   693  		if err != nil {
   694  			zclog.Error(err)
   695  			dbError = true
   696  			if caerrors.IsFatalError(err) {
   697  				return err
   698  			}
   699  		}
   700  
   701  		err = ca.loadAffiliationsTable()
   702  		if err != nil {
   703  			zclog.Error(err)
   704  			dbError = true
   705  		}
   706  	}
   707  
   708  	if dbError {
   709  		return errors.Errorf("Failed to initialize %s database at %s ", dbCfg.Type, ds)
   710  	}
   711  
   712  	ca.db.SetDBInitialized(true)
   713  	zclog.Infof("Initialized %s database at %s", dbCfg.Type, ds)
   714  
   715  	return nil
   716  }
   717  
   718  // Close CA's DB
   719  func (ca *CA) closeDB() error {
   720  	if ca.db != nil {
   721  		err := ca.db.Close()
   722  		ca.db = nil
   723  		if err != nil {
   724  			return errors.Wrapf(err, "Failed to close CA database, where CA home directory is '%s'", ca.HomeDir)
   725  		}
   726  	}
   727  	return nil
   728  }
   729  
   730  // Initialize the user registry interface
   731  func (ca *CA) initUserRegistry() error {
   732  	zclog.Debug("Initializing identity registry")
   733  	var err error
   734  	ldapCfg := &ca.Config.LDAP
   735  
   736  	if ldapCfg.Enabled {
   737  		// Use LDAP for the user registry
   738  		ca.registry, err = ldap.NewClient(ldapCfg, ca.server.csp)
   739  		zclog.Debugf("Initialized LDAP identity registry; err=%s", err)
   740  		if err == nil {
   741  			zclog.Info("Successfully initialized LDAP client")
   742  		} else {
   743  			zclog.Warnf("Failed to initialize LDAP client; err=%s", err)
   744  		}
   745  		return err
   746  	}
   747  
   748  	// Use the DB for the user registry
   749  	ca.registry = NewDBAccessor(ca.db)
   750  	zclog.Debug("Initialized DB identity registry")
   751  	return nil
   752  }
   753  
   754  // Initialize the enrollment signer
   755  func (ca *CA) initEnrollmentSigner() (err error) {
   756  	zclog.Debug("Initializing enrollment signer")
   757  	c := ca.Config
   758  
   759  	// If there is a config, use its signing policy. Otherwise create a default policy.
   760  	var policy *config.Signing
   761  	if c.Signing != nil {
   762  		policy = c.Signing
   763  	} else {
   764  		policy = &config.Signing{
   765  			Profiles: map[string]*config.SigningProfile{},
   766  			Default:  config.DefaultConfig(),
   767  		}
   768  		policy.Default.CAConstraint.IsCA = true
   769  	}
   770  
   771  	// Make sure the policy reflects the new remote
   772  	parentServerURL := ca.Config.Intermediate.ParentServer.URL
   773  	if parentServerURL != "" {
   774  		err = policy.OverrideRemotes(parentServerURL)
   775  		if err != nil {
   776  			return errors.Wrap(err, "Failed initializing enrollment signer")
   777  		}
   778  	}
   779  
   780  	ca.enrollSigner, err = util.BccspBackedSigner(c.CA.Certfile, c.CA.Keyfile, policy, ca.csp)
   781  	if err != nil {
   782  		return err
   783  	}
   784  	ca.enrollSigner.SetDBAccessor(ca.certDBAccessor)
   785  
   786  	// Successful enrollment
   787  	return nil
   788  }
   789  
   790  // loadUsersTable adds the configured users to the table if not already found
   791  func (ca *CA) loadUsersTable() error {
   792  	zclog.Debug("Loading identity table")
   793  	registry := &ca.Config.Registry
   794  	for _, id := range registry.Identities {
   795  		zclog.Debugf("Loading identity '%s'", id.Name)
   796  		err := ca.addIdentity(&id, false)
   797  		if err != nil {
   798  			return errors.WithMessage(err, "Failed to load identity table")
   799  		}
   800  	}
   801  	zclog.Debug("Successfully loaded identity table")
   802  	return nil
   803  }
   804  
   805  // loadAffiliationsTable adds the configured affiliations to the table
   806  func (ca *CA) loadAffiliationsTable() error {
   807  	zclog.Debug("Loading affiliations table")
   808  	err := ca.loadAffiliationsTableR(ca.Config.Affiliations, "")
   809  	if err != nil {
   810  		return errors.WithMessage(err, "Failed to load affiliations table")
   811  	}
   812  	zclog.Debug("Successfully loaded affiliations table")
   813  	return nil
   814  }
   815  
   816  // Recursive function to load the affiliations table hierarchy
   817  func (ca *CA) loadAffiliationsTableR(val interface{}, parentPath string) (err error) {
   818  	var path string
   819  	if val == nil {
   820  		return nil
   821  	}
   822  	switch val := val.(type) {
   823  	case string:
   824  		path = affiliationPath(val, parentPath)
   825  		err = ca.addAffiliation(path, parentPath)
   826  		if err != nil {
   827  			return err
   828  		}
   829  	case []string:
   830  		for _, ele := range val {
   831  			err = ca.loadAffiliationsTableR(ele, parentPath)
   832  			if err != nil {
   833  				return err
   834  			}
   835  		}
   836  	case []interface{}:
   837  		for _, ele := range val {
   838  			err = ca.loadAffiliationsTableR(ele, parentPath)
   839  			if err != nil {
   840  				return err
   841  			}
   842  		}
   843  	default:
   844  		for name, ele := range val.(map[string]interface{}) {
   845  			path = affiliationPath(name, parentPath)
   846  			err = ca.addAffiliation(path, parentPath)
   847  			if err != nil {
   848  				return err
   849  			}
   850  			err = ca.loadAffiliationsTableR(ele, path)
   851  			if err != nil {
   852  				return err
   853  			}
   854  		}
   855  	}
   856  	return nil
   857  }
   858  
   859  // Add an identity to the registry
   860  func (ca *CA) addIdentity(id *CAConfigIdentity, errIfFound bool) error {
   861  	var err error
   862  	user, _ := ca.registry.GetUser(id.Name, nil)
   863  	if user != nil {
   864  		if errIfFound {
   865  			return errors.Errorf("Identity '%s' is already registered", id.Name)
   866  		}
   867  		zclog.Debugf("Identity '%s' already registered, loaded identity", user.GetName())
   868  		return nil
   869  	}
   870  
   871  	id.MaxEnrollments, err = getMaxEnrollments(id.MaxEnrollments, ca.Config.Registry.MaxEnrollments)
   872  	if err != nil {
   873  		return caerrors.NewFatalError(caerrors.ErrConfig, "Configuration Error: %s", err)
   874  	}
   875  
   876  	attrs, err := attr.ConvertAttrs(id.Attrs)
   877  
   878  	if err != nil {
   879  		return err
   880  	}
   881  
   882  	rec := cadbuser.Info{
   883  		Name:           id.Name,
   884  		Pass:           id.Pass,
   885  		Type:           id.Type,
   886  		Affiliation:    id.Affiliation,
   887  		Attributes:     attrs,
   888  		MaxEnrollments: id.MaxEnrollments,
   889  		Level:          ca.levels.Identity,
   890  	}
   891  	err = ca.registry.InsertUser(&rec)
   892  	if err != nil {
   893  		return errors.WithMessage(err, fmt.Sprintf("Failed to insert identity '%s'", id.Name))
   894  	}
   895  	zclog.Debugf("Registered identity: %+v", id)
   896  	return nil
   897  }
   898  
   899  func (ca *CA) addAffiliation(path, parentPath string) error {
   900  	return ca.registry.InsertAffiliation(path, parentPath, ca.levels.Affiliation)
   901  }
   902  
   903  // CertDBAccessor returns the certificate DB accessor for CA
   904  func (ca *CA) CertDBAccessor() *CertDBAccessor {
   905  	return ca.certDBAccessor
   906  }
   907  
   908  // DBAccessor returns the registry DB accessor for server
   909  func (ca *CA) DBAccessor() cadbuser.Registry {
   910  	return ca.registry
   911  }
   912  
   913  // GetDB returns pointer to database
   914  func (ca *CA) GetDB() db.FabricCADB {
   915  	return ca.db
   916  }
   917  
   918  // GetCertificate returns a single certificate matching serial and aki, if multiple certificates
   919  // found for serial and aki an error is returned
   920  func (ca *CA) GetCertificate(serial, aki string) (*certdb.CertificateRecord, error) {
   921  	certs, err := ca.CertDBAccessor().GetCertificate(serial, aki)
   922  	if err != nil {
   923  		return nil, err
   924  	}
   925  	if len(certs) == 0 {
   926  		return nil, caerrors.NewAuthenticationErr(caerrors.ErrCertNotFound, "Certificate not found with AKI '%s' and serial '%s'", aki, serial)
   927  	}
   928  	if len(certs) > 1 {
   929  		return nil, caerrors.NewAuthenticationErr(caerrors.ErrCertNotFound, "Multiple certificates found, when only should exist with AKI '%s' and serial '%s' combination", aki, serial)
   930  	}
   931  	return &certs[0], nil
   932  }
   933  
   934  // Make all file names in the CA config absolute
   935  func (ca *CA) makeFileNamesAbsolute() error {
   936  	zclog.Debug("Making CA filenames absolute")
   937  
   938  	fields := []*string{
   939  		&ca.Config.CA.Certfile,
   940  		&ca.Config.CA.Keyfile,
   941  		&ca.Config.CA.Chainfile,
   942  	}
   943  	err := util.MakeFileNamesAbsolute(fields, ca.HomeDir)
   944  	if err != nil {
   945  		return err
   946  	}
   947  	err = tls.AbsTLSClient(&ca.Config.DB.TLS, ca.HomeDir)
   948  	if err != nil {
   949  		return err
   950  	}
   951  	err = tls.AbsTLSClient(&ca.Config.LDAP.TLS, ca.HomeDir)
   952  	if err != nil {
   953  		return err
   954  	}
   955  	return nil
   956  }
   957  
   958  // Convert all comma separated strings to string arrays
   959  func (ca *CA) normalizeStringSlices() {
   960  	fields := []*[]string{
   961  		&ca.Config.CSR.Hosts,
   962  		&ca.Config.DB.TLS.CertFiles,
   963  		&ca.Config.LDAP.TLS.CertFiles,
   964  	}
   965  	for _, namePtr := range fields {
   966  		norm := util.NormalizeStringSlice(*namePtr)
   967  		*namePtr = norm
   968  	}
   969  }
   970  
   971  // userHasAttribute returns nil error and the value of the attribute
   972  // if the user has the attribute, or an appropriate error if the user
   973  // does not have this attribute.
   974  func (ca *CA) userHasAttribute(username, attrname string) (string, error) {
   975  	val, err := ca.getUserAttrValue(username, attrname)
   976  	if err != nil {
   977  		return "", err
   978  	}
   979  	if val == "" {
   980  		return "", errors.Errorf("Identity '%s' does not have attribute '%s'", username, attrname)
   981  	}
   982  	return val, nil
   983  }
   984  
   985  // attributeIsTrue returns nil if the attribute has
   986  // one of the following values: "1", "t", "T", "true", "TRUE", "True";
   987  // otherwise it will return an error
   988  func (ca *CA) attributeIsTrue(username, attrname string) error {
   989  	val, err := ca.userHasAttribute(username, attrname)
   990  	if err != nil {
   991  		return err
   992  	}
   993  	val2, err := strconv.ParseBool(val)
   994  	if err != nil {
   995  		return errors.Wrapf(err, "Invalid value for attribute '%s' of identity '%s'", attrname, username)
   996  	}
   997  	if val2 {
   998  		return nil
   999  	}
  1000  	return errors.Errorf("Attribute '%s' is not set to true for identity '%s'", attrname, username)
  1001  }
  1002  
  1003  // getUserAttrValue returns a user's value for an attribute
  1004  func (ca *CA) getUserAttrValue(username, attrname string) (string, error) {
  1005  	zclog.Debugf("getUserAttrValue identity=%s, attr=%s", username, attrname)
  1006  	userFromCaDB, err := ca.registry.GetUser(username, []string{attrname})
  1007  	if err != nil {
  1008  		return "", err
  1009  	}
  1010  	attrval, err := userFromCaDB.GetAttribute(attrname)
  1011  	if err != nil {
  1012  		return "", errors.WithMessage(err, fmt.Sprintf("Failed to get attribute '%s' for user '%s'", attrname, userFromCaDB.GetName()))
  1013  	}
  1014  	zclog.Debugf("getUserAttrValue identity=%s, name=%s, value=%s", username, attrname, attrval)
  1015  	return attrval.Value, nil
  1016  }
  1017  
  1018  // getUserAffiliation returns a user's affiliation
  1019  func (ca *CA) getUserAffiliation(username string) (string, error) {
  1020  	zclog.Debugf("getUserAffiliation identity=%s", username)
  1021  	user, err := ca.registry.GetUser(username, nil)
  1022  	if err != nil {
  1023  		return "", err
  1024  	}
  1025  	aff := cadbuser.GetAffiliation(user)
  1026  	zclog.Debugf("getUserAffiliation identity=%s, aff=%s", username, aff)
  1027  	return aff, nil
  1028  }
  1029  
  1030  // fillCAInfo fills the CA info structure appropriately
  1031  func (ca *CA) fillCAInfo(info *api.CAInfoResponseNet) error {
  1032  	caChain, err := ca.getCAChain()
  1033  	if err != nil {
  1034  		return err
  1035  	}
  1036  	info.CAName = ca.Config.CA.Name
  1037  	info.CAChain = util.B64Encode(caChain)
  1038  
  1039  	ipkBytes, err := ca.issuer.IssuerPublicKey()
  1040  	if err != nil {
  1041  		return err
  1042  	}
  1043  	rpkBytes, err := ca.issuer.RevocationPublicKey()
  1044  	if err != nil {
  1045  		return err
  1046  	}
  1047  	info.IssuerPublicKey = util.B64Encode(ipkBytes)
  1048  	info.IssuerRevocationPublicKey = util.B64Encode(rpkBytes)
  1049  	return nil
  1050  }
  1051  
  1052  // Performs checks on the provided CA cert to make sure it's valid
  1053  func (ca *CA) validateCertAndKey(certFile string, keyFile string) error {
  1054  	zclog.Debug("Validating the CA certificate and key")
  1055  	var err error
  1056  	var certPEM []byte
  1057  
  1058  	certPEM, err = ioutil.ReadFile(certFile)
  1059  	if err != nil {
  1060  		return errors.Wrapf(err, certificateError+" '%s'", certFile)
  1061  	}
  1062  
  1063  	cert, err := util.GetX509CertificateFromPEM(certPEM)
  1064  	if err != nil {
  1065  		return errors.WithMessage(err, fmt.Sprintf(certificateError+" '%s'", certFile))
  1066  	}
  1067  
  1068  	if err = validateDates(cert); err != nil {
  1069  		return errors.WithMessage(err, fmt.Sprintf(certificateError+" '%s'", certFile))
  1070  	}
  1071  	if err = validateUsage(cert, ca.Config.CA.Name); err != nil {
  1072  		return errors.WithMessage(err, fmt.Sprintf(certificateError+" '%s'", certFile))
  1073  	}
  1074  	if err = validateIsCA(cert); err != nil {
  1075  		return errors.WithMessage(err, fmt.Sprintf(certificateError+" '%s'", certFile))
  1076  	}
  1077  	if err = validateKeyType(cert); err != nil {
  1078  		return errors.WithMessage(err, fmt.Sprintf(certificateError+" '%s'", certFile))
  1079  	}
  1080  	if err = validateKeySize(cert); err != nil {
  1081  		return errors.WithMessage(err, fmt.Sprintf(certificateError+" '%s'", certFile))
  1082  	}
  1083  	if err = validateMatchingKeys(cert, keyFile); err != nil {
  1084  		return errors.WithMessage(err, fmt.Sprintf("Invalid certificate and/or key in files '%s' and '%s'", certFile, keyFile))
  1085  	}
  1086  	zclog.Debug("Validation of CA certificate and key successful")
  1087  
  1088  	return nil
  1089  }
  1090  
  1091  // Returns expiration of the CA certificate
  1092  func (ca *CA) getCACertExpiry() (time.Time, time.Time, error) {
  1093  	var notAfter time.Time
  1094  	var notBefore time.Time
  1095  	signer, ok := ca.enrollSigner.(*cflocalsigner.Signer)
  1096  	if ok {
  1097  		cacert, err := signer.Certificate("", "ca")
  1098  		if err != nil {
  1099  			zclog.Errorf("Failed to get CA certificate for CA %s: %s", ca.Config.CA.Name, err)
  1100  			return notBefore, notAfter, err
  1101  		} else if cacert != nil {
  1102  			notAfter = cacert.NotAfter
  1103  			notBefore = cacert.NotBefore
  1104  		}
  1105  	} else {
  1106  		zclog.Errorf("Not expected condition as the enrollSigner can only be cfssl/signer/local/Signer")
  1107  		return notBefore, notAfter, errors.New("Unexpected error while getting CA certificate expiration")
  1108  	}
  1109  	return notBefore, notAfter, nil
  1110  }
  1111  
  1112  func canSignCRL(cert *x509.Certificate) bool {
  1113  	return cert.KeyUsage&x509.KeyUsageCRLSign != 0
  1114  }
  1115  
  1116  func validateDates(cert *x509.Certificate) error {
  1117  	zclog.Debug("Check CA certificate for valid dates")
  1118  
  1119  	notAfter := cert.NotAfter
  1120  	currentTime := time.Now().UTC()
  1121  
  1122  	if currentTime.After(notAfter) {
  1123  		return errors.New("Certificate provided has expired")
  1124  	}
  1125  
  1126  	notBefore := cert.NotBefore
  1127  	if currentTime.Before(notBefore) {
  1128  		return errors.New("Certificate provided not valid until later date")
  1129  	}
  1130  
  1131  	return nil
  1132  }
  1133  
  1134  func validateUsage(cert *x509.Certificate, caName string) error {
  1135  	zclog.Debug("Check CA certificate for valid usages")
  1136  
  1137  	if cert.KeyUsage == 0 {
  1138  		return errors.New("No usage specified for certificate")
  1139  	}
  1140  
  1141  	if cert.KeyUsage&x509.KeyUsageCertSign == 0 {
  1142  		return errors.New("The 'cert sign' key usage is required")
  1143  	}
  1144  
  1145  	if !canSignCRL(cert) {
  1146  		zclog.Warnf("The CA certificate for the CA '%s' does not have 'crl sign' key usage, so the CA will not be able generate a CRL", caName)
  1147  	}
  1148  	return nil
  1149  }
  1150  
  1151  func validateIsCA(cert *x509.Certificate) error {
  1152  	zclog.Debug("Check CA certificate for valid IsCA value")
  1153  
  1154  	if !cert.IsCA {
  1155  		return errors.New("Certificate not configured to be used for CA")
  1156  	}
  1157  
  1158  	return nil
  1159  }
  1160  
  1161  // 国密改造后只支持sm2
  1162  func validateKeyType(cert *x509.Certificate) error {
  1163  	zclog.Debug("Check that key type is supported")
  1164  
  1165  	switch cert.PublicKey.(type) {
  1166  	case *sm2.PublicKey:
  1167  		return nil
  1168  	default:
  1169  		return errors.New("Unsupported key type: not sm2")
  1170  	}
  1171  }
  1172  
  1173  func validateKeySize(cert *x509.Certificate) error {
  1174  	zclog.Debug("Check that key size is of appropriate length")
  1175  
  1176  	switch cert.PublicKey.(type) {
  1177  	// case *rsa.PublicKey:
  1178  	// 	size := cert.PublicKey.(*rsa.PublicKey).N.BitLen()
  1179  	// 	if size < 2048 {
  1180  	// 		return errors.New("Key size is less than 2048 bits")
  1181  	// 	}
  1182  	case *sm2.PublicKey:
  1183  		size := cert.PublicKey.(*sm2.PublicKey).Params().N.BitLen()
  1184  		if size != 256 {
  1185  			return errors.New("Key size must be 256 bits")
  1186  		}
  1187  	}
  1188  
  1189  	return nil
  1190  }
  1191  
  1192  // 国密对应后只支持sm2
  1193  func validateMatchingKeys(cert *x509.Certificate, keyFile string) error {
  1194  	zclog.Debug("Check that public key and private key match")
  1195  
  1196  	keyPEM, err := ioutil.ReadFile(keyFile)
  1197  	if err != nil {
  1198  		return err
  1199  	}
  1200  
  1201  	pubKey := cert.PublicKey
  1202  	switch pubKey := pubKey.(type) {
  1203  	// TODO 添加sm2分支
  1204  	case *sm2.PublicKey:
  1205  		privKey, err := util.GetSM2PrivateKey(keyPEM)
  1206  		if err != nil {
  1207  			return err
  1208  		}
  1209  		if pubKey.X.Cmp(privKey.X) != 0 || pubKey.Y.Cmp(privKey.Y) != 0 {
  1210  			return errors.New("sm2 private key does not match public key")
  1211  		}
  1212  	// case *rsa.PublicKey:
  1213  	// 	privKey, err := util.GetRSAPrivateKey(keyPEM)
  1214  	// 	if err != nil {
  1215  	// 		return err
  1216  	// 	}
  1217  
  1218  	// 	if privKey.PublicKey.N.Cmp(pubKey.N) != 0 {
  1219  	// 		return errors.New("Public key and private key do not match")
  1220  	// 	}
  1221  	// case *ecdsa.PublicKey:
  1222  	// 	// pub, _ := cert.PublicKey.(*ecdsa.PublicKey)
  1223  	// 	// TODO 这里的分支可能不需要了
  1224  	// 	switch pubKey.Curve {
  1225  	// 	case sm2.P256Sm2():
  1226  	// 		privKey, err := util.GetSM2PrivateKey(keyPEM)
  1227  	// 		if err != nil {
  1228  	// 			return err
  1229  	// 		}
  1230  	// 		if pubKey.X.Cmp(privKey.X) != 0 || pubKey.Y.Cmp(privKey.Y) != 0 {
  1231  	// 			return errors.New("sm2 private key does not match public key")
  1232  	// 		}
  1233  	// 	default:
  1234  	// 		privKey, err := util.GetECPrivateKey(keyPEM)
  1235  	// 		if err != nil {
  1236  	// 			return err
  1237  	// 		}
  1238  
  1239  	// 		if privKey.PublicKey.X.Cmp(pubKey.X) != 0 {
  1240  	// 			return errors.New("Public key and private key do not match")
  1241  	// 		}
  1242  	// 	}
  1243  	default:
  1244  		return errors.New("Unsupported public key")
  1245  	}
  1246  
  1247  	return nil
  1248  }
  1249  
  1250  // Load CN from existing enrollment information
  1251  func (ca *CA) loadCNFromEnrollmentInfo(certFile string) (string, error) {
  1252  	zclog.Debug("Loading CN from existing enrollment information")
  1253  	cert, err := util.ReadFile(certFile)
  1254  	if err != nil {
  1255  		zclog.Debugf("No cert found at %s", certFile)
  1256  		return "", err
  1257  	}
  1258  	name, err := util.GetEnrollmentIDFromPEM(cert)
  1259  	if err != nil {
  1260  		return "", err
  1261  	}
  1262  	return name, nil
  1263  }
  1264  
  1265  // This function returns an error if the version specified in the configuration file is greater than the server version
  1266  func (ca *CA) checkConfigLevels() error {
  1267  	var err error
  1268  	serverVersion := metadata.GetVersion()
  1269  	configVersion := ca.Config.Version
  1270  	zclog.Debugf("Checking configuration file version '%+v' against server version: '%+v'", configVersion, serverVersion)
  1271  	// Check configuration file version against server version to make sure that newer configuration file is not being used with server
  1272  	cmp, err := metadata.CmpVersion(configVersion, serverVersion)
  1273  	if err != nil {
  1274  		return errors.WithMessage(err, "Failed to compare version")
  1275  	}
  1276  	if cmp == -1 {
  1277  		return errors.Errorf("Configuration file version '%s' is higher than server version '%s'", configVersion, serverVersion)
  1278  	}
  1279  	cfg, err := metadata.GetLevels(ca.Config.Version)
  1280  	if err != nil {
  1281  		return err
  1282  	}
  1283  	ca.levels = cfg
  1284  	return nil
  1285  }
  1286  
  1287  func (ca *CA) checkDBLevels() error {
  1288  	// Check database table levels against server levels to make sure that a database levels are compatible with server
  1289  	levels, err := db.CurrentDBLevels(ca.db)
  1290  	if err != nil {
  1291  		return err
  1292  	}
  1293  	sl, err := metadata.GetLevels(metadata.GetVersion())
  1294  	if err != nil {
  1295  		return err
  1296  	}
  1297  	zclog.Debugf("Checking database levels '%+v' against server levels '%+v'", levels, sl)
  1298  	if (levels.Identity > sl.Identity) || (levels.Affiliation > sl.Affiliation) || (levels.Certificate > sl.Certificate) ||
  1299  		(levels.Credential > sl.Credential) || (levels.Nonce > sl.Nonce) || (levels.RAInfo > sl.RAInfo) {
  1300  		return caerrors.NewFatalError(caerrors.ErrDBLevel, "The version of the database is newer than the server version.  Upgrade your server.")
  1301  	}
  1302  	return nil
  1303  }
  1304  
  1305  func writeFile(file string, buf []byte, perm os.FileMode) error {
  1306  	err := os.MkdirAll(filepath.Dir(file), 0755)
  1307  	if err != nil {
  1308  		return err
  1309  	}
  1310  	return ioutil.WriteFile(file, buf, perm)
  1311  }
  1312  
  1313  func affiliationPath(name, parent string) string {
  1314  	if parent == "" {
  1315  		return name
  1316  	}
  1317  	return fmt.Sprintf("%s.%s", parent, name)
  1318  }
  1319  
  1320  func parseDuration(str string) time.Duration {
  1321  	d, err := time.ParseDuration(str)
  1322  	if err != nil {
  1323  		panic(err)
  1324  	}
  1325  	return d
  1326  }
  1327  
  1328  func initSigningProfile(spp **config.SigningProfile, expiry time.Duration, isCA bool) {
  1329  	sp := *spp
  1330  	if sp == nil {
  1331  		sp = &config.SigningProfile{CAConstraint: config.CAConstraint{IsCA: isCA}}
  1332  		*spp = sp
  1333  	}
  1334  	if sp.Usage == nil {
  1335  		sp.Usage = []string{"cert sign", "crl sign"}
  1336  	}
  1337  	if sp.Expiry == 0 {
  1338  		sp.Expiry = expiry
  1339  	}
  1340  	if sp.ExtensionWhitelist == nil {
  1341  		sp.ExtensionWhitelist = map[string]bool{}
  1342  	}
  1343  	// This is set so that all profiles permit an attribute extension in CFSSL
  1344  	sp.ExtensionWhitelist[attrmgr.AttrOIDString] = true
  1345  }
  1346  
  1347  func getMigrator(driverName string, tx db.FabricCATx, curLevels, srvLevels *dbutil.Levels) (db.Migrator, error) {
  1348  	var migrator db.Migrator
  1349  	switch driverName {
  1350  	case "sqlite3":
  1351  		migrator = sqlite.NewMigrator(tx, curLevels, srvLevels)
  1352  	case "mysql":
  1353  		migrator = mysql.NewMigrator(tx, curLevels, srvLevels)
  1354  	case "postgres":
  1355  		migrator = postgres.NewMigrator(tx, curLevels, srvLevels)
  1356  	default:
  1357  		return nil, errors.Errorf("Unsupported database type: %s", driverName)
  1358  	}
  1359  	return migrator, nil
  1360  }