_alpm_gpg_checksig was renamed to _alpm_gpg_checksig_memory.
It checks signatures which are in memory. The packages' signatures
are stored in the repository database and are kept in memory when
they need to be verified.

_alpm_gpg_checksig_file is very similar to _alpm_gpg_checksig_memory,
but the signature is read from a file.

The return values for both functions are: 0 = valid; 1 = invalid;
-1 = error while verifying.

Signed-off-by: Denis A. Altoé Falqueto <[email protected]>
---
 lib/libalpm/signing.c |  159 ++++++++++++++++++++++++++++++++++++-------------
 lib/libalpm/signing.h |    3 +-
 2 files changed, 120 insertions(+), 42 deletions(-)

diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c
index 2b15528..781a1d1 100644
--- a/lib/libalpm/signing.c
+++ b/lib/libalpm/signing.c
@@ -91,21 +91,76 @@ error:
        RET_ERR(PM_ERR_GPGME, 1);
 }
 
+static int gpgme_checksig(gpgme_ctx_t ctx, gpgme_data_t filedata, gpgme_data_t 
sigdata,
+                         char *filepath)
+{
+       int ret = 0;
+       gpgme_error_t err;
+       gpgme_signature_t gpgsig;
+       gpgme_verify_result_t result;
+
+       /* here's where the magic happens */
+       err = gpgme_op_verify(ctx, sigdata, filedata, NULL);
+       CHECK_ERR();
+       result = gpgme_op_verify_result(ctx);
+       gpgsig = result->signatures;
+       if (!gpgsig || gpgsig->next) {
+               _alpm_log(PM_LOG_ERROR, _("Unexpected number of signatures\n"));
+               ret = -1;
+               goto error;
+       }
+       fprintf(stdout, "\nsummary=%x\n", gpgsig->summary);
+       fprintf(stdout, "fpr=%s\n", gpgsig->fpr);
+       fprintf(stdout, "status=%d\n", gpgsig->status);
+       fprintf(stdout, "timestamp=%lu\n", gpgsig->timestamp);
+       fprintf(stdout, "wrong_key_usage=%u\n", gpgsig->wrong_key_usage);
+       fprintf(stdout, "pka_trust=%u\n", gpgsig->pka_trust);
+       fprintf(stdout, "chain_model=%u\n", gpgsig->chain_model);
+       fprintf(stdout, "validity=%d\n", gpgsig->validity);
+       fprintf(stdout, "validity_reason=%d\n", gpgsig->validity_reason);
+       fprintf(stdout, "key=%d\n", gpgsig->pubkey_algo);
+       fprintf(stdout, "hash=%d\n", gpgsig->hash_algo);
+
+       if(gpgsig->summary & GPGME_SIGSUM_VALID) {
+               /* good signature, continue */
+               _alpm_log(PM_LOG_DEBUG, _("Package %s has a valid 
signature.\n"),
+                               filepath);
+       } else if(gpgsig->summary & GPGME_SIGSUM_GREEN) {
+               /* 'green' signature, not sure what to do here */
+               _alpm_log(PM_LOG_WARNING, _("Package %s has a green 
signature.\n"),
+                               filepath);
+       } else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) {
+               pm_errno = PM_ERR_SIG_UNKNOWN;
+               _alpm_log(PM_LOG_WARNING, _("Package %s has a signature from an 
unknown key.\n"),
+                               filepath);
+               ret = -1;
+       } else {
+               /* we'll capture everything else here */
+               pm_errno = PM_ERR_SIG_INVALID;
+               _alpm_log(PM_LOG_ERROR, _("Package %s has an invalid 
signature.\n"),
+                               filepath);
+               ret = 1;
+       }
+       return ret;
+error:
+       _alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err));
+       RET_ERR(PM_ERR_GPGME, 1);
+}
+
 /**
  * Check the PGP package signature for the given package file.
  * @param pkgpath the full path to a package file
  * @param sig PGP signature data in raw form (already decoded)
  * @return a int value : 0 (valid), 1 (invalid), -1 (an error occured)
  */
-int _alpm_gpgme_checksig(const char *pkgpath, const pmpgpsig_t *sig)
+int _alpm_gpgme_checksig_memory(const char *pkgpath, const pmpgpsig_t *sig)
 {
        int ret = 0;
        gpgme_error_t err;
        gpgme_ctx_t ctx;
        gpgme_data_t pkgdata, sigdata;
        gpgme_verify_result_t result;
-       gpgme_signature_t gpgsig;
-       FILE *pkgfile = NULL, *sigfile = NULL;
+       FILE *pkgfile = NULL;
 
        ALPM_LOG_FUNC;
 
@@ -137,58 +192,80 @@ int _alpm_gpgme_checksig(const char *pkgpath, const 
pmpgpsig_t *sig)
        err = gpgme_data_new_from_mem(&sigdata, (char*)sig->rawdata, 
sig->rawlen, 0);
        CHECK_ERR();
 
-       /* here's where the magic happens */
-       err = gpgme_op_verify(ctx, sigdata, pkgdata, NULL);
+       ret = gpgme_checksig(ctx, pkgdata, sigdata, pkgpath);
+error:
+       gpgme_data_release(sigdata);
+       gpgme_data_release(pkgdata);
+       gpgme_release(ctx);
+       if(pkgfile) {
+               fclose(pkgfile);
+       }
+       if(err != GPG_ERR_NO_ERROR) {
+               _alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), 
gpgme_strerror(err));
+               RET_ERR(PM_ERR_GPGME, -1);
+       }
+       return(ret);
+}
+
+/**
+ * Check the PGP signature for the some file
+ * @param filepath the full path to the signed file
+ * @param sigpath the full path to the signature file
+ * @return a int value : 0 (valid), 1 (invalid), -1 (an error occured)
+ */
+int _alpm_gpgme_checksig_file(const char *filepath, const char *sigpath)
+{
+       int ret = 0;
+       gpgme_error_t err;
+       gpgme_ctx_t ctx;
+       gpgme_data_t filedata, sigdata;
+       gpgme_verify_result_t result;
+       gpgme_signature_t gpgsig;
+       FILE *file = NULL, *sigfile = NULL;
+
+       ALPM_LOG_FUNC;
+
+       if(!filepath || access(filepath, R_OK) != 0) {
+               RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
+       }
+       if(gpgme_init()) {
+               /* pm_errno was set in gpgme_init() */
+               return(-1);
+       }
+       err = gpgme_new(&ctx);
        CHECK_ERR();
-       result = gpgme_op_verify_result(ctx);
-               gpgsig = result->signatures;
-       if (!gpgsig || gpgsig->next) {
-               _alpm_log(PM_LOG_ERROR, _("Unexpected number of signatures\n"));
+
+       /* create our necessary data objects to verify the signature */
+       /* first the package itself */
+       file = fopen(filepath, "rb");
+       if(file == NULL) {
+               pm_errno = PM_ERR_PKG_OPEN;
                ret = -1;
                goto error;
        }
-       fprintf(stdout, "\nsummary=%x\n", gpgsig->summary);
-       fprintf(stdout, "fpr=%s\n", gpgsig->fpr);
-       fprintf(stdout, "status=%d\n", gpgsig->status);
-       fprintf(stdout, "timestamp=%lu\n", gpgsig->timestamp);
-       fprintf(stdout, "wrong_key_usage=%u\n", gpgsig->wrong_key_usage);
-       fprintf(stdout, "pka_trust=%u\n", gpgsig->pka_trust);
-       fprintf(stdout, "chain_model=%u\n", gpgsig->chain_model);
-       fprintf(stdout, "validity=%d\n", gpgsig->validity);
-       fprintf(stdout, "validity_reason=%d\n", gpgsig->validity_reason);
-       fprintf(stdout, "key=%d\n", gpgsig->pubkey_algo);
-       fprintf(stdout, "hash=%d\n", gpgsig->hash_algo);
+       err = gpgme_data_new_from_stream(&filedata, file);
+       CHECK_ERR();
 
-       if(gpgsig->summary & GPGME_SIGSUM_VALID) {
-               /* good signature, continue */
-               _alpm_log(PM_LOG_DEBUG, _("Package %s has a valid 
signature.\n"),
-                               pkgpath);
-       } else if(gpgsig->summary & GPGME_SIGSUM_GREEN) {
-               /* 'green' signature, not sure what to do here */
-               _alpm_log(PM_LOG_WARNING, _("Package %s has a green 
signature.\n"),
-                               pkgpath);
-       } else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) {
+       /* next create data object for the signature */
+       sigfile = fopen(sigpath, "rb");
+       if (sigfile == NULL) {
                pm_errno = PM_ERR_SIG_UNKNOWN;
-               _alpm_log(PM_LOG_WARNING, _("Package %s has a signature from an 
unknown key.\n"),
-                               pkgpath);
                ret = -1;
-       } else {
-               /* we'll capture everything else here */
-               pm_errno = PM_ERR_SIG_INVALID;
-               _alpm_log(PM_LOG_ERROR, _("Package %s has an invalid 
signature.\n"),
-                               pkgpath);
-               ret = 1;
+               goto error;
        }
+       err = gpgme_data_new_from_stream(&sigdata, sigfile);
+       CHECK_ERR();
 
+       ret = gpgme_checksig(ctx, filedata, sigdata, filepath);
 error:
        gpgme_data_release(sigdata);
-       gpgme_data_release(pkgdata);
+       gpgme_data_release(filedata);
        gpgme_release(ctx);
        if(sigfile) {
                fclose(sigfile);
        }
-       if(pkgfile) {
-               fclose(pkgfile);
+       if(file) {
+               fclose(file);
        }
        if(err != GPG_ERR_NO_ERROR) {
                _alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), 
gpgme_strerror(err));
@@ -207,7 +284,7 @@ int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg)
        ALPM_LOG_FUNC;
        ASSERT(pkg != NULL, return(0));
 
-       return(_alpm_gpgme_checksig(alpm_pkg_get_filename(pkg),
+       return(_alpm_gpgme_checksig_memory(alpm_pkg_get_filename(pkg),
                        alpm_pkg_get_pgpsig(pkg)));
 }
 
diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h
index c004697..9ae3dc1 100644
--- a/lib/libalpm/signing.h
+++ b/lib/libalpm/signing.h
@@ -21,7 +21,8 @@
 
 #include "alpm.h"
 
-int _alpm_gpgme_checksig(const char *pkgpath, const pmpgpsig_t *sig);
+int _alpm_gpgme_checksig_memory(const char *pkgpath, const pmpgpsig_t *sig);
+int _alpm_gpgme_checksig_file(const char *filepath, const char *sigpath);
 
 #endif /* _ALPM_SIGNING_H */
 
-- 
1.7.1.1


Reply via email to