Setting up a third-party root Certification Authority (CA) with Hyperledger Fabric

8 min.
a screen displaying code, with parts of the code blurred out
 

Hyperledger Fabric is one of the most successful projects of the Hyperledger Consortium, born within the Linux Foundation. In addition to being an excellent tool for the creation and development of distributed systems especially in the business environment, Hyperledger Fabric offers multiple configuration possibilities.

One of the very important but at the same time underestimated features is the possibility to integrate a third-party Certification Authority (CA) within the system to be developed. In this article, we will describe the steps to follow to create a system that has a third-party Root CA and an Intermediate CA that will integrate the former into the Fabric environment. This problem has already been addressed in the past, however, this article, although based on several articles, provides a working environment with the latest and newest version of Hyperledger Fabric (v 2.2).

 

Next to all prerequisites related to Hyperledger Fabric itself, the following tools must be installed to be able to follow this tutorial:

  1. Docker
  2. Docker Compose
  3. Openssl 1.1.1d (*)

*Version 1.1.1d is not strictly necessary, but previous versions may create some problems

 

To have a working demo simply perform the following steps. First, download the repository containing the files needed for the network to work.

git clone https://github.com/ZappaBoy/fabric-mwe.git

Then enter into the repository folder.

cd fabric-mwe/external-ca/

Finally, start the initialization script.

./start.sh

The script will download all necessary components and then start the docker containers that will compose the network structure. In case of errors, check that all dependencies have been installed correctly and that there are no conflicts with other dockers. To return to a clean environment you can use the command below:

./destroy.sh.

This script removes all files, dockers, and docker volumes created by the tutorial by resetting the environment to its initial state.

 

Walkthrough

 

The initialization script performs all tasks needed to set up the tutorial example. In this section, we are going to walk through all operations performed by the script in order to analyze and explain all the operations needed for a correct setup of a third-party root CA and its supporting intermediate CA.

 

Define some useful variables


As the network utilizes country information, as a first step we define SUBJ and CSR_NAMES variables.

export SUBJ=”/C=IT/ST=Italy/L=Italy/O=org1.example.com/OU=Example/CN=”

export CSR_NAMES=”C=IT,ST=Italy,L=Italy,O=org1.example.com”

Hyperledger Fabric binaries downloads


As a second step, the script downloads the Hyperledger Fabric v2.2 binaries.

curl -sSL http://bit.ly/2ysbOFE | bash -s

rm -f config/configtx.yaml config/core.yaml config/orderer.yaml

These will be necessary to carry out Fabric’s proprietary operations such as instantiation and installation of chaincodes, CAs interaction, and the creation of the cryptographic elements necessary for the communication of network elements.

Cryptographic elements


After downloading the Fabric binaries, the script generates the cryptographic elements for the Orderer.

export PATH=$PWD/bin:$PATH

cryptogen generate — config=./crypto-config.yaml

In order for everything to work properly, we also need to create a folder structure for the certificates and keys of the organization and its peer.

ORG_DIR=$PWD/crypto-config/peerOrganizations/org1.example.com

PEER_DIR=$ORG_DIR/peers/peer0.org1.example.com

IDENTITY_REGISTRAR_DIR=$ORG_DIR/users/admin

TLS_REGISTRAR_DIR=$ORG_DIR/users/tlsadmin

ADMIN_DIR=$ORG_DIR/users/Admin@org1.example.com

mkdir -p $ORG_DIR/ca $ORG_DIR/tlsca $ORG_DIR/msp $PEER_DIR $IDENTITY_REGISTRAR_DIR $TLS_REGISTRAR_DIR $ADMIN_DIR

Root CA Structure


Along the same lines, now we have to create a structure to store Root CA data.

mkdir -p identity-rca/private identity-rca/certs identity-rca/newcerts identity-rca/crl

touch identity-rca/index.txt identity-rca/serial

echo 1000 > identity-rca/serial

echo 1000 > identity-rca/crlnumber

And create a private key for the Root CA using the same standard used by Hyperledger Fabric (ECDSA with prime256v1 curve).

openssl ecparam -name prime256v1 -genkey -noout -out identity-rca/private/rca.identity.org1.example.com.key

We also generate a Certificate Signing Request (CSR).

openssl req -config openssl_root-identity.cnf -new -x509 -sha256 -extensions v3_ca -key identity-rca/private/rca.identity.org1.example.com.key -out identity-rca/certs/rca.identity.org1.example.com.cert -days 3650 -subj “${SUBJ}rca.identity.org1.example.com”

Similarly to the Root CA, we now create a folder structure for the Root TLS CA and key pairs.

mkdir -p tls-rca/private tls-rca/certs tls-rca/newcerts tls-rca/crl

touch tls-rca/index.txt tls-rca/serial

echo 1000 > tls-rca/serial

echo 1000 > tls-rca/crlnumber

openssl ecparam -name prime256v1 -genkey -noout -out tls-rca/private/rca.tls.org1.example.com.key

openssl req -config openssl_root-tls.cnf -new -x509 -sha256 -extensions v3_ca -key tls-rca/private/rca.tls.org1.example.com.key -out tls-rca/certs/rca.tls.org1.example.com.cert -days 3650 -subj “${SUBJ}rca.tls.org1.example.com”

Intermediate CA structure

We now move on to the creation of the necessary structure for the intermediate CA. First, we generate a private key and a Certificate Signing Request (CSR) belonging to the same organization.

openssl ecparam -name prime256v1 -genkey -noout -out $ORG_DIR/ca/ica.identity.org1.example.com.key

openssl req -new -sha256 -key $ORG_DIR/ca/ica.identity.org1.example.com.key -out $ORG_DIR/ca/ica.identity.org1.example.com.csr -subj “${SUBJ}ica.identity.org1.example.com”

openssl ca -batch -config openssl_root-identity.cnf -extensions v3_intermediate_ca -days 1825 -notext -md sha256 -in $ORG_DIR/ca/ica.identity.org1.example.com.csr -out $ORG_DIR/ca/ica.identity.org1.example.com.cert

We now create the “chain” file containing both Root CA and Intermediate CA certificates.

cat $ORG_DIR/ca/ica.identity.org1.example.com.cert $PWD/identity-rca/certs/rca.identity.org1.example.com.cert > $ORG_DIR/ca/chain.identity.org1.example.com.cert

Finally, as for the TLS Root CA, we generate the structure for the Intermediate TLS CA.

openssl ecparam -name prime256v1 -genkey -noout -out $ORG_DIR/tlsca/ica.tls.org1.example.com.key

openssl req -new -sha256 -key $ORG_DIR/tlsca/ica.tls.org1.example.com.key -out $ORG_DIR/tlsca/ica.tls.org1.example.com.csr -subj “${SUBJ}ica.tls.org1.example.com”

openssl ca -batch -config openssl_root-tls.cnf -extensions v3_intermediate_ca -days 1825 -notext -md sha256 -in $ORG_DIR/tlsca/ica.tls.org1.example.com.csr -out $ORG_DIR/tlsca/ica.tls.org1.example.com.cert

cat $ORG_DIR/tlsca/ica.tls.org1.example.com.cert $PWD/tls-rca/certs/rca.tls.org1.example.com.cert > $ORG_DIR/tlsca/chain.tls.org1.example.com.cert

Starting the network via docker

It is now time to start the network. First, we start the Intermediate CA and make sure the container is working and responding correctly

docker-compose up -d ica.org1.example.com

curl http://localhost:7054/cainfo\?ca\=ca

curl http://localhost:7054/cainfo\?ca\=tlsca

Before continuing, wait about a minute to make sure the network finishes its setup. After that, we proceed by creating an identity for the Admin and a user.

export FABRIC_CA_CLIENT_HOME=$IDENTITY_REGISTRAR_DIR

fabric-ca-client enroll — caname ca — csr.names “${CSR_NAMES}” -m admin -u http://admin:adminpw@localhost:7054

fabric-ca-client register — caname ca — id.name Admin@org1.example.com — id.secret adminpw — id.type admin — id.affiliation org1 -u http://localhost:7054

fabric-ca-client register — caname ca — id.name peer0.org1.example.com — id.secret mysecret — id.type peer — id.affiliation org1 -u http://localhost:7054

export FABRIC_CA_CLIENT_HOME=$ADMIN_DIR

fabric-ca-client enroll — caname ca — csr.names “${CSR_NAMES}” -m Admin@org1.example.com -u http://Admin@org1.example.com:adminpw@localhost:7054

cp $ORG_DIR/ca/chain.identity.org1.example.com.cert $ADMIN_DIR/msp/chain.cert

cp $PWD/nodeou.yaml $ADMIN_DIR/msp/config.yaml

export FABRIC_CA_CLIENT_HOME=$PEER_DIR

fabric-ca-client enroll — caname ca — csr.names “${CSR_NAMES}” -m peer0.org1.example.com -u http://peer0.org1.example.com:mysecret@localhost:7054

cp $ORG_DIR/ca/chain.identity.org1.example.com.cert $PEER_DIR/msp/chain.cert

cp $PWD/nodeou.yaml $PEER_DIR/msp/config.yaml

We then generate the certificates and key pairs to use the TLS connection between the network elements.

export FABRIC_CA_CLIENT_HOME=$TLS_REGISTRAR_DIR

fabric-ca-client enroll — caname tlsca — csr.names “${CSR_NAMES}” -m admin -u http://admin:adminpw@localhost:7054

fabric-ca-client register — caname tlsca — id.name peer0.org1.example.com — id.secret mysecret — id.type peer — id.affiliation org1 -u http://localhost:7054

export FABRIC_CA_CLIENT_HOME=$PEER_DIR/tls

fabric-ca-client enroll — caname tlsca — csr.names “${CSR_NAMES}” -m peer0.org1.example.com -u http://peer0.org1.example.com:mysecret@localhost:7054

cp $PEER_DIR/tls/msp/signcerts/*.pem $PEER_DIR/tls/server.crt

cp $PEER_DIR/tls/msp/keystore/* $PEER_DIR/tls/server.key

cat $PEER_DIR/tls/msp/intermediatecerts/*.pem $PEER_DIR/tls/msp/cacerts/*.pem > $PEER_DIR/tls/ca.crt

rm -rf $PEER_DIR/tls/msp $PEER_DIR/tls/*.yaml

By now it should already be clear that certificates can indeed be created via a third-party Root CA within a Hyperledger Fabric network with the help of an Intermediate CA. With the following steps, we create a channel and utilize a sample chaincode to make sure the network is working properly. To do so, we first prepare a structure for Membership Service Providers (MSP).

mkdir -p $ORG_DIR/msp/admincerts $ORG_DIR/msp/intermediatecerts $ORG_DIR/msp/cacerts $ORG_DIR/msp/tlscacerts $ORG_DIR/msp/tlsintermediatecerts

cp $PEER_DIR/msp/cacerts/*.pem $ORG_DIR/msp/cacerts/

cp $PEER_DIR/msp/intermediatecerts/*.pem $ORG_DIR/msp/intermediatecerts/

cp $PWD/tls-rca/certs/rca.tls.org1.example.com.cert $ORG_DIR/msp/tlscacerts/

cp $ORG_DIR/tlsca/ica.tls.org1.example.com.cert $ORG_DIR/msp/tlsintermediatecerts/

cp $ORG_DIR/ca/chain.identity.org1.example.com.cert $ORG_DIR/msp/chain.cert

cp $PWD/nodeou.yaml $ORG_DIR/msp/config.yaml

After that, it is time to create a genesis block and a channel.

export FABRIC_CFG_PATH=${PWD}

configtxgen -profile OrdererGenesis -outputBlock ./config/genesis.block -channelID genesis-channel

configtxgen -profile Channel -outputCreateChannelTx ./config/${CHANNELID}.tx -channelID ${CHANNELID}

We are now ready to start the Orderer, peer, and CLI dockers.

docker-compose up -d orderer.example.com peer0.org1.example.com cli

Now it is time to create the channel’s artifacts and connect it to the network. To do so, we also define an ID for the channel.

export CHANNELID=”MYCHANNELID”

docker exec cli peer channel create -o orderer.example.com:7050 — tls — cafile /var/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem -c ${CHANNELID} -f /config/${CHANNELID}.tx

docker exec cli peer channel join -b ${CHANNELID}.block

For testing the network, we install one of the sample chaincodes provided by Hyperledger Fabric for such purpose, the “marbles” chaincode.

docker exec cli peer chaincode install -n marbles -v 1.0 -l node -p /opt/gopath/src/github.com/marbles02/node -v 1.0

docker exec cli peer chaincode instantiate -o orderer.example.com:7050 — tls — cafile /var/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C ${CHANNELID} -n marbles -l “node” -v 1.0 -c ‘{“Args”:[“init”]}’ -P “OR(‘Org1MSP.member’)”

Such chaincode will be used to test the network by manipulating the two marbles variables and then checking for their correct value.

docker exec cli peer chaincode invoke -o orderer.example.com:7050 — tls — cafile /var/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C ${CHANNELID} -n marbles -c ‘{“Args”:[“initMarble”,”marble2",”red”,”50",”tom”]}’ — waitForEvent

docker exec cli peer chaincode query -C ${CHANNELID} -n marbles -c ‘{“Args”:[“readMarble”,”marble2"]}’

If everything went well, the values shown by the second command should match the ones entered in the first command. We have therefore demonstrated that it is possible to integrate a Certification Authority within the Hyperledger Fabric structure.

A special thanks goes to Federico Zappone who authored the tutorial repo and helped to redact most of this article. Secondly, as most of this tutorial has been realized drawing from a tutorial for previous Fabric versions shared for free online by Aldred Benedict, Federico and I would like to thank him for his great contributions.

Posted By

Damiano D'Amici

Damiano D'Amici

Head Of Product & Co-Founder
Damiano is the Co-founder and Head of Product at AstraKode, where he specializes in transforming innovative ideas into reality. With extensive experience in software analysis, development, and product ... read more

Share