1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
|
/* packet.h - packet read/write stuff
* Copyright (C) 1998 Free Software Foundation, Inc.
*
* This file is part of GNUPG.
*
* GNUPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GNUPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef G10_PACKET_H
#define G10_PACKET_H
#include "types.h"
#include "iobuf.h"
#include "mpi.h"
#include "cipher.h"
#include "filter.h"
typedef enum {
PKT_NONE =0,
PKT_PUBKEY_ENC =1, /* public key encrypted packet */
PKT_SIGNATURE =2, /* secret key encrypted packet */
PKT_SYMKEY_ENC =3, /* session key packet (OpenPGP)*/
PKT_ONEPASS_SIG =4, /* one pass sig packet (OpenPGP)*/
PKT_SECRET_KEY =5, /* secret key */
PKT_PUBLIC_KEY =6, /* public key */
PKT_SECRET_SUBKEY =7, /* secret subkey (OpenPGP) */
PKT_COMPRESSED =8, /* compressed data packet */
PKT_ENCRYPTED =9, /* conventional encrypted data */
PKT_MARKER =10, /* marker packet (OpenPGP) */
PKT_PLAINTEXT =11, /* plaintext data with filename and mode */
PKT_RING_TRUST =12, /* keyring trust packet */
PKT_USER_ID =13, /* user id packet */
PKT_PUBLIC_SUBKEY =14, /* public subkey (OpenPGP) */
PKT_OLD_COMMENT =16, /* comment packet from an OpenPGP draft */
PKT_COMMENT =61 /* new comment packet (private) */
} pkttype_t;
typedef struct packet_struct PACKET;
typedef struct {
byte mode;
byte hash_algo;
byte salt[8];
u32 count;
} STRING2KEY;
typedef struct {
byte version;
byte cipher_algo; /* cipher algorithm used */
STRING2KEY s2k;
byte seskeylen; /* keylength in byte or 0 for no seskey */
byte seskey[1];
} PKT_symkey_enc;
typedef struct {
u32 keyid[2]; /* 64 bit keyid */
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
byte throw_keyid;
MPI data[PUBKEY_MAX_NENC];
} PKT_pubkey_enc;
typedef struct {
u32 keyid[2]; /* 64 bit keyid */
byte sig_class; /* sig classification */
byte digest_algo; /* algorithm used for digest */
byte pubkey_algo; /* algorithm used for public key scheme */
byte last; /* a stupid flag */
} PKT_onepass_sig;
typedef struct {
ulong local_id; /* internal use, valid if > 0 */
struct {
unsigned checked:1; /* signature has been checked */
unsigned valid:1; /* signature is good (if checked is set) */
unsigned unknown_critical:1;
} flags;
u32 keyid[2]; /* 64 bit keyid */
u32 timestamp; /* signature made */
byte version;
byte sig_class; /* sig classification, append for MD calculation*/
byte pubkey_algo; /* algorithm used for public key scheme */
/* (PUBKEY_ALGO_xxx) */
byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */
byte *hashed_data; /* all subpackets with hashed data (v4 only) */
byte *unhashed_data; /* ditto for unhashed data */
byte digest_start[2]; /* first 2 bytes of the digest */
MPI data[PUBKEY_MAX_NSIG];
} PKT_signature;
/****************
* Note about the pkey/skey elements: We assume that the secret keys
* has the same elemts as the public key at the begin of the array, so
* that npkey < nskey and it is possible to compare the secret and
* public keys by comparing the first npkey elements of pkey againts skey.
*/
typedef struct {
u32 timestamp; /* key made */
u32 expiredate; /* expires at this date or 0 if not at all */
byte hdrbytes; /* number of header bytes */
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
byte pubkey_usage; /* for now only used to pass it to getkey() */
ulong local_id; /* internal use, valid if > 0 */
u32 keyid[2]; /* calculated by keyid_from_pk() */
byte *namehash; /* if != NULL: found by this name */
MPI pkey[PUBKEY_MAX_NPKEY];
} PKT_public_key;
typedef struct {
u32 timestamp; /* key made */
u32 expiredate; /* expires at this date or 0 if not at all */
byte hdrbytes; /* number of header bytes */
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
byte pubkey_usage;
byte is_protected; /* The secret info is protected and must */
/* be decrypted before use, the protected */
/* MPIs are simply (void*) pointers to memory */
/* and should never be passed to a mpi_xxx() */
struct {
byte algo; /* cipher used to protect the secret information*/
STRING2KEY s2k;
byte iv[8]; /* initialization vector for CFB mode */
} protect;
MPI skey[PUBKEY_MAX_NSKEY];
u16 csum; /* checksum */
} PKT_secret_key;
typedef struct {
int len; /* length of data */
char data[1];
} PKT_comment;
typedef struct {
int len; /* length of the name */
char name[1];
} PKT_user_id;
typedef struct {
u32 len; /* reserved */
byte new_ctb;
byte algorithm;
IOBUF buf; /* IOBUF reference */
} PKT_compressed;
typedef struct {
u32 len; /* length of encrypted data */
byte new_ctb;
IOBUF buf; /* IOBUF reference */
} PKT_encrypted;
typedef struct {
u32 len; /* length of encrypted data */
IOBUF buf; /* IOBUF reference */
byte new_ctb;
int mode;
u32 timestamp;
int namelen;
char name[1];
} PKT_plaintext;
/* combine all packets into a union */
struct packet_struct {
pkttype_t pkttype;
union {
void *generic;
PKT_symkey_enc *symkey_enc; /* PKT_SYMKEY_ENC */
PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */
PKT_onepass_sig *onepass_sig; /* PKT_ONEPASS_SIG */
PKT_signature *signature; /* PKT_SIGNATURE */
PKT_public_key *public_key; /* PKT_PUBLIC_[SUB)KEY */
PKT_secret_key *secret_key; /* PKT_SECRET_[SUB]KEY */
PKT_comment *comment; /* PKT_COMMENT */
PKT_user_id *user_id; /* PKT_USER_ID */
PKT_compressed *compressed; /* PKT_COMPRESSED */
PKT_encrypted *encrypted; /* PKT_ENCRYPTED */
PKT_plaintext *plaintext; /* PKT_PLAINTEXT */
} pkt;
};
#define init_packet(a) do { (a)->pkttype = 0; \
(a)->pkt.generic = NULL; \
} while(0)
typedef enum {
SIGSUBPKT_TEST_CRITICAL=-3,
SIGSUBPKT_LIST_UNHASHED=-2,
SIGSUBPKT_LIST_HASHED =-1,
SIGSUBPKT_NONE = 0,
SIGSUBPKT_SIG_CREATED = 2, /* signature creation time */
SIGSUBPKT_SIG_EXPIRE = 3, /* signature expiration time */
SIGSUBPKT_EXPORTABLE = 4, /* exportable */
SIGSUBPKT_TRUST = 5, /* trust signature */
SIGSUBPKT_REGEXP = 6, /* regular expression */
SIGSUBPKT_REVOCABLE = 7, /* revocable */
SIGSUBPKT_KEY_EXPIRE = 9, /* key expiration time */
SIGSUBPKT_ARR =10, /* additional recipient request */
SIGSUBPKT_PREF_SYM =11, /* preferred symmetric algorithms */
SIGSUBPKT_REV_KEY =12, /* revocation key */
SIGSUBPKT_ISSUER =16, /* issuer key ID */
SIGSUBPKT_NOTATION =20, /* notation data */
SIGSUBPKT_PREF_HASH =21, /* preferred hash algorithms */
SIGSUBPKT_PREF_COMPR =22, /* preferred compression algorithms */
SIGSUBPKT_KS_FLAGS =23, /* key server preferences */
SIGSUBPKT_PREF_KS =24, /* preferred key server */
SIGSUBPKT_PRIMARY_UID =25, /* primary user id */
SIGSUBPKT_POLICY =26, /* policy URL */
SIGSUBPKT_KEY_FLAGS =27, /* key flags */
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
SIGSUBPKT_PRIV_ADD_SIG =101 /* signatur is also valid for this uid */
} sigsubpkttype_t;
/*-- mainproc.c --*/
int proc_packets( IOBUF a );
int proc_signature_packets( IOBUF a, STRLIST signedfiles, const char *sigfile );
int proc_encryption_packets( IOBUF a );
int list_packets( IOBUF a );
/*-- parse-packet.c --*/
int set_packet_list_mode( int mode );
int search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos );
int parse_packet( IOBUF inp, PACKET *ret_pkt);
int copy_all_packets( IOBUF inp, IOBUF out );
int copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff );
int skip_some_packets( IOBUF inp, unsigned n );
const byte *parse_sig_subpkt( const byte *buffer,
sigsubpkttype_t reqtype, size_t *ret_n );
const byte *parse_sig_subpkt2( PKT_signature *sig,
sigsubpkttype_t reqtype, size_t *ret_n );
/*-- build-packet.c --*/
int build_packet( IOBUF inp, PACKET *pkt );
u32 calc_packet_length( PACKET *pkt );
void hash_public_key( MD_HANDLE md, PKT_public_key *pk );
void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
const byte *buffer, size_t buflen );
void build_sig_subpkt_from_sig( PKT_signature *sig );
/*-- free-packet.c --*/
void free_symkey_enc( PKT_symkey_enc *enc );
void free_pubkey_enc( PKT_pubkey_enc *enc );
void free_seckey_enc( PKT_signature *enc );
int digest_algo_from_sig( PKT_signature *sig );
void release_public_key_parts( PKT_public_key *pk );
void free_public_key( PKT_public_key *key );
void release_secret_key_parts( PKT_secret_key *sk );
void free_secret_key( PKT_secret_key *sk );
void free_user_id( PKT_user_id *uid );
void free_comment( PKT_comment *rem );
void free_packet( PACKET *pkt );
PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s );
PKT_public_key *copy_public_key_new_namehash( PKT_public_key *d,
PKT_public_key *s,
const byte *namehash );
PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
PKT_user_id *copy_user_id( PKT_user_id *d, PKT_user_id *s );
int cmp_public_keys( PKT_public_key *a, PKT_public_key *b );
int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b );
int cmp_signatures( PKT_signature *a, PKT_signature *b );
int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
/*-- sig-check.c --*/
int signature_check( PKT_signature *sig, MD_HANDLE digest );
/*-- seckey-cert.c --*/
int is_secret_key_protected( PKT_secret_key *sk );
int check_secret_key( PKT_secret_key *sk, int retries );
int protect_secret_key( PKT_secret_key *sk, DEK *dek );
/*-- pubkey-enc.c --*/
int get_session_key( PKT_pubkey_enc *k, DEK *dek );
/*-- compress.c --*/
int handle_compressed( PKT_compressed *cd,
int (*callback)(IOBUF, void *), void *passthru );
/*-- encr-data.c --*/
int decrypt_data( PKT_encrypted *ed, DEK *dek );
int encrypt_data( PKT_encrypted *ed, DEK *dek );
/*-- plaintext.c --*/
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
int nooutput, int clearsig );
int ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname );
/*-- comment.c --*/
int write_comment( IOBUF out, const char *s );
/*-- sign.c --*/
int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
PKT_user_id *uid, PKT_public_key *subpk,
PKT_secret_key *sk,
int sigclass, int digest_algo,
int (*mksubpkt)(PKT_signature *, void *),
void *opaque );
/*-- keygen.c --*/
PKT_user_id *generate_user_id(void);
#endif /*G10_PACKET_H*/
|