Skip to content

Commit

Permalink
[FAB-2668] Ensure revocation updates DB
Browse files Browse the repository at this point in the history
Case1: Revoke all user certificates
Case2: Revoke user certificate by SN and AKI

Ensure case in-sensitivity w/r/t hexadeciaml digits
Ensure cross-org revocation is dis-allowed
Ensure revocation is dis-allowed for user w/o revoker attribute
Ensure DB user table is updated properly
Ensure DB certificate table is updated properly
Ensure user can revoke own certificate

Also update setup script to allow for longer timeouts;
The sqlite3 DB is inordinately slow in initialiaing
large numbers of affiliations.

Change-Id: I0040df5548210c311d1e09862bf3e99eee61a213
Signed-off-by: rennman <eabailey@us.ibm.com>
  • Loading branch information
rennman committed Apr 6, 2017
1 parent 4456f65 commit ee2ec59
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 80 deletions.
6 changes: 4 additions & 2 deletions scripts/fvt/fabric-ca_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ backend fabric-cas
function startFabricCa() {
local inst=$1
local start=$SECONDS
local timeout=8
local timeout="$((TIMEOUT*2))"
local now=0
local server_addr=127.0.0.$inst
# if not explcitly set, use default
Expand Down Expand Up @@ -221,8 +221,9 @@ function killAllFabricCas() {
test -n "$proxypids" && kill $proxypids
}
while getopts "\?hRCISKXLDTAd:t:l:n:c:k:x:g:m:p:r:" option; do
while getopts "\?hRCISKXLDTAd:t:l:n:c:k:x:g:m:p:r:o:" option; do
case "$option" in
o) TIMEOUT="$OPTARG" ;;
d) DRIVER="$OPTARG" ;;
r) USER_CA_PORT="$OPTARG" ;;
p) HTTP_PORT="$OPTARG" ;;
Expand All @@ -249,6 +250,7 @@ while getopts "\?hRCISKXLDTAd:t:l:n:c:k:x:g:m:p:r:" option; do
esac
done
: ${TIMEOUT:="10"}
: ${HTTP_PORT:="3755"}
: ${DBNAME:="fabric_ca"}
: ${MAXENROLL:="1"}
Expand Down
258 changes: 180 additions & 78 deletions scripts/fvt/revoke_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,99 +2,201 @@
FABRIC_CA="$GOPATH/src/github.com/hyperledger/fabric-ca"
SCRIPTDIR="$FABRIC_CA/scripts/fvt"
TESTDATA="$FABRIC_CA/testdata"
FABRIC_CA_EXEC="$FABRIC_CA/bin/fabric-ca"
FABRIC_CA_HOME="$HOME/fabric-ca"
export CA_CFG_PATH="/tmp/revoke_test"
RC=0
URI="localhost:8888"
DB="$TESTDATA/fabric_ca.db"
USERS=("admin" "admin2" "notadmin")
PSWDS=("adminpw" "adminpw2" "pass")
# FIXME should not require user:pass
URI="http://user:pass@localhost:8888"
DB="fabric_ca"
USERS=("admin" "admin2" "notadmin" "testUser" "testUser2" "testUser3" )
PSWDS=("adminpw" "adminpw2" "pass" "user1" "user2" "user3" )
#USERS=("admin" "admin2" "notadmin")
#PSWDS=("adminpw" "adminpw2" "pass")
HTTP_PORT="3755"
export FABRIC_CA_HOME="/tmp/${USERS[1]}"

. $SCRIPTDIR/fabric-ca_utils


# Expected codes
# user cert
test1Result="1 good"
test2Result="1 revoked"
test3Result="1 revoked"
genAffYaml() {
local Planet=(0 1)
local Landmass=(0)
local Country=(0 1)
local Province=(0 1 2)
local Locale=(0)
local City=(0 1)
local Hood=(0 1 2 3 4 5 6)
echo "affiliations:"
indent="${indent} "
for P in ${Planet[@]}; do
echo "${indent}Planet$P:"
indent="${indent} "
for L in ${Landmass[@]}; do
echo "${indent}Landmass$L:"
indent="${indent} "
for C in ${Country[@]}; do
echo "${indent}Country$C:"
indent="${indent} "
for R in ${Province[@]}; do
echo "${indent}Province$R:"
indent="${indent} "
for O in ${Locale[@]}; do
echo "${indent}Locale$O:"
indent="${indent} "
for I in ${City[@]}; do
echo "${indent}City$I:"
indent="${indent} "
for H in ${Hood[@]}; do
echo "${indent}- Hood$H"
done
indent="${indent# }"
done
indent="${indent# }"
done
indent="${indent# }"
done
indent="${indent# }"
done
indent="${indent# }"
done
indent="${indent# }"
done
indent="${indent} "
}

function testStatus() {
local user="$1"
user_status=$(sqlite3 $DB "SELECT * FROM users WHERE (id=\"$user\");")
cert_status=$(sqlite3 $DB "SELECT * FROM certificates WHERE (id=\"$user\");")
user_status_code=$(echo $user_status | awk -F'|' '{print $6}')
cert_status_code=$(echo $cert_status | awk -F'|' '{print $5}')
echo "$user_status_code $cert_status_code"
local user="$1"
local driver="$2"
: ${driver:="sqlite3"}
case $driver in
sqlite3)
user_status=$(sqlite3 $CA_CFG_PATH/$DB "SELECT * FROM users WHERE (id=\"$user\");")
cert_status=$(sqlite3 $CA_CFG_PATH/$DB "SELECT * FROM certificates WHERE (id=\"$user\");")
user_status_code=$(echo $user_status | awk -F'|' '{print $6}')
cert_status_code=$(echo $cert_status | awk -F'|' '{print $5}')
;;
mysql)
user_status_code=$(mysql --host=localhost --user=root --password=mysql -e "SELECT * FROM users WHERE (id=\"$user\");" $DB| awk -F'\t' -v u=$user '$1~u {print $6}')
cert_status_code=$(mysql --host=localhost --user=root --password=mysql -e "SELECT * FROM certificates WHERE (id=\"$user\");" $DB| awk -F'\t' -v u=$user '$1~u {print $5}')
;;
postgres)
user_status_code=$(/usr/bin/psql -U postgres -h localhost -c "SELECT id,state FROM users WHERE id='$user';" --dbname=fabric_ca | awk -v u=$user -F'|' '$1~u {gsub(/ /,"");print $2}')
cert_status_code=$(/usr/bin/psql -U postgres -h localhost -c "SELECT id,encode(status,'escape') FROM certificates WHERE id='$user';" --dbname=fabric_ca | awk -v u=$user -F'|' '$1~u {gsub(/ /,"");print $2}')
;;
esac
echo "$user_status_code $cert_status_code"
}

# Expected codes
# user cert
enrolledGood="1 good"
enrolledRevoked="1 revoked"
revokedRevoked="-1 revoked"
TEST_RESULTS=("$revokedRevoked" "$revokedRevoked" "$enrolledRevoked" "$enrolledRevoked" "$enrolledGood" "$enrolledGood" )

cd $TESTDATA
python -m SimpleHTTPServer $HTTP_PORT &
HTTP_PID=$!
pollServer python localhost "$HTTP_PORT" || ErrorExit "Failed to start HTTP server"
echo $HTTP_PID
trap "kill $HTTP_PID; CleanUp" INT


# Kill any running servers
$SCRIPTDIR/fabric-ca_setup.sh -R -x $FABRIC_CA_HOME

# Setup CA server
$SCRIPTDIR/fabric-ca_setup.sh -I -S -X

# Enroll
i=-1
while test $((i++)) -lt 2; do
FABRIC_CA_HOME="/tmp/${USERS[i]}"
$SCRIPTDIR/enroll.sh -u "${USERS[i]}" -p "${PSWDS[i]}" -x "/tmp/${USERS[i]}"
trap "kill $HTTP_PID; CleanUp; exit 1" INT


for driver in mysql postgres sqlite3; do
echo ""
echo ""
echo ""
echo ""
echo "=====================> TESTING $driver"
# Kill any running servers
$SCRIPTDIR/fabric-ca_setup.sh -R -d $driver

# Setup CA server
$SCRIPTDIR/fabric-ca_setup.sh -D -I -d $driver
genAffYaml >> $CA_CFG_PATH/runFabricCaFvt.yaml
$SCRIPTDIR/fabric-ca_setup.sh -o 60 -D -S -X -d $driver -x $CA_CFG_PATH
if test "$?" -ne 0; then
kill $HTTP_PID
wait $HTTP_PID
ErrorExit "Failed to setup server" RC
fi
sleep 5
# Enroll admin, admin2, notadmin, testUser
i=-1
while test $((i++)) -lt 5; do
enroll "${USERS[i]}" "${PSWDS[i]}" "$CA_CFG_PATH/${USERS[i]}"
done

# notadmin cannot revoke
export FABRIC_CA_CLIENT_HOME="/tmp/revoke_test/${USERS[2]}"
$FABRIC_CA_CLIENTEXEC revoke -u $URI --eid ${USERS[1]}
test "$?" -eq 0 && ErrorMsg "Non-revoker successfully revoked cert"

# Check the DB contents
while test $((i++)) -lt 3; do
test "$(testStatus ${USERS[i]} $driver)" = "$enrolledGood" ||
ErrorMsg "Incorrect user/certificate status for ${USERS[i]}" RC
done

### Ensure case-insensitivity by using both upper/lower case
### in two separate instances
# Grab the serial number of notadmin cert
SN_UC="$(openssl x509 -noout -serial -in $CA_CFG_PATH/${USERS[2]}/msp/signcerts/cert.pem | awk -F'=' '{print toupper($2)}')"
# and the auth keyid of notadmin cert - translate upper to lower case
AKI_UC=$(openssl x509 -noout -text -in $CA_CFG_PATH/${USERS[2]}/msp/signcerts/cert.pem |awk '/keyid/ {gsub(/ *keyid:|:/,"",$1);print toupper($0)}')

# Grab the serial number of testUser cert
SN_LC="$(openssl x509 -noout -serial -in $CA_CFG_PATH/${USERS[3]}/msp/signcerts/cert.pem | awk -F'=' '{print tolower($2)}')"
# and the auth keyid of testUser cert - translate upper to lower case
AKI_LC=$(openssl x509 -noout -text -in $CA_CFG_PATH/${USERS[3]}/msp/signcerts/cert.pem |awk '/keyid/ {gsub(/ *keyid:|:/,"",$1);print tolower($0)}')

# Revoke the certs
echo "=========================> REVOKING by --eid"
export FABRIC_CA_CLIENT_HOME="/tmp/revoke_test/${USERS[0]}"
#### Blanket revoke all of admin2 certs
$FABRIC_CA_CLIENTEXEC revoke -u $URI --eid ${USERS[1]}

#### Revoke notadmin's cert by serial number and authority keyid
#### using upper-case hexidecimal
echo "=========================> REVOKING by -s -a (UPPERCASE)"
$FABRIC_CA_CLIENTEXEC revoke -s $SN_UC -a $AKI_UC -u $URI

#### Ensure that revoking an already revoked cert doesn't blow up
echo "=========================> Issuing duplicate revoke by -s -a"
$FABRIC_CA_CLIENTEXEC revoke -s $SN_UC -a $AKI_UC -u $URI

#### Revoke using lower-case hexadeciaml
# FIXME - should allow combination of SN + AKI + EID
#$FABRIC_CA_CLIENTEXEC revoke -s $SN_LC -a $AKI_LC -u $URI --eid ${USERS[3]}
echo "=========================> REVOKING by -s -a (LOWERCASE)"
$FABRIC_CA_CLIENTEXEC revoke -s $SN_LC -a $AKI_LC -u $URI

echo "=========================> REVOKING by --eid"
export FABRIC_CA_CLIENT_HOME="/tmp/revoke_test/${USERS[0]}"
#### Revoke across affiliations not allowed
$FABRIC_CA_CLIENTEXEC revoke -u $URI --eid ${USERS[5]}

#### Revoke my own cert
echo "=========================> REVOKING self"
$FABRIC_CA_CLIENTEXEC revoke --eid ${USERS[0]}

# Verify the DB update
for ((i=${#USERS[@]}; i<=0; i--)); do
test "$(testStatus ${USERS[i-1]} $driver)" = "${TEST_RESULTS[i-1]}" ||
ErrorMsg "Incorrect user/certificate status for ${USERS[i-1]}" RC
done

# Veriy that the cert is no longer usable
export FABRIC_CA_CLIENT_HOME="/tmp/revoke_test/${USERS[0]}"
register ${USERS[0]} 'user100'
test "$?" -eq 0 && ErrorMsg "${USERS[0]} authenticated with revoked certificate" RC
export FABRIC_CA_CLIENT_HOME="/tmp/revoke_test/${USERS[1]}"
register ${USERS[1]} 'user101'
test "$?" -eq 0 && ErrorMsg "${USERS[1]} authenticated with revoked certificate" RC

# Verify the DB update
for ((i=${#USERS[@]}; i<=0; i--)); do
test "$(testStatus ${USERS[i-1]} $driver)" = "${TEST_RESULTS[i-1]}" ||
ErrorMsg "Incorrect user/certificate status for ${USERS[i-1]}" RC
done
done

# notadmin cannot revoke
FABRIC_CA_HOME="/tmp/${USERS[2]}"
$FABRIC_CA_EXEC client revoke $URI ${USERS[2]}
test "$?" -eq 0 && ErrorMsg "Non-revoker successfully revoked cert"

# Check the DB contents
test "$(testStatus ${USERS[0]})" = "$test1Result" ||
ErrorMsg "Incorrect user/certificate status for ${USERS[0]}" RC
test "$(testStatus ${USERS[1]})" = "$test1Result" ||
ErrorMsg "Incorrect user/certificate status for ${USERS[1]}" RC

# Grab the serial number of admin cert (convert to decimal)
SN=$(echo "ibase=16;$(openssl x509 -noout -serial -in /tmp/${USERS[0]}/cert.pem | awk -F'=' '{print $2}')" | bc)
# and the auth keyid of admin cert - translate upper to lower case
AKI=$(openssl x509 -noout -text -in /tmp/${USERS[0]}/cert.pem |awk '/keyid/ {gsub(/ *keyid:|:/,"",$1);print tolower($0)}')

# Revoke the certs
FABRIC_CA_HOME="/tmp/${USERS[0]}"
#### Blanket all of admin2 certs
$FABRIC_CA_EXEC client revoke $URI ${USERS[1]}
#### Revoke admin's cert by serial number and authority keyid
$FABRIC_CA_EXEC client revoke -serial $SN -aki $AKI $URI ${USERS[0]}

# Verify the DB update
test "$(testStatus ${USERS[0]})" = "$test2Result" ||
ErrorMsg "Incorrect user/certificate status for ${USERS[0]}" RC
test "$(testStatus ${USERS[1]})" = "$test2Result" ||
ErrorMsg "Incorrect user/certificate status for ${USERS[1]}" RC

# Veriy that the cert is no longer usable
FABRIC_CA_HOME="/tmp/${USERS[0]}"
$SCRIPTDIR/register.sh -u 'user100'
FABRIC_CA_HOME="/tmp/${USERS[0]}"
test "$?" -eq 0 && ErrorMsg "${USERS[0]} authenticated with revoked certificate" RC
FABRIC_CA_HOME="/tmp/${USERS[1]}"
$SCRIPTDIR/register.sh -u 'user101'
test "$?" -eq 0 && ErrorMsg "${USERS[1]} authenticated with revoked certificate" RC

# Verify the DB update
test "$(testStatus ${USERS[0]})" = "$test3Result" ||
ErrorMsg "Incorrect user/certificate status for ${USERS[0]}" RC
test "$(testStatus ${USERS[1]})" = "$test3Result" ||
ErrorMsg "Incorrect user/certificate status for ${USERS[1]}" RC

CleanUp $RC
kill $HTTP_PID
wait $HTTP_PID
Expand Down

0 comments on commit ee2ec59

Please sign in to comment.