From 2474704d330521c4761371da1c6f778307c0b29a Mon Sep 17 00:00:00 2001 From: Anil Ambati Date: Thu, 21 Sep 2017 08:53:58 -0400 Subject: [PATCH] [FAB-6967] Added steps to query by a revoked user Steps include: revoking a user, generating a CRL, updating the CRL in the configuration block of the channel, and finally querying the chaincode using the revoked user credentials. The query will fail as it is invoked by a revoked user. Change-Id: I3b0f26d9b5a78475b6f42543b0e17458e9ce2a73 Signed-off-by: Anil Ambati --- fabric-ca/scripts/env.sh | 26 ++++++++ fabric-ca/scripts/run-fabric.sh | 102 ++++++++++++++++++++++++++++-- fabric-ca/scripts/setup-fabric.sh | 2 +- 3 files changed, 124 insertions(+), 6 deletions(-) diff --git a/fabric-ca/scripts/env.sh b/fabric-ca/scripts/env.sh index 51623ba3..bad894a5 100755 --- a/fabric-ca/scripts/env.sh +++ b/fabric-ca/scripts/env.sh @@ -78,6 +78,13 @@ export FABRIC_CA_CLIENT_ID_AFFILIATION=org1 # Set to true to enable use of intermediate CAs USE_INTERMEDIATE_CA=true + +# Config block file path +CONFIG_BLOCK_FILE=/tmp/config_block.pb + +# Update config block payload file path +CONFIG_UPDATE_ENVELOPE_FILE=/tmp/config_update_as_envelope.pb + # initOrgVars function initOrgVars { if [ $# -ne 1 ]; then @@ -245,6 +252,25 @@ function switchToUserIdentity { fi } +# Revokes the fabric user +function revokeFabricUser { + switchToAdminIdentity + export FABRIC_CA_CLIENT_HOME=$ORG_ADMIN_HOME + logr "Revoking the user '$USER_NAME' of the organization '$ORG' with Fabric CA Client home directory set to $FABRIC_CA_CLIENT_HOME ..." + export FABRIC_CA_CLIENT_TLS_CERTFILES=$CA_CHAINFILE + fabric-ca-client revoke -d --revoke.name $USER_NAME +} + +# Generates a CRL that contains serial numbers of all revoked enrollment certificates. +# The generated CRL is placed in the crls folder of the admin's MSP +function generateCRL { + switchToAdminIdentity + export FABRIC_CA_CLIENT_HOME=$ORG_ADMIN_HOME + logr "Generating CRL for the organization '$ORG' with Fabric CA Client home directory set to $FABRIC_CA_CLIENT_HOME ..." + export FABRIC_CA_CLIENT_TLS_CERTFILES=$CA_CHAINFILE + fabric-ca-client gencrl -d +} + # Copy the org's admin cert into some target MSP directory # This is only required if ADMINCERTS is enabled. function copyAdminCert { diff --git a/fabric-ca/scripts/run-fabric.sh b/fabric-ca/scripts/run-fabric.sh index 58441a46..9ffcfc2d 100755 --- a/fabric-ca/scripts/run-fabric.sh +++ b/fabric-ca/scripts/run-fabric.sh @@ -25,7 +25,7 @@ function main { # Set ORDERER_PORT_ARGS to the args needed to communicate with the 1st orderer IFS=', ' read -r -a OORGS <<< "$ORDERER_ORGS" initOrdererVars ${OORGS[0]} 1 - ORDERER_PORT_ARGS="-o $ORDERER_HOST:7050 --tls true --cafile $CA_CHAINFILE" + ORDERER_PORT_ARGS="-o $ORDERER_HOST:7050 --tls --cafile $CA_CHAINFILE" # Convert PEER_ORGS to an array named PORGS IFS=', ' read -r -a PORGS <<< "$PEER_ORGS" @@ -85,10 +85,30 @@ function main { switchToUserIdentity chaincodeQuery 90 - logr "Congratulations! The tests ran successfully." + initPeerVars ${PORGS[0]} 1 + switchToUserIdentity + + # Revoke the user and generate CRL using admin's credentials + revokeFabricUser + generateCRL + + # Fetch config block + fetchConfigBlock + + # Create config update envelope with CRL and update the config block of the channel + createConfigUpdatePayloadWithCRL + updateConfigBlock + + # querying the chaincode should fail as the user is revoked + switchToUserIdentity + queryAsRevokedUser + if [ "$?" -ne 0 ]; then + logr "The revoked user $USER_NAME should have failed to query the chaincode in the channel '$CHANNEL_NAME'" + exit 1 + fi + logr "Congratulations! The tests ran successfully." done=true - } # Enroll as a peer admin and create the channel @@ -121,12 +141,12 @@ function joinChannel { done } -chaincodeQuery () { +function chaincodeQuery { if [ $# -ne 1 ]; then fatalr "Usage: chaincodeQuery " fi set +e - logr "Querying chaincode in channel '$CHANNEL_NAME' on peer '$PEER_HOST' ..." + logr "Querying chaincode in the channel '$CHANNEL_NAME' on the peer '$PEER_HOST' ..." local rc=1 local starttime=$(date +%s) # Continue to poll until we get a successful response or reach QUERY_TIMEOUT @@ -146,6 +166,29 @@ chaincodeQuery () { fatalr "Failed to query channel '$CHANNEL_NAME' on peer '$PEER_HOST'; expected value was $1 and found $VALUE" } +function queryAsRevokedUser { + set +e + logr "Querying the chaincode in the channel '$CHANNEL_NAME' on the peer '$PEER_HOST' as revoked user '$USER_NAME' ..." + local starttime=$(date +%s) + # Continue to poll until we get an expected response or reach QUERY_TIMEOUT + while test "$(($(date +%s)-starttime))" -lt "$QUERY_TIMEOUT"; do + sleep 1 + peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >& log.txt + if [ $? -ne 0 ]; then + err=$(cat log.txt | grep "The certificate has been revoked") + if [ "$err" != "" ]; then + logr "Expected error occurred when the revoked user '$USER_NAME' queried the chaincode in the channel '$CHANNEL_NAME'" + set -e + return 0 + fi + fi + echo -n "." + done + set -e + cat log.txt + cat log.txt >> $RUN_SUMFILE + return 1 +} function makePolicy { POLICY="OR(" @@ -168,6 +211,55 @@ function installChaincode { peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric-samples/chaincode/abac } +function fetchConfigBlock { + logr "Fetching the configuration block of the channel '$CHANNEL_NAME'" + peer channel fetch config $CONFIG_BLOCK_FILE -c $CHANNEL_NAME $ORDERER_PORT_ARGS +} + +function updateConfigBlock { + logr "Updating the configuration block of the channel '$CHANNEL_NAME'" + peer channel update -f $CONFIG_UPDATE_ENVELOPE_FILE -c $CHANNEL_NAME $ORDERER_PORT_ARGS +} + +function createConfigUpdatePayloadWithCRL { + logr "Creating config update payload with the generated CRL for the organization '$ORG'" + # Start the configtxlator + configtxlator start & + configtxlator_pid=$! + log "configtxlator_pid:$configtxlator_pid" + logr "Sleeping 5 seconds for configtxlator to start..." + sleep 5 + + pushd /tmp + + CTLURL=http://127.0.0.1:7059 + # Convert the config block protobuf to JSON + curl -X POST --data-binary @$CONFIG_BLOCK_FILE $CTLURL/protolator/decode/common.Block > config_block.json + # Extract the config from the config block + jq .data.data[0].payload.data.config config_block.json > config.json + + # Update crl in the config json + crl=$(cat $CORE_PEER_MSPCONFIGPATH/crls/crl*.pem | base64 | tr -d '\n') + cat config.json | jq '.channel_group.groups.Application.groups.'"${ORG}"'.values.MSP.value.config.revocation_list = ["'"${crl}"'"]' > updated_config.json + + # Create the config diff protobuf + curl -X POST --data-binary @config.json $CTLURL/protolator/encode/common.Config > config.pb + curl -X POST --data-binary @updated_config.json $CTLURL/protolator/encode/common.Config > updated_config.pb + curl -X POST -F original=@config.pb -F updated=@updated_config.pb $CTLURL/configtxlator/compute/update-from-configs -F channel=$CHANNEL_NAME > config_update.pb + + # Convert the config diff protobuf to JSON + curl -X POST --data-binary @config_update.pb $CTLURL/protolator/decode/common.ConfigUpdate > config_update.json + + # Create envelope protobuf container config diff to be used in the "peer channel update" command to update the channel configuration block + echo '{"payload":{"header":{"channel_header":{"channel_id":"'"${CHANNEL_NAME}"'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' > config_update_as_envelope.json + curl -X POST --data-binary @config_update_as_envelope.json $CTLURL/protolator/encode/common.Envelope > $CONFIG_UPDATE_ENVELOPE_FILE + + # Stop configtxlator + kill $configtxlator_pid + + popd +} + function finish { if [ "$done" = true ]; then logr "See $RUN_LOGFILE for more details" diff --git a/fabric-ca/scripts/setup-fabric.sh b/fabric-ca/scripts/setup-fabric.sh index f0dbb6ac..3983dbb1 100755 --- a/fabric-ca/scripts/setup-fabric.sh +++ b/fabric-ca/scripts/setup-fabric.sh @@ -68,7 +68,7 @@ function registerPeerIdentities { done log "Registering admin identity with $CA_NAME" # The admin identity has the "hf.admin" attribute which is added to ECert by default - fabric-ca-client register -d --id.name $ADMIN_NAME --id.secret $ADMIN_PASS --id.attrs "hf.admin=true:ecert,abac.init=true:ecert" + fabric-ca-client register -d --id.name $ADMIN_NAME --id.secret $ADMIN_PASS --id.attrs "hf.Revoker=true,hf.GenCRL=true,hf.admin=true:ecert,abac.init=true:ecert" log "Registering user identity with $CA_NAME" fabric-ca-client register -d --id.name $USER_NAME --id.secret $USER_PASS done