You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dkim.h 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef DKIM_H_
  17. #define DKIM_H_
  18. #include "config.h"
  19. #include "event.h"
  20. #include "dns.h"
  21. #include "ref.h"
  22. #ifdef HAVE_OPENSSL
  23. #include <openssl/rsa.h>
  24. #include <openssl/engine.h>
  25. #endif
  26. /* Main types and definitions */
  27. #define DKIM_SIGNHEADER "DKIM-Signature"
  28. /* DKIM signature header */
  29. /* special DNS tokens */
  30. #define DKIM_DNSKEYNAME "_domainkey"
  31. /* reserved DNS sub-zone */
  32. #define DKIM_DNSPOLICYNAME "_adsp" /* reserved DNS sub-zone */
  33. /* Canonization methods */
  34. #define DKIM_CANON_UNKNOWN (-1) /* unknown method */
  35. #define DKIM_CANON_SIMPLE 0 /* as specified in DKIM spec */
  36. #define DKIM_CANON_RELAXED 1 /* as specified in DKIM spec */
  37. #define DKIM_CANON_DEFAULT DKIM_CANON_SIMPLE
  38. /* Signature methods */
  39. #define DKIM_SIGN_UNKNOWN (-2) /* unknown method */
  40. #define DKIM_SIGN_DEFAULT (-1) /* use internal default */
  41. #define DKIM_SIGN_RSASHA1 0 /* an RSA-signed SHA1 digest */
  42. #define DKIM_SIGN_RSASHA256 1 /* an RSA-signed SHA256 digest */
  43. /* Params */
  44. #define DKIM_PARAM_UNKNOWN (-1) /* unknown */
  45. #define DKIM_PARAM_SIGNATURE 0 /* b */
  46. #define DKIM_PARAM_SIGNALG 1 /* a */
  47. #define DKIM_PARAM_DOMAIN 2 /* d */
  48. #define DKIM_PARAM_CANONALG 3 /* c */
  49. #define DKIM_PARAM_QUERYMETHOD 4 /* q */
  50. #define DKIM_PARAM_SELECTOR 5 /* s */
  51. #define DKIM_PARAM_HDRLIST 6 /* h */
  52. #define DKIM_PARAM_VERSION 7 /* v */
  53. #define DKIM_PARAM_IDENTITY 8 /* i */
  54. #define DKIM_PARAM_TIMESTAMP 9 /* t */
  55. #define DKIM_PARAM_EXPIRATION 10 /* x */
  56. #define DKIM_PARAM_COPIEDHDRS 11 /* z */
  57. #define DKIM_PARAM_BODYHASH 12 /* bh */
  58. #define DKIM_PARAM_BODYLENGTH 13 /* l */
  59. /* Errors (from OpenDKIM) */
  60. #define DKIM_SIGERROR_UNKNOWN (-1) /* unknown error */
  61. #define DKIM_SIGERROR_OK 0 /* no error */
  62. #define DKIM_SIGERROR_VERSION 1 /* unsupported version */
  63. #define DKIM_SIGERROR_DOMAIN 2 /* invalid domain (d=/i=) */
  64. #define DKIM_SIGERROR_EXPIRED 3 /* signature expired */
  65. #define DKIM_SIGERROR_FUTURE 4 /* signature in the future */
  66. #define DKIM_SIGERROR_TIMESTAMPS 5 /* x= < t= */
  67. #define DKIM_SIGERROR_UNUSED 6 /* OBSOLETE */
  68. #define DKIM_SIGERROR_INVALID_HC 7 /* c= invalid (header) */
  69. #define DKIM_SIGERROR_INVALID_BC 8 /* c= invalid (body) */
  70. #define DKIM_SIGERROR_MISSING_A 9 /* a= missing */
  71. #define DKIM_SIGERROR_INVALID_A 10 /* a= invalid */
  72. #define DKIM_SIGERROR_MISSING_H 11 /* h= missing */
  73. #define DKIM_SIGERROR_INVALID_L 12 /* l= invalid */
  74. #define DKIM_SIGERROR_INVALID_Q 13 /* q= invalid */
  75. #define DKIM_SIGERROR_INVALID_QO 14 /* q= option invalid */
  76. #define DKIM_SIGERROR_MISSING_D 15 /* d= missing */
  77. #define DKIM_SIGERROR_EMPTY_D 16 /* d= empty */
  78. #define DKIM_SIGERROR_MISSING_S 17 /* s= missing */
  79. #define DKIM_SIGERROR_EMPTY_S 18 /* s= empty */
  80. #define DKIM_SIGERROR_MISSING_B 19 /* b= missing */
  81. #define DKIM_SIGERROR_EMPTY_B 20 /* b= empty */
  82. #define DKIM_SIGERROR_CORRUPT_B 21 /* b= corrupt */
  83. #define DKIM_SIGERROR_NOKEY 22 /* no key found in DNS */
  84. #define DKIM_SIGERROR_DNSSYNTAX 23 /* DNS reply corrupt */
  85. #define DKIM_SIGERROR_KEYFAIL 24 /* DNS query failed */
  86. #define DKIM_SIGERROR_MISSING_BH 25 /* bh= missing */
  87. #define DKIM_SIGERROR_EMPTY_BH 26 /* bh= empty */
  88. #define DKIM_SIGERROR_CORRUPT_BH 27 /* bh= corrupt */
  89. #define DKIM_SIGERROR_BADSIG 28 /* signature mismatch */
  90. #define DKIM_SIGERROR_SUBDOMAIN 29 /* unauthorized subdomain */
  91. #define DKIM_SIGERROR_MULTIREPLY 30 /* multiple records returned */
  92. #define DKIM_SIGERROR_EMPTY_H 31 /* h= empty */
  93. #define DKIM_SIGERROR_INVALID_H 32 /* h= missing req'd entries */
  94. #define DKIM_SIGERROR_TOOLARGE_L 33 /* l= value exceeds body size */
  95. #define DKIM_SIGERROR_MBSFAILED 34 /* "must be signed" failure */
  96. #define DKIM_SIGERROR_KEYVERSION 35 /* unknown key version */
  97. #define DKIM_SIGERROR_KEYUNKNOWNHASH 36 /* unknown key hash */
  98. #define DKIM_SIGERROR_KEYHASHMISMATCH 37 /* sig-key hash mismatch */
  99. #define DKIM_SIGERROR_NOTEMAILKEY 38 /* not an e-mail key */
  100. #define DKIM_SIGERROR_UNUSED2 39 /* OBSOLETE */
  101. #define DKIM_SIGERROR_KEYTYPEMISSING 40 /* key type missing */
  102. #define DKIM_SIGERROR_KEYTYPEUNKNOWN 41 /* key type unknown */
  103. #define DKIM_SIGERROR_KEYREVOKED 42 /* key revoked */
  104. #define DKIM_SIGERROR_KEYDECODE 43 /* key couldn't be decoded */
  105. #define DKIM_SIGERROR_MISSING_V 44 /* v= tag missing */
  106. #define DKIM_SIGERROR_EMPTY_V 45 /* v= tag empty */
  107. /* Check results */
  108. #define DKIM_CONTINUE 0 /* continue */
  109. #define DKIM_REJECT 1 /* reject */
  110. #define DKIM_TRYAGAIN 2 /* try again later */
  111. #define DKIM_NOTFOUND 3 /* requested record not found */
  112. #define DKIM_RECORD_ERROR 4 /* error requesting record */
  113. typedef struct rspamd_dkim_context_s {
  114. rspamd_mempool_t *pool;
  115. gint sig_alg;
  116. gint header_canon_type;
  117. gint body_canon_type;
  118. gsize len;
  119. gchar *domain;
  120. gchar *selector;
  121. time_t timestamp;
  122. time_t expiration;
  123. gint8 *b;
  124. gint8 *bh;
  125. guint bhlen;
  126. guint blen;
  127. GPtrArray *hlist;
  128. guint ver;
  129. gchar *dns_key;
  130. const gchar *dkim_header;
  131. GChecksum *headers_hash;
  132. GChecksum *body_hash;
  133. } rspamd_dkim_context_t;
  134. typedef struct rspamd_dkim_key_s {
  135. guint8 *keydata;
  136. guint keylen;
  137. gsize decoded_len;
  138. guint ttl;
  139. #ifdef HAVE_OPENSSL
  140. RSA *key_rsa;
  141. BIO *key_bio;
  142. EVP_PKEY *key_evp;
  143. #endif
  144. ref_entry_t ref;
  145. } rspamd_dkim_key_t;
  146. struct rspamd_task;
  147. /* Err MUST be freed if it is not NULL, key is allocated by slice allocator */
  148. typedef void (*dkim_key_handler_f)(rspamd_dkim_key_t *key, gsize keylen,
  149. rspamd_dkim_context_t *ctx, gpointer ud, GError *err);
  150. /**
  151. * Create new dkim context from signature
  152. * @param sig message's signature
  153. * @param pool pool to allocate memory from
  154. * @param time_jitter jitter in seconds to allow time diff while checking
  155. * @param err pointer to error object
  156. * @return new context or NULL
  157. */
  158. rspamd_dkim_context_t * rspamd_create_dkim_context (const gchar *sig,
  159. rspamd_mempool_t *pool,
  160. guint time_jitter,
  161. GError **err);
  162. /**
  163. * Make DNS request for specified context and obtain and parse key
  164. * @param ctx dkim context from signature
  165. * @param resolver dns resolver object
  166. * @param s async session to make request
  167. * @return
  168. */
  169. gboolean rspamd_get_dkim_key (rspamd_dkim_context_t *ctx,
  170. struct rspamd_task *task,
  171. dkim_key_handler_f handler,
  172. gpointer ud);
  173. /**
  174. * Check task for dkim context using dkim key
  175. * @param ctx dkim verify context
  176. * @param key dkim key (from cache or from dns request)
  177. * @param task task to check
  178. * @return
  179. */
  180. gint rspamd_dkim_check (rspamd_dkim_context_t *ctx,
  181. rspamd_dkim_key_t *key,
  182. struct rspamd_task *task);
  183. /**
  184. * Free DKIM key
  185. * @param key
  186. */
  187. void rspamd_dkim_key_free (rspamd_dkim_key_t *key);
  188. #endif /* DKIM_H_ */