/*- * Copyright (c) 2012 Alistair Crooks * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef NETPGP_VERIFY_H_ #define NETPGP_VERIFY_H_ 20120928 #include #include #ifndef PGPV_ARRAY /* creates 2 unsigned vars called "name"c and "name"size in current scope */ /* also creates an array called "name"s in current scope */ #define PGPV_ARRAY(type, name) \ unsigned name##c; unsigned name##vsize; type *name##s #endif /* 64bit key ids */ #define PGPV_KEYID_LEN 8 #define PGPV_STR_KEYID_LEN (PGPV_KEYID_LEN + PGPV_KEYID_LEN + 1) /* bignum structure */ typedef struct pgpv_bignum_t { void *bn; /* hide the implementation details */ uint16_t bits; /* cached number of bits */ } pgpv_bignum_t; /* right now, our max binary digest length is 20 bytes */ #define PGPV_MAX_HASH_LEN 20 /* fingerprint */ typedef struct pgpv_fingerprint_t { uint8_t hashalg; /* algorithm for digest */ uint8_t v[PGPV_MAX_HASH_LEN]; /* the digest */ uint32_t len; /* its length */ } pgpv_fingerprint_t; /* specify size for array of bignums */ #define PGPV_MAX_PUBKEY_BN 4 /* public key */ typedef struct pgpv_pubkey_t { pgpv_fingerprint_t fingerprint; /* key fingerprint i.e. digest */ uint8_t keyid[PGPV_KEYID_LEN]; /* last 8 bytes of v4 keys */ int64_t birth; /* creation time */ int64_t expiry; /* expiry time */ pgpv_bignum_t bn[PGPV_MAX_PUBKEY_BN]; /* bignums */ uint8_t keyalg; /* key algorithm */ uint8_t hashalg; /* hash algorithm */ uint8_t version; /* key version */ } pgpv_pubkey_t; #define PGPV_MAX_SESSKEY_BN 2 /* a (size, byte array) string */ typedef struct pgpv_string_t { size_t size; uint8_t *data; } pgpv_string_t; typedef struct pgpv_ref_t { void *vp; size_t offset; unsigned mem; } pgpv_ref_t; #define PGPV_MAX_SECKEY_BN 4 typedef struct pgpv_compress_t { pgpv_string_t s; uint8_t compalg; } pgpv_compress_t; /* a packet dealing with trust */ typedef struct pgpv_trust_t { uint8_t level; uint8_t amount; } pgpv_trust_t; /* a signature sub packet */ typedef struct pgpv_sigsubpkt_t { pgpv_string_t s; uint8_t tag; uint8_t critical; } pgpv_sigsubpkt_t; #define PGPV_MAX_SIG_BN 2 typedef struct pgpv_signature_t { uint8_t *signer; /* key id of signer */ pgpv_ref_t hashstart; uint8_t *hash2; uint8_t *mpi; int64_t birth; int64_t keyexpiry; int64_t expiry; uint32_t hashlen; uint8_t version; uint8_t type; uint8_t keyalg; uint8_t hashalg; uint8_t trustlevel; uint8_t trustamount; pgpv_bignum_t bn[PGPV_MAX_SIG_BN]; char *regexp; char *pref_key_server; char *policy; char *features; char *why_revoked; uint8_t *revoke_fingerprint; uint8_t revoke_alg; uint8_t revoke_sensitive; uint8_t trustsig; uint8_t revocable; uint8_t pref_symm_alg; uint8_t pref_hash_alg; uint8_t pref_compress_alg; uint8_t key_server_modify; uint8_t notation; uint8_t type_key; uint8_t primary_userid; uint8_t revoked; /* subtract 1 to get real reason, 0 == not revoked */ } pgpv_signature_t; /* a signature packet */ typedef struct pgpv_sigpkt_t { pgpv_signature_t sig; uint16_t subslen; uint16_t unhashlen; PGPV_ARRAY(pgpv_sigsubpkt_t, subpkts); } pgpv_sigpkt_t; /* a one-pass signature packet */ typedef struct pgpv_onepass_t { uint8_t keyid[PGPV_KEYID_LEN]; uint8_t version; uint8_t type; uint8_t hashalg; uint8_t keyalg; uint8_t nested; } pgpv_onepass_t; /* a literal data packet */ typedef struct pgpv_litdata_t { uint8_t *filename; pgpv_string_t s; uint32_t secs; uint8_t namelen; char format; unsigned mem; size_t offset; size_t len; } pgpv_litdata_t; /* user attributes - images */ typedef struct pgpv_userattr_t { size_t len; PGPV_ARRAY(pgpv_string_t, subattrs); } pgpv_userattr_t; /* a general PGP packet */ typedef struct pgpv_pkt_t { uint8_t tag; uint8_t newfmt; uint8_t allocated; uint8_t mement; size_t offset; pgpv_string_t s; union { pgpv_sigpkt_t sigpkt; pgpv_onepass_t onepass; pgpv_litdata_t litdata; pgpv_compress_t compressed; pgpv_trust_t trust; pgpv_pubkey_t pubkey; pgpv_string_t userid; pgpv_userattr_t userattr; } u; } pgpv_pkt_t; /* a memory structure */ typedef struct pgpv_mem_t { size_t size; size_t cc; uint8_t *mem; FILE *fp; uint8_t dealloc; const char *allowed; /* the types of packet that are allowed */ } pgpv_mem_t; /* packet parser */ typedef struct pgpv_signed_userid_t { pgpv_string_t userid; PGPV_ARRAY(pgpv_signature_t, sigs); uint8_t primary_userid; uint8_t revoked; } pgpv_signed_userid_t; typedef struct pgpv_signed_userattr_t { pgpv_userattr_t userattr; PGPV_ARRAY(pgpv_signature_t, sigs); uint8_t revoked; } pgpv_signed_userattr_t; typedef struct pgpv_signed_subkey_t { pgpv_pubkey_t subkey; pgpv_signature_t revoc_self_sig; PGPV_ARRAY(pgpv_signature_t, sigs); } pgpv_signed_subkey_t; typedef struct pgpv_primarykey_t { pgpv_pubkey_t primary; pgpv_signature_t revoc_self_sig; PGPV_ARRAY(pgpv_signature_t, direct_sigs); PGPV_ARRAY(pgpv_signed_userid_t, signed_userids); PGPV_ARRAY(pgpv_signed_userattr_t, signed_userattrs); PGPV_ARRAY(pgpv_signed_subkey_t, signed_subkeys); size_t fmtsize; uint8_t primary_userid; } pgpv_primarykey_t; /* everything stems from this structure */ typedef struct pgpv_t { PGPV_ARRAY(pgpv_pkt_t, pkts); /* packet array */ PGPV_ARRAY(pgpv_primarykey_t, primaries); /* array of primary keys */ PGPV_ARRAY(pgpv_mem_t, areas); /* areas we read packets from */ PGPV_ARRAY(size_t, datastarts); /* starts of data packets */ size_t pkt; /* when parsing, current pkt number */ const char *op; /* the operation we're doing */ } pgpv_t; #define PGPV_REASON_LEN 128 /* when searching, we define a cursor, and fill in an array of subscripts */ typedef struct pgpv_cursor_t { pgpv_t *pgp; /* pointer to pgp tree */ char *field; /* field we're searching on */ char *op; /* operation we're doing */ char *value; /* value we're searching for */ void *ptr; /* for regexps etc */ PGPV_ARRAY(uint32_t, found); /* array of matched subscripts */ PGPV_ARRAY(size_t, datacookies); /* cookies to retrieve matched data */ int64_t sigtime; /* time of signature */ char why[PGPV_REASON_LEN]; /* reason for bad signature */ } pgpv_cursor_t; #ifndef __BEGIN_DECLS # if defined(__cplusplus) # define __BEGIN_DECLS extern "C" { # define __END_DECLS } # else # define __BEGIN_DECLS # define __END_DECLS # endif #endif __BEGIN_DECLS int pgpv_read_pubring(pgpv_t */*pgp*/, const void */*keyringfile/mem*/, ssize_t /*size*/); size_t pgpv_verify(pgpv_cursor_t */*cursor*/, pgpv_t */*pgp*/, const void */*mem/file*/, ssize_t /*size*/); size_t pgpv_get_verified(pgpv_cursor_t */*cursor*/, size_t /*cookie*/, char **/*ret*/); size_t pgpv_get_entry(pgpv_t */*pgp*/, unsigned /*ent*/, char **/*ret*/); int pgpv_close(pgpv_t */*pgp*/); __END_DECLS #endif