Skip to content

Commit

Permalink
Upgraded to work on a more modern OpenSSL.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Aug 11, 2017
1 parent 32e0c05 commit 0664d93
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 70 deletions.
59 changes: 32 additions & 27 deletions dkimsign.cpp
Expand Up @@ -61,23 +61,28 @@ CDKIMSign::CDKIMSign()
{
m_EmptyLineCount = 0;
m_pfnHdrCallback = NULL;
EVP_SignInit(&m_allman_sha1ctx, EVP_sha1());
EVP_SignInit(&m_Hdr_ietf_sha1ctx, EVP_sha1());
EVP_DigestInit(&m_Bdy_ietf_sha1ctx, EVP_sha1());
m_allman_sha1ctx = EVP_MD_CTX_new();
EVP_SignInit(m_allman_sha1ctx, EVP_sha1());
m_Hdr_ietf_sha1ctx = EVP_MD_CTX_new();
EVP_SignInit(m_Hdr_ietf_sha1ctx, EVP_sha1());
m_Bdy_ietf_sha1ctx = EVP_MD_CTX_new();
EVP_DigestInit(m_Bdy_ietf_sha1ctx, EVP_sha1());
#ifdef HAVE_EVP_SHA256
EVP_SignInit(&m_Hdr_ietf_sha256ctx, EVP_sha256());
EVP_DigestInit(&m_Bdy_ietf_sha256ctx, EVP_sha256());
m_Hdr_ietf_sha256ctx = EVP_MD_CTX_new();
EVP_SignInit(m_Hdr_ietf_sha256ctx, EVP_sha256());
m_Bdy_ietf_sha256ctx = EVP_MD_CTX_new();
EVP_DigestInit(m_Bdy_ietf_sha256ctx, EVP_sha256());
#endif
}

CDKIMSign::~CDKIMSign()
{
EVP_MD_CTX_cleanup(&m_allman_sha1ctx);
EVP_MD_CTX_cleanup(&m_Hdr_ietf_sha1ctx);
EVP_MD_CTX_cleanup(&m_Bdy_ietf_sha1ctx);
EVP_MD_CTX_free(m_allman_sha1ctx);
EVP_MD_CTX_free(m_Hdr_ietf_sha1ctx);
EVP_MD_CTX_free(m_Bdy_ietf_sha1ctx);
#ifdef HAVE_EVP_SHA256
EVP_MD_CTX_cleanup(&m_Hdr_ietf_sha256ctx);
EVP_MD_CTX_cleanup(&m_Bdy_ietf_sha256ctx);
EVP_MD_CTX_free(m_Hdr_ietf_sha256ctx);
EVP_MD_CTX_free(m_Bdy_ietf_sha256ctx);
#endif
}

Expand Down Expand Up @@ -129,32 +134,32 @@ CDKIMSign::Hash(const char *szBuffer, int nBufLength, bool bHdr, bool bAllmanOnl
{
if (bAllmanOnly) {
if (m_nIncludeBodyHash & DKIM_BODYHASH_ALLMAN_1)
EVP_SignUpdate(&m_allman_sha1ctx, szBuffer, nBufLength);
EVP_SignUpdate(m_allman_sha1ctx, szBuffer, nBufLength);
} else {
if (m_nIncludeBodyHash < DKIM_BODYHASH_IETF_1)
EVP_SignUpdate(&m_allman_sha1ctx, szBuffer, nBufLength);
EVP_SignUpdate(m_allman_sha1ctx, szBuffer, nBufLength);
else
if (m_nIncludeBodyHash & DKIM_BODYHASH_IETF_1) {
if (m_nIncludeBodyHash & DKIM_BODYHASH_ALLMAN_1)
EVP_SignUpdate(&m_allman_sha1ctx, szBuffer, nBufLength);
EVP_SignUpdate(m_allman_sha1ctx, szBuffer, nBufLength);
#ifdef HAVE_EVP_SHA256
if (m_nHash & DKIM_HASH_SHA256) {
if (bHdr)
EVP_SignUpdate(&m_Hdr_ietf_sha256ctx, szBuffer, nBufLength);
EVP_SignUpdate(m_Hdr_ietf_sha256ctx, szBuffer, nBufLength);
else
EVP_DigestUpdate(&m_Bdy_ietf_sha256ctx, szBuffer, nBufLength);
EVP_DigestUpdate(m_Bdy_ietf_sha256ctx, szBuffer, nBufLength);
}
if (m_nHash != DKIM_HASH_SHA256) {
if (bHdr)
EVP_SignUpdate(&m_Hdr_ietf_sha1ctx, szBuffer, nBufLength);
EVP_SignUpdate(m_Hdr_ietf_sha1ctx, szBuffer, nBufLength);
else
EVP_DigestUpdate(&m_Bdy_ietf_sha1ctx, szBuffer, nBufLength);
EVP_DigestUpdate(m_Bdy_ietf_sha1ctx, szBuffer, nBufLength);
}
#else
if (bHdr)
EVP_SignUpdate(&m_Hdr_ietf_sha1ctx, szBuffer, nBufLength);
EVP_SignUpdate(m_Hdr_ietf_sha1ctx, szBuffer, nBufLength);
else
EVP_DigestUpdate(&m_Bdy_ietf_sha1ctx, szBuffer, nBufLength);
EVP_DigestUpdate(m_Bdy_ietf_sha1ctx, szBuffer, nBufLength);
#endif
}
}
Expand Down Expand Up @@ -753,9 +758,9 @@ int CDKIMSign::ConstructSignature(char *szPrivKey, bool bUseIetfBodyHash, bool b
unsigned char Hash[EVP_MAX_MD_SIZE];
unsigned int nHashLen = 0;
#ifdef HAVE_EVP_SHA256
EVP_DigestFinal(bUseSha256 ? &m_Bdy_ietf_sha256ctx : &m_Bdy_ietf_sha1ctx, Hash, &nHashLen);
EVP_DigestFinal(bUseSha256 ? m_Bdy_ietf_sha256ctx : m_Bdy_ietf_sha1ctx, Hash, &nHashLen);
#else
EVP_DigestFinal(&m_Bdy_ietf_sha1ctx, Hash, &nHashLen);
EVP_DigestFinal(m_Bdy_ietf_sha1ctx, Hash, &nHashLen);
#endif
bio = BIO_new(BIO_s_mem());
if (!bio) {
Expand Down Expand Up @@ -804,12 +809,12 @@ int CDKIMSign::ConstructSignature(char *szPrivKey, bool bUseIetfBodyHash, bool b
sTemp = sSignedSig.c_str();
if (bUseIetfBodyHash) {
#ifdef HAVE_EVP_SHA256
EVP_SignUpdate(bUseSha256 ? &m_Hdr_ietf_sha256ctx : &m_Hdr_ietf_sha1ctx, sTemp.c_str(), sTemp.size());
EVP_SignUpdate(bUseSha256 ? m_Hdr_ietf_sha256ctx : m_Hdr_ietf_sha1ctx, sTemp.c_str(), sTemp.size());
#else
EVP_SignUpdate(&m_Hdr_ietf_sha1ctx, sTemp.c_str(), sTemp.size());
EVP_SignUpdate(m_Hdr_ietf_sha1ctx, sTemp.c_str(), sTemp.size());
#endif
} else
EVP_SignUpdate(&m_allman_sha1ctx, sTemp.c_str(), sTemp.size());
EVP_SignUpdate(m_allman_sha1ctx, sTemp.c_str(), sTemp.size());
if (!(bio = BIO_new_mem_buf(szPrivKey, -1)))
return DKIM_OUT_OF_MEMORY;
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
Expand All @@ -826,12 +831,12 @@ int CDKIMSign::ConstructSignature(char *szPrivKey, bool bUseIetfBodyHash, bool b
}
if (bUseIetfBodyHash) {
#ifdef HAVE_EVP_SHA256
nSignRet = EVP_SignFinal(bUseSha256 ? &m_Hdr_ietf_sha256ctx : &m_Hdr_ietf_sha1ctx, sig, &siglen, pkey);
nSignRet = EVP_SignFinal(bUseSha256 ? m_Hdr_ietf_sha256ctx : m_Hdr_ietf_sha1ctx, sig, &siglen, pkey);
#else
nSignRet = EVP_SignFinal(&m_Hdr_ietf_sha1ctx, sig, &siglen, pkey);
nSignRet = EVP_SignFinal(m_Hdr_ietf_sha1ctx, sig, &siglen, pkey);
#endif
} else
nSignRet = EVP_SignFinal(&m_allman_sha1ctx, sig, &siglen, pkey);
nSignRet = EVP_SignFinal(m_allman_sha1ctx, sig, &siglen, pkey);
EVP_PKEY_free(pkey);
if (!nSignRet) {
OPENSSL_free(sig);
Expand Down
10 changes: 5 additions & 5 deletions dkimsign.h
Expand Up @@ -58,11 +58,11 @@ class CDKIMSign:public CDKIMBase {
bool IsRequiredHeader(const string & sTag);
int ConstructSignature(char *szPrivKey, bool bUseIetfBodyHash, bool bUseSha256);
int AssembleReturnedSig(char *szPrivKey);
EVP_MD_CTX m_Hdr_ietf_sha1ctx; /* the header hash for ietf sha1 */
EVP_MD_CTX m_Hdr_ietf_sha256ctx; /* the header hash for ietf sha256 */
EVP_MD_CTX m_Bdy_ietf_sha1ctx; /* the body hash for ietf sha1 */
EVP_MD_CTX m_Bdy_ietf_sha256ctx; /* the body hash for ietf sha256 */
EVP_MD_CTX m_allman_sha1ctx; /* the hash for allman sha1 */
EVP_MD_CTX *m_Hdr_ietf_sha1ctx; /* the header hash for ietf sha1 */
EVP_MD_CTX *m_Hdr_ietf_sha256ctx; /* the header hash for ietf sha256 */
EVP_MD_CTX *m_Bdy_ietf_sha1ctx; /* the body hash for ietf sha1 */
EVP_MD_CTX *m_Bdy_ietf_sha256ctx; /* the body hash for ietf sha256 */
EVP_MD_CTX *m_allman_sha1ctx; /* the hash for allman sha1 */
int m_Canon; // canonization method
int m_EmptyLineCount;
string hParam;
Expand Down
35 changes: 20 additions & 15 deletions dkimverify.cpp
Expand Up @@ -73,8 +73,8 @@ SignatureInfo::SignatureInfo(bool s)
{
VerifiedBodyCount = 0;
UnverifiedBodyCount = 0;
EVP_MD_CTX_init(&m_Hdr_ctx);
EVP_MD_CTX_init(&m_Bdy_ctx);
m_Hdr_ctx = EVP_MD_CTX_new();
m_Bdy_ctx = EVP_MD_CTX_new();
m_pSelector = NULL;
Status = DKIM_SUCCESS;
m_nHash = 0;
Expand All @@ -84,8 +84,12 @@ SignatureInfo::SignatureInfo(bool s)

SignatureInfo::~SignatureInfo()
{
EVP_MD_CTX_cleanup(&m_Hdr_ctx);
EVP_MD_CTX_cleanup(&m_Bdy_ctx);
#if 0 // !!! FIXME: these are bogus-freeing. Track that down.
if (m_Hdr_ctx)
EVP_MD_CTX_free(m_Hdr_ctx);
if (m_Bdy_ctx)
EVP_MD_CTX_free(m_Bdy_ctx);
#endif
}

inline bool
Expand Down Expand Up @@ -430,7 +434,7 @@ CDKIMVerify::GetResults(int *sCount, int *sSize)
// check the body hash
unsigned char md[EVP_MAX_MD_SIZE];
unsigned len = 0;
int res = EVP_DigestFinal(&i->m_Bdy_ctx, md, &len);
int res = EVP_DigestFinal(i->m_Bdy_ctx, md, &len);
if (!res || len != i->BodyHashData.length() || memcmp(i->BodyHashData.data(), md, len) != 0) {
// body hash mismatch
// if the selector is in testing mode...
Expand Down Expand Up @@ -466,7 +470,7 @@ CDKIMVerify::GetResults(int *sCount, int *sSize)
}
i->Hash(sSignedSig.c_str(), sSignedSig.length());
assert(i->m_pSelector != NULL);
int res = EVP_VerifyFinal(&i->m_Hdr_ctx, (unsigned char *) i->SignatureData.data(),
int res = EVP_VerifyFinal(i->m_Hdr_ctx, (unsigned char *) i->SignatureData.data(),
i->SignatureData.length(), i->m_pSelector->PublicKey);
if (res == 1) {
if (i->UnverifiedBodyCount == 0)
Expand Down Expand Up @@ -552,9 +556,9 @@ SignatureInfo::Hash(const char *szBuffer, unsigned nBufLength, bool IsBody)
}
}
if (IsBody && !BodyHashData.empty()) {
EVP_DigestUpdate(&m_Bdy_ctx, szBuffer, nBufLength);
EVP_DigestUpdate(m_Bdy_ctx, szBuffer, nBufLength);
} else {
EVP_VerifyUpdate(&m_Hdr_ctx, szBuffer, nBufLength);
EVP_VerifyUpdate(m_Hdr_ctx, szBuffer, nBufLength);
}
if (m_SaveCanonicalizedData) {
CanonicalizedData.append(szBuffer, nBufLength);
Expand Down Expand Up @@ -616,15 +620,15 @@ CDKIMVerify::ProcessHeaders(void)
// initialize the hashes
#ifdef HAVE_EVP_SHA256
if (sig.m_nHash == DKIM_HASH_SHA256) {
EVP_VerifyInit(&sig.m_Hdr_ctx, EVP_sha256());
EVP_DigestInit(&sig.m_Bdy_ctx, EVP_sha256());
EVP_VerifyInit(sig.m_Hdr_ctx, EVP_sha256());
EVP_DigestInit(sig.m_Bdy_ctx, EVP_sha256());
} else {
EVP_VerifyInit(&sig.m_Hdr_ctx, EVP_sha1());
EVP_DigestInit(&sig.m_Bdy_ctx, EVP_sha1());
EVP_VerifyInit(sig.m_Hdr_ctx, EVP_sha1());
EVP_DigestInit(sig.m_Bdy_ctx, EVP_sha1());
}
#else
EVP_VerifyInit(&sig.m_Hdr_ctx, EVP_sha1());
EVP_DigestInit(&sig.m_Bdy_ctx, EVP_sha1());
EVP_VerifyInit(sig.m_Hdr_ctx, EVP_sha1());
EVP_DigestInit(sig.m_Bdy_ctx, EVP_sha1());
#endif
// compute the hash of the header
vector < list < string >::reverse_iterator > used;
Expand Down Expand Up @@ -1100,7 +1104,8 @@ SelectorInfo::Parse(char *Buffer)
if (pkey == NULL)
return DKIM_SELECTOR_PUBLIC_KEY_INVALID;
// make sure public key is the correct type (we only support rsa)
if (pkey->type == EVP_PKEY_RSA || pkey->type == EVP_PKEY_RSA2) {
const int pkeytype = EVP_PKEY_base_id(pkey);
if (pkeytype == EVP_PKEY_RSA || pkeytype == EVP_PKEY_RSA2) {
PublicKey = pkey;
} else {
EVP_PKEY_free(pkey);
Expand Down
4 changes: 2 additions & 2 deletions dkimverify.h
Expand Up @@ -77,8 +77,8 @@ class SignatureInfo {
time_t ExpireTime;
unsigned VerifiedBodyCount;
unsigned UnverifiedBodyCount;
EVP_MD_CTX m_Hdr_ctx;
EVP_MD_CTX m_Bdy_ctx;
EVP_MD_CTX *m_Hdr_ctx;
EVP_MD_CTX *m_Bdy_ctx;
SelectorInfo *m_pSelector;
int Status;
int m_nHash; // use one of the DKIM_HASH_xxx constants here
Expand Down
35 changes: 20 additions & 15 deletions libdomainkeys-0.69/domainkeys.c
Expand Up @@ -120,7 +120,7 @@ typedef struct
{
/* STARTPRIV */
int dkmarker; /* in case somebody casts in */
EVP_MD_CTX mdctx; /* the hash */
EVP_MD_CTX *mdctx; /* the hash */
int signing; /* our current signing/verifying state */
int in_headers; /* true if we're still processing headers */
char *header; /* points to a malloc'ed block for header. */
Expand Down Expand Up @@ -256,12 +256,17 @@ void dk_shutdown(DK_LIB * dklib)
{
DK_MFREE(dklib);
}
CRYPTO_cleanup_all_ex_data();
// CRYPTO_cleanup_all_ex_data();
}

/* start a new header */
static DK_STAT dkinit_new_header(DK *dk)
{
dk->mdctx = EVP_MD_CTX_new();
if (!dk->mdctx)
{
return DKERR(DK_STAT_NORESOURCE);
}
dk->headermax = DK_BLOCK;
dk->header = DK_MALLOC(DK_BLOCK);
if (!dk->header)
Expand Down Expand Up @@ -503,7 +508,7 @@ DK *dk_sign(DK_LIB *dklib, DK_STAT *statp, int canon)
return NULL;
}
dk->canon = canon; /* TC13-simple, TC13-nofws */
EVP_SignInit(&dk->mdctx, dklib->md);
EVP_SignInit(dk->mdctx, dklib->md);

if (statp)
{
Expand Down Expand Up @@ -541,7 +546,7 @@ DK *dk_verify(DK_LIB *dklib, DK_STAT *statp)
}
return NULL;
}
EVP_VerifyInit(&dk->mdctx, dklib->md);
EVP_VerifyInit(dk->mdctx, dklib->md);

if (statp)
{
Expand Down Expand Up @@ -928,14 +933,14 @@ static void dkhash(DK *dk, const unsigned char *ptr)
{

#ifndef DK_HASH_BUFF
EVP_DigestUpdate(&dk->mdctx, "\r\n", 2);
EVP_DigestUpdate(dk->mdctx, "\r\n", 2);
#else
/* buffer hack */
dk->hash_buff[dk->hash_buff_len++] = '\r';
dk->hash_buff[dk->hash_buff_len++] = '\n';
if (dk->hash_buff_len >= (DK_BLOCK - 1))
{
EVP_DigestUpdate(&dk->mdctx, dk->hash_buff, dk->hash_buff_len);
EVP_DigestUpdate(dk->mdctx, dk->hash_buff, dk->hash_buff_len);
dk->hash_buff_len = 0;
}
/* buffer hack */
Expand All @@ -955,13 +960,13 @@ static void dkhash(DK *dk, const unsigned char *ptr)
if (dk->canon == DK_CANON_SIMPLE)//if nofws we ignore \r
{
#ifndef DK_HASH_BUFF
EVP_DigestUpdate(&dk->mdctx, "\r", 1);
EVP_DigestUpdate(dk->mdctx, "\r", 1);
#else
/* buffer hack */
dk->hash_buff[dk->hash_buff_len++] = '\r';
if (dk->hash_buff_len >= (DK_BLOCK - 1))
{
EVP_DigestUpdate(&dk->mdctx, dk->hash_buff, dk->hash_buff_len);
EVP_DigestUpdate(dk->mdctx, dk->hash_buff, dk->hash_buff_len);
dk->hash_buff_len = 0;
}
/* buffer hack */
Expand All @@ -977,13 +982,13 @@ static void dkhash(DK *dk, const unsigned char *ptr)
dk->state --;
}
#ifndef DK_HASH_BUFF
EVP_DigestUpdate(&dk->mdctx, ptr, 1);
EVP_DigestUpdate(dk->mdctx, ptr, 1);
#else
/* buffer hack */
dk->hash_buff[dk->hash_buff_len++] = *ptr;
if (dk->hash_buff_len >= (DK_BLOCK - 1))
{
EVP_DigestUpdate(&dk->mdctx, dk->hash_buff, dk->hash_buff_len);
EVP_DigestUpdate(dk->mdctx, dk->hash_buff, dk->hash_buff_len);
dk->hash_buff_len = 0;
}
/* buffer hack */
Expand Down Expand Up @@ -1746,10 +1751,10 @@ DK_STAT dk_end(DK *dk, DK_FLAGS *dkf)
//clean out hash buffer
dk->hash_buff[dk->hash_buff_len++] = '\r';
dk->hash_buff[dk->hash_buff_len++] = '\n';
EVP_DigestUpdate(&dk->mdctx, dk->hash_buff, dk->hash_buff_len);
EVP_DigestUpdate(dk->mdctx, dk->hash_buff, dk->hash_buff_len);
dk->hash_buff_len = 0;
#else
EVP_DigestUpdate(&dk->mdctx, "\r\n", 2);
EVP_DigestUpdate(dk->mdctx, "\r\n", 2);
#endif
#ifdef DK_DEBUG
fprintf(stderr,"\r\n");
Expand Down Expand Up @@ -1949,7 +1954,7 @@ DK_STAT dk_end(DK *dk, DK_FLAGS *dkf)
}

/* using that key, verify that the digest is properly signed */
i = EVP_VerifyFinal(&dk->mdctx, md_value, md_len, publickey);
i = EVP_VerifyFinal(dk->mdctx, md_value, md_len, publickey);

if (i > 0)
{
Expand Down Expand Up @@ -2058,7 +2063,7 @@ DK_STAT dk_getsig(DK *dk, void *privatekey, unsigned char buf[], size_t len)

siglen = EVP_PKEY_size(pkey);
sig = (unsigned char*) OPENSSL_malloc(siglen);
EVP_SignFinal(&dk->mdctx, sig, &siglen, pkey);
EVP_SignFinal(dk->mdctx, sig, &siglen, pkey);
EVP_PKEY_free(pkey);

bio = BIO_new(BIO_s_mem());
Expand Down Expand Up @@ -2152,7 +2157,7 @@ DK_STAT dk_free(DK *dk, int doClearErrState)
#ifdef DK_HASH_BUFF
DK_MFREE(dk->hash_buff);
#endif
EVP_MD_CTX_cleanup(&dk->mdctx);
EVP_MD_CTX_free(dk->mdctx);
DK_MFREE(dk->header); /* alloc'ing dk->header is not optional. */
dk->dkmarker = ~DKMARK;
DK_MFREE(dk);
Expand Down
6 changes: 3 additions & 3 deletions qmail-remote.c
Expand Up @@ -266,8 +266,8 @@ char *append;
{
#ifdef TLS
/* shouldn't talk to the client unless in an appropriate state */
int state = ssl ? ssl->state : SSL_ST_BEFORE;
if (state & SSL_ST_OK || (!smtps && state & SSL_ST_BEFORE))
const OSSL_HANDSHAKE_STATE state = ssl ? SSL_get_state(ssl) : TLS_ST_BEFORE;
if (state & TLS_ST_OK || (!smtps && state & TLS_ST_BEFORE))
#endif
substdio_putsflush(&smtpto,"QUIT\r\n");
/* waiting for remote side is just too ridiculous */
Expand Down Expand Up @@ -493,7 +493,7 @@ int tls_init()
X509_NAME *subj = X509_get_subject_name(peercert);
i = X509_NAME_get_index_by_NID(subj, NID_commonName, -1);
if (i >= 0) {
const ASN1_STRING *s = X509_NAME_get_entry(subj, i)->value;
const ASN1_STRING *s = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, i));
if (s) { peer.len = s->length; peer.s = s->data; }
}
if (peer.len <= 0) {
Expand Down

0 comments on commit 0664d93

Please sign in to comment.