-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathupki-cli.sh
More file actions
executable file
·158 lines (146 loc) · 4.98 KB
/
upki-cli.sh
File metadata and controls
executable file
·158 lines (146 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/bin/bash
if [[ $EUID -eq 0 ]]; then
echo "This script must NOT be run as root !"
exit 1
fi
echo -e "\t\t..:: uPKI Client ::.."
# Set default VARS
RA_URL='certificates.prohacktive.io' # Should be remove in public release !!! ;)
CERT_PATH="${HOME}/.upki"
if [[ ! -d ${CERT_PATH} ]]; then
mkdir -p ${CERT_PATH}
fi
function usage {
echo "This script allow generation of uPKI client certificates and keys."
echo "Note: certificates, requests and keys will be generated by default in ${CERT_PATH}"
echo ""
echo "Usage: $0 [--add] [--renew]"
echo ""
echo "Options:"
echo -e "\t- url\tSet the RA url"
echo -e "\t- add\tAdd a certificate"
echo -e "\t- renew\tRenew all certificates"
echo -e "\t- path\tSet the path where to generate certificates"
echo ""
}
function check_ca {
# Retrieve CA certificate
echo "[+] Check CA certificate"
wget -q -O /tmp/ca.crt --no-check-certificate https://${RA_URL}/certs/ca.crt
CA_DATA=$(cat /tmp/ca.crt | jq '.certificate' | sed 's/"//g')
echo -ne "${CA_DATA}" > /tmp/ca.crt
CHECKSUM=$(cat /tmp/ca.crt | sha256sum)
# If first time store file
if [[ ! -f "${CERT_PATH}/ca.crt" ]]; then
echo -ne "${CA_DATA}" > "${CERT_PATH}/ca.crt"
# If CA certificate exists check it has not changed!
else
NEO_CHKSUM=$(cat "${CERT_PATH}/ca.crt" | sha256sum)
if [[ "${CHECKSUM}" != "${NEO_CHKSUM}" ]]; then
echo "[!] WARNING CA CERTIFICATE HAS CHANGED!!"
while true; do
read -p "Do you want to continue ? (y/n)" yn
case $yn in
[Yy]* ) echo -ne "${CA_DATA}" > "${CERT_PATH}/ca.crt"; break;;
[Nn]* ) exit;;
* ) echo "Please answer 'Y' or 'N'.";;
esac
done
fi
fi
}
function generate {
echo "[+] Retrieve magic command"
wget -q -O /tmp/magic --content-on-error --ca-cert="${CERT_PATH}/ca.crt" --post-data="{'cn':${2},'sans':[]}" --header='Content-Type:application/json' "https://${RA_URL}/magic/${1}"
MAGIC_CMD=$(cat /tmp/magic | jq '.command')
echo -ne ${MAGIC_CMD}
# Auto-certify node
certify $1 $2
}
function certify {
# Gather CSR data for certificate renewal
CSR_DATA=$(cat ${CERT_PATH}/${1}.${2}.csr)
echo "[+] Certify node (${1}) ${2}"
wget -q -O /tmp/client.crt --content-on-error --ca-certificate="${CERT_PATH}/ca.crt" --post-data="data={'CSR':${3}}" --header='Content-Type:application/json' "https://${RA_URL}/certify"
cat /tmp/client.crt
# Should update node state to 'signed' in ${HOME}/.upki/cli.nodes.json
}
function renew {
echo "[+] Renew node (${1}) ${2}"
wget -q -O /tmp/client.crt --content-on-error --ca-certificate="${CERT_PATH}/ca.crt" --private-key="${CERT_PATH}/${1}.${2}.key" --certificate="${CERT_PATH}/${1}.${2}.crt" "https://${RA_URL}/clients/renew"
cat /tmp/client.crt
}
POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-a|--add)
ADD=1
shift # past argument
;;
-u|--url)
RA_URL="$2"
shift # past argument
shift # past argument
;;
-p|--path)
CERT_PATH="$2"
shift # past argument
shift # past argument
;;
-r|--renew)
RENEW=1
shift # past argument
;;
-h|--help)
usage >&2
shift # past argument
exit 1
;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
# Avoid calling script without action
if [[ -z ${ADD} && -z ${RENEW} ]]; then
usage
exit 1
fi
# Always check CA Certificates
check_ca
# Avoid renew without config
if [[ ! -f ${HOME}/.upki/cli.nodes.json && ${RENEW} ]]; then
echo "[!] Missing uPKI config, please add certificate first"
exit 1
# Setup new certificate
elif [[ ${ADD} ]]; then
read -p "Set certificate name (CN): " NAME
read -p "Set certificate profile: " PROFILE
echo "[+] Store config data"
NEO_ENTRY="{ \"state\": \"init\", \"name\": \"${NAME}\", \"profile\": \"${PROFILE}\", \"sans\": [], \"p12\": false, \"passwd\": null }"
cat ${HOME}/.upki/cli.nodes.json | jq ".[.| length] |= . + ${NEO_ENTRY}" > ${HOME}/.upki/cli.nodes.json
# Generate key, request and certificate
generate ${PROFILE} ${NAME}
# Renew existing certs
else
CONFIG_DATA=$(cat ${HOME}/.upki/cli.nodes.json)
for row in $(echo "${CONFIG_DATA}" | jq -r '.[] | @base64'); do
_jq() {
echo ${row} | base64 --decode | jq -r ${1}
}
NAME=$(_jq '.name')
PROFILE=$(_jq '.profile')
STATE=$(_jq '.state')
# If CSR file does not exists
if [[ "${STATE}" != "signed" || ! -f ${CERT_PATH}/${PROFILE}.${NAME}.csr ]]; then
generate ${PROFILE} ${NAME}
# No need to renew a new cert
exit 1
fi
renew ${PROFILE} ${NAME}
done
fi