1 /* This file is part of Mailfromd.
2    Copyright (C) 2020-2021 Sergey Poznyakoff
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 /* DKIM implementation defines */
18 
19 /* Verification result codes are defined in status.h */
20 #include <mflib/status.h>
21 
22 /* Canonicalization types. */
23 enum {
24 	DKIM_CANON_ERR = -1,
25 	DKIM_CANON_SIMPLE,
26 	DKIM_CANON_RELAXED
27 };
28 
29 #define DKIM_VERSION "1"
30 #define DKIM_KEYRECORD_VERSION "DKIM1"
31 #define DKIM_SIGNATURE_HEADER "DKIM-Signature"
32 #define DKIM_QUERY_METHOD "dns/txt"
33 #define DKIM_ALGORITHM "rsa-sha256"
34 /* Special value for the signature "l" member */
35 #define DKIM_LENGTH_ALL ((size_t)~0)
36 
37 /*
38  * Structure governing creation and verification of a DKIM signature.
39  * Most members are named after the DKIM-Signature tags.
40  * See RFC 6376, 3.5.  "The DKIM-Signature Header Field" (page 17).
41  */
42 struct dkim_signature {
43 	char *a;
44 	uint8_t *b;
45 	uint8_t *bh;
46 	int canon[2];
47 	char *d;
48 	char *s;
49 	char *h;
50 	char *i;
51 	size_t l;
52 	char *q;
53 	time_t t;
54 	time_t x;
55 	char *v;
56 };
57 
58 /* Convert canonicalization type to a DKIM_CANON_ constant. */
59 int dkim_str_to_canon_type(char const *str, char **endp);
60 
61 /*
62  * Create canonicalizer filter for STREAM.  Use canonicalization types
63  * supplied by CANON_HEADER and CANON_BODY.  FLAGS are mailutils stream
64  * flags (normally MU_STREAM_READ).
65  */
66 int dkim_canonicalizer_create(mu_stream_t *pstream,
67 			      mu_stream_t stream,
68 			      int canon_header,
69 			      int canon_body,
70 			      int flags);
71 
72 /*
73  * Sign the message MSG using the SIG and private key PRIV_KEY.
74  * Return the created DKIM-Signature header in RET_SIGHDR.
75  */
76 int mfd_dkim_sign(mu_message_t msg, struct dkim_signature *sig,
77 		  char *priv_key, char **ret_sighdr);
78 
79 int dkim_header_list_match(char const *h_list, char const *h);
80 
81 /* Explanatory error codes */
82 enum {
83 	DKIM_EXPL_OK                  = _MFL_DKIM_EXPL_OK,
84 	DKIM_EXPL_NO_SIG	      = _MFL_DKIM_EXPL_NO_SIG,
85 	DKIM_EXPL_INTERNAL_ERROR      = _MFL_DKIM_EXPL_INTERNAL_ERROR,
86 	DKIM_EXPL_SIG_SYNTAX	      = _MFL_DKIM_EXPL_SIG_SYNTAX,
87 	DKIM_EXPL_SIG_MISS	      = _MFL_DKIM_EXPL_SIG_MISS,
88 	DKIM_EXPL_DOMAIN_MISMATCH     = _MFL_DKIM_EXPL_DOMAIN_MISMATCH,
89 	DKIM_EXPL_BAD_VERSION	      = _MFL_DKIM_EXPL_BAD_VERSION,
90 	DKIM_EXPL_BAD_ALGORITHM	      = _MFL_DKIM_EXPL_BAD_ALGORITHM,
91 	DKIM_EXPL_BAD_QUERY	      = _MFL_DKIM_EXPL_BAD_QUERY,
92 	DKIM_EXPL_FROM		      = _MFL_DKIM_EXPL_FROM,
93 	DKIM_EXPL_EXPIRED	      = _MFL_DKIM_EXPL_EXPIRED,
94 	DKIM_EXPL_DNS_UNAVAIL	      = _MFL_DKIM_EXPL_DNS_UNAVAIL,
95 	DKIM_EXPL_DNS_NOTFOUND	      = _MFL_DKIM_EXPL_DNS_NOTFOUND,
96 	DKIM_EXPL_KEY_SYNTAX	      = _MFL_DKIM_EXPL_KEY_SYNTAX,
97 	DKIM_EXPL_KEY_REVOKED	      = _MFL_DKIM_EXPL_KEY_REVOKED,
98 	DKIM_EXPL_BAD_BODY	      = _MFL_DKIM_EXPL_BAD_BODY,
99 	DKIM_EXPL_BAD_BASE64	      = _MFL_DKIM_EXPL_BAD_BASE64,
100 	DKIM_EXPL_BAD_SIG             = _MFL_DKIM_EXPL_BAD_SIG,
101 };
102 
103 /* Verification error codes */
104 enum {
105 	DKIM_VERIFY_OK = _MFL_DKIM_VERIFY_OK,
106 	DKIM_VERIFY_PERMFAIL = _MFL_DKIM_VERIFY_PERMFAIL,
107 	DKIM_VERIFY_TEMPFAIL = _MFL_DKIM_VERIFY_TEMPFAIL,
108 };
109 
110 int mfd_dkim_verify(mu_message_t msg, char **sigstr);
111 
112 extern char const *dkim_explanation_str[];
113 extern int dkim_result_trans[];
114