As some of you may already know, I worked on several blockchain projects mainly with Hyperledger Fabric. We did talk with the client, gathered information, created requirements from that, and started to develop. This is basically the usual software development project.
If you come to point about requirements then you should know that each client has its own requirements. But these are things you already know, right? Of course you do. Every client has its own requirement and I shouldn't bother you with things you already know. I will go straight to the topic because you may have landed on this article when you are not a beginner. Honestly, the real reason is that the demonstration part will take some time for you to do it by yourself and even more time for me to write it down.
There is a requirement I have to tell you that is highly prioritized in every permissioned Blockchain project - maybe all software development projects. You may have a guess if you check the title but I will tell you anyway.
Yes, you are right it is Revocation. Revocation is by far the most important keyword which is been searched together with IT-Security in a search engine. In this article, we will briefly explain what revocation can mean in Hyperledger Fabric in combination with a Fabric CA and show this in an extended demonstration. I want you to learn how to revoke certificates at your home - or where ever you are right now. That is quite nice, right? I hope you like it and I could solve a problem you may have in your current project.
What is this mysterious Fabric CA?
To be honest, there is absolutely nothing mysterious about it. It is like every other CA with some adjustments to the Hyperledger Fabric network. The mysterious Fabric CA is a build-in component from Hyperledger Fabric which takes care of issuing the private key and the belonging certificate - so the cryptographic material - for every component of an organization in a network. So basically, the identity of a peer or an admin user is managed by the CA. This doesn't sound so complicated yet, right? Of course not but visualization is always a good supporter to save it in the memory of your brain.
Demonstration
So, how do I want to show you revocation today? Don't worry it won't be anything super special. I am a fan of easy snippets so that everyone (even beginner) can follow me.
Based on the test-network we receive in the fabric-samples we will have two organizations (We don't need more) which will be bootstrapped through the script. Each organization will have a ca certificate, a peer signing certificate, a peer TLS certificate, an admin certificate, and a user1 certificate. The goal is to revoke the User1 certificate so that he can't read or write anything into the blockchain.
It sounds simple but if you do this the first time you should try to understand each step before you go to the next.
This was a quite long introduction and I feel sorry for that but let's dive in now.
1. Bring up the basic test-network and start the journey
The first step we should do is to run the test-network from the fabric-samples in the official Hyperledger Fabric Github repository. If you don't know what I am talking about or haven't installed the prerequisites yet, then you should start with that before running the test-network. I will link the article here.
I assume you are ready to go and we can bring it up with deploying the basic-asset-transfer chaincode. Note that all the commends in this article will be taken within the test-network folder so be sure that this is the current folder you are in.
./network.sh up createChannel -ca
./network.sh deployCC
The network should be up and running with Fabric CAs for each organization. If you check this out in docker with the command 'docker ps' you should see a similar outcome as the following screenshot shows:
As I said before, we use the Fabric CA from the test-network in this demonstration and you should know that by default this CA acts as a Root CA. What does that mean? The answer is, It creates a private key for himself together with a self-signed certificate which allows him to create cryptographic material for all the other components within the organization.
Therefore in our example, we will have the private key and the signing certificate for Peer0, Admin, and User1 in the 'test-network/organizations' folder. For the crispiness of this article, we won't go through that. If you are interested in a deeper explanation of the cryptographic material or the Fabric CA then let me know that in the comments.
Back to business. We finished bootstrapping our network. Now, we should quickly investigate the identities we had created from Fabric CA. Herefore we will use the following command and investigate them.
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
export FABRIC_CA_CLIENT_HOME=$PWD/organizations/peerOrganizations/org1.example.com/
export FABRIC_CA_CLIENT_TLS_CERTFILES=$PWD/organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem
fabric-ca-client identity list
You can see a list of identities that were issued by the Fabric CA of Org1. Note that identity doesn't mean that it belongs to only one certificate. As we mentioned before the Peer0 has a signing certificate and also a separate TLS certificate.
For the completeness of this step, we should also investigate the certificate of User1.
fabric-ca-client certificate list --id user1
You should see now the certificate of User1 issued by the CA. Please keep your eyes on the issuer name and the serial number field because when we do the revocation the serial number will be shown as a return value.
2. Revoke the certificates of User1 from Org1
The Fabric CA can either revoke a specific certificate or a whole identity that contains all certificates. We will go with the identity. Let's go straight to the revocation command.
fabric-ca-client revoke -e user1
What did we do here? The Fabric CA revoked all the certificates belonging to the identity of User1. Great! No, it is not because the network doesn't know that the certificate has been revoked and therefore User1 is still able to do transactions. So how can we inform the network about the revocation? Well, the same as other global Certification Authorities do with distributing a Certification Revocation List (CRL). The CRL contains all revoked certificates which were issued from a Fabric CA of one particular organization. With the following command, we can do that.
fabric-ca-client gencrl
The CRL is been created and saved into the crypto-folder of the organization as a 'crl.pem' file. Yes great! Nope. There is still one step missing. The network still doesn't know about it and we have to update the configuration of the channel.
Test the current network with the different identities through the CLI Container
Before we do that let us start a CLI container where we will also update the configuration block of the channel. For this, you must create a 'docker-compose-cli.yaml' file in the root of your test-network with the following specifications (https://bit.ly/2IUorPt):
When you created the file the "fun" part can start. Bring up the container and connect to it through the terminal.
docker-compose -f docker-compose-cli.yaml up -d
docker exec -it Org1cli bash
Let's prove that we can invoke transactions through the Admin and User1 credentials because there is no revocation information exposed to the network yet. Initially, the container starts with the MSP config path of the Admin user.
peer chaincode invoke -o orderer.example.com:7050 -C mychannel --tls --cafile $ORDERER_CA -n basic --peerAddresses $CORE_PEER_ADDRESS --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles ../organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitLedger","Args":[]}'
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
You should get a invoke successfully message from the first command and should see the created assets on the blockchain. When we change the MSP config path to User1 we should be able to query the data, too. See the commands below to do that
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
Is this the case so far? Yes? Then let's continue with updating the configuration block.
Update the Channel Config Block through the CLI
This step can create headaches if you don't know what you are doing. Trust me, I killed a lot of aspirin pills when I had to update the channel config block during my projects. So, I will stick to the official documentation on fabric and just modify less as possible to reach our goal.
First of all, I want to change back to be an Admin. Yes, we need to because why should User1 be able to modify or read any config block, right? Well, in the default configuration, it will also work with User1 but let us bring add a bit of a productive flavor and let us pretend that we set the permission of User1 to a lower level.
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
Now we can fetch the latest config block and chop all the metadata off we don't need.
peer channel fetch config config_block.pb -c mychannel
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json
I really thought a lot of if I should also explain the configuration block in this tutorial but I decided to link the official Fabric documentation for you and you can read about it if you are interested. If you have a specific question or want me to create an article for a topic where you need help to please reach out to me or comment on this article.
Back to business (again), we have fetched the latest configuration block and have to transform the certificate in the 'crl.pem' into a Base64 JSON file.
export crl64=$(cat ../organizations/peerOrganizations/org1.example.com/msp/crls/crl.pem | base64)
jq -n --arg crl "$crl64" '{revocation_list: [$crl]}' > crl.json
If you investigated the config.json you will see the Path 'channel_group -> groups -> Application -> groups -> Org1MSP-> values -> MSP -> value -> config -> revocation_list'. Here is an empty array where we have to add the Base64 String from the created 'crl.json'.
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org1MSP":{"values":{"MSP":{"value":{"config":.[1]}}}}}}}}}' config.json crl.json > modified_config.json
Please investigate the modified_config.json. It is in the 'renewtutorial' folder in your test-network. It was automatically created when you brought up the CLI container. You will see that we added the revocation list into the attribute. I added a screenshot just for you.
The following commands have the goal to create an envelope that has to be agreed by the organizations in the network so that the new update can take place. To explain each of these steps in detail would increase the complexity in this article to a level where I don't want to have it. And you too. Trust me.
So basically what we do is to compare the latest config block with the modified config block and take the delta and create an updated envelope (A piece of information where the network knows this is the change) for the network.
configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id mychannel --original config.pb --updated modified_config.pb --output crl_update.pb
configtxlator proto_decode --input crl_update.pb --type common.ConfigUpdate | jq . > crl_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat crl_update.json)'}}}' | jq . > crl_update_in_envelope.json
configtxlator proto_encode --input crl_update_in_envelope.json --type common.Envelope --output crl_update_in_envelope.pb
We have now an updated envelope which has to be signed by Org1 and Org2. Let's do that with the CLI. First, we sign it with Org1.
peer channel signconfigtx -f crl_update_in_envelope.pb
For signing and finally updating the channel, we will use Org2 and have to modify our CLI for that.
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051
peer channel update -f crl_update_in_envelope.pb -c mychannel -o orderer.example.com:7050 --tls --cafile $ORDERER_CA
Done! Yes! You can be proud of you if you came this far. I was it too when I did it the first time. But it feels like you don't trust me and want to see evidence for that. No problem I will show you. Take back to your seat.
Test the network with the revoked User1 certificate and fulfill your expectations
You can handle this small chapter as a bonus from me to you. We will take a look at how the Admin or User1 will behave with this revocation list published in the newest configuration block. What do we expect? Fabric should allow us to make transactions with the Admin User and forbid the ones invoked by User1. The following commands have to be done still from the CLI we running. If it is still with the configuration parameter of Org2 we will switch it to Org1 and query all assets from the ledger.
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
You should be able to see all Assets created at the beginning of this article because you are invoking as Admin. And now the Final. We switch the MSP config path to User1 and try the same query again. I know you praying now that you did everything right. But don't worry there is always some mistake happen which makes your life harder for a few hours until you find out that a small typo was the reason for it.
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
The result should give permission denied and that means you did it!!!!!! You feel the endorphin going through your body? I am feeling it too but not because of this tutorial. It is because I finished another article and delivered the Hyperledger community another piece of my work life.
Conclusion
I want to take this conclusion as short as possible. We have seen in this article how to invoke a certificate in running the Hyperledger Fabric network. It is not easy-going (Actually nothing in Fabric is easy-going) and needs a little bit of effort to complete this tutorial but this skill is been necessary for your production environment.
The last hint I want to give you on your way is that be careful what you revoke because once you revoke the Admin of the Fabric CA you will lockout yourself. This will be not only creating headaches. It will also be a pain in your a**. For sure.
If you liked this article please let me know that and also feel free to comment on any problems you matched during you tried it by yourself. Thank you and see you next time.
Comentários