Skip to content

Commit

Permalink
feat: Add support for FIPS 140-3 encryption compliance check
Browse files Browse the repository at this point in the history
Signed-off-by: Anurag Rajawat <[email protected]>
  • Loading branch information
anurag-rajawat committed Jun 3, 2024
1 parent 667b189 commit 632ed8b
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:latest
FROM ubuntu:22.04

RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openssl ca-certificates curl netcat jq
RUN curl -LO https://dl.k8s.io/release/v1.27.2/bin/linux/amd64/kubectl --output-dir /usr/local/bin/ && chmod +x /usr/local/bin/kubectl
Expand Down
2 changes: 2 additions & 0 deletions config/addr.list
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ dh480.badssl.com:443 BadSSL
isunknownaddress.com:12345 LocalTest
localhost:9090 webserver
localhost:22 localssh
apigateway-fips.us-east-1.amazonaws.com:443 AmazonAPIGateway
dynamodb-fips.ca-west-1.amazonaws.com:443 AmazonDynamoDB
91 changes: 91 additions & 0 deletions config/fips-140-3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{
"TLS_versions": [
{
"TLS_version": "TLSv1.0_1.1",
"cipher_suites": [
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
}
]
},
{
"TLS_version": "TLSv1.2",
"cipher_suites": [
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CCM"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CCM"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
}
]
},
{
"TLS_version": "TLSv1.3",
"cipher_suites": [
{
"cipher_suite": "TLS_AES_256_GCM_SHA384"
},
{
"cipher_suite": "TLS_AES_128_GCM_SHA256"
},
{
"cipher_suite": "TLS_AES_128_CCM_SHA256"
},
{
"cipher_suite": "TLS_AES_128_CCM_8_SHA256"
}
]
}
]
}
110 changes: 109 additions & 1 deletion k8s/job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,106 @@ subjects:
name: k8tls-serviceact
namespace: k8tls
---
apiVersion: v1
kind: ConfigMap
metadata:
name: k8tls-cm
namespace: k8tls
immutable: true
data:
fips-140-3.json: |
{
"TLS_versions": [
{
"TLS_version": "TLSv1.0_1.1",
"cipher_suites": [
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
}
]
},
{
"TLS_version": "TLSv1.2",
"cipher_suites": [
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CCM"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CCM"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
},
{
"cipher_suite": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"
},
{
"cipher_suite": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
}
]
},
{
"TLS_version": "TLSv1.3",
"cipher_suites": [
{
"cipher_suite": "TLS_AES_256_GCM_SHA384"
},
{
"cipher_suite": "TLS_AES_128_GCM_SHA256"
},
{
"cipher_suite": "TLS_AES_128_CCM_SHA256"
},
{
"cipher_suite": "TLS_AES_128_CCM_8_SHA256"
}
]
}
]
}
---
apiVersion: batch/v1
kind: Job
metadata:
Expand All @@ -42,8 +142,16 @@ spec:
serviceAccountName: k8tls-serviceact
containers:
- name: k8tls
image: kubearmor/k8tls:latest
image: kubearmor/k8tls:latest
command: ["./k8s_tlsscan"]
volumeMounts:
- mountPath: /home/k8tls/config/
name: config
readOnly: true
restartPolicy: Never
volumes:
- name: config
configMap:
name: k8tls-cm
backoffLimit: 4
---
88 changes: 85 additions & 3 deletions src/findings_tls
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ opensslscan()
tmp=/tmp/tls.out
rm -f $tmp 2>/dev/null
timeout 2s openssl s_client -CApath /etc/ssl/certs/ -connect "$SVC_Address" -brief < /dev/null 2>$tmp
# echo "ret=$ret"
# cat $tmp
conn_estd=0
while read line; do
[[ "$line" == "CONNECTION ESTABLISHED" ]] && conn_estd=1
Expand All @@ -18,14 +16,15 @@ opensslscan()
printf -v "TLS_$key" '%s' "$val"
TLS_Status="TLS"
done < $tmp
fips_compliance_check
[[ "$TLS_Verification_error" != "" ]] && TLS_Verification="$TLS_Verification_error"
}

tls_csvreport()
{
[[ "$csvout" == "" ]] && return
cat << EOF >> $csvout
"$SVC_Name","$SVC_Address","$TLS_Status","$TLS_Protocol_version","$TLS_Ciphersuite","$TLS_Hash_used","$TLS_Signature_type","$TLS_Verification"
"$SVC_Name","$SVC_Address","$TLS_Status","$TLS_Protocol_version","$TLS_Ciphersuite","$TLS_Hash_used","$TLS_Signature_type","$TLS_Verification","$FIPS_140_3_Compliant"
EOF
}

Expand Down Expand Up @@ -122,3 +121,86 @@ k8tls_tls_02certificateChecks()
EOF
}

fips_compliance_check()
{
do_openssl_scan
if [ "$TLS_Status" != "TLS" ]; then
control_id="3.2"
description="Secure TLS protocol is required to meet the requirements of FIPS-140-3 compliant encryption."
severity="critical"
solution="Implement secure TLS protocol (TLS >= v1.2)"
FIPS_140_3_Compliant="No"

appendSpec
return
fi

control_id="3.3"
description="Approved ciphers to meet the requirements of FIPS-140-3 compliant encryption."
severity="medium"

case "$TLS_Protocol_version" in
"TLSv1.1"|"TLSv1.0")
ciphers="`jq '.TLS_versions[0].cipher_suites[] | join(", ")' $FIPS_140_3_APPROVED_CIPHERS`"
solution="use FIPS-approved ciphers: [`echo $ciphers | sed 's/\"//g' | sed 's/ /, /g; s/, $//'`]"
FIPS_140_3_Compliant="No"

result=$(jq ".TLS_versions[0].cipher_suites[] | select(.cipher_suite == \"$TLS_Ciphersuite\") | any" "$FIPS_140_3_APPROVED_CIPHERS")

[[ $result == "true" ]] && {
FIPS_140_3_Compliant="Yes"
description="Using Secure TLS protocol and FIPS-approved Ciphers. FIPS-approved ciphersuite in use is $TLS_Ciphersuite"
solution="NA"
}
;;

"TLSv1.2")
ciphers="`jq '.TLS_versions[1].cipher_suites[] | join(", ")' $FIPS_140_3_APPROVED_CIPHERS`"
solution="use FIPS-approved ciphers: [`echo $ciphers | sed 's/\"//g' | sed 's/ /, /g; s/, $//'`]"
FIPS_140_3_Compliant="No"

result=$(jq ".TLS_versions[1].cipher_suites[] | select(.cipher_suite == \"$TLS_Ciphersuite\") | any" "$FIPS_140_3_APPROVED_CIPHERS")

[[ $result == "true" ]] && {
FIPS_140_3_Compliant="Yes"
description="Using Secure TLS protocol and FIPS-approved Ciphers. FIPS-approved ciphersuite in use is $TLS_Ciphersuite"
solution="NA"
}
;;

"TLSv1.3")
ciphers="`jq '.TLS_versions[2].cipher_suites[] | join(", ")' $FIPS_140_3_APPROVED_CIPHERS`"
solution="use FIPS-approved ciphers: [`echo $ciphers | sed 's/\"//g' | sed 's/ /, /g; s/, $//'`]"
FIPS_140_3_Compliant="No"

result=$(jq ".TLS_versions[2].cipher_suites[] | select(.cipher_suite == \"$TLS_Ciphersuite\") | any" "$FIPS_140_3_APPROVED_CIPHERS")

[[ $result == "true" ]] && {
FIPS_140_3_Compliant="Yes"
description="Using Secure TLS protocol and FIPS-approved Ciphers. FIPS-approved ciphersuite in use is $TLS_Ciphersuite"
solution="NA"
}
;;
esac

appendSpec
}

appendSpec()
{
cat << EOF >> $TMPJSONSEC
{
"plugin": "fips-140-3-compliance-check",
"title": "FIPS 140-3 compliant encryption check",
"compliance": "FIPS.140.3",
"control-id": "$control_id",
"cipherSuiteInUse": "$TLS_Ciphersuite",
"description": "$description",
"link": "https://www.gsa.gov/system/files?file=SSL-TLS-Implementation-%5BCIO-IT-Security-14-69-Rev-7%5D-06-12-2023.pdf",
"severity": "$severity",
"remediationEstEffort": "medium",
"solution": "$solution",
"compliant": "$FIPS_140_3_Compliant"
},
EOF
}
5 changes: 4 additions & 1 deletion src/tlsscan
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/bin/bash

BDIR=`dirname $0`
FIPS_140_3_APPROVED_CIPHERS="config/fips-140-3.json"
chk_cmd()
{
if ! command -v $1 &>/dev/null; then
Expand Down Expand Up @@ -57,7 +58,7 @@ csvheader()
{
[[ "$csvout" == "" ]] && return
if [ ! -f "$csvout" ]; then
echo "Name,Address,Status,Version,Ciphersuite,Hash,Signature,Verification" > $csvout
echo "Name,Address,Status,Version,Ciphersuite,Hash,Signature,Verification,FIPS_140_3_Compliant" > $csvout
fi
}

Expand Down Expand Up @@ -128,12 +129,14 @@ getsummary()
"self-signed certificate"
"insecure port"
"connection failure"
"FIPS 140-3 non-compliant"
)
regex_arr=(
"certificate has expired"
"self-signed certificate"
"PLAIN_TEXT"
"CONNFAIL"
"No"
)
echo "Status,Count" > $summcsv
for((i=0;;i++)); do
Expand Down

0 comments on commit 632ed8b

Please sign in to comment.