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