77f74560bc25059325b93e5715fc94298ba80d69
[users/jgh/exim.git] / src / src / pdkim / pdkim.h
1 /* $Cambridge: exim/src/src/pdkim/pdkim.h,v 1.1.2.4 2009/02/27 17:04:20 tom Exp $ */
2 /* pdkim.h */
3
4 #include "sha1.h"
5 #include "sha2.h"
6 #include "rsa.h"
7 #include "base64.h"
8
9 #define PDKIM_SIGNATURE_VERSION "1"
10 #define PDKIM_MAX_BODY_LINE_LEN 1024
11 #define PDKIM_DEBUG
12 #define PDKIM_DEFAULT_SIGN_HEADERS "From:Sender:Reply-To:Subject:Date:"\
13                              "Message-ID:To:Cc:MIME-Version:Content-Type:"\
14                              "Content-Transfer-Encoding:Content-ID:"\
15                              "Content-Description:Resent-Date:Resent-From:"\
16                              "Resent-Sender:Resent-To:Resent-Cc:"\
17                              "Resent-Message-ID:In-Reply-To:References:"\
18                              "List-Id:List-Help:List-Unsubscribe:"\
19                              "List-Subscribe:List-Post:List-Owner:List-Archive"
20
21
22 /* Function success / error codes */
23 #define PDKIM_OK              0
24 #define PDKIM_FAIL            -1
25 #define PDKIM_ERR_OOM         -100
26 #define PDKIM_ERR_RSA_PRIVKEY -101
27 #define PDKIM_ERR_RSA_SIGNING -102
28 #define PDKIM_ERR_LONG_LINE   -103
29
30 /* Main verification status */
31 #define PDKIM_VERIFY_NONE      0
32 #define PDKIM_VERIFY_INVALID   1
33 #define PDKIM_VERIFY_FAIL      2
34 #define PDKIM_VERIFY_PASS      3
35
36 /* Extended verification status */
37 #define PDKIM_VERIFY_FAIL_NONE    0
38 #define PDKIM_VERIFY_FAIL_BODY    1
39 #define PDKIM_VERIFY_FAIL_MESSAGE 2
40
41
42
43
44
45
46
47 #ifdef PDKIM_DEBUG
48 void pdkim_quoteprint(FILE *, char *, int, int);
49 #endif
50
51 typedef struct pdkim_stringlist {
52   char *value;
53   void *next;
54 } pdkim_stringlist;
55 pdkim_stringlist *pdkim_append_stringlist(pdkim_stringlist *, char *);
56
57
58 #define PDKIM_STR_ALLOC_FRAG 256
59 typedef struct pdkim_str {
60   char         *str;
61   unsigned int  len;
62   unsigned int  allocated;
63 } pdkim_str;
64 pdkim_str *pdkim_strnew (char *);
65 char      *pdkim_strcat (pdkim_str *, char *);
66 char      *pdkim_strncat(pdkim_str *, char *, int);
67 void       pdkim_strfree(pdkim_str *);
68
69 #define PDKIM_QUERYMETHOD_DNS_TXT 0
70 /* extern char *pdkim_querymethods[]; */
71
72 #define PDKIM_ALGO_RSA_SHA256 0
73 #define PDKIM_ALGO_RSA_SHA1   1
74 /* extern char *pdkim_algos[]; */
75
76 #define PDKIM_CANON_SIMPLE   0
77 #define PDKIM_CANON_RELAXED  1
78 /* extern char *pdkim_canons[]; */
79
80
81 /* -------------------------------------------------------------------------- */
82 /* Public key as (usually) fetched from DNS */
83 typedef struct pdkim_pubkey {
84   char *version;                  /* v=  */
85   char *granularity;              /* g=  */
86
87   int num_hash_algos;
88   int **hash_algos;               /* h=  */
89
90   int keytype;                    /* k=  */
91   int srvtype;                    /* s=  */
92
93   char *notes;                    /* n=  */
94   char *key;                      /* p=  */
95
96   int testing;                    /* t=y */
97   int no_subdomaining;            /* t=s */
98 } pdkim_pubkey;
99
100 /* -------------------------------------------------------------------------- */
101 /* Signature as it appears in a DKIM-Signature header */
102 typedef struct pdkim_signature {
103
104   /* Bits stored in a DKIM signature header ------ */
105   int version;                    /* v=   */
106   int algo;                       /* a=   */
107   int canon_headers;              /* c=x/ */
108   int canon_body;                 /* c=/x */
109   int querymethod;                /* q=   */
110
111   char *selector;                 /* s=   */
112   char *domain;                   /* d=   */
113   char *identity;                 /* i=   */
114
115   unsigned long created;          /* t=   */
116   unsigned long expires;          /* x=   */
117   unsigned long bodylength;       /* l=   */
118
119   char *headernames;              /* h=   */
120   char *copiedheaders;            /* z=   */
121
122   char *sigdata;                  /* b=   */
123   char *bodyhash;                 /* bh=  */
124
125   int   sigdata_len;
126   int   bodyhash_len;
127
128   /* Signing specific ---------------------------- */
129   char *rsa_privkey;     /* Private RSA key */
130   char *sign_headers;    /* To-be-signed header names */
131
132   /* Verification specific ----------------------- */
133   pdkim_pubkey pubkey;   /* Public key used to verify this signature. */
134   int headernames_pos;   /* Current position in header name list */
135   char *rawsig_no_b_val; /* Original signature header w/o b= tag value. */
136   void *next;            /* Pointer to next signature in list. */
137   int verify_status;     /* Verification result */
138   int verify_ext_status; /* Extended verification result */
139
140   /* Per-signature helper variables -------------- */
141   sha1_context sha1_body;
142   sha2_context sha2_body;
143   unsigned long signed_body_bytes;
144   pdkim_stringlist *headers;
145 } pdkim_signature;
146
147
148 /* -------------------------------------------------------------------------- */
149 /* Context to keep state between all operations */
150
151 #define PDKIM_MODE_SIGN     0
152 #define PDKIM_MODE_VERIFY   1
153 #define PDKIM_INPUT_NORMAL  0
154 #define PDKIM_INPUT_SMTP    1
155
156 typedef struct pdkim_ctx {
157
158   /* PDKIM_MODE_VERIFY or PDKIM_MODE_SIGN */
159   int mode;
160
161   /* PDKIM_INPUT_SMTP or PDKIM_INPUT_NORMAL */
162   int input_mode;
163
164   /* One (signing) or several chained (verification) signatures */
165   pdkim_signature *sig;
166
167   /* Coder's little helpers */
168   pdkim_str *cur_header;
169   char       linebuf[PDKIM_MAX_BODY_LINE_LEN];
170   int        linebuf_offset;
171   int        seen_lf;
172   int        seen_eod;
173   int        past_headers;
174   int        num_buffered_crlf;
175
176 #ifdef PDKIM_DEBUG
177   /* A FILE pointer. When not NULL, debug output will be generated
178     and sent to this stream */
179   FILE *debug_stream;
180 #endif
181
182 } pdkim_ctx;
183
184
185 int   header_name_match       (char *, char *, int);
186 char *pdkim_relax_header      (char *, int);
187
188 int   pdkim_update_bodyhash   (pdkim_ctx *, char *, int);
189 int   pdkim_finish_bodyhash   (pdkim_ctx *);
190
191 int   pdkim_bodyline_complete (pdkim_ctx *);
192 int   pdkim_header_complete   (pdkim_ctx *);
193
194 int   pdkim_feed              (pdkim_ctx *, char *, int);
195 int   pdkim_feed_finish       (pdkim_ctx *, char **);
196
197 char *pdkim_create_header     (pdkim_signature *, int);
198
199 pdkim_ctx
200      *pdkim_init_sign         (char *, char *, char *);
201
202 pdkim_ctx
203      *pdkim_init_verify       (void);
204
205 int   pdkim_set_optional      (pdkim_ctx *,
206                                int,
207                                char *, char *,
208                                int, int,
209                                unsigned long, int,
210                                unsigned long,
211                                unsigned long);
212
213 void  pdkim_free_sig          (pdkim_signature *);
214 void  pdkim_free_ctx          (pdkim_ctx *);
215
216
217 #ifdef PDKIM_DEBUG
218 void  pdkim_set_debug_stream  (pdkim_ctx *, FILE *);
219 #endif