Function sequoia_ffi::openpgp::parse::stream::pgp_detached_verifier_new[][src]

#[no_mangle]
pub extern "C" fn pgp_detached_verifier_new<'a>(
    errp: Option<&mut *mut Error>,
    policy: *const Policy,
    signature_input: *mut Reader,
    get_certs: extern "C" fn(_: *mut HelperCookie, _: *const *mut KeyID, _: usize, _: &mut *mut *mut Cert, _: *mut usize, _: *mut fn(_: *mut c_void)) -> Status,
    check: extern "C" fn(_: *mut HelperCookie, _: *const MessageStructure<'_>) -> Status,
    inspect: Option<extern "C" fn(_: *mut HelperCookie, _: *const PacketParser<'_>) -> Status>,
    cookie: *mut HelperCookie,
    time: time_t
) -> Maybe<DetachedVerifier>
Expand description

Verifies a detached OpenPGP signature.

C Declaration

pgp_detached_verifier_t
pgp_detached_verifier_new (pgp_error_t *errp,
                           const pgp_policy_t policy,
                           pgp_reader_t signature_input,
                           pgp_get_public_keys_callback_t get_certs,
                           pgp_check_callback_t check,
                           pgp_inspect_callback_t inspect,
                           pgp_helper_cookie_t cookie,
                           time_t time);

Sending objects across thread boundaries

If you send a Sequoia object (like a pgp_verifier_t) that reads from an callback across thread boundaries, you must make sure that the callbacks and cookie support that as well.

Examples

#define _GNU_SOURCE
#include <assert.h>
#include <error.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sequoia/openpgp.h>

struct verify_cookie {
  pgp_cert_t key;
};

static pgp_status_t
get_certs_cb (void *cookie_opaque,
                    pgp_keyid_t *keyids, size_t keyids_len,
                    pgp_cert_t **certs, size_t *certs_len,
                    void (**our_free)(void *))
{
  /* Feed the Certs to the verifier here.  */
  struct verify_cookie *cookie = cookie_opaque;
  *certs = malloc (sizeof (pgp_cert_t));
  assert (*certs);
  *certs[0] = cookie->key;
  *certs_len = 1;
  *our_free = free;
  return PGP_STATUS_SUCCESS;
}

static pgp_status_t
check_cb (void *cookie_opaque, pgp_message_structure_t structure)
{
  pgp_message_structure_iter_t iter =
    pgp_message_structure_into_iter (structure);
  pgp_message_layer_t layer = pgp_message_structure_iter_next (iter);
  assert (layer);
  pgp_verification_result_iter_t results;
  if (pgp_message_layer_signature_group (layer, &results)) {
    pgp_verification_result_t result =
      pgp_verification_result_iter_next (results);
    assert (result);
    assert (pgp_verification_result_good_checksum (result, NULL, NULL,
                                                   NULL, NULL, NULL));
    pgp_verification_result_free (result);
  } else {
    assert (! "reachable");
  }
  pgp_verification_result_iter_free (results);
  pgp_message_layer_free (layer);
  pgp_message_structure_iter_free (iter);
  return PGP_STATUS_SUCCESS;
}

int
main (int argc, char **argv)
{
  pgp_status_t rc;
  pgp_cert_t cert;
  pgp_reader_t signature;
  pgp_reader_t source;
  pgp_detached_verifier_t verifier;
  pgp_policy_t policy = pgp_standard_policy ();

  cert = pgp_cert_from_file (NULL,
    "../openpgp/tests/data/keys/emmelie-dorothea-dina-samantha-awina-ed25519.pgp");
  assert(cert);

  signature = pgp_reader_from_file (
    NULL,
    "../openpgp/tests/data/messages/a-cypherpunks-manifesto.txt.ed25519.sig");
  assert (signature);

  source = pgp_reader_from_file (
    NULL, "../openpgp/tests/data/messages/a-cypherpunks-manifesto.txt");
  assert (source);

  struct verify_cookie cookie = {
    .key = cert,  /* Move.  */
  };
  verifier = pgp_detached_verifier_new (NULL, policy, signature,
    get_certs_cb, check_cb, NULL,
    &cookie, 1554542219);
  assert (verifier);

  rc = pgp_detached_verifier_verify (NULL, verifier, source);
  assert (rc == PGP_STATUS_SUCCESS);

  pgp_detached_verifier_free (verifier);
  pgp_reader_free (source);
  pgp_reader_free (signature);
  pgp_policy_free (policy);
  return 0;
}