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