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 #define DKIM_CALL WINAPI 23 #else 24 #define DKIM_CALL 25 #define MAKELONG(a,b) ((long)(((unsigned)(a) & 0xffff) | (((unsigned)(b) & 0xffff) << 16))) 26 #endif 27 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 // DKIM Body hash versions 34 #define DKIM_BODYHASH_ALLMAN_1 1 35 #define DKIM_BODYHASH_IETF_1 2 36 #define DKIM_BODYHASH_BOTH DKIM_BODYHASH_ALLMAN_1 | DKIM_BODYHASH_IETF_1 37 38 // DKIM hash algorithms 39 #define DKIM_HASH_SHA1 1 40 #define DKIM_HASH_SHA256 2 41 #define DKIM_HASH_SHA1_AND_256 DKIM_HASH_SHA1 | DKIM_HASH_SHA256 42 43 // DKIM canonicalization methods 44 #define DKIM_CANON_SIMPLE 1 45 #define DKIM_CANON_NOWSP 2 46 #define DKIM_CANON_RELAXED 3 47 48 #define DKIM_SIGN_SIMPLE MAKELONG(DKIM_CANON_SIMPLE,DKIM_CANON_SIMPLE) 49 #define DKIM_SIGN_SIMPLE_RELAXED MAKELONG(DKIM_CANON_RELAXED,DKIM_CANON_SIMPLE) 50 #define DKIM_SIGN_RELAXED MAKELONG(DKIM_CANON_RELAXED,DKIM_CANON_RELAXED) 51 #define DKIM_SIGN_RELAXED_SIMPLE MAKELONG(DKIM_CANON_SIMPLE,DKIM_CANON_RELAXED) 52 53 // DKIM Error codes 54 #define DKIM_SUCCESS 0 // operation successful 55 #define DKIM_FAIL -1 // verify error: message is suspicious 56 #define DKIM_BAD_SYNTAX -2 // signature error: DKIM-Signature could not parse or has bad tags/values 57 #define DKIM_SIGNATURE_BAD -3 // signature error: RSA verify failed 58 #define DKIM_SIGNATURE_BAD_BUT_TESTING -4 // signature error: RSA verify failed but testing 59 #define DKIM_SIGNATURE_EXPIRED -5 // signature error: x= is old 60 #define DKIM_SELECTOR_INVALID -6 // signature error: selector doesn't parse or contains invalid values 61 #define DKIM_SELECTOR_GRANULARITY_MISMATCH -7 // signature error: selector g= doesn't match i= 62 #define DKIM_SELECTOR_KEY_REVOKED -8 // signature error: selector p= empty 63 #define DKIM_SELECTOR_DOMAIN_NAME_TOO_LONG -9 // signature error: selector domain name too long to request 64 #define DKIM_SELECTOR_DNS_TEMP_FAILURE -10 // signature error: temporary dns failure requesting selector 65 #define DKIM_SELECTOR_DNS_PERM_FAILURE -11 // signature error: permanent dns failure requesting selector 66 #define DKIM_SELECTOR_PUBLIC_KEY_INVALID -12 // signature error: selector p= value invalid or wrong format 67 #define DKIM_NO_SIGNATURES -13 // process error, no sigs 68 #define DKIM_NO_VALID_SIGNATURES -14 // process error, no valid sigs 69 #define DKIM_BODY_HASH_MISMATCH -15 // sigature verify error: message body does not hash to bh value 70 #define DKIM_SELECTOR_ALGORITHM_MISMATCH -16 // signature error: selector h= doesn't match signature a= 71 #define DKIM_STAT_INCOMPAT -17 // signature error: incompatible v= 72 #define DKIM_UNSIGNED_FROM -18 // signature error: not all message's From headers in signature 73 #define DKIM_OUT_OF_MEMORY -20 // memory allocation failed 74 #define DKIM_INVALID_CONTEXT -21 // DKIMContext structure invalid for this operation 75 #define DKIM_NO_SENDER -22 // signing error: Could not find From: or Sender: header in message 76 #define DKIM_BAD_PRIVATE_KEY -23 // signing error: Could not parse private key 77 #define DKIM_BUFFER_TOO_SMALL -24 // signing error: Buffer passed in is not large enough 78 #define DKIM_MAX_ERROR -25 // set this to 1 greater than the highest error code (but negative) 79 80 // DKIM_SUCCESS // verify result: all signatures verified 81 // signature result: signature verified 82 #define DKIM_FINISHED_BODY 1 // process result: no more message body is needed 83 #define DKIM_PARTIAL_SUCCESS 2 // verify result: at least one but not all signatures verified 84 #define DKIM_NEUTRAL 3 // verify result: no signatures verified but message is not suspicous 85 #define DKIM_SUCCESS_BUT_EXTRA 4 // signature result: signature verified but it did not include all of the body 86 87 88 89 // This function is called once for each header in the message 90 // return 1 to include this header in the signature and 0 to exclude. 91 typedef int (DKIM_CALL *DKIMHEADERCALLBACK)(const char* szHeader); 92 93 // This function is called to retrieve a TXT record from DNS 94 typedef int (DKIM_CALL *DKIMDNSCALLBACK)(const char* szFQDN, char* szBuffer, int nBufLen ); 95 96 #ifdef _WIN32 97 #include <pshpack1.h> 98 #endif 99 100 typedef struct DKIMContext_t 101 { 102 unsigned int reserved1; 103 unsigned int reserved2; 104 void* reserved3; 105 } DKIMContext; 106 107 typedef struct DKIMSignOptions_t 108 { 109 int nCanon; // canonization 110 int nIncludeBodyLengthTag; // 0 = don't include l= tag, 1 = include l= tag 111 int nIncludeTimeStamp; // 0 = don't include t= tag, 1 = include t= tag 112 int nIncludeQueryMethod; // 0 = don't include q= tag, 1 = include q= tag 113 char szSelector[80]; // selector - required 114 char szDomain[256]; // domain - optional - if empty, domain is computed from sender 115 char szIdentity[256]; // for i= tag, if empty tag will not be included in sig 116 unsigned long expireTime; // for x= tag, if 0 tag will not be included in sig 117 DKIMHEADERCALLBACK pfnHeaderCallback; // header callback 118 char szRequiredHeaders[256]; // colon-separated list of headers that must be signed 119 int nHash; // use one of the DKIM_HASH_xx constants here 120 // even if not present in the message 121 int nIncludeCopiedHeaders; // 0 = don't include z= tag, 1 = include z= tag 122 int nIncludeBodyHash; // use one of the DKIM_BODYHASH_xx constants here 123 } DKIMSignOptions; 124 125 typedef struct DKIMVerifyOptions_t 126 { 127 DKIMDNSCALLBACK pfnSelectorCallback; // selector record callback 128 DKIMDNSCALLBACK pfnPracticesCallback; // ADSP record callback 129 int nHonorBodyLengthTag; // 0 = ignore l= tag, 1 = use l= tag to limit the amount of body verified 130 int nCheckPractices; // 0 = use default (unknown) practices, 1 = request and use author domain signing practices 131 int nSubjectRequired; // 0 = subject is required to be signed, 1 = not required 132 int nSaveCanonicalizedData; // 0 = canonicalized data is not saved, 1 = canonicalized data is saved 133 int nAllowUnsignedFromHeaders; // 0 = From headers not included in the signature are not allowed, 1 = allowed 134 } DKIMVerifyOptions; 135 136 typedef struct DKIMVerifyDetails_t 137 { 138 char *szSignature; 139 char *szSignatureDomain; 140 char *szIdentityDomain; 141 char *szCanonicalizedData; 142 int nResult; 143 } DKIMVerifyDetails; 144 145 146 #ifdef _WIN32 147 #include <poppack.h> 148 #endif 149 150 int DKIM_CALL DKIMSignInit( DKIMContext* pSignContext, DKIMSignOptions* pOptions ); 151 int DKIM_CALL DKIMSignProcess( DKIMContext* pSignContext, char* szBuffer, int nBufLength ); 152 int DKIM_CALL DKIMSignGetSig( DKIMContext* pSignContext, char* szPrivKey, char* szSignature, int nSigLength ); 153 int DKIM_CALL DKIMSignGetSig2( DKIMContext* pSignContext, char* szPrivKey, char** pszSignature ); 154 void DKIM_CALL DKIMSignFree( DKIMContext* pSignContext ); 155 156 int DKIM_CALL DKIMVerifyInit( DKIMContext* pVerifyContext, DKIMVerifyOptions* pOptions ); 157 int DKIM_CALL DKIMVerifyProcess( DKIMContext* pVerifyContext, char* szBuffer, int nBufLength ); 158 int DKIM_CALL DKIMVerifyResults( DKIMContext* pVerifyContext ); 159 int DKIM_CALL DKIMVerifyGetDetails( DKIMContext* pVerifyContext, int* nSigCount, DKIMVerifyDetails** pDetails, char* szPractices ); 160 void DKIM_CALL DKIMVerifyFree( DKIMContext* pVerifyContext ); 161 162 char *DKIM_CALL DKIMVersion(); 163 164 char *DKIM_CALL DKIMGetErrorString( int ErrorCode ); 165 166 #ifdef __cplusplus 167 } 168 #endif 169