Skip to content

Commit

Permalink
[FAB-3228] Fix/clarify CA pathlen constraints
Browse files Browse the repository at this point in the history
The name of the pathlen fields were wrong in the default config
file.  This change set corrects the field names and adds documentation
to the generated config file and the user's guide to describe the values.
It also adds a test case which shows that by default a root CA allows
intermediate CAs to be enrolled, but enrolling an intermediate CA
with an intermediate CA will fail (by default).

The pathlen constraints of a CA allow the depth of a CA hierarchy
to be limited.  The CA hierarchy refers to the root CA having
child intermediate CAs which can in turn have child intermediate CAs.

Change-Id: I1ed202946a738ae49e91a94cca312c0b393d2325
Signed-off-by: Keith Smith <[email protected]>
  • Loading branch information
Keith Smith committed Jun 3, 2017
1 parent 07f1a83 commit 22dc710
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 44 deletions.
51 changes: 45 additions & 6 deletions cmd/fabric-ca-server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ registry:
affiliation: ""
maxenrollments: -1
attrs:
hf.Registrar.Roles: "client,user,peer,validator,auditor,ca"
hf.Registrar.Roles: "client,user,peer,validator,auditor"
hf.Registrar.DelegateRoles: "client,user,validator,auditor"
hf.Revoker: true
hf.IntermediateCA: true
Expand Down Expand Up @@ -215,6 +215,9 @@ affiliations:
# The "ca" profile subsection is used to sign intermediate CA certificates;
# the default expiration ("expiry" field) is "43800h" which is 5 years in hours.
# Note that "isca" is true, meaning that it issues a CA certificate.
# A maxpathlen of 0 means that the intermediate CA cannot issue other
# intermediate CA certificates, though it can still issue end entity certificates.
# (See RFC 5280, section 4.2.1.9)
#############################################################################
signing:
default:
Expand All @@ -228,16 +231,28 @@ signing:
expiry: 43800h
caconstraint:
isca: true
maxpathlen: 0
###########################################################################
# Certificate Signing Request (CSR) section.
# This controls the creation of the root CA certificate.
# The expiration for the root CA certificate is configured with the
# "ca.expiry" field below, whose default value is "131400h" which is
# 15 years in hours.
# The pathlength field is used to limit CA certificate hierarchy as described
# in section 4.2.1.9 of RFC 5280.
# Examples:
# 1) No pathlength value means no limit is requested.
# 2) pathlength == 1 means a limit of 1 is requested which is the default for
# a root CA. This means the root CA can issue intermediate CA certificates,
# but these intermediate CAs may not in turn issue other CA certificates
# though they can still issue end entity certificates.
# 3) pathlength == 0 means a limit of 0 is requested;
# this is the default for an intermediate CA, which means it can not issue
# CA certificates though it can still issue end entity certificates.
###########################################################################
csr:
cn: fabric-ca-server
cn: <<<COMMONNAME>>>
names:
- C: US
ST: "North Carolina"
Expand All @@ -248,15 +263,13 @@ csr:
- <<<MYHOST>>>
- localhost
ca:
pathlen:
pathlenzero:
expiry: 131400h
pathlength: <<<PATHLENGTH>>>
#############################################################################
# BCCSP (BlockChain Crypto Service Provider) section is used to select which
# crypto library implementation to use
#############################################################################
bccsp:
default: SW
sw:
Expand All @@ -282,7 +295,7 @@ bccsp:
# For each CA config file in the list, generate a separate signing CA. Each CA
# config file in this list MAY contain all of the same elements as are found in
# the server config file except port, debug, and tls sections.
#
#
# Examples:
# fabric-ca-server start -b admin:adminpw --cacount 2
#
Expand Down Expand Up @@ -379,6 +392,21 @@ func configInit() (err error) {
return err
}

// The pathlength field controls how deep the CA hierarchy when requesting
// certificates. If it is explicitly set to 0, set the PathLenZero field to
// true as CFSSL expects.
pl := "csr.ca.pathlength"
if viper.IsSet(pl) && viper.GetInt(pl) == 0 {
serverCfg.CAcfg.CSR.CA.PathLenZero = true
}
// The maxpathlen field controls how deep the CA hierarchy when issuing
// a CA certificate. If it is explicitly set to 0, set the PathLenZero
// field to true as CFSSL expects.
pl = "signing.profiles.ca.caconstraint.maxpathlen"
if viper.IsSet(pl) && viper.GetInt(pl) == 0 {
serverCfg.CAcfg.Signing.Profiles["ca"].CAConstraint.MaxPathLenZero = true
}

return nil
}

Expand Down Expand Up @@ -416,6 +444,17 @@ func createDefaultConfigFile() error {
cfg := strings.Replace(defaultCfgTemplate, "<<<ADMIN>>>", user, 1)
cfg = strings.Replace(cfg, "<<<ADMINPW>>>", pass, 1)
cfg = strings.Replace(cfg, "<<<MYHOST>>>", myhost, 1)
purl := viper.GetString("intermediate.parentserver.url")
log.Debugf("parent server URL: '%s'", purl)
if purl == "" {
// This is a root CA
cfg = strings.Replace(cfg, "<<<COMMONNAME>>>", "fabric-ca-server", 1)
cfg = strings.Replace(cfg, "<<<PATHLENGTH>>>", "1", 1)
} else {
// This is an intermediate CA
cfg = strings.Replace(cfg, "<<<COMMONNAME>>>", "", 1)
cfg = strings.Replace(cfg, "<<<PATHLENGTH>>>", "0", 1)
}

// Now write the file
cfgDir := filepath.Dir(cfgFileName)
Expand Down
124 changes: 86 additions & 38 deletions docs/source/users-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -299,36 +299,56 @@ the server's home directory (see `Fabric CA Server <#server>`__ section more inf

#############################################################################
# TLS section for the server's listening port
#
# The following types are supported for client authentication: NoClientCert,
# RequestClientCert, RequireAnyClientCert, VerfiyClientCertIfGiven,
# and RequireAndVerifyClientCert.
#
# Certfiles is a list of root certificate authorities that the server uses
# when verifying client certificates.
#############################################################################
tls:
# Enable TLS (default: false)
enabled: false
# TLS for the server's listening port
certfile: ca-cert.pem
keyfile: ca-key.pem
clientauth:
type: noclientcert
certfiles:

#############################################################################
# The CA section contains the key and certificate files used when
# issuing enrollment certificates (ECerts) and transaction
# The CA section contains information related to the Certificate Authority
# including the name of the CA, which should be unique for all members
# of a blockchain network. It also includes the key and certificate files
# used when issuing enrollment certificates (ECerts) and transaction
# certificates (TCerts).
# The chainfile (if it exists) contains the certificate chain which
# should be trusted for this CA, where the 1st in the chain is always the
# root CA certificate.
#############################################################################
ca:
# Certificate file (default: ca-cert.pem)
certfile: ca-cert.pem
# Name of this CA
name:
# Key file (default: ca-key.pem)
keyfile: ca-key.pem
# Certificate file (default: ca-cert.pem)
certfile: ca-cert.pem
# Chain file (default: chain-cert.pem)
chainfile: ca-chain.pem

#############################################################################
# The registry section controls how the Fabric CA server does two things:
# 1) authenticates enrollment requests which contain identity name and
# password (also known as enrollment ID and secret).
# The registry section controls how the fabric-ca-server does two things:
# 1) authenticates enrollment requests which contain a username and password
# (also known as an enrollment ID and secret).
# 2) once authenticated, retrieves the identity's attribute names and
# values which the Fabric CA server optionally puts into TCerts
# values which the fabric-ca-server optionally puts into TCerts
# which it issues for transacting on the Hyperledger Fabric blockchain.
# These attributes are useful for making access control decisions in
# chaincode.
# There are two main configuration options:
# 1) The Fabric CA server is the registry
# 2) An LDAP server is the registry, in which case the Fabric CA server
# 1) The fabric-ca-server is the registry
# 2) An LDAP server is the registry, in which case the fabric-ca-server
# calls the LDAP server to perform these tasks.
#############################################################################
registry:
Expand All @@ -342,20 +362,21 @@ the server's home directory (see `Fabric CA Server <#server>`__ section more inf
pass: <<<ADMINPW>>>
type: client
affiliation: ""
maxenrollments: -1
attrs:
hf.Registrar.Roles: "client,user,peer,validator,auditor,ca"
hf.Registrar.Roles: "client,user,peer,validator,auditor"
hf.Registrar.DelegateRoles: "client,user,validator,auditor"
hf.Revoker: true
hf.IntermediateCA: true

#############################################################################
# Database section
# Supported types are: "sqlite3", "postgres", and "mysql".
# The datasource value depends on the type.
# If the type is "sqlite3", the datasource value is a file name to use
# as the database store. Since "sqlite3" is an embedded database, it
# may not be used if you want to run the Fabric CA server in a cluster.
# To run the Fabric CA server in a cluster, you must choose "postgres"
# may not be used if you want to run the fabric-ca-server in a cluster.
# To run the fabric-ca-server in a cluster, you must choose "postgres"
# or "mysql".
#############################################################################
db:
Expand All @@ -371,9 +392,9 @@ the server's home directory (see `Fabric CA Server <#server>`__ section more inf

#############################################################################
# LDAP section
# If LDAP is enabled, the Fabric CA server calls LDAP to:
# 1) authenticate enrollment ID and secret (i.e. identity name and password)
# for enrollment requests
# If LDAP is enabled, the fabric-ca-server calls LDAP to:
# 1) authenticate enrollment ID and secret (i.e. username and password)
# for enrollment requests;
# 2) To retrieve identity attributes
#############################################################################
ldap:
Expand All @@ -400,57 +421,83 @@ the server's home directory (see `Fabric CA Server <#server>`__ section more inf

#############################################################################
# Signing section
#
# The "default" subsection is used to sign enrollment certificates;
# the default expiration ("expiry" field) is "8760h", which is 1 year in hours.
#
# The "ca" profile subsection is used to sign intermediate CA certificates;
# the default expiration ("expiry" field) is "43800h" which is 5 years in hours.
# Note that "isca" is true, meaning that it issues a CA certificate.
# A maxpathlen of 0 means that the intermediate CA cannot issue other
# intermediate CA certificates, though it can still issue end entity certificates.
# (See RFC 5280, section 4.2.1.9)
#############################################################################
signing:
default:
usage:
- cert sign
expiry: 8760h
profiles:
ca:
usage:
- cert sign
expiry: 8000h
expiry: 43800h
caconstraint:
isca: true
default:
usage:
- cert sign
expiry: 8000h
maxpathlen: 0

###########################################################################
# Certificate Signing Request section for generating the CA certificate
# Certificate Signing Request (CSR) section.
# This controls the creation of the root CA certificate.
# The expiration for the root CA certificate is configured with the
# "ca.expiry" field below, whose default value is "131400h" which is
# 15 years in hours.
# The pathlength field is used to limit CA certificate hierarchy as described
# in section 4.2.1.9 of RFC 5280.
# Examples:
# 1) No pathlength value means no limit is requested.
# 2) pathlength == 1 means a limit of 1 is requested which is the default for
# a root CA. This means the root CA can issue intermediate CA certificates,
# but these intermediate CAs may not in turn issue other CA certificates
# though they can still issue end entity certificates.
# 3) pathlength == 0 means a limit of 0 is requested;
# this is the default for an intermediate CA, which means it can not issue
# CA certificates though it can still issue end entity certificates.
###########################################################################
csr:
cn: fabric-ca-server
cn: <<<COMMONNAME>>>
names:
- C: US
ST: North Carolina
ST: "North Carolina"
L:
O: Hyperledger
OU: Fabric
hosts:
- <<<MYHOST>>>
- localhost
ca:
pathlen:
pathlenzero:
expiry:
expiry: 131400h
pathlength: <<<PATHLENGTH>>>

#############################################################################
# Crypto section configures the crypto primitives used for all
# BCCSP (BlockChain Crypto Service Provider) section is used to select which
# crypto library implementation to use
#############################################################################
crypto:
software:
hash_family: SHA2
security_level: 256
ephemeral: false
key_store_dir: keys
bccsp:
default: SW
sw:
hash: SHA2
security: 256
filekeystore:
# The directory used for the software file-based keystore
keystore: msp/keystore

#############################################################################
# Multi CA section
#
# Each Fabric CA server contains one CA by default. This section is used
# to configure multiple CAs in a single server.
#
# The fabric-ca-server init and start commands support the following two
# additional mutually exclusive options:
#
# 1) --cacount <number-of-CAs>
# Automatically generate <number-of-CAs> non-default CAs. The names of these
# additional CAs are "ca1", "ca2", ... "caN", where "N" is <number-of-CAs>
Expand Down Expand Up @@ -510,6 +557,7 @@ the server's home directory (see `Fabric CA Server <#server>`__ section more inf
caname:

enrollment:
hosts:
profile:
label:

Expand Down
36 changes: 36 additions & 0 deletions scripts/fvt/intermediateca_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

FABRIC_CA="$GOPATH/src/github.com/hyperledger/fabric-ca"
SCRIPTDIR="$FABRIC_CA/scripts/fvt"
. $SCRIPTDIR/fabric-ca_utils
RC=0

TDIR=intermediateca-tests

mkdir -p $TDIR/root
cd $TDIR/root
fabric-ca-server start -b admin:adminpw -d > server.log 2>&1&
cd ../..
sleep 1

mkdir -p $TDIR/int1
cd $TDIR/int1
fabric-ca-server start -b admin:adminpw -u http://admin:adminpw@localhost:7054 -p 7055 -d > server.log 2>&1&
cd ../..
sleep 1

fabric-ca-client getcacert -u http://admin:adminpw@localhost:7055
test $? -ne 0 && ErrorExit "Failed to talk to intermediate CA1"

fabric-ca-server init -b admin:adminpw -u http://admin:adminpw@localhost:7055 -d
test $? -eq 0 && ErrorExit "CA2 should have failed to initialize"

$SCRIPTDIR/fabric-ca_setup.sh -R

CleanUp $RC
exit $RC

0 comments on commit 22dc710

Please sign in to comment.