23#define _strnicmp strncasecmp
24#define _stricmp strcasecmp
25#define LOWORD(l) ((unsigned)(l) & 0xffff)
26#define HIWORD(l) ((unsigned)(l) >> 16)
244 SigHdrs.append(szBuffer,nBufLength);
268 if (
_strnicmp(sTag.c_str(),
"X-",2) == 0 ||
269 _stricmp(sTag.c_str(),
"Authentication-Results:") == 0 ||
270 _stricmp(sTag.c_str(),
"Return-Path:") == 0) {
279 bool bConvert =
false;
282 static unsigned char hexchars[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'};
284 unsigned char *
d = (
unsigned char*)dest;
285 for (
const unsigned char *s = (
const unsigned char *)source; *s !=
'\0'; s++)
287 if (*s >= 33 && *s <= 126 && *s !=
'=' && *s !=
':' && *s !=
';' && *s !=
'|') {
292 *
d++ = hexchars[*s >> 4];
293 *
d++ = hexchars[*s & 15];
308 if (
_strnicmp(sHdr.c_str(),
"X",1) == 0)
return;
309 if (
_strnicmp(sHdr.c_str(),
"From:",5) == 0) {
sFrom.assign(sHdr.c_str() + 5); }
310 if (
_strnicmp(sHdr.c_str(),
"Sender:",7) == 0) {
sSender.assign(sHdr.c_str() + 7); }
313 string::size_type pos = sHdr.find(
':');
315 if (pos != string::npos) {
317 char *workBuffer =
new char[sHdr.size() * 3 + 1];
319 sTag.assign(sHdr.substr(0,pos));
320 sValue.assign(sHdr.substr(pos + 1,string::npos));
340 map<string,list<string>::reverse_iterator> IterMap;
341 map<string,list<string>::reverse_iterator>::iterator IterMapIter;
342 list<string>::reverse_iterator riter;
343 list<string>::iterator iter;
345 bool bFromHeaderFound =
false;
352 string::size_type pos = sTag.find(
':');
354 if (pos != string::npos) {
355 int nSignThisTag = 1;
358 sTag.erase(pos + 1,string::npos);
361 if (
_stricmp(sTag.c_str(),
"From:") == 0) {
362 bFromHeaderFound =
true;
381 if (nSignThisTag > 0) {
385 IterMapIter = IterMap.find(sTag);
387 riter = (IterMapIter == IterMap.end()) ?
HeaderList.rbegin() : IterMapIter->second;
391 if (
_strnicmp(riter->c_str(),sTag.c_str(),sTag.size()) == 0) {
396 IterMap[sTag] = riter;
405 if(!bFromHeaderFound) {
406 string sFrom(
"From:");
432 Hash(sHdr.c_str(),sHdr.size(),
true);
441 for (
char *s = (
char*)sTemp.c_str(); *s !=
'\0' && *s !=
':'; s++) {
442 if (*s >=
'A' && *s <=
'Z')
446 Hash(sTemp.c_str(),sTemp.size(),
true);
453 Hash(sTemp.c_str(),sTemp.length(),
true);
464 if (nBufLength > 0) {
466 Hash(
"\r\n",2,
false);
470 Hash(szBuffer,nBufLength,
false);
471 Hash(
"\r\n",2,
false);
476 Hash(
"\r\n",2,
false);
483 if (nBufLength > 0) {
484 Hash(szBuffer,nBufLength,
false);
490 if (nBufLength > 0) {
492 Hash(
"\r\n",2,
false);
496 Hash(szBuffer,nBufLength,
false);
499 Hash(
"\r\n",2,
false);
512 string::size_type pos, poss, pose;
515 if (!
sFrom.empty()) {
516 sAddress.assign(
sFrom);
526 poss = sAddress.find(
'<');
527 if (poss != string::npos)
528 sAddress.erase(0,poss);
531 pose = sAddress.find(
'>');
532 if (pose != string::npos)
533 sAddress.erase(pose,string::npos);
535 if (pose == poss + 1)
return false;
538 pos = sAddress.find(
'@');
539 if (pos == string::npos)
543 sDomain.assign (sAddress.c_str() + pos + 1);
558 m_sSig.assign(
"DKIM-Signature:");
570 int nTagLen = strlen(Tag);
596 sprintf(szValue,
"%lu",nValue);
625 string::size_type pos = 0;
629 while (pos < sValue.size()) {
631 if (len > sValue.size() - pos)
632 len = sValue.size() - pos;
633 m_sSig.append(sValue.substr(pos,len));
637 if (pos < sValue.size()) {
645 while (pos < sValue.size()) {
647 string::size_type brkpos;
649 if (sValue.size() - pos < len) {
650 brkpos = sValue.size();
652 brkpos = sValue.rfind(cbrk,pos + len);
655 if (brkpos == string::npos || brkpos < pos) {
656 brkpos = sValue.find(cbrk,pos);
657 if (brkpos == string::npos) {
658 brkpos = sValue.size();
662 len = brkpos - pos + 1;
664 m_sSig.append(sValue.substr(pos,len));
669 if (pos < sValue.size()) {
685 if (szRSAKey == NULL && szECCKey == NULL) {
689 if (pszSignature == NULL) {
712 string::size_type start = 0;
715 while (end != string::npos) {
796 unsigned char Hash[4096];
797 unsigned int nHashLen = 0;
808 bio = BIO_new(BIO_s_mem());
811 b64 = BIO_new(BIO_f_base64());
816 BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
818 if (BIO_write(b64,
Hash,nHashLen) < (
int)nHashLen) {
851 sSignedSig.assign(
m_sSig.c_str());
861 sTemp = sSignedSig.c_str();
868 EVP_SignUpdate(
m_Hdr_sha1ctx,sTemp.c_str(),sTemp.size());
break;
872 SigHdrs.append(sTemp.c_str(),sTemp.size());
876 bio = BIO_new_mem_buf(szPrivKey, -1);
879 pkey = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL);
883 siglen = EVP_PKEY_size(pkey);
885 sig = (
unsigned char*) OPENSSL_malloc(siglen);
894 unsigned char* SignMsg;
898 nSignRet = EVP_SignFinal(
m_Hdr_sha1ctx,sig,&siglen,pkey);
break;
903 SignMsg = (
unsigned char*)
SigHdrs.c_str();
905 sig = (
unsigned char*) OPENSSL_malloc(sig_len);
907 siglen = (
unsigned int) sig_len;
break;
916 bio = BIO_new(BIO_s_mem());
921 b64 = BIO_new(BIO_f_base64());
927 BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
930 if (BIO_write(b64,sig,siglen) < (
int) siglen) {
982 string ed25519Sig, sha256Sig, sha1Sig;
988 ed25519Sig.assign(
m_sSig);
1018 if (!ed25519Sig.empty()) {
1026 if (!sha1Sig.empty()) {
1033 if (!sha256Sig.empty()) {
static string RelaxHeader(const string &sHeader)
static void CompressSWSP(char *pBuffer, int &nBufLength)
static void RemoveSWSP(char *szBuffer)
list< string > HeaderList
DKIMHEADERCALLBACK m_pfnHdrCallback
EVP_MD_CTX * m_Hdr_ed25519ctx
int GetSig2(char *szRSAPrivKey, char *szECCPrivKey, char **pszSignature)
bool ParseFromAddress(void)
int m_nIncludeCopiedHeaders
void AddInterTagSpace(int nSizeOfNextTag)
void ProcessHeader(const string &sHdr)
EVP_MD_CTX * m_Edy_sha256ctx
bool IsRequiredHeader(const string &sTag)
void GetHeaderParams(const string &sHdr)
EVP_MD_CTX * m_Hdr_sha1ctx
bool m_IncludeBodyLengthTag
EVP_MD_CTX * m_Hdr_sha256ctx
virtual int ProcessBody(char *szBuffer, int nBufLength, bool bEOF) override
EVP_MD_CTX * m_Bdy_sha256ctx
void AddTagToSig(const char *const Tag, const string &sValue, char cbrk, bool bFold)
int ConstructSignature(char *szSignKey, int nSigAlg)
EVP_MD_CTX * m_Bdy_sha1ctx
void AddFoldedValueToSig(const string &sValue, char cbrk)
bool m_bReturnedSigAssembled
int AssembleReturnedSig(char *szRSAPrivKey, char *szECCPrivKey)
virtual int ProcessHeaders(void) override
bool SignThisTag(const string &sTag)
void Hash(const char *szBuffer, int nBufLength, bool bHdr)
int m_nIncludeQueryMethod
@ OptimalHeaderLineLength
#define DKIM_BUFFER_TOO_SMALL
#define DKIM_CANON_SIMPLE
#define DKIM_OUT_OF_MEMORY
#define DKIM_CANON_RELAXED
#define DKIM_HASH_RSA256_AND_ED25519
#define DKIM_BAD_PRIVATE_KEY
#define DKIM_SIGN_RELAXED
#define DKIM_HASH_SHA1_AND_SHA256
#define DKIM_SIGN_RELAXED_SIMPLE
#define DKIM_SIGN_SIMPLE_RELAXED
#define DKIM_HASH_ED25519
bool ConvertHeaderToQuotedPrintable(const char *source, char *dest)
int nIncludeBodyLengthTag
DKIMHEADERCALLBACK pfnHeaderCallback
int nIncludeCopiedHeaders