summaryrefslogtreecommitdiff
path: root/src/include/dkim.h
blob: 27c3b731ba9ee2baa508f5d1b0ac90850164b9ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*****************************************************************************
*  Copyright 2005 Alt-N Technologies, Ltd.
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  This code incorporates intellectual property owned by Yahoo! and licensed
*  pursuant to the Yahoo! DomainKeys Patent License Agreement.
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*  Changes done by ¢feh@fehcom.de obeying the above license
*
*****************************************************************************/
#define DKIM_CALL
#define MAKELONG(a, b) ((long)(((unsigned)(a) & 0xffff) | (((unsigned)(b) & 0xffff) << 16)))

#ifdef __cplusplus
extern "C" {
#endif

// DKIM hash algorithms
#define DKIM_HASH_SHA1               1
#define DKIM_HASH_SHA256             2
#define DKIM_HASH_SHA1_AND_SHA256    3
#define DKIM_HASH_ED25519            4
#define DKIM_HASH_RSA256_AND_ED25519 5

// DKIM canonicalization methods
#define DKIM_CANON_SIMPLE  1
#define DKIM_CANON_NOWSP   2
#define DKIM_CANON_RELAXED 3

#define DKIM_SIGN_SIMPLE         MAKELONG(DKIM_CANON_SIMPLE, DKIM_CANON_SIMPLE)
#define DKIM_SIGN_SIMPLE_RELAXED MAKELONG(DKIM_CANON_RELAXED, DKIM_CANON_SIMPLE)
#define DKIM_SIGN_RELAXED        MAKELONG(DKIM_CANON_RELAXED, DKIM_CANON_RELAXED)
#define DKIM_SIGN_RELAXED_SIMPLE MAKELONG(DKIM_CANON_SIMPLE, DKIM_CANON_RELAXED)

// clang-format off
// DKIM Error codes
#define DKIM_SUCCESS                        0  // operation successful
#define DKIM_FAIL                          -1  // verify error: message is suspicious
#define DKIM_BAD_SYNTAX                    -2  // signature error: DKIM-Signature could not parse or has bad tags/values
#define DKIM_SIGNATURE_BAD                 -3  // signature error: RSA/ED25519 verify failed
#define DKIM_SIGNATURE_BAD_BUT_TESTING     -4  // signature error: RSA/ED25519 verify failed but testing
#define DKIM_SIGNATURE_EXPIRED             -5  // signature error: x= is old
#define DKIM_SELECTOR_INVALID              -6  // signature error: selector doesn't parse or contains invalid values
#define DKIM_SELECTOR_GRANULARITY_MISMATCH -7  // signature error: selector g= doesn't match i=
#define DKIM_SELECTOR_KEY_REVOKED          -8  // signature error: selector p= empty
#define DKIM_SELECTOR_DOMAIN_NAME_TOO_LONG -9  // signature error: selector domain name too long to request
#define DKIM_SELECTOR_DNS_TEMP_FAILURE    -10  // signature error: temporary dns failure requesting selector
#define DKIM_SELECTOR_DNS_PERM_FAILURE    -11  // signature error: permanent dns failure requesting selector
#define DKIM_SELECTOR_PUBLIC_KEY_INVALID  -12  // signature error: selector p= value invalid or wrong format
#define DKIM_NO_SIGNATURES                -13  // process error, no sigs
#define DKIM_NO_VALID_SIGNATURES          -14  // process error, no valid sigs
#define DKIM_BODY_HASH_MISMATCH           -15  // sigature verify error: message body does not hash to bh value
#define DKIM_SELECTOR_ALGORITHM_MISMATCH  -16  // signature error: selector h= doesn't match signature a=
#define DKIM_STAT_INCOMPAT                -17  // signature error: incompatible v=
#define DKIM_UNSIGNED_FROM                -18  // signature error: not all message's From headers in signature
#define DKIM_OUT_OF_MEMORY                -20  // memory allocation failed
#define DKIM_INVALID_CONTEXT              -21  // DKIMContext structure invalid for this operation
#define DKIM_NO_SENDER                    -22  // signing error: Could not find From: or Sender: header in message
#define DKIM_BAD_PRIVATE_KEY              -23  // signing error: Could not parse private key
#define DKIM_BUFFER_TOO_SMALL             -24  // signing error: Buffer passed in is not large enough
#define DKIM_MAX_ERROR                    -25  // set this to 1 greater than the highest error code (but negative)

// DKIM_SUCCESS    // verify result: all signatures verified
// signature result: signature verified
#define DKIM_FINISHED_BODY     1  // process result: no more message body is needed
#define DKIM_PARTIAL_SUCCESS   2  // verify result: at least one but not all signatures verified
#define DKIM_NEUTRAL           3  // verify result: no signatures verified but message is not suspicous
#define DKIM_SUCCESS_BUT_EXTRA 4  // signature result: signature verified but it did not include all of the body
// clang-format on

// This function is called once for each header in the message
// return 1 to include this header in the signature and 0 to exclude.
typedef int (*DKIMHEADERCALLBACK)(const char *szHeader);

// This function is called to retrieve a TXT record from DNS
typedef int (*DKIMDNSCALLBACK)(const char *szFQDN, char *szBuffer, int nBufLen);

typedef struct DKIMContext_t {
  unsigned int reserved1;
  unsigned int reserved2;
  void *reserved3;
} DKIMContext;

typedef struct DKIMSignOptions_t {
  int nCanon;                            // canonization
  int nIncludeBodyLengthTag;             // 0 = don't include l= tag, 1 = include l= tag
  int nIncludeTimeStamp;                 // 0 = don't include t= tag, 1 = include t= tag
  int nIncludeQueryMethod;               // 0 = don't include q= tag, 1 = include q= tag
  char szSelector[64];                   // selector - required
  char szSelectorE[64];                  // 2nd selector - optional
  char szDomain[256];                    // domain - optional - if empty, domain is computed from sender
  char szIdentity[256];                  // for i= tag, if empty tag will not be included in sig
  unsigned long expireTime;              // for x= tag, if 0 tag will not be included in sig
  DKIMHEADERCALLBACK pfnHeaderCallback;  // header callback
  char szRequiredHeaders[256];           // colon-separated list of headers that must be signed
  int nHash;                             // use one of the DKIM_HASH_xx constants here
                                         // even if not present in the message
  int nIncludeCopiedHeaders;             // 0 = don't include z= tag, 1 = include z= tag
} DKIMSignOptions;

// clang-format off
typedef struct DKIMVerifyOptions_t {
  DKIMDNSCALLBACK pfnSelectorCallback;   // selector record callback
  DKIMDNSCALLBACK pfnPracticesCallback;  // ADSP record callback
  int nHonorBodyLengthTag;               // 0 = ignore l= tag, 1 = use l= tag to limit the amount of body verified
  int nCheckPractices;                   // 0 = use default (unknown) practices, 1 = request and use author domain signing practices
  int nSubjectRequired;                  // 0 = subject is required to be signed, 1 = not required
  int nSaveCanonicalizedData;            // 0 = canonicalized data is not saved, 1 = canonicalized data is saved
  int nAllowUnsignedFromHeaders;         // 0 = From headers not included in the signature are not allowed, 1 = allowed
} DKIMVerifyOptions;
// clang-format on

typedef struct DKIMVerifyDetails_t {
  char *szSignature;
  char *szSignatureDomain;
  char *szIdentityDomain;
  char *szCanonicalizedData;
  int nResult;
} DKIMVerifyDetails;

int DKIM_CALL DKIMSignInit(DKIMContext *pSignContext, DKIMSignOptions *pOptions);
int DKIM_CALL DKIMSignProcess(DKIMContext *pSignContext, char *szBuffer, int nBufLength);
int DKIM_CALL DKIMSignGetSig2(
    DKIMContext *pSignContext, char *szRSAPrivKey, char *szECCPrivKey, char **pszSignature);
void DKIM_CALL DKIMSignFree(DKIMContext *pSignContext);

int DKIM_CALL DKIMVerifyInit(DKIMContext *pVerifyContext, DKIMVerifyOptions *pOptions);
int DKIM_CALL DKIMVerifyProcess(DKIMContext *pVerifyContext, const char *szBuffer, int nBufLength);
int DKIM_CALL DKIMVerifyResults(DKIMContext *pVerifyContext);
int DKIM_CALL DKIMVerifyGetDetails(
    DKIMContext *pVerifyContext, int *nSigCount, DKIMVerifyDetails **pDetails, char *szPractices);
void DKIM_CALL DKIMVerifyFree(DKIMContext *pVerifyContext);

// const char *DKIM_CALL DKIMVersion();

const char *DKIM_CALL DKIMGetErrorString(int ErrorCode);

int _DKIM_ReportResult(const char *, const char *, const char *);
const char *DKIM_ErrorResult(const int);

#ifdef __cplusplus
}
#endif