github.com/silveraid/fabric-ca@v1.1.0-preview.0.20180127000700-71974f53ab08/cmd/fabric-ca-server/config.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "io/ioutil" 21 "os" 22 "path/filepath" 23 "strings" 24 25 "github.com/pkg/errors" 26 27 "github.com/cloudflare/cfssl/log" 28 "github.com/hyperledger/fabric-ca/lib" 29 "github.com/hyperledger/fabric-ca/lib/metadata" 30 "github.com/hyperledger/fabric-ca/util" 31 ) 32 33 const ( 34 longName = "Hyperledger Fabric Certificate Authority Server" 35 shortName = "fabric-ca server" 36 cmdName = "fabric-ca-server" 37 envVarPrefix = "FABRIC_CA_SERVER" 38 homeEnvVar = "FABRIC_CA_SERVER_HOME" 39 caNameReqMsg = "ca.name property is required but is missing from the configuration file" 40 ) 41 42 const ( 43 defaultCfgTemplate = `############################################################################# 44 # This is a configuration file for the fabric-ca-server command. 45 # 46 # COMMAND LINE ARGUMENTS AND ENVIRONMENT VARIABLES 47 # ------------------------------------------------ 48 # Each configuration element can be overridden via command line 49 # arguments or environment variables. The precedence for determining 50 # the value of each element is as follows: 51 # 1) command line argument 52 # Examples: 53 # a) --port 443 54 # To set the listening port 55 # b) --ca-keyfile ../mykey.pem 56 # To set the "keyfile" element in the "ca" section below; 57 # note the '-' separator character. 58 # 2) environment variable 59 # Examples: 60 # a) FABRIC_CA_SERVER_PORT=443 61 # To set the listening port 62 # b) FABRIC_CA_SERVER_CA_KEYFILE="../mykey.pem" 63 # To set the "keyfile" element in the "ca" section below; 64 # note the '_' separator character. 65 # 3) configuration file 66 # 4) default value (if there is one) 67 # All default values are shown beside each element below. 68 # 69 # FILE NAME ELEMENTS 70 # ------------------ 71 # The value of all fields whose name ends with "file" or "files" are 72 # name or names of other files. 73 # For example, see "tls.certfile" and "tls.clientauth.certfiles". 74 # The value of each of these fields can be a simple filename, a 75 # relative path, or an absolute path. If the value is not an 76 # absolute path, it is interpretted as being relative to the location 77 # of this configuration file. 78 # 79 ############################################################################# 80 81 # Version of config file 82 version: <<<VERSION>>> 83 84 # Server's listening port (default: 7054) 85 port: 7054 86 87 # Enables debug logging (default: false) 88 debug: false 89 90 # Size limit of an acceptable CRL in bytes (default: 512000) 91 crlsizelimit: 512000 92 93 ############################################################################# 94 # TLS section for the server's listening port 95 # 96 # The following types are supported for client authentication: NoClientCert, 97 # RequestClientCert, RequireAnyClientCert, VerifyClientCertIfGiven, 98 # and RequireAndVerifyClientCert. 99 # 100 # Certfiles is a list of root certificate authorities that the server uses 101 # when verifying client certificates. 102 ############################################################################# 103 tls: 104 # Enable TLS (default: false) 105 enabled: false 106 # TLS for the server's listening port 107 certfile: 108 keyfile: 109 clientauth: 110 type: noclientcert 111 certfiles: 112 113 ############################################################################# 114 # The CA section contains information related to the Certificate Authority 115 # including the name of the CA, which should be unique for all members 116 # of a blockchain network. It also includes the key and certificate files 117 # used when issuing enrollment certificates (ECerts) and transaction 118 # certificates (TCerts). 119 # The chainfile (if it exists) contains the certificate chain which 120 # should be trusted for this CA, where the 1st in the chain is always the 121 # root CA certificate. 122 ############################################################################# 123 ca: 124 # Name of this CA 125 name: 126 # Key file (is only used to import a private key into BCCSP) 127 keyfile: 128 # Certificate file (default: ca-cert.pem) 129 certfile: 130 # Chain file 131 chainfile: 132 133 ############################################################################# 134 # The gencrl REST endpoint is used to generate a CRL that contains revoked 135 # certificates. This section contains configuration options that are used 136 # during gencrl request processing. 137 ############################################################################# 138 crl: 139 # Specifies expiration for the generated CRL. The number of hours 140 # specified by this property is added to the UTC time, the resulting time 141 # is used to set the 'Next Update' date of the CRL. 142 expiry: 24h 143 144 ############################################################################# 145 # The registry section controls how the fabric-ca-server does two things: 146 # 1) authenticates enrollment requests which contain a username and password 147 # (also known as an enrollment ID and secret). 148 # 2) once authenticated, retrieves the identity's attribute names and 149 # values which the fabric-ca-server optionally puts into TCerts 150 # which it issues for transacting on the Hyperledger Fabric blockchain. 151 # These attributes are useful for making access control decisions in 152 # chaincode. 153 # There are two main configuration options: 154 # 1) The fabric-ca-server is the registry. 155 # This is true if "ldap.enabled" in the ldap section below is false. 156 # 2) An LDAP server is the registry, in which case the fabric-ca-server 157 # calls the LDAP server to perform these tasks. 158 # This is true if "ldap.enabled" in the ldap section below is true, 159 # which means this "registry" section is ignored. 160 ############################################################################# 161 registry: 162 # Maximum number of times a password/secret can be reused for enrollment 163 # (default: -1, which means there is no limit) 164 maxenrollments: -1 165 166 # Contains identity information which is used when LDAP is disabled 167 identities: 168 - name: <<<ADMIN>>> 169 pass: <<<ADMINPW>>> 170 type: client 171 affiliation: "" 172 attrs: 173 hf.Registrar.Roles: "peer,orderer,client,user" 174 hf.Registrar.DelegateRoles: "peer,orderer,client,user" 175 hf.Revoker: true 176 hf.IntermediateCA: true 177 hf.GenCRL: true 178 hf.Registrar.Attributes: "*" 179 hf.AffiliationMgr: true 180 181 ############################################################################# 182 # Database section 183 # Supported types are: "sqlite3", "postgres", and "mysql". 184 # The datasource value depends on the type. 185 # If the type is "sqlite3", the datasource value is a file name to use 186 # as the database store. Since "sqlite3" is an embedded database, it 187 # may not be used if you want to run the fabric-ca-server in a cluster. 188 # To run the fabric-ca-server in a cluster, you must choose "postgres" 189 # or "mysql". 190 ############################################################################# 191 db: 192 type: sqlite3 193 datasource: fabric-ca-server.db 194 tls: 195 enabled: false 196 certfiles: 197 client: 198 certfile: 199 keyfile: 200 201 ############################################################################# 202 # LDAP section 203 # If LDAP is enabled, the fabric-ca-server calls LDAP to: 204 # 1) authenticate enrollment ID and secret (i.e. username and password) 205 # for enrollment requests; 206 # 2) To retrieve identity attributes 207 ############################################################################# 208 ldap: 209 # Enables or disables the LDAP client (default: false) 210 # If this is set to true, the "registry" section is ignored. 211 enabled: false 212 # The URL of the LDAP server 213 url: ldap://<adminDN>:<adminPassword>@<host>:<port>/<base> 214 # TLS configuration for the client connection to the LDAP server 215 tls: 216 certfiles: 217 client: 218 certfile: 219 keyfile: 220 # Attribute related configuration for mapping from LDAP entries to Fabric CA attributes 221 attribute: 222 # 'names' is an array of strings containing the LDAP attribute names which are 223 # requested from the LDAP server for an LDAP identity's entry 224 names: ['uid','member'] 225 # The 'converters' section is used to convert an LDAP entry to the value of 226 # a fabric CA attribute. 227 # For example, the following converts an LDAP 'uid' attribute 228 # whose value begins with 'revoker' to a fabric CA attribute 229 # named "hf.Revoker" with a value of "true" (because the boolean expression 230 # evaluates to true). 231 # converters: 232 # - name: hf.Revoker 233 # value: attr("uid") =~ "revoker*" 234 converters: 235 - name: 236 value: 237 # The 'maps' section contains named maps which may be referenced by the 'map' 238 # function in the 'converters' section to map LDAP responses to arbitrary values. 239 # For example, assume a user has an LDAP attribute named 'member' which has multiple 240 # values which are each a distinguished name (i.e. a DN). For simplicity, assume the 241 # values of the 'member' attribute are 'dn1', 'dn2', and 'dn3'. 242 # Further assume the following configuration. 243 # converters: 244 # - name: hf.Registrar.Roles 245 # value: map(attr("member"),"groups") 246 # maps: 247 # groups: 248 # - name: dn1 249 # value: peer 250 # - name: dn2 251 # value: client 252 # The value of the user's 'hf.Registrar.Roles' attribute is then computed to be 253 # "peer,client,dn3". This is because the value of 'attr("member")' is 254 # "dn1,dn2,dn3", and the call to 'map' with a 2nd argument of 255 # "group" replaces "dn1" with "peer" and "dn2" with "client". 256 maps: 257 groups: 258 - name: 259 value: 260 261 ############################################################################# 262 # Affiliation section 263 ############################################################################# 264 affiliations: 265 org1: 266 - department1 267 - department2 268 org2: 269 - department1 270 271 ############################################################################# 272 # Signing section 273 # 274 # The "default" subsection is used to sign enrollment certificates; 275 # the default expiration ("expiry" field) is "8760h", which is 1 year in hours. 276 # 277 # The "ca" profile subsection is used to sign intermediate CA certificates; 278 # the default expiration ("expiry" field) is "43800h" which is 5 years in hours. 279 # Note that "isca" is true, meaning that it issues a CA certificate. 280 # A maxpathlen of 0 means that the intermediate CA cannot issue other 281 # intermediate CA certificates, though it can still issue end entity certificates. 282 # (See RFC 5280, section 4.2.1.9) 283 # 284 # The "tls" profile subsection is used to sign TLS certificate requests; 285 # the default expiration ("expiry" field) is "8760h", which is 1 year in hours. 286 ############################################################################# 287 signing: 288 default: 289 usage: 290 - digital signature 291 expiry: 8760h 292 profiles: 293 ca: 294 usage: 295 - cert sign 296 - crl sign 297 expiry: 43800h 298 caconstraint: 299 isca: true 300 maxpathlen: 0 301 tls: 302 usage: 303 - signing 304 - key encipherment 305 - server auth 306 - client auth 307 - key agreement 308 expiry: 8760h 309 310 ########################################################################### 311 # Certificate Signing Request (CSR) section. 312 # This controls the creation of the root CA certificate. 313 # The expiration for the root CA certificate is configured with the 314 # "ca.expiry" field below, whose default value is "131400h" which is 315 # 15 years in hours. 316 # The pathlength field is used to limit CA certificate hierarchy as described 317 # in section 4.2.1.9 of RFC 5280. 318 # Examples: 319 # 1) No pathlength value means no limit is requested. 320 # 2) pathlength == 1 means a limit of 1 is requested which is the default for 321 # a root CA. This means the root CA can issue intermediate CA certificates, 322 # but these intermediate CAs may not in turn issue other CA certificates 323 # though they can still issue end entity certificates. 324 # 3) pathlength == 0 means a limit of 0 is requested; 325 # this is the default for an intermediate CA, which means it can not issue 326 # CA certificates though it can still issue end entity certificates. 327 ########################################################################### 328 csr: 329 cn: <<<COMMONNAME>>> 330 names: 331 - C: US 332 ST: "North Carolina" 333 L: 334 O: Hyperledger 335 OU: Fabric 336 hosts: 337 - <<<MYHOST>>> 338 - localhost 339 ca: 340 expiry: 131400h 341 pathlength: <<<PATHLENGTH>>> 342 343 ############################################################################# 344 # BCCSP (BlockChain Crypto Service Provider) section is used to select which 345 # crypto library implementation to use 346 ############################################################################# 347 bccsp: 348 default: SW 349 sw: 350 hash: SHA2 351 security: 256 352 filekeystore: 353 # The directory used for the software file-based keystore 354 keystore: msp/keystore 355 356 ############################################################################# 357 # Multi CA section 358 # 359 # Each Fabric CA server contains one CA by default. This section is used 360 # to configure multiple CAs in a single server. 361 # 362 # 1) --cacount <number-of-CAs> 363 # Automatically generate <number-of-CAs> non-default CAs. The names of these 364 # additional CAs are "ca1", "ca2", ... "caN", where "N" is <number-of-CAs> 365 # This is particularly useful in a development environment to quickly set up 366 # multiple CAs. 367 # 368 # 2) --cafiles <CA-config-files> 369 # For each CA config file in the list, generate a separate signing CA. Each CA 370 # config file in this list MAY contain all of the same elements as are found in 371 # the server config file except port, debug, and tls sections. 372 # 373 # Examples: 374 # fabric-ca-server start -b admin:adminpw --cacount 2 375 # 376 # fabric-ca-server start -b admin:adminpw --cafiles ca/ca1/fabric-ca-server-config.yaml 377 # --cafiles ca/ca2/fabric-ca-server-config.yaml 378 # 379 ############################################################################# 380 381 cacount: 382 383 cafiles: 384 385 ############################################################################# 386 # Intermediate CA section 387 # 388 # The relationship between servers and CAs is as follows: 389 # 1) A single server process may contain or function as one or more CAs. 390 # This is configured by the "Multi CA section" above. 391 # 2) Each CA is either a root CA or an intermediate CA. 392 # 3) Each intermediate CA has a parent CA which is either a root CA or another intermediate CA. 393 # 394 # This section pertains to configuration of #2 and #3. 395 # If the "intermediate.parentserver.url" property is set, 396 # then this is an intermediate CA with the specified parent 397 # CA. 398 # 399 # parentserver section 400 # url - The URL of the parent server 401 # caname - Name of the CA to enroll within the server 402 # 403 # enrollment section used to enroll intermediate CA with parent CA 404 # profile - Name of the signing profile to use in issuing the certificate 405 # label - Label to use in HSM operations 406 # 407 # tls section for secure socket connection 408 # certfiles - PEM-encoded list of trusted root certificate files 409 # client: 410 # certfile - PEM-encoded certificate file for when client authentication 411 # is enabled on server 412 # keyfile - PEM-encoded key file for when client authentication 413 # is enabled on server 414 ############################################################################# 415 intermediate: 416 parentserver: 417 url: 418 caname: 419 420 enrollment: 421 hosts: 422 profile: 423 label: 424 425 tls: 426 certfiles: 427 client: 428 certfile: 429 keyfile: 430 ` 431 ) 432 433 var ( 434 extraArgsError = "Unrecognized arguments found: %v\n\n%s" 435 ) 436 437 // Initialize config 438 func (s *ServerCmd) configInit() (err error) { 439 if !s.configRequired() { 440 return nil 441 } 442 443 s.cfgFileName, s.homeDirectory, err = util.ValidateAndReturnAbsConf(s.cfgFileName, s.homeDirectory, cmdName) 444 if err != nil { 445 return err 446 } 447 448 log.Debugf("Home directory: %s", s.homeDirectory) 449 450 // If the config file doesn't exist, create a default one 451 if !util.FileExists(s.cfgFileName) { 452 err = s.createDefaultConfigFile() 453 if err != nil { 454 return errors.WithMessage(err, "Failed to create default configuration file") 455 } 456 log.Infof("Created default configuration file at %s", s.cfgFileName) 457 } else { 458 log.Infof("Configuration file location: %s", s.cfgFileName) 459 } 460 461 // Read the config 462 s.myViper.AutomaticEnv() // read in environment variables that match 463 err = lib.UnmarshalConfig(s.cfg, s.myViper, s.cfgFileName, true) 464 if err != nil { 465 return err 466 } 467 468 // The pathlength field controls how deep the CA hierarchy when requesting 469 // certificates. If it is explicitly set to 0, set the PathLenZero field to 470 // true as CFSSL expects. 471 pl := "csr.ca.pathlength" 472 if s.myViper.IsSet(pl) && s.myViper.GetInt(pl) == 0 { 473 s.cfg.CAcfg.CSR.CA.PathLenZero = true 474 } 475 // The maxpathlen field controls how deep the CA hierarchy when issuing 476 // a CA certificate. If it is explicitly set to 0, set the PathLenZero 477 // field to true as CFSSL expects. 478 pl = "signing.profiles.ca.caconstraint.maxpathlen" 479 if s.myViper.IsSet(pl) && s.myViper.GetInt(pl) == 0 { 480 s.cfg.CAcfg.Signing.Profiles["ca"].CAConstraint.MaxPathLenZero = true 481 } 482 483 return nil 484 } 485 486 func (s *ServerCmd) createDefaultConfigFile() error { 487 var user, pass string 488 // If LDAP is enabled, authentication of enrollment requests are performed 489 // by using LDAP authentication; therefore, no bootstrap username and password 490 // are required. 491 ldapEnabled := s.myViper.GetBool("ldap.enabled") 492 if !ldapEnabled { 493 // When LDAP is disabled, the fabric-ca-server functions as its own 494 // identity registry; therefore, we require that the default configuration 495 // file have a bootstrap username and password that is used to enroll a 496 // bootstrap administrator. Other identities can be dynamically registered. 497 // Create the default config, but only if they provided this bootstrap 498 // username and password. 499 up := s.myViper.GetString("boot") 500 if up == "" { 501 return errors.New("The '-b user:pass' option is required") 502 } 503 ups := strings.Split(up, ":") 504 if len(ups) < 2 { 505 return errors.Errorf("The value '%s' on the command line is missing a colon separator", up) 506 } 507 if len(ups) > 2 { 508 ups = []string{ups[0], strings.Join(ups[1:], ":")} 509 } 510 user = ups[0] 511 pass = ups[1] 512 if len(user) >= 1024 { 513 return errors.Errorf("The identity name must be less than 1024 characters: '%s'", user) 514 } 515 if len(pass) == 0 { 516 return errors.New("An empty password in the '-b user:pass' option is not permitted") 517 } 518 } 519 520 var myhost string 521 var err error 522 myhost, err = os.Hostname() 523 if err != nil { 524 return err 525 } 526 527 // Do string subtitution to get the default config 528 cfg := strings.Replace(defaultCfgTemplate, "<<<VERSION>>>", metadata.Version, 1) 529 cfg = strings.Replace(cfg, "<<<ADMIN>>>", user, 1) 530 cfg = strings.Replace(cfg, "<<<ADMINPW>>>", pass, 1) 531 cfg = strings.Replace(cfg, "<<<MYHOST>>>", myhost, 1) 532 purl := s.myViper.GetString("intermediate.parentserver.url") 533 log.Debugf("parent server URL: '%s'", purl) 534 if purl == "" { 535 // This is a root CA 536 cfg = strings.Replace(cfg, "<<<COMMONNAME>>>", "fabric-ca-server", 1) 537 cfg = strings.Replace(cfg, "<<<PATHLENGTH>>>", "1", 1) 538 } else { 539 // This is an intermediate CA 540 cfg = strings.Replace(cfg, "<<<COMMONNAME>>>", "", 1) 541 cfg = strings.Replace(cfg, "<<<PATHLENGTH>>>", "0", 1) 542 } 543 544 // Now write the file 545 cfgDir := filepath.Dir(s.cfgFileName) 546 err = os.MkdirAll(cfgDir, 0755) 547 if err != nil { 548 return err 549 } 550 551 // Now write the file 552 return ioutil.WriteFile(s.cfgFileName, []byte(cfg), 0644) 553 }