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

Introduction

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).

Prerequisites

  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

Getting Started

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

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.

Credits

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store