1 /*
2 ** Copyright (c) 2005-2009 Sendmail, Inc. and its suppliers.
3 ** All rights reserved.
4 **
5 ** Copyright (c) 2009-2012, 2014, The Trusted Domain Project.
6 ** All rights reserved.
7 */
8
9 /* system includes */
10 #include <sys/types.h>
11 #include <string.h>
12 #include <assert.h>
13
14 /* libopendkim includes */
15 #include "dkim-tables.h"
16 #include "dkim-internal.h"
17
18 /* lookup tables */
19 static struct nametable prv_keyparams[] = /* key parameters */
20 {
21 { "a", DKIM_KEY_ALGORITHM },
22 { "n", DKIM_KEY_NOTES },
23 { "p", DKIM_KEY_DATA },
24 { "s", DKIM_KEY_SERVICE },
25 { "t", DKIM_KEY_FLAGS },
26 { "v", DKIM_KEY_VERSION },
27 { NULL, -1 }
28 };
29 struct nametable *keyparams = prv_keyparams;
30
31 static struct nametable prv_keyflags[] = /* key flags */
32 {
33 { "y", DKIM_SIGFLAG_TESTKEY },
34 { "s", DKIM_SIGFLAG_NOSUBDOMAIN },
35 { NULL, -1 }
36 };
37 struct nametable *keyflags = prv_keyflags;
38
39 static struct nametable prv_sigparams[] = /* signature parameters */
40 {
41 { "a", DKIM_PARAM_SIGNALG },
42 { "b", DKIM_PARAM_SIGNATURE },
43 { "bh", DKIM_PARAM_BODYHASH },
44 { "c", DKIM_PARAM_CANONALG },
45 { "d", DKIM_PARAM_DOMAIN },
46 { "h", DKIM_PARAM_HDRLIST },
47 { "i", DKIM_PARAM_IDENTITY },
48 { "l", DKIM_PARAM_BODYLENGTH },
49 { "q", DKIM_PARAM_QUERYMETHOD },
50 { "s", DKIM_PARAM_SELECTOR },
51 { "t", DKIM_PARAM_TIMESTAMP },
52 { "v", DKIM_PARAM_VERSION },
53 { "x", DKIM_PARAM_EXPIRATION },
54 { "z", DKIM_PARAM_COPIEDHDRS },
55 { NULL, -1 }
56 };
57 struct nametable *sigparams = prv_sigparams;
58
59 static struct nametable prv_algorithms[] = /* signing algorithms */
60 {
61 { "rsa-sha1", DKIM_SIGN_RSASHA1 },
62 { "rsa-sha256", DKIM_SIGN_RSASHA256 },
63 { NULL, -1 },
64 };
65 struct nametable *algorithms = prv_algorithms;
66
67 static struct nametable prv_canonicalizations[] = /* canonicalizations */
68 {
69 { "simple", DKIM_CANON_SIMPLE },
70 { "relaxed", DKIM_CANON_RELAXED },
71 { NULL, -1 },
72 };
73 struct nametable *canonicalizations = prv_canonicalizations;
74
75 static struct nametable prv_hashes[] = /* hashes */
76 {
77 { "sha1", DKIM_HASHTYPE_SHA1 },
78 { "sha256", DKIM_HASHTYPE_SHA256 },
79 { NULL, -1 },
80 };
81 struct nametable *hashes = prv_hashes;
82
83 static struct nametable prv_keytypes[] = /* key types */
84 {
85 { "rsa", DKIM_KEYTYPE_RSA },
86 { NULL, -1 },
87 };
88 struct nametable *keytypes = prv_keytypes;
89
90 static struct nametable prv_querytypes[] = /* query types */
91 {
92 { "dns", DKIM_QUERY_DNS },
93 { NULL, -1 },
94 };
95 struct nametable *querytypes = prv_querytypes;
96
97 static struct nametable prv_results[] = /* result codes */
98 {
99 { "Success", DKIM_STAT_OK },
100 { "Bad signature", DKIM_STAT_BADSIG },
101 { "No signature", DKIM_STAT_NOSIG },
102 { "No key", DKIM_STAT_NOKEY },
103 { "Unable to verify", DKIM_STAT_CANTVRFY },
104 { "Syntax error", DKIM_STAT_SYNTAX },
105 { "Resource unavailable", DKIM_STAT_NORESOURCE },
106 { "Internal error", DKIM_STAT_INTERNAL },
107 { "Revoked key", DKIM_STAT_REVOKED },
108 { "Invalid parameter", DKIM_STAT_INVALID },
109 { "Not implemented", DKIM_STAT_NOTIMPLEMENT },
110 { "Key retrieval failed", DKIM_STAT_KEYFAIL },
111 { "Reject requested", DKIM_STAT_CBREJECT },
112 { "Invalid result", DKIM_STAT_CBINVALID },
113 { "Try again later", DKIM_STAT_CBTRYAGAIN },
114 { "Multiple DNS replies", DKIM_STAT_MULTIDNSREPLY },
115 { NULL, -1 },
116 };
117 struct nametable *results = prv_results;
118
119 static struct nametable prv_settypes[] = /* set types */
120 {
121 { "key", DKIM_SETTYPE_KEY },
122 { "signature", DKIM_SETTYPE_SIGNATURE },
123 { "signature reporting", DKIM_SETTYPE_SIGREPORT },
124 { NULL, -1 },
125 };
126 struct nametable *settypes = prv_settypes;
127
128 static struct nametable prv_sigerrors[] = /* signature parsing errors */
129 {
130 { "no signature error", DKIM_SIGERROR_OK },
131 { "unsupported signature version", DKIM_SIGERROR_VERSION },
132 { "invalid domain coverage", DKIM_SIGERROR_DOMAIN },
133 { "signature expired", DKIM_SIGERROR_EXPIRED },
134 { "signature timestamp in the future", DKIM_SIGERROR_FUTURE },
135 { "signature timestamp order error", DKIM_SIGERROR_TIMESTAMPS },
136 { "invalid header canonicalization", DKIM_SIGERROR_INVALID_HC },
137 { "invalid body canonicalization", DKIM_SIGERROR_INVALID_BC },
138 { "signature algorithm missing", DKIM_SIGERROR_MISSING_A },
139 { "signature algorithm invalid", DKIM_SIGERROR_INVALID_A },
140 { "header list missing", DKIM_SIGERROR_MISSING_H },
141 { "body length value invalid", DKIM_SIGERROR_INVALID_L },
142 { "query method invalid", DKIM_SIGERROR_INVALID_Q },
143 { "query option invalid", DKIM_SIGERROR_INVALID_QO },
144 { "domain tag missing", DKIM_SIGERROR_MISSING_D },
145 { "domain tag empty", DKIM_SIGERROR_EMPTY_D },
146 { "selector tag missing", DKIM_SIGERROR_MISSING_S },
147 { "selector tag empty", DKIM_SIGERROR_EMPTY_S },
148 { "signature data missing", DKIM_SIGERROR_MISSING_B },
149 { "signature data empty", DKIM_SIGERROR_EMPTY_B },
150 { "signature data corrupt", DKIM_SIGERROR_CORRUPT_B },
151 { "key not found in DNS", DKIM_SIGERROR_NOKEY },
152 { "key DNS reply corrupt", DKIM_SIGERROR_DNSSYNTAX },
153 { "key DNS query failed", DKIM_SIGERROR_KEYFAIL },
154 { "body hash missing", DKIM_SIGERROR_MISSING_BH },
155 { "body hash empty", DKIM_SIGERROR_EMPTY_BH },
156 { "body hash corrupt", DKIM_SIGERROR_CORRUPT_BH },
157 { "signature verification failed", DKIM_SIGERROR_BADSIG },
158 { "unauthorized subdomain", DKIM_SIGERROR_SUBDOMAIN },
159 { "multiple keys found", DKIM_SIGERROR_MULTIREPLY },
160 { "header list tag empty", DKIM_SIGERROR_EMPTY_H },
161 { "header list missing required entries", DKIM_SIGERROR_INVALID_H },
162 { "length tag value exceeds body size", DKIM_SIGERROR_TOOLARGE_L },
163 { "unprotected header field", DKIM_SIGERROR_MBSFAILED },
164 { "unknown key version", DKIM_SIGERROR_KEYVERSION },
165 { "unknown key hash", DKIM_SIGERROR_KEYUNKNOWNHASH },
166 { "signature-key hash mismatch", DKIM_SIGERROR_KEYHASHMISMATCH },
167 { "not an e-mail key", DKIM_SIGERROR_NOTEMAILKEY },
168 { "key type missing", DKIM_SIGERROR_KEYTYPEMISSING },
169 { "unknown key type", DKIM_SIGERROR_KEYTYPEUNKNOWN },
170 { "key revoked", DKIM_SIGERROR_KEYREVOKED },
171 { "unable to apply public key", DKIM_SIGERROR_KEYDECODE },
172 { "version missing", DKIM_SIGERROR_MISSING_V },
173 { "version empty", DKIM_SIGERROR_EMPTY_V },
174 { "signing key too small", DKIM_SIGERROR_KEYTOOSMALL },
175 { NULL, -1 },
176 };
177 struct nametable *sigerrors = prv_sigerrors;
178
179 /* ===================================================================== */
180
181 /*
182 ** DKIM_CODE_TO_NAME -- translate a mnemonic code to its name
183 **
184 ** Parameters:
185 ** tbl -- name table
186 ** code -- code to translate
187 **
188 ** Return value:
189 ** Pointer to the name matching the provided code, or NULL if not found.
190 */
191
192 const char *
dkim_code_to_name(struct nametable * tbl,const int code)193 dkim_code_to_name(struct nametable *tbl, const int code)
194 {
195 int c;
196
197 assert(tbl != NULL);
198
199 for (c = 0; ; c++)
200 {
201 if (tbl[c].tbl_code == -1 && tbl[c].tbl_name == NULL)
202 return NULL;
203
204 if (tbl[c].tbl_code == code)
205 return tbl[c].tbl_name;
206 }
207 }
208
209 /*
210 ** DKIM_NAME_TO_CODE -- translate a name to a mnemonic code
211 **
212 ** Parameters:
213 ** tbl -- name table
214 ** name -- name to translate
215 **
216 ** Return value:
217 ** A mnemonic code matching the provided name, or -1 if not found.
218 */
219
220 const int
dkim_name_to_code(struct nametable * tbl,const char * name)221 dkim_name_to_code(struct nametable *tbl, const char *name)
222 {
223 int c;
224
225 assert(tbl != NULL);
226
227 for (c = 0; ; c++)
228 {
229 if (tbl[c].tbl_code == -1 && tbl[c].tbl_name == NULL)
230 return -1;
231
232 if (strcasecmp(tbl[c].tbl_name, name) == 0)
233 return tbl[c].tbl_code;
234 }
235 }
236