/* int main(int argc, char** argv) { gpgme_ctx_t ctx; gpgme_error_t err; init_gpgme(GPGME_PROTOCOL_OpenPGP); err = gpgme_new(&ctx); check_errors(err,"error with gpgme_new"); verify_signature(ctx,"signature.c.sig","signature.c"); return 0; } */ bool verify_signature(gpgme_ctx_t ctx, char* sig_path,char* file_path) { gpgme_error_t err; FILE* fp_sig = NULL; FILE* fp_msg = NULL; gpgme_data_t sig = NULL; gpgme_data_t msg = NULL; gpgme_verify_result_t result; fp_sig = fopen(sig_path,"rb"); //open file with signature if(!fp_sig) { err = gpg_error_from_syserror(); fprintf (stderr, PGM ": can't open `%s': %s\n", sig_path, gpg_strerror(err)); return false; } fp_msg = fopen(file_path,"rb"); //open file which want to check if(!fp_msg) { err = gpg_error_from_syserror(); fprintf(stderr,PGM ": cant open `%s`: %s\n", file_path, gpg_strerror(err)); return false; } err = gpgme_data_new_from_stream(&sig,fp_sig); //write to gpgme_data object from fp_sig stream(signature) if(err) { fprintf (stderr, PGM ": error allocating data object: %s\n",gpg_strerror (err)); return false; } if(fp_msg) { err = gpgme_data_new_from_stream(&msg,fp_msg); //write to gpgme_data object from fp_msg(file) if(err) { fprintf(stderr,PGM ": error allocation data object: %s\n",gpg_strerror(err)); return false; } } err = gpgme_op_verify(ctx,sig,msg,NULL); //verify signature check_errors(err,"error with verify"); result = gpgme_op_verify_result(ctx); //get result of checking signature if(result) { print_result_of_checking(result); //printf checking information } fclose(fp_sig); fclose(fp_msg); gpgme_data_release (msg); gpgme_data_release (sig); return true; }
static void geanypg_encrypt(encrypt_data * ed, gpgme_key_t * recp, int sign, int flags) { /* FACTORIZE */ gpgme_data_t plain, cipher; gpgme_error_t err; FILE * tempfile; tempfile = tmpfile(); if (!(tempfile)) { g_warning("%s: %s.", _("couldn't create tempfile"), strerror(errno)); return ; } gpgme_data_new_from_stream(&cipher, tempfile); gpgme_data_set_encoding(cipher, GPGME_DATA_ENCODING_ARMOR); geanypg_load_buffer(&plain); /* do the actual encryption */ if (sign) err = gpgme_op_encrypt_sign(ed->ctx, recp, flags, plain, cipher); else err = gpgme_op_encrypt(ed->ctx, recp, flags, plain, cipher); if (err != GPG_ERR_NO_ERROR && gpgme_err_code(err) != GPG_ERR_CANCELED) geanypg_show_err_msg(err); else if(gpgme_err_code(err) != GPG_ERR_CANCELED) { rewind(tempfile); geanypg_write_file(tempfile); } fclose(tempfile); /* release buffers */ gpgme_data_release(plain); gpgme_data_release(cipher); }
/* Return true if the file FNAME looks like an CMS file. There is no error return, just a best effort try to identify CMS in a file with a CMS object. */ int is_cms_file (const char *fname) { #ifdef HAVE_GPGME_DATA_IDENTIFY FILE *fp; gpgme_data_t dh; gpgme_data_type_t dt; fp = fopen (fname, "rb"); if (!fp) return 0; /* Not found - can't be a CMS file. */ if (gpgme_data_new_from_stream (&dh, fp)) { fclose (fp); return 0; } dt = gpgme_data_identify (dh, 0); gpgme_data_release (dh); fclose (fp); switch (dt) { case GPGME_DATA_TYPE_CMS_SIGNED: case GPGME_DATA_TYPE_CMS_ENCRYPTED: case GPGME_DATA_TYPE_CMS_OTHER: case GPGME_DATA_TYPE_X509_CERT: case GPGME_DATA_TYPE_PKCS12: return 1; default: return 0; } #else int result; FILE *fp; char *data; size_t datalen; fp = fopen (fname, "rb"); if (!fp) return 0; /* Not found - can't be a CMS file. */ data = malloc (CMS_BUFFER_SIZE); if (!data) { fclose (fp); return 0; /* Oops */ } datalen = fread (data, 1, CMS_BUFFER_SIZE - 1, fp); data[datalen] = 0; fclose (fp); result = detect_cms (data, datalen); free (data); return result; #endif }
char checkSignature(char *path, struct memory_identifier *memory) { gpgme_ctx_t context; gpgme_error_t err; gpgme_data_t signature, iso; FILE *file = fopen(path, "r"); if (file == NULL) { fprintf(stderr, "File %s not found!\n", path); fatal("Unable to open file!\n"); } gpgme_check_version(NULL); err = gpgme_new(&context); switch (err) { case GPG_ERR_NO_ERROR: break; case GPG_ERR_ENOMEM: fatal("There is not enough memory available to initialize gpgme. Aborting...\n"); default: break; } gpgme_set_protocol(context, GPGME_PROTOCOL_OpenPGP); err = gpgme_data_new_from_stream(&iso, file); if (err == GPG_ERR_ENOMEM) fatal("There was not enough memory to crate a new data buffer for gpgme. Aborting...\n"); err = gpgme_ctx_set_engine_info(context, GPGME_PROTOCOL_OpenPGP, "/usr/bin/gpg", "/etc/pacman.d/gnupg/"); if (err != GPG_ERR_NO_ERROR) { printf("Something went wrong while setting the engine info.\n"); return 1; } err = gpgme_data_new_from_mem(&signature, memory->chunk, memory->length, 1); if (err == GPG_ERR_ENOMEM) fatal("There was not enough memory to crate a new data buffer for gpgme. Aborting...\n"); err = gpgme_op_verify(context, signature, iso, NULL); if (err == GPG_ERR_NO_ERROR) return 0; else return 1; }
/** * Check the PGP signature for the given file path. * If base64_sig is provided, it will be used as the signature data after * decoding. If base64_sig is NULL, expect a signature file next to path * (e.g. "%s.sig"). * * The return value will be 0 if nothing abnormal happened during the signature * check, and -1 if an error occurred while checking signatures or if a * signature could not be found; pm_errno will be set. Note that "abnormal" * does not include a failed signature; the value in siglist should be checked * to determine if the signature(s) are good. * @param handle the context handle * @param path the full path to a file * @param base64_sig optional PGP signature data in base64 encoding * @param siglist a pointer to storage for signature results * @return 0 in normal cases, -1 if the something failed in the check process */ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path, const char *base64_sig, alpm_siglist_t *siglist) { int ret = -1, sigcount; gpgme_error_t gpg_err = 0; gpgme_ctx_t ctx; gpgme_data_t filedata, sigdata; gpgme_verify_result_t verify_result; gpgme_signature_t gpgsig; char *sigpath = NULL; unsigned char *decoded_sigdata = NULL; FILE *file = NULL, *sigfile = NULL; if(!path || _alpm_access(handle, NULL, path, R_OK) != 0) { RET_ERR(handle, ALPM_ERR_NOT_A_FILE, -1); } if(!siglist) { RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1); } siglist->count = 0; if(!base64_sig) { sigpath = _alpm_sigpath(handle, path); if(_alpm_access(handle, NULL, sigpath, R_OK) != 0 || (sigfile = fopen(sigpath, "rb")) == NULL) { _alpm_log(handle, ALPM_LOG_DEBUG, "sig path %s could not be opened\n", sigpath); handle->pm_errno = ALPM_ERR_SIG_MISSING; goto error; } } /* does the file we are verifying exist? */ file = fopen(path, "rb"); if(file == NULL) { handle->pm_errno = ALPM_ERR_NOT_A_FILE; goto error; } if(init_gpgme(handle)) { /* pm_errno was set in gpgme_init() */ goto error; } _alpm_log(handle, ALPM_LOG_DEBUG, "checking signature for %s\n", path); memset(&ctx, 0, sizeof(ctx)); memset(&sigdata, 0, sizeof(sigdata)); memset(&filedata, 0, sizeof(filedata)); gpg_err = gpgme_new(&ctx); CHECK_ERR(); /* create our necessary data objects to verify the signature */ gpg_err = gpgme_data_new_from_stream(&filedata, file); CHECK_ERR(); /* next create data object for the signature */ if(base64_sig) { /* memory-based, we loaded it from a sync DB */ size_t data_len; int decode_ret = alpm_decode_signature(base64_sig, &decoded_sigdata, &data_len); if(decode_ret) { handle->pm_errno = ALPM_ERR_SIG_INVALID; goto gpg_error; } gpg_err = gpgme_data_new_from_mem(&sigdata, (char *)decoded_sigdata, data_len, 0); } else { /* file-based, it is on disk */ gpg_err = gpgme_data_new_from_stream(&sigdata, sigfile); } CHECK_ERR(); /* here's where the magic happens */ gpg_err = gpgme_op_verify(ctx, sigdata, filedata, NULL); CHECK_ERR(); verify_result = gpgme_op_verify_result(ctx); CHECK_ERR(); if(!verify_result || !verify_result->signatures) { _alpm_log(handle, ALPM_LOG_DEBUG, "no signatures returned\n"); handle->pm_errno = ALPM_ERR_SIG_MISSING; goto gpg_error; } for(gpgsig = verify_result->signatures, sigcount = 0; gpgsig; gpgsig = gpgsig->next, sigcount++); _alpm_log(handle, ALPM_LOG_DEBUG, "%d signatures returned\n", sigcount); CALLOC(siglist->results, sigcount, sizeof(alpm_sigresult_t), handle->pm_errno = ALPM_ERR_MEMORY; goto gpg_error); siglist->count = sigcount; for(gpgsig = verify_result->signatures, sigcount = 0; gpgsig; gpgsig = gpgsig->next, sigcount++) { alpm_list_t *summary_list, *summary; alpm_sigstatus_t status; alpm_sigvalidity_t validity; gpgme_key_t key; alpm_sigresult_t *result; _alpm_log(handle, ALPM_LOG_DEBUG, "fingerprint: %s\n", gpgsig->fpr); summary_list = list_sigsum(gpgsig->summary); for(summary = summary_list; summary; summary = summary->next) { _alpm_log(handle, ALPM_LOG_DEBUG, "summary: %s\n", (const char *)summary->data); } alpm_list_free(summary_list); _alpm_log(handle, ALPM_LOG_DEBUG, "status: %s\n", gpgme_strerror(gpgsig->status)); _alpm_log(handle, ALPM_LOG_DEBUG, "timestamp: %lu\n", gpgsig->timestamp); if((time_t)gpgsig->timestamp > time(NULL)) { _alpm_log(handle, ALPM_LOG_DEBUG, "signature timestamp is greater than system time.\n"); } _alpm_log(handle, ALPM_LOG_DEBUG, "exp_timestamp: %lu\n", gpgsig->exp_timestamp); _alpm_log(handle, ALPM_LOG_DEBUG, "validity: %s; reason: %s\n", string_validity(gpgsig->validity), gpgme_strerror(gpgsig->validity_reason)); result = siglist->results + sigcount; gpg_err = gpgme_get_key(ctx, gpgsig->fpr, &key, 0); if(gpg_err_code(gpg_err) == GPG_ERR_EOF) { _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n"); gpg_err = GPG_ERR_NO_ERROR; /* we dupe the fpr in this case since we have no key to point at */ STRDUP(result->key.fingerprint, gpgsig->fpr, handle->pm_errno = ALPM_ERR_MEMORY; goto gpg_error); } else {
GpgME::Data::Data( FILE * fp ) { gpgme_data_t data; const gpgme_error_t e = gpgme_data_new_from_stream( &data, fp ); d = new Private( e ? 0 : data ); d->ref(); }
gpointer verify_signature (const gchar *detached_signature_path, const gchar *signed_file_path) { init_gpgme (); gpgme_ctx_t ctx; gpgme_signature_t sig; gpgme_data_t signature_data, signed_data; gpgme_error_t error = gpgme_new (&ctx); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); return GPGME_ERROR; } gpgme_set_armor (ctx, 1); error = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return GPGME_ERROR; } const char *keyring_dir = gpgme_get_dirinfo ("homedir"); error = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_OpenPGP, NULL, keyring_dir); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return GPGME_ERROR; } FILE *sig_fp = g_fopen (detached_signature_path, "r"); FILE *sig_data_fp = g_fopen (signed_file_path, "r"); if (sig_fp == NULL || sig_data_fp == NULL) { g_printerr ("Couldn't open input file\n"); gpgme_release (ctx); return FILE_OPEN_ERROR; } error = gpgme_data_new_from_stream (&signature_data, sig_fp); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); fclose (sig_fp); fclose (sig_data_fp); gpgme_release (ctx); return GPGME_ERROR; } error = gpgme_data_new_from_stream (&signed_data, sig_data_fp); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); fclose (sig_fp); fclose (sig_data_fp); gpgme_release (ctx); gpgme_data_release (signature_data); return GPGME_ERROR; } error = gpgme_op_verify (ctx, signature_data, signed_data, NULL); gpgme_data_release (signature_data); gpgme_data_release (signed_data); fclose (sig_fp); fclose (sig_data_fp); if (error != GPG_ERR_NO_ERROR) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return GPGME_ERROR; } gpgme_verify_result_t result = gpgme_op_verify_result (ctx); if (!result) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return GPGME_ERROR; } sig = result->signatures; if (!sig) { gpgme_release (ctx); return NO_GPG_KEYS_AVAILABLE; } for (; sig; sig = sig->next) { if ((sig->summary & GPGME_SIGSUM_VALID) || (sig->summary & GPGME_SIGSUM_GREEN)) { gpgme_release (ctx); return SIGNATURE_OK; } else if (sig->summary == 0 && sig->status == GPG_ERR_NO_ERROR) { // Valid but key is not certified with a trusted signature gpgme_release (ctx); return SIGNATURE_OK_KEY_NOT_TRUSTED; } } gpgme_release (ctx); return BAD_SIGNATURE; }
gpointer sign_file (const gchar *input_file_path, const gchar *fpr) { gpgme_error_t error; gpgme_ctx_t context; gpgme_key_t signing_key; gpgme_data_t clear_text, signed_text; gpgme_sign_result_t result; gchar *buffer; gssize nbytes; error = gpgme_new (&context); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); return GPGME_ERROR; } gpgme_set_armor (context, 0); error = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } const char *keyring_dir = gpgme_get_dirinfo ("homedir"); error = gpgme_ctx_set_engine_info (context, GPGME_PROTOCOL_OpenPGP, NULL, keyring_dir); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } error = gpgme_get_key (context, fpr, &signing_key, 1); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } error = gpgme_signers_add (context, signing_key); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (NULL, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } FILE *infp = g_fopen (input_file_path, "r"); if (infp == NULL) { g_printerr ("Couldn't open input file\n"); cleanup (NULL, NULL, NULL, NULL, &signing_key, &context); return FILE_OPEN_ERROR; } error = gpgme_data_new_from_stream (&clear_text, infp); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_data_new (&signed_text); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_op_sign (context, clear_text, signed_text, GPGME_SIG_MODE_DETACH); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } result = gpgme_op_sign_result (context); if (result->invalid_signers) { g_printerr ("Invalid signer found: %s\n", result->invalid_signers->fpr); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } if (!result->signatures || result->signatures->next) { g_printerr ("Unexpected number of signatures created\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_data_seek (signed_text, 0, SEEK_SET); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } buffer = g_try_malloc0 (SIG_MAXLEN); if (buffer == NULL) { g_printerr ("Couldn't allocate memory\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return MEMORY_ALLOCATION_ERROR; } nbytes = gpgme_data_read (signed_text, buffer, SIG_MAXLEN); if (nbytes == -1) { g_printerr ("Error while reading data\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } GError *gerr = NULL; gchar *output_file_path = g_strconcat (input_file_path, ".sig", NULL); GFile *fpout = g_file_new_for_path (output_file_path); GFileOutputStream *ostream = g_file_append_to (fpout, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &gerr); if (gerr != NULL) { g_printerr ("Couldn't open output file for writing\n"); cleanup (infp, fpout, NULL, output_file_path, &signing_key, &context); return FILE_OPEN_ERROR; } gssize wbytes = g_output_stream_write (G_OUTPUT_STREAM (ostream), buffer, nbytes, NULL, &gerr); if (wbytes == -1) { g_printerr ("Couldn't write the request number of bytes (%s)\n", gerr->message); cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context); return FILE_WRITE_ERROR; } cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context); return SIGN_OK; }
/** * Check the PGP signature for the given file path. * If base64_sig is provided, it will be used as the signature data after * decoding. If base64_sig is NULL, expect a signature file next to path * (e.g. "%s.sig"). * * The return value will be 0 if nothing abnormal happened during the signature * check, and -1 if an error occurred while checking signatures or if a * signature could not be found; pm_errno will be set. Note that "abnormal" * does not include a failed signature; the value in #result should be checked * to determine if the signature(s) are good. * @param handle the context handle * @param path the full path to a file * @param base64_sig optional PGP signature data in base64 encoding * @result * @return 0 in normal cases, -1 if the something failed in the check process */ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path, const char *base64_sig, alpm_sigresult_t *result) { int ret = -1, sigcount; gpgme_error_t err; gpgme_ctx_t ctx; gpgme_data_t filedata, sigdata; gpgme_verify_result_t verify_result; gpgme_signature_t gpgsig; char *sigpath = NULL; unsigned char *decoded_sigdata = NULL; FILE *file = NULL, *sigfile = NULL; if(!path || access(path, R_OK) != 0) { RET_ERR(handle, ALPM_ERR_NOT_A_FILE, -1); } if(!result) { RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1); } result->count = 0; if(!base64_sig) { size_t len = strlen(path) + 5; CALLOC(sigpath, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); snprintf(sigpath, len, "%s.sig", path); if(!access(sigpath, R_OK) == 0) { /* sigcount is 0 */ } } if(init_gpgme(handle)) { /* pm_errno was set in gpgme_init() */ return -1; } _alpm_log(handle, ALPM_LOG_DEBUG, "checking signature for %s\n", path); memset(&ctx, 0, sizeof(ctx)); memset(&sigdata, 0, sizeof(sigdata)); memset(&filedata, 0, sizeof(filedata)); err = gpgme_new(&ctx); CHECK_ERR(); /* create our necessary data objects to verify the signature */ file = fopen(path, "rb"); if(file == NULL) { handle->pm_errno = ALPM_ERR_NOT_A_FILE; goto error; } err = gpgme_data_new_from_stream(&filedata, file); CHECK_ERR(); /* next create data object for the signature */ if(base64_sig) { /* memory-based, we loaded it from a sync DB */ int data_len; int decode_ret = decode_signature(base64_sig, &decoded_sigdata, &data_len); if(decode_ret) { handle->pm_errno = ALPM_ERR_SIG_INVALID; goto error; } err = gpgme_data_new_from_mem(&sigdata, (char *)decoded_sigdata, data_len, 0); } else { /* file-based, it is on disk */ sigfile = fopen(sigpath, "rb"); if(sigfile == NULL) { handle->pm_errno = ALPM_ERR_SIG_MISSING; goto error; } err = gpgme_data_new_from_stream(&sigdata, sigfile); } CHECK_ERR(); /* here's where the magic happens */ err = gpgme_op_verify(ctx, sigdata, filedata, NULL); CHECK_ERR(); verify_result = gpgme_op_verify_result(ctx); CHECK_ERR(); if(!verify_result || !verify_result->signatures) { _alpm_log(handle, ALPM_LOG_DEBUG, "no signatures returned\n"); handle->pm_errno = ALPM_ERR_SIG_MISSING; goto error; } for(gpgsig = verify_result->signatures, sigcount = 0; gpgsig; gpgsig = gpgsig->next, sigcount++); _alpm_log(handle, ALPM_LOG_DEBUG, "%d signatures returned\n", sigcount); result->status = calloc(sigcount, sizeof(alpm_sigstatus_t)); result->uid = calloc(sigcount, sizeof(char*)); if(!result->status || !result->uid) { handle->pm_errno = ALPM_ERR_MEMORY; goto error; } result->count = sigcount; for(gpgsig = verify_result->signatures, sigcount = 0; gpgsig; gpgsig = gpgsig->next, sigcount++) { alpm_list_t *summary_list, *summary; alpm_sigstatus_t status; gpgme_key_t key; _alpm_log(handle, ALPM_LOG_DEBUG, "fingerprint: %s\n", gpgsig->fpr); summary_list = list_sigsum(gpgsig->summary); for(summary = summary_list; summary; summary = summary->next) { _alpm_log(handle, ALPM_LOG_DEBUG, "summary: %s\n", (const char *)summary->data); } alpm_list_free(summary_list); _alpm_log(handle, ALPM_LOG_DEBUG, "status: %s\n", gpgme_strerror(gpgsig->status)); _alpm_log(handle, ALPM_LOG_DEBUG, "timestamp: %lu\n", gpgsig->timestamp); _alpm_log(handle, ALPM_LOG_DEBUG, "exp_timestamp: %lu\n", gpgsig->exp_timestamp); _alpm_log(handle, ALPM_LOG_DEBUG, "validity: %s; reason: %s\n", string_validity(gpgsig->validity), gpgme_strerror(gpgsig->validity_reason)); err = gpgme_get_key(ctx, gpgsig->fpr, &key, 0); if(gpg_err_code(err) == GPG_ERR_EOF) { _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n"); err = GPG_ERR_NO_ERROR; } else { CHECK_ERR(); if(key->uids) { const char *uid = key->uids->uid; STRDUP(result->uid[sigcount], uid, handle->pm_errno = ALPM_ERR_MEMORY; goto error); _alpm_log(handle, ALPM_LOG_DEBUG, "key user: %s\n", uid); } gpgme_key_unref(key); } if(gpgsig->summary & GPGME_SIGSUM_VALID) { /* definite good signature */ _alpm_log(handle, ALPM_LOG_DEBUG, "result: valid signature\n"); status = ALPM_SIGSTATUS_VALID; } else if(gpgsig->summary & GPGME_SIGSUM_GREEN) { /* good signature */ _alpm_log(handle, ALPM_LOG_DEBUG, "result: green signature\n"); status = ALPM_SIGSTATUS_VALID; } else if(gpgsig->summary & GPGME_SIGSUM_RED) { /* definite bad signature, error */ _alpm_log(handle, ALPM_LOG_DEBUG, "result: red signature\n"); status = ALPM_SIGSTATUS_BAD; } else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) { _alpm_log(handle, ALPM_LOG_DEBUG, "result: signature from unknown key\n"); status = ALPM_SIGSTATUS_UNKNOWN; } else if(gpgsig->summary & GPGME_SIGSUM_KEY_EXPIRED) { _alpm_log(handle, ALPM_LOG_DEBUG, "result: key expired\n"); status = ALPM_SIGSTATUS_BAD; } else if(gpgsig->summary & GPGME_SIGSUM_SIG_EXPIRED) { _alpm_log(handle, ALPM_LOG_DEBUG, "result: signature expired\n"); status = ALPM_SIGSTATUS_BAD; } else { /* we'll capture everything else here */ _alpm_log(handle, ALPM_LOG_DEBUG, "result: invalid signature\n"); status = ALPM_SIGSTATUS_BAD; } result->status[sigcount] = status; } ret = 0; error: gpgme_data_release(sigdata); gpgme_data_release(filedata); gpgme_release(ctx); if(sigfile) { fclose(sigfile); } if(file) { fclose(file); } FREE(sigpath); FREE(decoded_sigdata); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { _alpm_log(handle, ALPM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err)); RET_ERR(handle, ALPM_ERR_GPGME, -1); } return ret; }
int main (int argc, char **argv) { int last_argc = -1; gpgme_error_t err; gpgme_ctx_t ctx; gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; FILE *fp_sig = NULL; gpgme_data_t sig = NULL; FILE *fp_msg = NULL; gpgme_data_t msg = NULL; gpgme_verify_result_t result; int print_status = 0; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--help")) show_usage (0); else if (!strcmp (*argv, "--verbose")) { verbose = 1; argc--; argv++; } else if (!strcmp (*argv, "--status")) { print_status = 1; argc--; argv++; } else if (!strcmp (*argv, "--openpgp")) { protocol = GPGME_PROTOCOL_OpenPGP; argc--; argv++; } else if (!strcmp (*argv, "--cms")) { protocol = GPGME_PROTOCOL_CMS; argc--; argv++; } else if (!strncmp (*argv, "--", 2)) show_usage (1); } if (argc < 1 || argc > 2) show_usage (1); fp_sig = fopen (argv[0], "rb"); if (!fp_sig) { err = gpgme_error_from_syserror (); fprintf (stderr, PGM ": can't open `%s': %s\n", argv[0], gpgme_strerror (err)); exit (1); } if (argc > 1) { fp_msg = fopen (argv[1], "rb"); if (!fp_msg) { err = gpgme_error_from_syserror (); fprintf (stderr, PGM ": can't open `%s': %s\n", argv[1], gpgme_strerror (err)); exit (1); } } init_gpgme (protocol); err = gpgme_new (&ctx); fail_if_err (err); gpgme_set_protocol (ctx, protocol); if (print_status) { gpgme_set_status_cb (ctx, status_cb, NULL); gpgme_set_ctx_flag (ctx, "full-status", "1"); } /* gpgme_set_ctx_flag (ctx, "raw-description", "1"); */ err = gpgme_data_new_from_stream (&sig, fp_sig); if (err) { fprintf (stderr, PGM ": error allocating data object: %s\n", gpgme_strerror (err)); exit (1); } if (fp_msg) { err = gpgme_data_new_from_stream (&msg, fp_msg); if (err) { fprintf (stderr, PGM ": error allocating data object: %s\n", gpgme_strerror (err)); exit (1); } } err = gpgme_op_verify (ctx, sig, msg, NULL); result = gpgme_op_verify_result (ctx); if (result) print_result (result); if (err) { fprintf (stderr, PGM ": verify failed: %s\n", gpgme_strerror (err)); exit (1); } gpgme_data_release (msg); gpgme_data_release (sig); gpgme_release (ctx); return 0; }