1 /*****************************************************************************
2 * Copyright 2005 Alt-N Technologies, Ltd.
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 * This code incorporates intellectual property owned by Yahoo! and licensed
11 * pursuant to the Yahoo! DomainKeys Patent License Agreement.
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *****************************************************************************/
20
21 #ifdef WIN32
22 #include <windows.h>
23 #pragma warning( disable: 4786 )
24 #else
25 #endif
26
27 #include "dkim.h"
28 #include "dkimsign.h"
29 #include "dkimverify.h"
30 #include "resource.h"
31 #include <string.h>
32
33 #define DKIMID ('D' | 'K'<<8 | 'I'<<16 | 'M'<<24)
34
35 #ifdef WIN32
36 //////////////////////////////////////////////////////////////////////
37 // DllMain
38 //////////////////////////////////////////////////////////////////////
DllMain(HANDLE hModule,DWORD dwReason,LPVOID lpReserved)39 BOOL APIENTRY DllMain( HANDLE hModule,
40 DWORD dwReason,
41 LPVOID lpReserved
42 )
43 {
44
45 switch (dwReason)
46 {
47 case DLL_PROCESS_ATTACH:
48 //g_Instance = (HINSTANCE)hModule;
49 break;
50
51 case DLL_PROCESS_DETACH:
52 break;
53 }
54
55 return TRUE;
56 }
57 #endif // #ifdef WIN32
58
59
InitContext(DKIMContext * pContext,bool bSign,void * pObject)60 static void InitContext( DKIMContext* pContext, bool bSign, void* pObject )
61 {
62 pContext->reserved1 = DKIMID;
63 pContext->reserved2 = bSign ? 1 : 0;
64 pContext->reserved3 = pObject;
65 }
66
ValidateContext(DKIMContext * pContext,bool bSign)67 static void* ValidateContext( DKIMContext* pContext, bool bSign )
68 {
69 if( pContext->reserved1 != DKIMID )
70 return NULL;
71
72 if( pContext->reserved2 != (unsigned int)(bSign ? 1 : 0) )
73 return NULL;
74
75 return pContext->reserved3;
76 }
77
DKIMSignInit(DKIMContext * pSignContext,DKIMSignOptions * pOptions)78 int DKIM_CALL DKIMSignInit( DKIMContext* pSignContext, DKIMSignOptions* pOptions )
79 {
80 int nRet = DKIM_OUT_OF_MEMORY;
81
82 CDKIMSign* pSign = new CDKIMSign;
83
84 if( pSign )
85 {
86 nRet = pSign->Init( pOptions );
87
88 if( nRet != DKIM_SUCCESS )
89 delete pSign;
90 }
91
92 if( nRet == DKIM_SUCCESS )
93 {
94 InitContext( pSignContext, true, pSign );
95 }
96
97 return nRet;
98 }
99
100
DKIMSignProcess(DKIMContext * pSignContext,char * szBuffer,int nBufLength)101 int DKIM_CALL DKIMSignProcess( DKIMContext* pSignContext, char* szBuffer, int nBufLength )
102 {
103 CDKIMSign* pSign = (CDKIMSign*)ValidateContext( pSignContext, true );
104
105 if( pSign )
106 {
107 return pSign->Process( szBuffer, nBufLength, false );
108 }
109
110 return DKIM_INVALID_CONTEXT;
111 }
112
113
DKIMSignGetSig(DKIMContext * pSignContext,char * szPrivKey,char * szSignature,int nSigLength)114 int DKIM_CALL DKIMSignGetSig( DKIMContext* pSignContext, char* szPrivKey, char* szSignature, int nSigLength )
115 {
116 CDKIMSign* pSign = (CDKIMSign*)ValidateContext( pSignContext, true );
117
118 if( pSign )
119 {
120 return pSign->GetSig( szPrivKey, szSignature, nSigLength );
121 }
122
123 return DKIM_INVALID_CONTEXT;
124 }
125
DKIMSignGetSig2(DKIMContext * pSignContext,char * szPrivKey,char ** pszSignature)126 int DKIM_CALL DKIMSignGetSig2( DKIMContext* pSignContext, char* szPrivKey, char** pszSignature )
127 {
128 CDKIMSign* pSign = (CDKIMSign*)ValidateContext( pSignContext, true );
129
130 if( pSign )
131 {
132 return pSign->GetSig2( szPrivKey, pszSignature );
133 }
134
135 return DKIM_INVALID_CONTEXT;
136
137 }
138
139
140
DKIMSignFree(DKIMContext * pSignContext)141 void DKIM_CALL DKIMSignFree( DKIMContext* pSignContext )
142 {
143 CDKIMSign* pSign = (CDKIMSign*)ValidateContext( pSignContext, true );
144
145 if( pSign )
146 {
147 delete pSign;
148 pSignContext->reserved3 = NULL;
149 }
150 }
151
152
DKIMVerifyInit(DKIMContext * pVerifyContext,DKIMVerifyOptions * pOptions)153 int DKIM_CALL DKIMVerifyInit( DKIMContext* pVerifyContext, DKIMVerifyOptions* pOptions )
154 {
155 int nRet = DKIM_OUT_OF_MEMORY;
156
157 CDKIMVerify* pVerify = new CDKIMVerify;
158
159 if( pVerify )
160 {
161 nRet = pVerify->Init( pOptions );
162 if( nRet != DKIM_SUCCESS )
163 delete pVerify;
164 }
165
166 if( nRet == DKIM_SUCCESS )
167 {
168 InitContext( pVerifyContext, false, pVerify );
169 }
170
171 return nRet;
172 }
173
174
DKIMVerifyProcess(DKIMContext * pVerifyContext,char * szBuffer,int nBufLength)175 int DKIM_CALL DKIMVerifyProcess( DKIMContext* pVerifyContext, char* szBuffer, int nBufLength )
176 {
177 CDKIMVerify* pVerify = (CDKIMVerify*)ValidateContext( pVerifyContext, false );
178
179 if( pVerify )
180 {
181 return pVerify->Process( szBuffer, nBufLength, false );
182 }
183
184 return DKIM_INVALID_CONTEXT;
185 }
186
187
DKIMVerifyResults(DKIMContext * pVerifyContext)188 int DKIM_CALL DKIMVerifyResults( DKIMContext* pVerifyContext )
189 {
190 CDKIMVerify* pVerify = (CDKIMVerify*)ValidateContext( pVerifyContext, false );
191
192 if( pVerify )
193 {
194 return pVerify->GetResults();
195 }
196
197 return DKIM_INVALID_CONTEXT;
198 }
199
200
DKIMVerifyGetDetails(DKIMContext * pVerifyContext,int * nSigCount,DKIMVerifyDetails ** pDetails,char * szPractices)201 int DKIM_CALL DKIMVerifyGetDetails( DKIMContext* pVerifyContext, int* nSigCount, DKIMVerifyDetails** pDetails, char* szPractices )
202 {
203 szPractices[0] = '\0';
204
205 CDKIMVerify* pVerify = (CDKIMVerify*)ValidateContext( pVerifyContext, false );
206
207 if( pVerify )
208 {
209 strcpy(szPractices, pVerify->GetPractices());
210 return pVerify->GetDetails(nSigCount, pDetails);
211 }
212
213 return DKIM_INVALID_CONTEXT;
214 }
215
216
DKIMVerifyFree(DKIMContext * pVerifyContext)217 void DKIM_CALL DKIMVerifyFree( DKIMContext* pVerifyContext )
218 {
219 CDKIMVerify* pVerify = (CDKIMVerify*)ValidateContext( pVerifyContext, false );
220
221 if( pVerify )
222 {
223 delete pVerify;
224 pVerifyContext->reserved3 = NULL;
225 }
226 }
227
228
DKIMVersion()229 char* DKIM_CALL DKIMVersion()
230 {
231 return VERSION_STRING;
232 }
233
234
235 static char* DKIMErrorStrings[-1-DKIM_MAX_ERROR] = {
236 "DKIM_FAIL",
237 "DKIM_BAD_SYNTAX",
238 "DKIM_SIGNATURE_BAD",
239 "DKIM_SIGNATURE_BAD_BUT_TESTING",
240 "DKIM_SIGNATURE_EXPIRED",
241 "DKIM_SELECTOR_INVALID",
242 "DKIM_SELECTOR_GRANULARITY_MISMATCH",
243 "DKIM_SELECTOR_KEY_REVOKED",
244 "DKIM_SELECTOR_DOMAIN_NAME_TOO_LONG",
245 "DKIM_SELECTOR_DNS_TEMP_FAILURE",
246 "DKIM_SELECTOR_DNS_PERM_FAILURE",
247 "DKIM_SELECTOR_PUBLIC_KEY_INVALID",
248 "DKIM_NO_SIGNATURES",
249 "DKIM_NO_VALID_SIGNATURES",
250 "DKIM_BODY_HASH_MISMATCH",
251 "DKIM_SELECTOR_ALGORITHM_MISMATCH",
252 "DKIM_STAT_INCOMPAT",
253 "DKIM_UNSIGNED_FROM",
254 "DKIM_OUT_OF_MEMORY",
255 "DKIM_INVALID_CONTEXT",
256 "DKIM_NO_SENDER",
257 "DKIM_BAD_PRIVATE_KEY",
258 "DKIM_BUFFER_TOO_SMALL",
259 };
260
261
DKIMGetErrorString(int ErrorCode)262 char* DKIM_CALL DKIMGetErrorString( int ErrorCode )
263 {
264 if (ErrorCode >= 0 || ErrorCode <= DKIM_MAX_ERROR)
265 return "Unknown";
266 else
267 return DKIMErrorStrings[-1-ErrorCode];
268 }
269