+ int result = 0;
+ int valid = 0;
+ size_t bytes_read = 0;
+ unsigned char buffer[8192];
+
+ if (filename == NULL)
+ return -1;
+
+ gpgme_signature_t verification_signatures;
+ gpgme_verify_result_t verification_result;
+ gpgme_data_t ciphertext_data;
+ gpgme_data_t plaintext_data;
+ gpgme_engine_info_t enginfo;
+ gpgme_ctx_t gpg_context;
+ gpgme_error_t err;
+
+ /* Initialize gpgme */
+ setlocale (LC_ALL, "");
+ gpgme_check_version(NULL);
+ gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
+ err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
+ if (err != GPG_ERR_NO_ERROR) {
+ pb_log("%s: OpenPGP support not available\n", __func__);
+ return -1;
+ }
+ err = gpgme_get_engine_info(&enginfo);
+ if (err != GPG_ERR_NO_ERROR) {
+ pb_log("%s: GPG engine failed to initialize\n", __func__);
+ return -1;
+ }
+ err = gpgme_new(&gpg_context);
+ if (err != GPG_ERR_NO_ERROR) {
+ pb_log("%s: GPG context could not be created\n", __func__);
+ return -1;
+ }
+ err = gpgme_set_protocol(gpg_context, GPGME_PROTOCOL_OpenPGP);
+ if (err != GPG_ERR_NO_ERROR) {
+ pb_log("%s: GPG protocol could not be set\n", __func__);
+ return -1;
+ }
+ if (keyring_path)
+ err = gpgme_ctx_set_engine_info (gpg_context,
+ GPGME_PROTOCOL_OpenPGP,
+ enginfo->file_name, keyring_path);
+ else
+ err = gpgme_ctx_set_engine_info (gpg_context,
+ GPGME_PROTOCOL_OpenPGP,
+ enginfo->file_name, enginfo->home_dir);
+ if (err != GPG_ERR_NO_ERROR) {
+ pb_log("%s: Could not set GPG engine information\n", __func__);
+ return -1;
+ }
+ err = gpgme_data_new(&plaintext_data);
+ if (err != GPG_ERR_NO_ERROR) {
+ pb_log("%s: Could not create GPG plaintext data buffer\n",
+ __func__);
+ return -1;
+ }
+ err = gpgme_data_new_from_file(&ciphertext_data, filename, 1);
+ if (err != GPG_ERR_NO_ERROR) {
+ pb_log("%s: Could not create GPG ciphertext data buffer"
+ " from file '%s'\n", __func__, filename);
+ return -1;
+ }
+
+ /* Decrypt and verify file */
+ err = gpgme_op_decrypt_verify(gpg_context, ciphertext_data,
+ plaintext_data);
+ if (err != GPG_ERR_NO_ERROR) {
+ pb_log("%s: Could not decrypt file\n", __func__);
+ return -1;
+ }
+ verification_result = gpgme_op_verify_result(gpg_context);
+ verification_signatures = verification_result->signatures;
+ while (verification_signatures) {
+ if (verification_signatures->status == GPG_ERR_NO_ERROR) {
+ pb_log("%s: Good signature for key ID '%s' ('%s')\n",
+ __func__,
+ verification_signatures->fpr, filename);
+ /* Verify fingerprint is present in authorized
+ * signatures file
+ */
+ char *auth_sig_line = NULL;
+ size_t auth_sig_len = 0;
+ ssize_t auth_sig_read;
+ rewind(authorized_signatures_handle);
+ while ((auth_sig_read = getline(&auth_sig_line,
+ &auth_sig_len,
+ authorized_signatures_handle)) != -1) {
+ auth_sig_len = strlen(auth_sig_line);
+ while ((auth_sig_line[auth_sig_len-1] == '\n')
+ || (auth_sig_line[auth_sig_len-1] == '\r'))
+ auth_sig_len--;
+ auth_sig_line[auth_sig_len] = 0;
+ if (strcmp(auth_sig_line,
+ verification_signatures->fpr) == 0)
+ valid = 1;
+ }
+ free(auth_sig_line);
+ }
+ else {
+ pb_log("%s: Signature for key ID '%s' ('%s') invalid."
+ " Status: %08x\n", __func__,
+ verification_signatures->fpr, filename,
+ verification_signatures->status);
+ }
+ verification_signatures = verification_signatures->next;
+ }