mng_gpg 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. #!/bin/sh
  2. #set -x
  3. clear
  4. ###
  5. #
  6. # Author: Stéphane HUC
  7. # mail: devs@stephane-huc.net
  8. #
  9. # License: GNU/GPL 3
  10. #
  11. # GitLab: https://framasoft.git/hucste/tools/
  12. #
  13. # Date: 2016/11/30
  14. #
  15. ###
  16. ###
  17. # Manage Key GPG by fingerprint
  18. ###
  19. #
  20. # This script need gpg, hkt, openssl tools:
  21. # For .deb: apt-get install gnupg gnupg-curl hopenpgp-tools parcimonie openssl
  22. #
  23. ###
  24. dir_gpg="/home/$USER/.gnupg/" # folder GPG
  25. file_cfg_gpg="${dir_gpg}gpg.conf"
  26. installer="apt install" # modify segun your distrib!
  27. paquets="gnupg gnupg-curl hopenpgp-tools parcimonie openssl"
  28. # variables mssg
  29. mssg_ask_dl_crt_sks="Voulez-vous télécharger le certificat SKS depuis le serveur : "
  30. mssg_ask_dl_fp="Voulez-vous télécharger la clé correspondante à l'empreinte ?"
  31. mssg_ask_mail="Veuillez saisir votre email : "
  32. mssg_ask_1stall_bin="Voulez-vous installer les paquets nécessaires ? (${paquets}) : "
  33. mssg_ask_1stall_crt_sks="Voulez-vous installer le certificat des serveurs SKS ?"
  34. mssg_ask_local_sign_fp="Voulez-vous signer localement la clé GPG correspondant à l'empreinte ? "
  35. mssg_ask_mng_crt_sks="Voulez-vous vérifier puis inspecter le certificat SKS téléchargé ? "
  36. mssg_ask_ok_fp="*** S'il y a une information en rouge, vous ne devriez probablement pas utiliser la clé GPG correspondante ! \n Est-ce que tout est vert ? "
  37. mssg_ask_public_sign_fp="Voulez-vous signer publiquement la clé GPG correspondant à l'empreinte ? "
  38. mssg_ask_vrf_fp="Voulez-vous vérifier la clé correspondante à l'empreinte ? "
  39. mssg_help="
  40. ############################### Utilisation ###################################
  41. Usage: $0 [OPTION] <argument>
  42. Gérer des clés GPG ... de préférence, par leur empreinte !
  43. *** Options de base ***
  44. -h|-H|-?|help : Afficher l'aide
  45. create : Créer correctement une clé GPG
  46. fp|fingerprint : Gérer correctement une clé GPG à partir de son empreinte ...
  47. NE PAS LE FAIRE avec l'identifiant GPG long ou court !
  48. Mettez l'empreinte entre simple quote ou double quotes ...
  49. *** Autres Commandes ***
  50. info : Quelques informations pertinentes à prendre en compte ...
  51. install|i-sks : Installer le certificat des serveurs SKS, puis le vérifier.
  52. C'est même la première chose à faire en utilisant ce script !
  53. i-bin : Installer les binaires suivants :
  54. ${paquets}
  55. ###############################################################################
  56. "
  57. mssg_1fo_bad_uid="Vous n'avez pas lancé le script avec des droits administrateurs !"
  58. mssg_1fo_cfg="
  59. ###############################################################################
  60. Vous devriez modifier votre fichier de config personnel ${file_cfg_gpg}
  61. en ajoutant ces autres options :
  62. keyserver-options include-revoked
  63. keyserver-options no-try-dns-srv
  64. list-options show-uid-validity
  65. verify-options show-uid-validity
  66. use-agent
  67. auto-key-locate local
  68. auto-key-locate keyserver
  69. cert-digest-algo SHA512
  70. default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
  71. fixed-list-mode
  72. keyid-format 0xlong
  73. personal-cipher-preferences AES256 AES192 AES CAST5
  74. personal-digest-preferences SHA512
  75. utf8-strings
  76. with-fingerprint
  77. Renseignez-vous sur chacune de ces options, mais sachez que ce sont les plus
  78. sécurisantes à ce jour !
  79. ###############################################################################
  80. "
  81. mssg_1fo_cfg_sks="
  82. ###############################################################################
  83. Vous devriez configurer votre fichier personnel ${file_cfg_gpg},
  84. pour y ajouter/modifier les options suivantes :
  85. keyserver hkps://hkps.pool.sks-keyservers.net
  86. keyserver-options ca-cert-file=${dir_gpg}/sks-keyservers.netCA.pem
  87. keyserver-options no-honor-keyserver-url
  88. Ensuite, il vous faut ajouter les paquets suivants : gnupg-curl, parcimonie
  89. N'utilisez plus l'option '--refresh-keys' de gpg ; c'est parcimonie qui le
  90. fera de manière sécurisée, selon les ajouts que vous venez de faire à votre
  91. fichier de config personnel.
  92. Ces options permettent d'interroger les serveurs de clés, en SSL,
  93. sur le port 443 !
  94. ###############################################################################
  95. "
  96. mssg_1fo_create_end="### Création de votre clé GPG terminée ! ###"
  97. mssg_1fo_create_key="
  98. ###############################################################################
  99. Vous vous apprêtez à créer une clé GPG - très bien !
  100. Par sécurité, choisissez seulement l'algorithme RSA ...
  101. Choisissez une longueur de 4096 bits - à spécifier impérativement !!!
  102. Renseignez ABSOLUMENT une adresse mail valide, et
  103. Paramétrez une phrase-de-passe - ne LAISSEZ pas vide !!! (min 13 caractères)
  104. ###############################################################################
  105. "
  106. mssg_1fo_dl_crt_sks="=> Téléchargement du certificat SKS : "
  107. mssg_1fo_dlt_key="
  108. ###############################################################################
  109. Vous allez supprimer la clé secrete !
  110. Si c'est bien votre choix, répondez par 'y' aux questions ...
  111. ###############################################################################
  112. "
  113. mssg_1fo_edit_key_photo="
  114. ###############################################################################
  115. Ajouter une photo est une très bonne idée !
  116. Pour ajouter une photo à votre clé GPG, il vous faudra taper quelques
  117. informations :
  118. Quand vous verrez l'invite 'gpg >', écrivez : addphoto
  119. 1/ Enter JPEG filename for photo ID: /dir_img/votre_photo.jpg
  120. 2/ Confirmez par 'y'
  121. 3/ Restituez votre phrase-de-passe lorsqu'elle sera demandée
  122. Puis à l'invite 'gpg >', écrivez : save
  123. ###############################################################################
  124. "
  125. mssg_1fo_edit_key_pref="
  126. ###############################################################################
  127. Paramétrez les préférences de hash est une bonne chose à faire !
  128. Pour cela, il vous faudra taper quelques informations :
  129. Quand vous verrez l'invite 'gpg >', écrivez :
  130. setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
  131. 1/ Confirmez par 'y'
  132. 2/ Restituez votre phrase-de-passe lorsqu'elle sera demandée
  133. Puis à l'invite 'gpg >', écrivez : save
  134. ###############################################################################
  135. "
  136. mssg_1fo_edit_key_subkey="
  137. ###############################################################################
  138. Ajoutez une sous-clé, pour signer, est une bonne chose à faire !
  139. Pour cela, il vous faudra taper quelques informations :
  140. Quand vous verrez l'invite 'gpg >', écrivez : addkey
  141. 1/ Restituez votre phrase-de-passe lorsqu'elle sera demandée ...
  142. 2/ Choisissez l'algorithme RSA pour signer
  143. 3/ Choisissez une longueur de 4096 bits - à spécifier impérativement !!!
  144. 4/ Choisissez la durée de validité : pas besoin d'expiration
  145. 5/ Confirmez par 'y' les autres choix
  146. Puis à l'invite 'gpg >', écrivez : save
  147. ###############################################################################
  148. "
  149. mssg_1fo_fp_main="Empreinte de la clé principale : "
  150. mssg_1fo_import_key="Vous allez importer un fichier de clés '${file}' !"
  151. mssg_1fo_1spect_crt_sks_ssl="=> Inspection du certificat SKS avec OpenSSL : "
  152. mssg_1fo_1stall_bin="### Phase d'installation de paquets nécessaires ###"
  153. mssg_1fo_1stall_crt_sks="### Phase d'installation du certificat SKS nécessaire ###"
  154. mssg_1fo_1stall_local_crt_sks="=> Téléchargement du fichier '%s' vers le répertoire '/home/%s/.gnupg/' : \n"
  155. mssg_1fo_1stall_end="### Installation du certificat SKS terminée ! ###"
  156. mssg_1fo_rvk_key="
  157. ###############################################################################
  158. Maintenant, vous allez générer un certificat de révocation, nécessaire ...
  159. Ce fichier de révocation sera utile si votre clé GPG est perdue, volée, ou
  160. compromise !
  161. ###############################################################################
  162. "
  163. mssg_1fo_script="Veuillez exécuter le script ainsi : "
  164. mssg_1fo_svg_asc="
  165. ###############################################################################
  166. Il est IMPÉRATIF de sauvegarder vos fichiers de révocation, vos exports de
  167. clés privés ailleurs !
  168. NE LES LAISSEZ PAS SUR/DANS VOTRE DISQUE DUR !
  169. PROTÉGEZ-LES ... Cela est de votre responsabilité !!!
  170. ###############################################################################
  171. "
  172. mssg_1fo_vrf_crt_sks_gpg="=> Vérification du certificat SKS par GPG : "
  173. mssg_1fo_vrf_crt_sks_ssl="=> Vérification du certificat SKS avec OpenSSL : "
  174. mssg_ko_crt_sks="Le certificat SKS est incorrect \n Ne l'utilisez pas !"
  175. mssg_ko_export_file="Il semble que le fichier ${file} n'a pas pu être exporté !"
  176. mssg_ko_not_fp="Vous n'avez pas saisi d'identifiant de clé, voire mieux d'empreinte de clé GPG ! "
  177. mssg_ko_rvk_cert="Le certificat de revocation '${file_rvk_crt}' n'a pas pu être créé !"
  178. mssg_ko_script="Le script va s'arrêter !"
  179. mssg_ok_crt_sks="Le certificat SKS est correct !"
  180. mssg_ok_export_file="Il semble que le fichier ${file} a pu être exporté !"
  181. mssg_ok_rvk_cert="Le certificat de revocation '${file_rvk_crt}' a bien été créé !"
  182. mssg_ready_to_create_key="Êtes-vous prêt à créer votre clé GPG ? "
  183. mssg_ready_to_edit_key="Êtes-vous prêt à modifier votre clé GPG ? "
  184. # SKS Informations url: https://sks-keyservers.net/verify_tls.php
  185. sks_file_cert_fingerprint="79:1B:27:A3:8E:66:7F:80:27:81:4D:4E:68:E7:C4:78:A4:5D:5A:17"
  186. sks_file_cert_url="https://sks-keyservers.net/sks-keyservers.netCA.pem"
  187. sks_file_sign_url="https://sks-keyservers.net/sks-keyservers.netCA.pem.asc"
  188. sks_x509_ski="E4 C3 2A 09 14 67 D8 4D 52 12 4E 93 3C 13 E8 A0 8D DA B6 F3" # SKS X509v3 Subject Key Identifier
  189. # others variables: DO NOT TOUCH !!!
  190. choice="$1"
  191. fingerprint="$2"
  192. file_cert=""
  193. file_id="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)"
  194. file_output_gpg="${dir_gpg}/gpg_output.${file_id}"
  195. gpg_email=""
  196. pwd="$(pwd)"
  197. search_fp="Empreinte|Fingerprint"
  198. search_sign="signature"
  199. ###############################################################################
  200. ####
  201. ##
  202. # FUNCTIONS
  203. ##
  204. ###
  205. ###############################################################################
  206. ask_mail() {
  207. display_mssg "" "${mssg_ask_mail}"
  208. read gpg_email
  209. }
  210. confirm () {
  211. mssg="$(printf "%s" "$1" "$2")"
  212. read -r -p "${mssg} [y|n] " response
  213. case "$response" in
  214. y|Y|o|O|1)
  215. true
  216. ;;
  217. *)
  218. false
  219. ;;
  220. esac
  221. }
  222. delete_file() { [ $(which shred) ] && shred --remove "$1" || rm -f "$1"; }
  223. detect_uid() {
  224. if [ $(id -u) -ne 0 ]; then
  225. display_mssg "KO" "${mssg_1fo_bad_uid}"
  226. stop
  227. exit 1;
  228. fi
  229. }
  230. display_mssg() {
  231. local statut="$1" info="$2" var="$3"
  232. case "${statut}" in
  233. "KO") printf "[ \033[0;31m%s\033[0;m ]\t%s\n" "${statut}" "${info}" ;;
  234. "OK") printf "[ \033[0;32m%s\033[0;m ]\t%s\n" "${statut}" "${info}" ;;
  235. *)
  236. if [ -n "${var}" ]; then
  237. printf "%s %s\n" "${info}" "${var}"
  238. else
  239. printf "%s\n" "${info}"
  240. fi
  241. ;;
  242. esac
  243. unset statut info
  244. }
  245. gpg_create_key() {
  246. display_mssg "" "${mssg_1fo_create_key}"
  247. if confirm "${mssg_ready_to_create_key}"; then
  248. if gpg --gen-key; then
  249. sleep 1
  250. gpg_edit_key "photo"
  251. sleep 1
  252. gpg_edit_key "pref"
  253. sleep 1
  254. gpg_edit_key "subkey"
  255. sleep 1
  256. gpg_create_rvk_cert
  257. sleep 1
  258. gpg_export_master_key "private"
  259. gpg_export_master_key "public"
  260. sleep 1
  261. display_mssg "" "${mssg_1fo_svg_asc}"
  262. sleep 1
  263. gpg_from_master_to_ptb_key
  264. display_mssg "" "${mssg_1fo_create_end}"
  265. fi
  266. fi
  267. }
  268. gpg_create_rvk_cert(){
  269. display_mssg "" "${mssg_1fo_rvk_key}"
  270. [ -z "${gpg_mail}" ] && ask_mail
  271. local file_rvk_crt="${dir_gpg}${gpg_email}.rev.asc"
  272. if gpg --output "${file_rvk_crt}" --gen-revoke "${gpg_email}"; then
  273. display_mssg "OK" "${mssg_ok_rvk_crt}"
  274. else
  275. display_mssg "KO" "${mssg_ko_rvk_crt}"
  276. fi
  277. unset file_rvk_crt
  278. }
  279. gpg_echo_secrets_fingerprints() {
  280. # pour memo ; afficher l'empreinte de ses clés privées
  281. gpg --with-fingerprint --list-secret-key
  282. }
  283. gpg_edit_key() {
  284. if confirm "${mssg_ready_to_edit_key}"; then
  285. case "$1" in
  286. "photo") display_mssg "" "${mssg_1fo_edit_key_photo}" ;;
  287. "pref") display_mssg "" "${mssg_1fo_edit_key_pref}" ;;
  288. "subkey") display_mssg "" "${mssg_1fo_edit_key_subkey}" ;;
  289. esac
  290. [ -z "${gpg_mail}" ] && ask_mail
  291. gpg --edit-key "${gpg_email}"
  292. fi
  293. }
  294. gpg_export_master_key() {
  295. [ -z "${gpg_mail}" ] && ask_mail
  296. case "$1" in
  297. "private")
  298. file="${dir_gpg}${gpg_email}.private_key.asc"
  299. gpg --export-secret-keys --armor "${gpg_email}" > "${file}"
  300. ;;
  301. "public")
  302. file="${dir_gpg}${gpg_email}.public_key.asc"
  303. gpg --export --armor "${gpg_email}" > "${file}"
  304. ;;
  305. esac
  306. [ -f "${file}" ] && display_mssg "OK" "${mssg_ok_export_file}" || display_mssg "KO" "${mssg_ko_export_file}"
  307. unset file_asc
  308. }
  309. gpg_from_master_to_ptb_key() {
  310. [ -z "${gpg_mail}" ] && ask_mail
  311. file="${dir_gpg}${gpg_email}_subkeys"
  312. gpg --export-secret-subkeys "${gpg_email}" > "${file}"
  313. if [ -f "${file}" ]; then
  314. display_mssg "OK" "${mssg_ok_export_file}"
  315. confirm "${mssg_1fo_dlt_key}" && gpg --delete-secret-key "${gpg_email}"
  316. display_mssg "" "${mssg_1fo_import_key}" && gpg --import "${file}"
  317. delete_file "${file}"
  318. gpg_echo_secrets_fingerprints
  319. else
  320. display_mssg "KO" "${mssg_ko_export_file}"
  321. fi
  322. unset file_subkeys
  323. }
  324. gpg_get_fingerprint() { gpg --recv-key "${fingerprint}"; }
  325. gpg_send_fingerprint() { gpg --send-keys "${fingerprint}"; }
  326. gpg_sign_fingerprint() {
  327. case "$1" in
  328. "local") gpg --lsign-key "${fingerprint}" ;;
  329. "public") gpg --sign-key "${fingerprint}" ;;
  330. esac
  331. }
  332. gpg_verify() {
  333. local file_sign="$1" file_to_sign="$2"
  334. gpg --verify "${file_sign}" "${file_to_sign}" 2>"${file_output_gpg}"
  335. }
  336. hkt_verify_fingerprint() { hkt export-pubkeys "${fingerprint}" | hokey lint; }
  337. mng_gpg_infos() {
  338. awk '/'${search_sign}'/ { print $0 }' "${file_output_gpg}"
  339. fingerprint="$(awk -F ':' '/^'${search_fp}'/ { print $2 }' "${file_output_gpg}")"
  340. display_mssg "" "${mssg_1fo_fp_main}${fingerprint}"
  341. }
  342. install_paquets() {
  343. display_mssg "" "${mssg_1fo_1stall_bin}"
  344. confirm "${mssg_ask_1stall_bin}" && { detect_uid && ${installer} gnupg gnupg-curl hopenpgp-tools parcimonie openssl; }
  345. }
  346. install_sks() {
  347. if confirm "${mssg_ask_dl_crt_sks}" "${sks_file_cert_url}"; then
  348. display_mssg "" "${mssg_1fo_dl_crt_sks}"
  349. #dld cert and sign files from sks server.
  350. for file in $sks_file_cert_url $sks_file_sign_url; do
  351. printf "${mssg_1fo_1stall_local_crt_sks}" "${file}" "$USER"
  352. cd "${dir_gpg}"
  353. curl -O $file
  354. cd "${pwd}"
  355. done
  356. fi
  357. if confirm "${mssg_ask_mng_crt_sks}"; then
  358. file_cert="/home/$USER/.gnupg/$(echo "$sks_file_cert_url" | cut -d '/' -f 4)"
  359. sks_X509_ski="$(replace "${sks_x509_ski}")" # DO NOT TOUCH;
  360. # verify cert SKS
  361. display_mssg "" "${mssg_1fo_vrf_crt_sks_ssl}" "${file_cert}"
  362. ossl_verify_cert
  363. sleep 1
  364. # inspect cert SKS
  365. display_mssg "" "${mssg_1fo_1spect_crt_sks_ssl}" "${file_cert}"
  366. [ "$(ossl_inspect_cert)" = "${sks_X509_ski}" ] && display_mssg "OK" "${mssg_ok_crt_sks}" || display_mssg "KO" "${mssg_ko_crt_sks}"
  367. sleep 1
  368. # verify with GPG
  369. display_mssg "" "${mssg_1fo_vrf_crt_sks_gpg}"
  370. gpg_verify "${file_cert}.asc" "${file_cert}"
  371. sleep 1
  372. # verify infos GPG
  373. mng_gpg_infos
  374. sleep 1
  375. mng_fingerprint
  376. sleep 1
  377. fi
  378. display_mssg "" "${mssg_1fo_cfg_sks}"
  379. sleep 1
  380. display_mssg "" "${mssg_1fo_1stall_end}"
  381. delete_file "${file_output_gpg}"
  382. }
  383. launcher() {
  384. case "${choice}" in
  385. create)
  386. gpg_create_key
  387. ;;
  388. fp|fingerprint)
  389. if [ -n "${fingerprint}" ]; then
  390. mng_fingerprint
  391. else
  392. display_mssg "KO" "${mssg_ko_not_fp}"
  393. display_mssg "" "${mssg_1fo_script}$0 fingerprint \"gpg:fingreprint\" !"
  394. fi
  395. ;;
  396. -h|-H|-\?|help)
  397. display_mssg "" "${mssg_help}"
  398. ;;
  399. info)
  400. display_mssg "" "${mssg_1fo_cfg}${mssg_1fo_cfg_sks}"
  401. ;;
  402. i-bin)
  403. install_paquets
  404. ;;
  405. i-sks|install)
  406. display_mssg "" "${mssg_1fo_1stall_crt_sks}"
  407. confirm "${mssg_ask_1stall_crt_sks}" && install_sks
  408. ;;
  409. *)
  410. display_mssg "" "${mssg_1fo_script}$0 [create|fingerprint|help|info|install] <argument>"
  411. stop
  412. ;;
  413. esac
  414. }
  415. mng_fingerprint() {
  416. confirm "${mssg_ask_dl_fp}" "${fingerprint}" && gpg_get_fingerprint
  417. sleep 1
  418. confirm "${mssg_ask_vrf_fp}" "${fingerprint}" && hkt_verify_fingerprint
  419. confirm "${mssg_ask_ok_fp}" || stop
  420. confirm "${mssg_ask_local_sign_fp}" "${fingerprint}" && gpg_sign_fingerprint "local"
  421. confirm "${mssg_ask_public_sign_fp}" "${fingerprint}" && gpg_sign_fingerprint "public"
  422. }
  423. ossl_inspect_cert() {
  424. #openssl x509 -in "${file_cert}" -noout -text | grep "X509v3 Subject Key Identifier" -A1;
  425. openssl x509 -in "${file_cert}" -noout -text | grep "X509v3 Subject Key Identifier" -A1 | tail -n1 | tr -d ' ';
  426. }
  427. ossl_verify_cert() { openssl verify -trusted "${file_cert}" -check_ss_sig "${file_cert}"; }
  428. # replace symbole space by ':' if exists...
  429. replace() { printf '%s' "$1" | sed -e 's# #:#g'; }
  430. stop() {
  431. display_mssg "KO" "${mssg_ko_script}"
  432. exit 1;
  433. }
  434. launcher