{"id":20677631,"url":"https://github.com/kicksecure/gpg-bash-lib","last_synced_at":"2025-04-19T21:05:29.353Z","repository":{"id":25888997,"uuid":"29329451","full_name":"Kicksecure/gpg-bash-lib","owner":"Kicksecure","description":"gpg file verification bash library, addresses comprehensive threat model, that covers file name tampering, indefinite freeze, rollback, endless data attacks, etc.","archived":false,"fork":false,"pushed_at":"2023-11-11T20:15:12.000Z","size":908,"stargazers_count":12,"open_issues_count":1,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2023-11-11T21:23:22.630Z","etag":null,"topics":["bash-scripts","diagnostic-output","gpg","security","verification"],"latest_commit_sha":null,"homepage":"https://www.kicksecure.com/wiki/imprint","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kicksecure.png","metadata":{"files":{"readme":"README.mediawiki","changelog":"changelog.upstream","contributing":"CONTRIBUTING.md","funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2015-01-16T02:43:53.000Z","updated_at":"2023-11-11T21:23:26.003Z","dependencies_parsed_at":"2023-11-11T21:23:25.770Z","dependency_job_id":"c1208736-be89-4fb0-8798-9f9eb642546f","html_url":"https://github.com/Kicksecure/gpg-bash-lib","commit_stats":null,"previous_names":[],"tags_count":40,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kicksecure%2Fgpg-bash-lib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kicksecure%2Fgpg-bash-lib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kicksecure%2Fgpg-bash-lib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kicksecure%2Fgpg-bash-lib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kicksecure","download_url":"https://codeload.github.com/Kicksecure/gpg-bash-lib/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224969898,"owners_count":17400294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash-scripts","diagnostic-output","gpg","security","verification"],"created_at":"2024-11-16T21:16:33.949Z","updated_at":"2024-11-16T21:16:34.530Z","avatar_url":"https://github.com/Kicksecure.png","language":"Shell","readme":"= Why =\n\nWriting bash scripts that do file verification using gpg that really is secure\nand passes a comprehensive threat model, that covers indefinite freeze,\nrollback, endless data attacks, etc. is hard.\n\ngpg-bash-lib's goal is to provide a bash library that we can collaboratively\ndevelop, audit and abstract the hard work into reuseable functions.\n\nChecking gpg exit codes only is insufficient.\n[http://lists.gnupg.org/pipermail/gnupg-devel/2005-December/022559.html Quote Werner Koch]\n([https://gnupg.org/ gnupg] lead developer):\n\u003cblockquote\u003e\"there is no clear distinction between the codes and for proper error reporting\nyou are advised to use the --status-fd messages.\"\u003c/blockquote\u003e\n\n(For a definition of these attacks, see\n[https://www.updateframework.com TUF] ([https://github.com/theupdateframework/tuf The Update Framework])'s\n[https://github.com/theupdateframework/tuf/blob/develop/SECURITY.md threat model] ([http://www.webcitation.org/6F7Io2ncN w]).)\n\n= What does it do =\n\n* Abstracts file verification into common functions.\n* Allows detecting of stale files, i.e. detection downgrade or indefinite freeze attacks by implementing a valid-until like mechanism.\n* Internally parses gpg's --status-file output.\n* It is signal friendly.\n* Detects endless data attacks, aborts and reports this.\n* Detects indefinite freeze and rollback (downgrade) attacks and reports this.\n* Can help with verification of names of files, that are otherwise not covered by default when using gpg.\n* Provide diagnostic output (variables) that contain information if the local clock is sane by comparing signature creation date with local clock.\n\n= What does it NOT do =\n\n* Anything else not mentioned above in \"What does it do\".\n\n= Requirements =\n\n* bash\n\n= Installation =\n\u003cpre\u003e\nsudo make install\n\u003c/pre\u003e\n\nOr see [https://github.com/Whonix/gpg-bash-lib/blob/master/README_generic.md \u003ctt\u003eREADME_generic.md\u003c/tt\u003e].\n\n= Usage =\n\n== Practical ==\n\n=== Examples ===\nSee [https://github.com/Whonix/gpg-bash-lib/blob/master/usr/share/gpg-bash-lib/examples/ \u003ctt\u003e/usr/share/gpg-bash-lib/examples/\u003c/tt\u003e] folder.\n\n=== Mini Demo ===\nAfter installation, if you would run the following command.\n\n[https://github.com/Whonix/gpg-bash-lib/blob/master/usr/share/gpg-bash-lib/examples/one \u003ctt\u003e/usr/share/gpg-bash-lib/examples/one\u003c/tt\u003e]\n\nYou would see the following output.\n\n\u003cpre\u003e\nyour_script_begin: ...\nverification: BEGIN\nverification: END\nyour_script_output: BEGIN\ngpg_bash_lib_output_failure_status: false\ngpg_bash_lib_output_gpg_verify_exit_code: 0\ngpg_bash_lib_output_goodsig_status: true\ngpg_bash_lib_output_validsig_status: true\ngpg_bash_lib_output_fingerprint_in_hex: 5E08605EBEA0FE88695DCB88FD0A8B4171DFE4E4\ngpg_bash_lib_output_signed_on_unixtime: 1422049448\ngpg_bash_lib_output_signed_on_date: March 01 13:56:27 UTC 2015\ngpg_bash_lib_output_notation[$file@name]: test-file\ngpg_bash_lib_output_file_name_tampering: false\ngpg_bash_lib_output_freshness_status: true\ngpg_bash_lib_output_freshness_detail: current\ngpg_bash_lib_output_freshness_msg:\n- Freshness: Signature is current.\n- valid-max: Signatures are valid up to 30 days.\n- Signature Creation Date: March 01 13:56:27 UTC 2015\n- Current System Date    : March 02 16:0:55 UTC 2015\n- Local System Clock: Your clock seems okay.\n- Relative Signature Creation Time: According to your system clock, signature was created 2 days 26 minutes 3 seconds ago.\ngpg_bash_lib_output_alright_status: true\nyour_script_output: END\n\u003c/pre\u003e\n\nAll information (Signature Creation Date, etc.) are easily accessible through\nseparate variables, which are all documented below.\n\n== Example Implementations ==\n\n* [https://github.com/Whonix/whonixcheck whonixcheck]: See function [https://github.com/Whonix/whonixcheck/blob/fd60ad1c09d3681fd15c1370d1fbf3a9ba854aad/usr/lib/whonixcheck/check_news#L122 verify_whonix_news].\n* [https://github.com/Whonix/tb-updater tb-updater]: See function [https://github.com/Whonix/tb-updater/blob/95d0ce13c601cb62d5f70b06dd80eb92d857cfbe/usr/bin/update-torbrowser#L901 tb_gpg_verify] and function [https://github.com/Whonix/tb-updater/blob/95d0ce13c601cb62d5f70b06dd80eb92d857cfbe/usr/bin/update-torbrowser#L644 tb_confirm_update].\n\n== Theoretical ==\n\n=== Introduction ===\n\nIt is assumed, that your script downloaded a data file as well as a signature file. A separate folder containing the keys that are supposed to be used for gpg verification, such as for example \u003ctt\u003e/usr/share/program-name/signing-keys.d\u003c/tt\u003e is required as a prerequisite. You can then use this library to do the gpg verification for you.\n\nSet at least all required \u003ctt\u003egpg_bash_lib_input_*\u003c/tt\u003e variables, that are documented below. Then run the main function \u003ctt\u003egpg_bash_lib_function_main_verify\u003c/tt\u003e (or just one function you wish to use). Then enjoy the \u003ctt\u003egpg_bash_lib_output_*\u003c/tt\u003e variables, that this library has set for you.\n\nIf you wish to run \u003ctt\u003egpg_bash_lib_function_main_verify\u003c/tt\u003e another time, store the variables you want to keep in variables of your own, because they will be overridden on subsequent runs.\n\n=== Variables ===\n\n==== Input Variables ====\n\n===== \u003ctt\u003egpg_bash_lib_input_temp_folder\u003c/tt\u003e =====\n* description: Folder that can be used for temporary files. Warning: that folder will be deleted before usage to make sure it is clean!\n* required: no\n* defaults to: \u003ctt\u003e\"$(mktemp --directory)\"\u003c/tt\u003e\n* expected value: \u003ctt\u003e/path/to/temp/folder\u003c/tt\u003e\n* example: \u003ctt\u003egpg_bash_lib_input_temp_folder=/home/user/some-tmp-folder\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_key_import_dir\u003c/tt\u003e =====\n* description: The folder that contains gpg signing keys that are supposed to be accepted. Must already exist. Must contain gpg public keys.\n* required: yes\n* expected value: \u003ctt\u003e/path/to/folder\u003c/tt\u003e\n* example: \u003ctt\u003egpg_bash_lib_input_key_import_dir=/usr/share/program-name/signing-keys.d\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_file_name_enforce\u003c/tt\u003e =====\n* description: Enforce, that the name of the file is stored in the \u003ctt\u003efile@name\u003c/tt\u003e OpenPGP notation and matches the actual file name. If enabled, \u003ctt\u003egpg_bash_lib_output_alright_status\u003c/tt\u003e will be set to \u003ctt\u003etrue\u003c/tt\u003e if it matches. Otherwise to \u003ctt\u003efalse\u003c/tt\u003e. Rather \u003ctt\u003egpg_bash_lib_output_file_name_tampering\u003c/tt\u003e will be set to \u003ctt\u003etrue\u003c/tt\u003e (match), \u003ctt\u003emissing\u003c/tt\u003e (no \u003ctt\u003efile@name\u003c/tt\u003e OpenPGP notation inside the signature, \u003ctt\u003efalse\u003c/tt\u003e (mismatch) accordingly.\n* required: no\n* defaults to: disabled by default\n* expected value: \u003ctt\u003etrue\u003c/tt\u003e or \u003ctt\u003efalse\u003c/tt\u003e\n* example: \u003ctt\u003egpg_bash_lib_input_file_name_enforce=true\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_cleanup\u003c/tt\u003e =====\n* description: Delete the folder stored in the \u003ctt\u003egpg_bash_lib_input_temp_folder\u003c/tt\u003e variable or not.\n* required: no\n* defaults to: disabled by default\n* expected value: \u003ctt\u003etrue\u003c/tt\u003e or \u003ctt\u003efalse\u003c/tt\u003e\n* example: \u003ctt\u003egpg_bash_lib_input_cleanup=true\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_data_file\u003c/tt\u003e =====\n* description: The data file that is supposed to be verified.\n* required: yes\n* expected value: \u003ctt\u003e/path/to/file\u003c/tt\u003e\n* example: \u003ctt\u003egpg_bash_lib_input_data_file=/home/user/some-file.tar.gz\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_sig_file\u003c/tt\u003e =====\n* description: The signature file that is supposed to be verified.\n* required: yes\n* expected value: \u003ctt\u003e/path/to/file\u003c/tt\u003e\n* example: \u003ctt\u003egpg_bash_lib_input_data_file=/home/user/some-file.tar.gz.asc\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_error_handler_extra\u003c/tt\u003e =====\n* description: Custom error handler function you may wish to invoke in case the ERR trap function \u003ctt\u003egpg_bash_lib_function_error_handler\u003c/tt\u003e gets ever hit.\n* required: no\n* defaults to: none\n* expected value: A command or bash function name.\n* example usage:\n\n\u003cpre\u003e\ngpg_bash_lib_input_error_handler_extra='error_handler'\n\u003c/pre\u003e\n\n\u003cpre\u003e\ngpg_bash_lib_input_error_handler_extra='error_handler \"$gpg_bash_lib_output_error_handler_message\"'\n\u003c/pre\u003e\n\n\u003cpre\u003e\ngpg_bash_lib_input_error_handler_extra='error_handler \"$gpg_bash_lib_output_error_handler_message\" ; return 0'\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_verify_timeout_after\u003c/tt\u003e =====\n* description: After how many seconds a gpg verification attempt should be forced timeout. Sends signal SIGTERM to gpg. Useful to defeat an endless data attacks or bugs. Increase this value when you are working with bigger files and/or slow systems.\n* required: no\n* defaults to: 10\n* expected value: integer\n* example: \u003ctt\u003egpg_bash_lib_input_verify_timeout_after=120\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_verify_kill_after\u003c/tt\u003e =====\n* description: After how many seconds, if gpg did not react to SIGTERM due to timeout (see above), signal SIGKILL should be used. Useful to defeat an endless data attacks or bugs.\n* required: no\n* defaults to: 10\n* expected value: integer\n* example: \u003ctt\u003egpg_bash_lib_input_verify_timeout_after=20\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_maximum_age_in_seconds\u003c/tt\u003e =====\n* description: After how many seconds, a signature is considered outdated. gpg adds the creation time of the signature (Signature Creation Date) to every signature. That value is detected (see also variables \u003ctt\u003egpg_bash_lib_output_signed_on_unixtime\u003c/tt\u003e and \u003ctt\u003egpg_bash_lib_output_signed_on_date\u003c/tt\u003e below) and compared against this variable.\n* required: no\n* defaults to: 2592000 (which is sane as 1 month)\n* expected value: integer\n* example: \u003ctt\u003egpg_bash_lib_input_maximum_age_in_seconds=2592000\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_input_slow_clock_lenient_up_to_seconds\u003c/tt\u003e =====\n* description: After how many seconds, a signature is considered outdated.\n* required: no\n* defaults to: 1800 (which is same as 30 minutes)\n* expected value: integer\n* example: \u003ctt\u003egpg_bash_lib_input_slow_clock_lenient_up_to_seconds=1800\u003c/tt\u003e\n\n==== Output Variables ====\n\n===== \u003ctt\u003egpg_bash_lib_output_failure_status\u003c/tt\u003e =====\n* possible values: \u003ctt\u003etrue\u003c/tt\u003e or \u003ctt\u003efalse\u003c/tt\u003e\n* recommendation: Make sure to check for this value! Since the trap \u003ctt\u003egpg_bash_lib_function_error_handler\u003c/tt\u003e has been invoked, something unexpected, a bug has occurred. Regard this as verification failed.\n* example usage:\n\u003cpre\u003e\nif [ \"$gpg_bash_lib_output_failure_status\" = \"true\" ]; then\n   echo 'Fatal signature verification error! Report this bug!' \u003e\u00262\n   exit 1\nfi\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_diagnostic_message\u003c/tt\u003e =====\n* possible values: A verbose diagnostic textual string.\n* recommendation: Display this value when running your script in verbose mode.\n* example content:\n\u003cpre\u003e\ngpg_bash_lib_internal_gpg_verify_status_fd_file: /tmp/tmp.lZDa3dOyUr/gpg_bash_lib_internal_gpg_verify_status_fd_file\ngpg_bash_lib_internal_gpg_verify_output_file: /tmp/tmp.lZDa3dOyUr/gpg_bash_lib_internal_gpg_verify_output_file\ngpg_bash_lib_output_gpg_import_output:\ngpg: keyring `/tmp/tmp.lZDa3dOyUr/secring.gpg' created\ngpg: keyring `/tmp/tmp.lZDa3dOyUr/pubring.gpg' created\ngpg: /tmp/tmp.lZDa3dOyUr/trustdb.gpg: trustdb created\ngpg: key 01C1FA07: public key \"auto generated local signing key \u003cauto@local-signing.key\u003e\" imported\ngpg: Total number processed: 1\ngpg:               imported: 1  (RSA: 1)\ngpg_bash_lib_output_gpg_verify_output:\ngpg: Signature made Wed 25 Feb 2015 12:17:44 AM UTC using RSA key ID 8006F538\ngpg: Good signature from \"auto generated local signing key \u003cauto@local-signing.key\u003e\"\ngpg: Signature notation: file@name=test-file\ngpg: WARNING: This key is not certified with a trusted signature!\ngpg:          There is no indication that the signature belongs to the owner.\nPrimary key fingerprint: EB53 FEB4 7F25 ED3B 22F6  7D8B 87A3 BF01 01C1 FA07\n     Subkey fingerprint: E0A4 BE54 D1D8 1354 17FB  1CC2 42B6 02D3 8006 F538\ngpg_bash_lib_output_gpg_verify_status_fd_output:\n[GNUPG:] SIG_ID wW/AZUo5pHeQTTOWMwGTynGlLXQ 2015-02-25 1424823464\n[GNUPG:] GOODSIG 42B602D38006F538 auto generated local signing key \u003cauto@local-signing.key\u003e\n[GNUPG:] NOTATION_NAME file@name\n[GNUPG:] NOTATION_DATA test-file\n[GNUPG:] VALIDSIG E0A4BE54D1D8135417FB1CC242B602D38006F538 2015-02-25 1424823464 0 4 0 1 2 00 EB53FEB47F25ED3B22F67D8B87A3BF0101C1FA07\n[GNUPG:] TRUST_UNDEFINED\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_gpg_import_output\u003c/tt\u003e =====\n* possible values: A textual string containing output of the \u003ctt\u003egpg --import\u003c/tt\u003e part.\n* recommendation: Since already included in \u003ctt\u003egpg_bash_lib_output_diagnostic_message\u003c/tt\u003e, you most likely will not need it.\n\n===== \u003ctt\u003egpg_bash_lib_output_gpg_verify_exit_code\u003c/tt\u003e =====\n* possible values: integer. The exit code of the \u003ctt\u003egpg --verify\u003c/tt\u003e action, most likely \u003ctt\u003e0\u003c/tt\u003e or other exit codes such as \u003ctt\u003e1\u003c/tt\u003e, or if timeout was reached, \u003ctt\u003e124\u003c/tt\u003e if sending signal sigterm was sufficient or \u003ctt\u003e137\u003c/tt\u003e if sending signal sigkill was required.\n* recommendation: Check if it is \u003ctt\u003e0\u003c/tt\u003e, since other exit codes indicate failures or timeouts. Probably better not to rely on it for anything else but debug output, since the unreliability of gpg verify exit codes is the reason this library has been implemented in the first place.\n* example value: \u003ctt\u003e0\u003c/tt\u003e\n* example usage:\n\u003cpre\u003e\n   case \"$gpg_bash_lib_output_gpg_verify_exit_code\" in\n      \"0\")\n         true\n         ;;\n      \"124\")\n         echo \"Soft gpg verification timeout!\" \u003e\u00262\n         exit 1\n         ;;\n      \"137\")\n         echo \"Hard gpg verification timeout!\" \u003e\u00262\n         exit 1\n         ;;\n      *)\n         echo \"gpg_bash_lib_output_gpg_verify_exit_code neither represents success nor timeout. It is: $gpg_bash_lib_output_gpg_verify_exit_code\" \u003e\u00262\n         exit 125\n         ;;\n   esac\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_gpg_verify_output\u003c/tt\u003e =====\n* possible values: A textual string containing output of the \u003ctt\u003egpg --verify\u003c/tt\u003e part.\n* recommendation: Since already included in \u003ctt\u003egpg_bash_lib_output_diagnostic_message\u003c/tt\u003e, you most likely will not need it.\n\n===== \u003ctt\u003egpg_bash_lib_output_gpg_verify_status_fd_output\u003c/tt\u003e =====\n* possible values: A textual string containing output of the \u003ctt\u003egpg --status-file\u003c/tt\u003e part.\n* recommendation: Since already included in \u003ctt\u003egpg_bash_lib_output_diagnostic_message\u003c/tt\u003e, you most likely will not need it.\n\n===== \u003ctt\u003egpg_bash_lib_output_signed_on_unixtime\u003c/tt\u003e =====\n* possible values: An integer, the Signature Creation Date represented as unixtime.\n* recommendation: Consider using this variable instead of \u003ctt\u003egpg_bash_lib_output_signed_on_date\u003c/tt\u003e by converting it to some formatted date string that you prefer.\n* example content: \u003ctt\u003e1419456919\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_signed_on_date\u003c/tt\u003e =====\n* possible values: \u003ctt\u003egpg_bash_lib_output_signed_on_unixtime\u003c/tt\u003econverted to a textual date string using.\n* recommendation: Show this variable in your script, ask the user for confirmation.\n* example content: \u003ctt\u003eMarch 01 13:56:27 UTC 2015\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_file_name_tampering\u003c/tt\u003e =====\n* possible values: Set to \u003ctt\u003etrue\u003c/tt\u003e (match), \u003ctt\u003emissing\u003c/tt\u003e (no \u003ctt\u003efile@name\u003c/tt\u003e OpenPGP notation inside the signature, \u003ctt\u003efalse\u003c/tt\u003e (mismatch) accordingly.\n* recommendation: If you are using \u003ctt\u003egpg_bash_lib_input_file_name_enforce=true\u003c/tt\u003e, you should check this value.\n* example content: \u003ctt\u003etrue\u003c/tt\u003e\n* example usage:\n\u003cpre\u003e\n   echo \"File name is       : $(basename \"$gpg_bash_lib_input_data_file\")\"\n   case \"$gpg_bash_lib_output_file_name_tampering\" in\n      \"false\")\n         echo \"File name should be: ${gpg_bash_lib_output_notation[$\"file@name\"]}\"\n         echo 'File name okay, has not been tampered with.'\n         ;;\n      \"missing\")\n         ## Not trying to access ${gpg_bash_lib_output_notation[$\"file@name\"]},\n         ## because that variable does not exist then.\n         echo 'File name tampering detected! file@name OpenPGP notation missing!' \u003e\u00262\n         exit 1\n         ;;\n      \"true\")\n         echo \"File name should be: ${gpg_bash_lib_output_notation[$\"file@name\"]}\"\n         echo 'File name tampering detected!' \u003e\u00262\n         exit 1\n         ;;\n      *)\n         echo \"gpg_bash_lib_output_file_name_tampering neither represents false, missing, nor success. It is: $gpg_bash_lib_output_gpg_verify_exit_code\" \u003e\u00262\n         exit 125\n         ;;\n   esac\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_notation[\"file@name\"]\u003c/tt\u003e =====\n* possible values: name of file that was signed or \u003ctt\u003e\"\"\u003c/tt\u003e if not in use (not using \u003ctt\u003egpg_bash_lib_input_file_name_enforce=true\u003c/tt\u003e).\n* example content: \u003ctt\u003etest-file\u003c/tt\u003e\n* example use:\n\u003cpre\u003e\necho \"gpg_bash_lib_output_notation[file@name]: ${gpg_bash_lib_output_notation[$\"file@name\"]}\"\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_slow_clock_lenient_up_to_pretty_output\u003c/tt\u003e =====\n* possible value: Textual string containing the duration of how lenient the clock leniency check is. (Contains the result of the conversion of \u003ctt\u003egpg_bash_lib_input_slow_clock_lenient_up_to_seconds\u003c/tt\u003e to a pretty format.)\n* example content: \u003ctt\u003e30 minutes\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_goodsig_status\u003c/tt\u003e =====\n* possible values: \u003ctt\u003etrue\u003c/tt\u003e (GOODSIG, key and signature valid) or \u003ctt\u003efalse\u003c/tt\u003e (BADSIG, EXPSIG, EXPKEYSIG, REVKEYSIG or ERRSIG).\n* recommendation: Check if its value is \u003ctt\u003etrue\u003c/tt\u003e. Abort otherwise.\n* example content: \u003ctt\u003etrue\u003c/tt\u003e\n* example usage:\n\u003cpre\u003e\nif [ ! \"$gpg_bash_lib_output_goodsig_status\" = \"true\" ]; then\n   echo 'Key or signature error (BADSIG, EXPSIG, EXPKEYSIG, REVKEYSIG or ERRSIG)!' \u003e\u00262\n   exit 1\nfi\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_validsig_status\u003c/tt\u003e =====\n* possible values: \u003ctt\u003etrue\u003c/tt\u003e (successful verification) or \u003ctt\u003efalse\u003c/tt\u003e (unsuccessful verification).\n* recommendation: Check if its value is \u003ctt\u003etrue\u003c/tt\u003e. Abort otherwise.\n* example content: \u003ctt\u003etrue\u003c/tt\u003e\n* example usage:\n\u003cpre\u003e\nif [ ! \"$gpg_bash_lib_output_validsig_status\" = \"true\" ]; then\n   echo 'Signature verification failed!' \u003e\u00262\n   exit 1\nfi\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_fingerprint_in_hex\u003c/tt\u003e =====\n* possible values: The fingerprint of the key that signed the file in hex or \u003ctt\u003e\"\"\u003c/tt\u003e in case of unsuccessful verification.\n* recommendation: May or may not be useful to show this value in your script (in verbose mode). Since we expect a separate folder that contains the only keys that will be accepted (see variable \u003ctt\u003egpg_bash_lib_input_key_import_dir\u003c/tt\u003e), it seems unnecessary to check for the fingerprint.\n* example content: \u003ctt\u003eF38633B0A3F06A55CC0076C81081641AC4D57DB9\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_current_unixtime\u003c/tt\u003e =====\n* possible values: integer, unixtime at time of running this library.\n\n===== \u003ctt\u003egpg_bash_lib_output_current_time\u003c/tt\u003e =====\n* possible values: A textual string, the output of \u003ctt\u003e\"$(date --utc \"+%B %d %H:%M:%S UTC %Y\")\"\u003c/tt\u003e at time of running this library.\n* example content: \u003ctt\u003eMarch 01 17:59:38 UTC 2015\u003c/tt\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_signed_on_unixtime_minus_current_unixtime\u003c/tt\u003e =====\n* possible values: An integer, that represents the Relative Signature Creation Time. See the example of \u003ctt\u003egpg_bash_lib_output_signed_on_unixtime_minus_current_unixtime_pretty\u003c/tt\u003e below to understand what it is doing. Can be used when \u003ctt\u003egpg_bash_lib_output_freshness_detail\u003c/tt\u003e is \u003ctt\u003eslow\u003c/tt\u003e or \u003ctt\u003elenient\u003c/tt\u003e.\n\n===== \u003ctt\u003egpg_bash_lib_output_signed_on_unixtime_minus_current_unixtime_pretty\u003c/tt\u003e =====\n* possible values: A textual string, \u003ctt\u003egpg_bash_lib_output_signed_on_unixtime_minus_current_unixtime\u003c/tt\u003e converted to a pretty format. Can be used when \u003ctt\u003egpg_bash_lib_output_freshness_detail\u003c/tt\u003e is \u003ctt\u003eslow\u003c/tt\u003e or \u003ctt\u003elenient\u003c/tt\u003e.\n* example usage:\n\u003cpre\u003e\nif [ \"$gpg_bash_lib_output_freshness_detail\" = \"slow\" ] || [ \"$gpg_bash_lib_output_freshness_detail\" = \"lenient\" ]; then\n   echo \"Relative Signature Creation Time: According to your system clock, signature was created $gpg_bash_lib_output_signed_on_unixtime_minus_current_unixtime_pretty before current time.\"\nfi\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_current_unixtime_minus_signed_on_unixtime\u003c/tt\u003e =====\n* possible values: An integer, that represents the Relative Signature Creation Time. See the example of \u003ctt\u003egpg_bash_lib_output_current_unixtime_minus_signed_on_unixtime_pretty\u003c/tt\u003e below to understand what it is doing. Can be used if \u003ctt\u003egpg_bash_lib_output_freshness_detail\u003c/tt\u003e is \u003ctt\u003ecurrent\u003c/tt\u003e or \u003ctt\u003eoutdated.\u003c/tt\u003e.\n\n===== \u003ctt\u003egpg_bash_lib_output_current_unixtime_minus_signed_on_unixtime_pretty\u003c/tt\u003e =====\n* possible values: A textual string, \u003ctt\u003egpg_bash_lib_output_current_unixtime_minus_signed_on_unixtime\u003c/tt\u003e converted to a pretty format. Can be used if \u003ctt\u003egpg_bash_lib_output_freshness_detail\u003c/tt\u003e is \u003ctt\u003ecurrent\u003c/tt\u003e or \u003ctt\u003eoutdated.\u003c/tt\u003e.\n* example usage:\n\u003cpre\u003e\nif [ \"$gpg_bash_lib_output_freshness_detail\" = \"current\" ] || [ \"$gpg_bash_lib_output_freshness_detail\" = \"outdated\" ]; then\n   echo \"Relative Signature Creation Time: According to your system clock, signature was created $gpg_bash_lib_output_current_unixtime_minus_signed_on_unixtime_pretty ago.\"\nfi\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_in_future_in_seconds\u003c/tt\u003e =====\n* possible values: In case of \u003ctt\u003egpg_bash_lib_output_freshness_detail\u003c/tt\u003e is \u003ctt\u003eoutdated\u003c/tt\u003e, it contains an estimation how many seconds the clock might be fast.\n\n===== \u003ctt\u003egpg_bash_lib_output_in_future_pretty_output\u003c/tt\u003e =====\n* possible values: A textual string, \u003ctt\u003egpg_bash_lib_output_in_future_in_seconds\u003c/tt\u003e converted to a pretty format.\n* example use:\n\u003cpre\u003e\necho \"gpg_bash_lib_output_in_future_pretty_output: $gpg_bash_lib_output_in_future_pretty_output\"\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_freshness_status\u003c/tt\u003e =====\n* possible values: \u003ctt\u003etrue\u003c/tt\u003e (fresh) or \u003ctt\u003efalse\u003c/tt\u003e (not fresh).\n* example use:\n\u003cpre\u003e\nif [ \"$gpg_bash_lib_output_freshness_status\" = \"true\" ]; then\n   echo \"Signature is current.\"\nelse\n   echo \"Signature NOT current.\" \u003e\u00262\n   exit 1\nfi\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_freshness_detail\u003c/tt\u003e =====\n* description: A string, that contains the result of the comparison of the\nlocal clock (unixtime) with the signature creation date (unixtime). The example\nbelow will explain this better.\n* possible values:\n** \u003ctt\u003elenient\u003c/tt\u003e (Signature is not yet valid, still within accepted range.)\n** \u003ctt\u003eslow\u003c/tt\u003e (Signature is not yet valid.)\n** \u003ctt\u003ecurrent\u003c/tt\u003e (Signature is current.)\n** \u003ctt\u003eoutdated\u003c/tt\u003e (Signature is no longer valid (outdated).)\n* recommended action: Reject files, if the signature freshness is apparently\n\u003ctt\u003eslow\u003c/tt\u003e, because that would indicate there either something is very wrong with\nthe signature or with the local system clock, or if the signature freshness\napparently \u003ctt\u003eoutdated\u003c/tt\u003e, because then there could be an indefinite freeze or\nrollback (downgrade) attack in place. Accept if the signature freshness is\napparently \u003ctt\u003ecurrent\u003c/tt\u003e or \u003ctt\u003elenient\u003c/tt\u003e. In the latter case, explain that state to\nthe user. Use a snippet similar to the example below.\n* example usage:\n\u003cpre\u003e\n   case \"$gpg_bash_lib_output_freshness_detail\" in\n      \"lenient\")\n         signature_creation_msg=\"Your clock might be slow.\nAccording to your system clock, signature was created $gpg_bash_lib_output_signed_on_unixtime_minus_current_unixtime_pretty before current time.\nYou can probably ignore this, because it still is within range. (Okay up to $gpg_bash_lib_output_maximum_age_pretty_output before.)\"\n         ## ...\n         ;;\n      \"slow\")\n         signature_creation_msg=\"Your clock might be slow.\nAccording to your system clock, signature was created $gpg_bash_lib_output_signed_on_unixtime_minus_current_unixtime_pretty before current time.\"\n         ## ...\n         ;;\n      \"outdated\")\n         signature_creation_msg=\"Signature looks quite old already.\nEither,\n- your clock might be fast (at least $gpg_bash_lib_output_in_future_pretty_output fast). $clock_hint\n- there is really no newer signature yet. Signature is really older than $gpg_bash_lib_output_maximum_age_pretty_output. already. (Older than $gpg_bash_lib_output_in_future_pretty_output already.)\n- this is a $0 bug\n- this is an attack\"\n         ## ...\n         ;;\n      \"current\")\n         signature_creation_msg=\"According to your system clock, signatures was created $gpg_bash_lib_output_current_unixtime_minus_signed_on_unixtime_pretty ago.\"\n         ## ...\n         ;;\n      *)\n         echo \"gpg_bash_lib_output_freshness_detail is neither lenient, nor slow, nor outdated, nor current, it is: $gpg_bash_lib_output_freshness_detail\" \u003e\u00262\n         exit 125\n         ;;\n   esac\n\u003c/pre\u003e\n\n===== \u003ctt\u003egpg_bash_lib_output_freshness_msg\u003c/tt\u003e =====\n* possible values: A textual string, that contains diagnostic output, that puts \u003ctt\u003egpg_bash_lib_output_freshness_detail\u003c/tt\u003e into more details, developers speech, that may or may not be useful to show in your script (when in verbose mode).\n\n===== \u003ctt\u003egpg_bash_lib_output_maximum_age_pretty_output\u003c/tt\u003e =====\n* possible values: A textual string, \u003ctt\u003egpg_bash_lib_input_maximum_age_in_seconds\u003c/tt\u003e converted into a pretty format.\n\n===== \u003ctt\u003egpg_bash_lib_output_alright_status\u003c/tt\u003e =====\n* possible values: \u003ctt\u003e\"\"\u003c/tt\u003e, \u003ctt\u003etrue\u003c/tt\u003e (if all checks succeeded) or \u003ctt\u003efalse\u003c/tt\u003e (if at least one check failed, such as if \u003ctt\u003egpg_bash_lib_input_file_name_enforce\u003c/tt\u003e was set to \u003ctt\u003etrue\u003c/tt\u003e, but verification of the name of the file failed or if the signature was not considered fresh).\n* example usage:\n\u003cpre\u003e\nif [ ! \"$gpg_bash_lib_output_alright_status\" = \"true\" ]; then\n   ## ...\n   exit 1\nfi\n\u003c/pre\u003e\n\n=== File Name Verification ===\n\nTo verify the names of files, i.e. to verify the \u003ctt\u003efile@name\u003c/tt\u003e OpenPGP Notation, see also variable \u003ctt\u003egpg_bash_lib_input_file_name_enforce\u003c/tt\u003e above.\n\nTo create a signature, that contains this OpenPGP notation, you might like to use something like the following command and and/or function.\n\n\u003cpre\u003esign_cmd() {\n   ## GPG signatures do not authenticate filenames by default, therefore add\n   ## the name of the file as a OpenPGP notation so at least users or scripts\n   ## that look at OpenPGP notations have a chance to detect if file names\n   ## have been tampered with. See also:\n   ## https://github.com/adrelanos/gpg-bash-lib\n   gpg --detach-sign --armor --yes --set-notation \"file@name\"=\"$(basename \"$1\")\" \"$1\"\n}\u003c/pre\u003e\nAnd for verification.\n\n\u003cpre\u003everify_cmd() {\n   gpg --verify-options show-notations --verify \"$1\"\n}\u003c/pre\u003e\n=== Security Tips ===\n\n==== Signature Creation Date Storage ====\n\nTo aid detection of indefinite freeze and rollback (downgrade) attacks, consider storing the Signature Creation Date (see variables \u003ctt\u003egpg_bash_lib_output_signed_on_unixtime\u003c/tt\u003e and/or \u003ctt\u003egpg_bash_lib_output_signed_on_date\u003c/tt\u003e) in a file, so you can compare them next time you download a supposedly newer signature. If the newly downloaded signature is older than the last known one, then maybe something is wrong.\n\n==== Signature Creation Date Preseeding ====\n\nThe above tip will not work for initial signature downloads. Therefore consider preseeding a sane initial value.\n\n==== Abstract it! ====\n\nLike the two above tips? We should abstract that code as well. Interested to implement it into gpg-bash-lib?\n\n==== Signature Freshness Updating ====\n\nIf you are the one providing the signatures, if there are no new releases, often recreate and reupload them to refresh the signature creation date.\n\n=== Library Conventions ===\n\nTo avoid conflicts with variables or function names, which your script might have defined earlier, the following conventions have been applied.\n\n* Function names start with \u003ctt\u003egpg_bash_lib_function_\u003c/tt\u003e.\n* Variable names found out by the library start with \u003ctt\u003egpg_bash_lib_output_\u003c/tt\u003e.\n* Variable names that may be input by the user start with \u003ctt\u003egpg_bash_lib_output_\u003c/tt\u003e.\n* Variable names that are only internally used start with \u003ctt\u003egpg_bash_lib_internal_\u003c/tt\u003e.\n\n=== Goodies ===\n\n==== SIGNAL Friendliness ====\n\nAny operations that could take longer, such as the \u003ctt\u003egpg --verify\u003c/tt\u003e operation, are executed using bash's \u003ctt\u003ewait\u003c/tt\u003e builtin. To explain this better, see the following pseudo code, it is the style that this library is using.\n\n\u003cpre\u003e\ngpg ... \u0026\ngpg_bash_lib_internal_gpg_verify_pid=\"$!\"\nwait \"$gpg_bash_lib_internal_gpg_verify_pid\" || { gpg_bash_lib_output_gpg_verify_exit_code=\"$?\" ; true; };\n\u003c/pre\u003e\n\nThis has the advantage, that your script can still react to any eventual trap's listening for example for signal SIGTERM.\n\n= Known Issues =\n\n* Multiple signatures in a single signature file are not well supported yet.\n* When there are multiple signatures in a single signature file, the signature will be accepted as valid, when at least one key from the signing key folder (see variable \u003ctt\u003egpg_bash_lib_input_key_import_dir\u003c/tt\u003e above) made a good signature. Feedback welcome on situations where there are multiple mixed good and bad signatures.\n* [https://phabricator.whonix.org/maniphest/?statuses=open%2Creview\u0026allProjects=PHID-PROJ-y7ggndpa2rbgbboyhoqp#R Issue Tracker]\n\n= Alternatives =\n\n* Writing your own custom code.\n* Please add any not listed here.\n\n= Forks, Patches, Testers, Comments, etc. =\n\nWelcome.\n\n= Author =\n\n* Patrick Schleizer\n* e-mail: adrelanos@whonix.org\n* [https://www.whonix.org/wiki/Patrick_Schleizer gpg]: 916B8D99C38EAF5E8ADC7A2A8D66066A2EEACCDA\n* twitter: https://twitter.com/adrelanos\n* twitter: https://twitter.com/Whonix\n* [https://www.whonix.org/wiki/Donate Donate]\n\n= License =\n\nGPLv3+\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkicksecure%2Fgpg-bash-lib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkicksecure%2Fgpg-bash-lib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkicksecure%2Fgpg-bash-lib/lists"}