57b6c6a66617b8410193654e139e0aa8cae1653c
[users/jgh/exim.git] / src / src / pdkim / pdkim.h
1 /* $Cambridge: exim/src/src/pdkim/pdkim.h,v 1.1.2.3 2009/02/26 16:07:36 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 /* 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
31 #ifdef PDKIM_DEBUG
32 void pdkim_quoteprint(FILE *, char *, int, int);
33 #endif
34
35
36 typedef struct pdkim_stringlist {
37   char *value;
38   void *next;
39 } pdkim_stringlist;
40 pdkim_stringlist *pdkim_append_stringlist(pdkim_stringlist *, char *);
41
42
43 #define PDKIM_STR_ALLOC_FRAG 256
44 typedef struct pdkim_str {
45   char         *str;
46   unsigned int  len;
47   unsigned int  allocated;
48 } pdkim_str;
49 pdkim_str *pdkim_strnew (char *);
50 char      *pdkim_strcat (pdkim_str *, char *);
51 char      *pdkim_strncat(pdkim_str *, char *, int);
52 void       pdkim_strfree(pdkim_str *);
53
54 #define PDKIM_QUERYMETHOD_DNS_TXT 0
55 /* extern char *pdkim_querymethods[]; */
56
57 #define PDKIM_ALGO_RSA_SHA256 0
58 #define PDKIM_ALGO_RSA_SHA1   1
59 /* extern char *pdkim_algos[]; */
60
61 #define PDKIM_CANON_SIMPLE   0
62 #define PDKIM_CANON_RELAXED  1
63 /* extern char *pdkim_canons[]; */
64
65
66 /* -------------------------------------------------------------------------- */
67 /* Public key as (usually) fetched from DNS */
68 typedef struct pdkim_pubkey {
69   char *version;                  /* v=  */
70   char *granularity;              /* g=  */
71
72   int num_hash_algos;
73   int **hash_algos;               /* h=  */
74
75   int keytype;                    /* k=  */
76   int srvtype;                    /* s=  */
77
78   char *notes;                    /* n=  */
79   char *key;                      /* p=  */
80
81   int testing;                    /* t=y */
82   int no_subdomaining;            /* t=s */
83 } pdkim_pubkey;
84
85 /* -------------------------------------------------------------------------- */
86 /* Signature as it appears in a DKIM-Signature header */
87 typedef struct pdkim_signature {
88
89   /* Bits stored in a DKIM signature header ------ */
90   int version;                    /* v=   */
91   int algo;                       /* a=   */
92   int canon_headers;              /* c=x/ */
93   int canon_body;                 /* c=/x */
94   int querymethod;                /* q=   */
95
96   char *sigdata;                  /* b=   */
97   char *bodyhash;                 /* bh=  */
98
99   char *selector;                 /* s=   */
100   char *domain;                   /* d=   */
101   char *identity;                 /* i=   */
102
103   unsigned long created;          /* t=   */
104   unsigned long expires;          /* x=   */
105   unsigned long bodylength;       /* l=   */
106
107   char *headernames;              /* h=   */
108   char *copiedheaders;            /* z=   */
109
110
111   /* Signing specific ---------------------------- */
112   char *rsa_privkey;     /* Private RSA key */
113   char *sign_headers;    /* To-be-signed header names */
114
115   /* Verification specific ----------------------- */
116   pdkim_pubkey pubkey;   /* Public key used to verify this signature. */
117   int verify_result;     /* Verification result */
118   char *rawsig_no_b_val; /* Original signature header w/o b= tag value. */
119   void *next;            /* Pointer to next signature in list. */
120
121   /* Per-signature helper variables -------------- */
122   sha1_context sha1_body;
123   sha2_context sha2_body;
124   unsigned long signed_body_bytes;
125   pdkim_stringlist *headers;
126 } pdkim_signature;
127
128
129 /* -------------------------------------------------------------------------- */
130 /* Context to keep state between all operations */
131
132 #define PDKIM_MODE_SIGN     0
133 #define PDKIM_MODE_VERIFY   1
134 #define PDKIM_INPUT_NORMAL  0
135 #define PDKIM_INPUT_SMTP    1
136
137 typedef struct pdkim_ctx {
138
139   /* PDKIM_MODE_VERIFY or PDKIM_MODE_SIGN */
140   int mode;
141
142   /* PDKIM_INPUT_SMTP or PDKIM_INPUT_NORMAL */
143   int input_mode;
144
145   /* One (signing) or several chained (verification) signatures */
146   pdkim_signature *sig;
147
148   /* Coder's little helpers */
149   pdkim_str *cur_header;
150   char       linebuf[PDKIM_MAX_BODY_LINE_LEN];
151   int        linebuf_offset;
152   int        seen_lf;
153   int        seen_eod;
154   int        past_headers;
155   int        num_buffered_crlf;
156
157 #ifdef PDKIM_DEBUG
158   /* A FILE pointer. When not NULL, debug output will be generated
159     and sent to this stream */
160   FILE *debug_stream;
161 #endif
162
163 } pdkim_ctx;
164
165
166 int   header_name_match       (char *, char *);
167 char *pdkim_relax_header      (char *, int);
168
169 int   pdkim_update_bodyhash   (pdkim_ctx *, char *, int);
170 int   pdkim_finish_bodyhash   (pdkim_ctx *);
171
172 int   pdkim_bodyline_complete (pdkim_ctx *);
173 int   pdkim_header_complete   (pdkim_ctx *);
174
175 int   pdkim_feed              (pdkim_ctx *, char *, int);
176 int   pdkim_feed_finish       (pdkim_ctx *, char **);
177
178 pdkim_str
179      *pdkim_create_header     (pdkim_signature *, int);
180
181 pdkim_ctx
182      *pdkim_init_sign         (char *, char *, char *);
183
184 pdkim_ctx
185      *pdkim_init_verify       (void);
186
187 int   pdkim_set_optional      (pdkim_ctx *,
188                                int,
189                                char *, char *,
190                                int, int,
191                                unsigned long, int,
192                                unsigned long,
193                                unsigned long);
194
195 void  pdkim_free_sig          (pdkim_signature *);
196 void  pdkim_free_ctx          (pdkim_ctx *);
197
198
199 #ifdef PDKIM_DEBUG
200 void  pdkim_set_debug_stream  (pdkim_ctx *, FILE *);
201 #endif