1 /*- 2 * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 #ifndef NETPGP_VERIFY_H_ 26 #define NETPGP_VERIFY_H_ 20140304 27 28 #define NETPGPVERIFY_VERSION "netpgpverify portable 20140304" 29 30 #include <sys/types.h> 31 32 #include <inttypes.h> 33 34 #ifndef PGPV_ARRAY 35 /* creates 2 unsigned vars called "name"c and "name"size in current scope */ 36 /* also creates an array called "name"s in current scope */ 37 #define PGPV_ARRAY(type, name) \ 38 unsigned name##c; unsigned name##vsize; type *name##s 39 #endif 40 41 /* 64bit key ids */ 42 #define PGPV_KEYID_LEN 8 43 #define PGPV_STR_KEYID_LEN (PGPV_KEYID_LEN + PGPV_KEYID_LEN + 1) 44 45 /* bignum structure */ 46 typedef struct pgpv_bignum_t { 47 void *bn; /* hide the implementation details */ 48 uint16_t bits; /* cached number of bits */ 49 } pgpv_bignum_t; 50 51 /* right now, our max binary digest length is 20 bytes */ 52 #define PGPV_MAX_HASH_LEN 64 53 54 /* fingerprint */ 55 typedef struct pgpv_fingerprint_t { 56 uint8_t hashalg; /* algorithm for digest */ 57 uint8_t v[PGPV_MAX_HASH_LEN]; /* the digest */ 58 uint32_t len; /* its length */ 59 } pgpv_fingerprint_t; 60 61 /* specify size for array of bignums */ 62 #define PGPV_MAX_PUBKEY_BN 4 63 64 /* public key */ 65 typedef struct pgpv_pubkey_t { 66 pgpv_fingerprint_t fingerprint; /* key fingerprint i.e. digest */ 67 uint8_t keyid[PGPV_KEYID_LEN]; /* last 8 bytes of v4 keys */ 68 int64_t birth; /* creation time */ 69 int64_t expiry; /* expiry time */ 70 pgpv_bignum_t bn[PGPV_MAX_PUBKEY_BN]; /* bignums */ 71 uint8_t keyalg; /* key algorithm */ 72 uint8_t hashalg; /* hash algorithm */ 73 uint8_t version; /* key version */ 74 } pgpv_pubkey_t; 75 76 #define PGPV_MAX_SESSKEY_BN 2 77 78 /* a (size, byte array) string */ 79 typedef struct pgpv_string_t { 80 size_t size; 81 uint8_t *data; 82 } pgpv_string_t; 83 84 typedef struct pgpv_ref_t { 85 void *vp; 86 size_t offset; 87 unsigned mem; 88 } pgpv_ref_t; 89 90 #define PGPV_MAX_SECKEY_BN 4 91 92 typedef struct pgpv_compress_t { 93 pgpv_string_t s; 94 uint8_t compalg; 95 } pgpv_compress_t; 96 97 /* a packet dealing with trust */ 98 typedef struct pgpv_trust_t { 99 uint8_t level; 100 uint8_t amount; 101 } pgpv_trust_t; 102 103 /* a signature sub packet */ 104 typedef struct pgpv_sigsubpkt_t { 105 pgpv_string_t s; 106 uint8_t tag; 107 uint8_t critical; 108 } pgpv_sigsubpkt_t; 109 110 #define PGPV_MAX_SIG_BN 2 111 112 typedef struct pgpv_signature_t { 113 uint8_t *signer; /* key id of signer */ 114 pgpv_ref_t hashstart; 115 uint8_t *hash2; 116 uint8_t *mpi; 117 int64_t birth; 118 int64_t keyexpiry; 119 int64_t expiry; 120 uint32_t hashlen; 121 uint8_t version; 122 uint8_t type; 123 uint8_t keyalg; 124 uint8_t hashalg; 125 uint8_t trustlevel; 126 uint8_t trustamount; 127 pgpv_bignum_t bn[PGPV_MAX_SIG_BN]; 128 char *regexp; 129 char *pref_key_server; 130 char *policy; 131 char *features; 132 char *why_revoked; 133 uint8_t *revoke_fingerprint; 134 uint8_t revoke_alg; 135 uint8_t revoke_sensitive; 136 uint8_t trustsig; 137 uint8_t revocable; 138 uint8_t pref_symm_alg; 139 uint8_t pref_hash_alg; 140 uint8_t pref_compress_alg; 141 uint8_t key_server_modify; 142 uint8_t notation; 143 uint8_t type_key; 144 uint8_t primary_userid; 145 uint8_t revoked; /* subtract 1 to get real reason, 0 == not revoked */ 146 } pgpv_signature_t; 147 148 /* a signature packet */ 149 typedef struct pgpv_sigpkt_t { 150 pgpv_signature_t sig; 151 uint16_t subslen; 152 uint16_t unhashlen; 153 PGPV_ARRAY(pgpv_sigsubpkt_t, subpkts); 154 } pgpv_sigpkt_t; 155 156 /* a one-pass signature packet */ 157 typedef struct pgpv_onepass_t { 158 uint8_t keyid[PGPV_KEYID_LEN]; 159 uint8_t version; 160 uint8_t type; 161 uint8_t hashalg; 162 uint8_t keyalg; 163 uint8_t nested; 164 } pgpv_onepass_t; 165 166 /* a literal data packet */ 167 typedef struct pgpv_litdata_t { 168 uint8_t *filename; 169 pgpv_string_t s; 170 uint32_t secs; 171 uint8_t namelen; 172 char format; 173 unsigned mem; 174 size_t offset; 175 size_t len; 176 } pgpv_litdata_t; 177 178 /* user attributes - images */ 179 typedef struct pgpv_userattr_t { 180 size_t len; 181 PGPV_ARRAY(pgpv_string_t, subattrs); 182 } pgpv_userattr_t; 183 184 /* a general PGP packet */ 185 typedef struct pgpv_pkt_t { 186 uint8_t tag; 187 uint8_t newfmt; 188 uint8_t allocated; 189 uint8_t mement; 190 size_t offset; 191 pgpv_string_t s; 192 union { 193 pgpv_sigpkt_t sigpkt; 194 pgpv_onepass_t onepass; 195 pgpv_litdata_t litdata; 196 pgpv_compress_t compressed; 197 pgpv_trust_t trust; 198 pgpv_pubkey_t pubkey; 199 pgpv_string_t userid; 200 pgpv_userattr_t userattr; 201 } u; 202 } pgpv_pkt_t; 203 204 /* a memory structure */ 205 typedef struct pgpv_mem_t { 206 size_t size; 207 size_t cc; 208 uint8_t *mem; 209 FILE *fp; 210 uint8_t dealloc; 211 const char *allowed; /* the types of packet that are allowed */ 212 } pgpv_mem_t; 213 214 /* packet parser */ 215 216 typedef struct pgpv_signed_userid_t { 217 pgpv_string_t userid; 218 PGPV_ARRAY(pgpv_signature_t, sigs); 219 uint8_t primary_userid; 220 uint8_t revoked; 221 } pgpv_signed_userid_t; 222 223 typedef struct pgpv_signed_userattr_t { 224 pgpv_userattr_t userattr; 225 PGPV_ARRAY(pgpv_signature_t, sigs); 226 uint8_t revoked; 227 } pgpv_signed_userattr_t; 228 229 typedef struct pgpv_signed_subkey_t { 230 pgpv_pubkey_t subkey; 231 pgpv_signature_t revoc_self_sig; 232 PGPV_ARRAY(pgpv_signature_t, sigs); 233 } pgpv_signed_subkey_t; 234 235 typedef struct pgpv_primarykey_t { 236 pgpv_pubkey_t primary; 237 pgpv_signature_t revoc_self_sig; 238 PGPV_ARRAY(pgpv_signature_t, direct_sigs); 239 PGPV_ARRAY(pgpv_signed_userid_t, signed_userids); 240 PGPV_ARRAY(pgpv_signed_userattr_t, signed_userattrs); 241 PGPV_ARRAY(pgpv_signed_subkey_t, signed_subkeys); 242 size_t fmtsize; 243 uint8_t primary_userid; 244 } pgpv_primarykey_t; 245 246 /* everything stems from this structure */ 247 typedef struct pgpv_t { 248 PGPV_ARRAY(pgpv_pkt_t, pkts); /* packet array */ 249 PGPV_ARRAY(pgpv_primarykey_t, primaries); /* array of primary keys */ 250 PGPV_ARRAY(pgpv_mem_t, areas); /* areas we read packets from */ 251 PGPV_ARRAY(size_t, datastarts); /* starts of data packets */ 252 size_t pkt; /* when parsing, current pkt number */ 253 const char *op; /* the operation we're doing */ 254 unsigned ssh; /* using ssh keys */ 255 } pgpv_t; 256 257 #define PGPV_REASON_LEN 128 258 259 /* when searching, we define a cursor, and fill in an array of subscripts */ 260 typedef struct pgpv_cursor_t { 261 pgpv_t *pgp; /* pointer to pgp tree */ 262 char *field; /* field we're searching on */ 263 char *op; /* operation we're doing */ 264 char *value; /* value we're searching for */ 265 void *ptr; /* for regexps etc */ 266 PGPV_ARRAY(uint32_t, found); /* array of matched subscripts */ 267 PGPV_ARRAY(size_t, datacookies); /* cookies to retrieve matched data */ 268 int64_t sigtime; /* time of signature */ 269 char why[PGPV_REASON_LEN]; /* reason for bad signature */ 270 } pgpv_cursor_t; 271 272 #ifndef __BEGIN_DECLS 273 # if defined(__cplusplus) 274 # define __BEGIN_DECLS extern "C" { 275 # define __END_DECLS } 276 # else 277 # define __BEGIN_DECLS 278 # define __END_DECLS 279 # endif 280 #endif 281 282 __BEGIN_DECLS 283 284 int pgpv_read_pubring(pgpv_t */*pgp*/, const void */*keyringfile/mem*/, ssize_t /*size*/); 285 int pgpv_read_ssh_pubkeys(pgpv_t */*pgp*/, const void */*keyring*/, ssize_t /*size*/); 286 287 size_t pgpv_verify(pgpv_cursor_t */*cursor*/, pgpv_t */*pgp*/, const void */*mem/file*/, ssize_t /*size*/); 288 size_t pgpv_get_verified(pgpv_cursor_t */*cursor*/, size_t /*cookie*/, char **/*ret*/); 289 290 size_t pgpv_get_entry(pgpv_t */*pgp*/, unsigned /*ent*/, char **/*ret*/, const char */*modifiers*/); 291 292 int pgpv_close(pgpv_t */*pgp*/); 293 294 __END_DECLS 295 296 #endif 297