#!/bin/bash set -euo pipefail check_cert_validity() { local cert=("${@}") # Get validity dates of certificate local expire=$(printf "%s\\n" "${cert[@]:1}" \ | openssl x509 \ -noout \ -dates \ | sed '/notAfter/!d;s/notAfter=//g;s/ /\\ /g' \ | xargs date +%s -d ) # Checks if certificate is valid at this date if [[ ${expire} -gt $(date +%s -d now) ]]; then return 0 else printf "%s: %s [%s %s]\\n" \ $"-- WARNING" \ $"Certificate was expired" \ $"Fingerprint=(SHA256)" \ ${cert[0]} return 1 fi } unzip_fingerprint() { local zip_source=${1:-} local fp_algo=sha256 local files=$( [[ -f "${zip_source}" ]] && \ (unzip -qql ${zip_source} | awk '{print $4}') ) # Unzip cert into array and compute their fingerprint printf "%s: %s\\n" $"Archive" "${zip_source}" local file; for file in ${files}; do readarray -t cert < <( unzip -p ${zip_source} ${file} \ | openssl x509 \ -fingerprint \ -${fp_algo} \ | sed 's/.*Fingerprint=//g;s/://g' ) # Check validity dates of certificate then writes it to disk if check_cert_validity "${cert[@]}"; then local cert_file="certs/${cert[0]}.crt" printf " %s %s\\n" $"Inflating" "certs/${file}" #printf " %s %s\\n" $"Inflating" "certs/${cert[0]}.crt" #printf " - %s=(%s) %s\\n" "Fingerprint" "${fp_algo^^}" "${cert[0]}" printf "%s\\n" "${cert[@]:1}" > "${cert_file}" fi done } copy_fingerprint() { local cert_source=${1:-} local fp_algo=sha256 readarray -t cert < <( cat ${cert_source} \ | openssl x509 \ -fingerprint \ -${fp_algo} \ | sed 's/.*Fingerprint=//g;s/://g' ) # Check validity dates of certificate then writes it to disk if check_cert_validity "${cert[@]}"; then local cert_file="certs/${cert[0]}.crt" printf "%s %s\\n" $"Copying" "certs/${cert_source}" printf "%s\\n" "${cert[@]:1}" > "${cert_file}" fi } #split() { # local certs=("${@}") # # printf "%s\\n" "${certs[@]}" \ # | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' \ # | csplit \ # --quiet \ # --elide-empty-files \ # --prefix ${random_prefix:-}-cert \ # --suffix-format=-%02d.crt \ # - '/-END CERTIFICATE-/1' \ # '{*}' #} function extract() { local file mkdir -p certs find cache -type f | while read file; do case "$(file -b --mime-type ${file})" in application/zip) unzip_fingerprint "${file}" ;; application/x-pem-file) copy_fingerprint ${file} ;; esac done } function classify() { # Create classified output directories mkdir -p certs/{ca-root,ca-trust,servers} # Process and classify generated files echo -e "\n-- CLASSIFYING CACHED CERTIFICATES\n" count=0 cert_files=$(find certs/ -maxdepth 1 -type f) for cert_file in ${cert_files}; do fingerprint="(SHA256) ${cert_file}" echo "+ Processing certificate [Fingerprint: ${fingerprint}]" issuer=$(openssl x509 -in "${cert_file}" -noout -issuer | sed 's/^issuer=//g') issuer_o=$(echo "${issuer}" | grep -iPo 'O\s*=\s*\K[^,]+' || :) subject=$(openssl x509 -in "${cert_file}" -noout -subject | sed 's/^subject=//g') subject_o=$(echo "${subject}" | grep -iPo 'O\s*=\s*\K[^,]+' || :) subject_cn=$(echo "${subject}" | grep -iPo 'CN\s*=\s*\K[^,]+' || :) cert_o=$(echo "${subject_o^^}" | sed -E "s/\s/_/g;s/'//g;s/\/.*//g;s/\*\.//g") cert_cn=$(echo "${subject_cn}" | sed -E "s/\s/_/g;s/\/.*//g;s/^\*\./wildcard-/g") # save temporary pem file to .CRT file if [[ "${subject_cn}" =~ "gov.br" ]]; then # it's a server certificate cert_crt_file="${issuer_o^^}-${cert_cn}.crt" openssl x509 -in "${cert_file}" -out "certs/servers/${cert_crt_file}" let count=count+1 elif [[ "${subject}" == "${issuer}" ]]; then # it's a root certificate (self-signed) cert_crt_file="${cert_o}-${cert_cn}.crt" openssl x509 -in "${cert_file}" -out "certs/ca-root/${cert_crt_file}" let count=count+1 else # it's an intermediate certificate cert_crt_file="${cert_o}-${cert_cn}.crt" openssl x509 -in "${cert_file}" -out "certs/ca-trust/${cert_crt_file}" let count=count+1 fi done echo "-- Processed certificates: ${count}" } function anchors() { echo -e "\n-- GENERATING P11-KIT SOURCE ANCHORS" local ca_list=$( (for cert in certs/{ca-root,ca-trust}/*.crt; do openssl x509 -in ${cert} -noout -subject \ | grep -iPo 'O\s*=\s*\K[^,]+' \ | sed -E "s/\s/_/g;s/'//g;s/\/.*//g;s/\*\.//g;s/.*/\U&/"; done; for cert in certs/servers/*.crt; do openssl x509 -in ${cert} -noout -issuer \ | grep -iPo 'O\s*=\s*\K[^,]+' \ | sed -E "s/\s/_/g;s/'//g;s/\/.*//g;s/\*\.//g;s/.*/\U&/"; done;) | sort -u) for ca in ${ca_list}; do echo -e "\n-> Generating p11-kit source anchors for CA \"${ca}\"" local out=pki/ca-trust-source/anchors/${ca,,}-ca-bundle.crt mkdir -p $(dirname ${out}); in= for c in $(find certs/{ca-root,ca-trust,servers}/ -name ${ca}*); do echo "+ Loading CA certificate: ${c}" in="${in} -certfile ${c}" done \ && openssl crl2pkcs7 -nocrl ${in} \ | openssl pkcs7 -print_certs -out ${out} done } cmd=${@:1}; shift ${cmd} ${@} exit 0 # vim: ts=2:sw=2:sts=2:et