Dear maintainer and Waldemar,
Building opendkim with --with-gnutls disables support for ed25519, so I've
taken a closer look at the problematic code and found the culprit code.
The error comes from the call to the openssl function RSA_sign in
libopendkim/dkim.c:3945:
RSA_sign takes as fifth argument a reference to an unsigned int (4 byte)
variable to return the length of the signature.
The opendkim-code uses a reference to the variable l of type size_t (unsigned
long, 8 bytes on s390x) casted as (signed) int reference for this.
This is fatal for a big endian system.
I've attached to patches:
1.) fix-RSA_sign-call.patch: fixes the call to RSA_sign by using a temporary
variable ui_l of the correct type unsigned int to get back the length from
RSA_sign and savely assigns the returned value to l after the call.
2.) fix-printf-types.patch: fixes several calls of printf in dkim.c that use
the signed int specifier "%d" to print size_t arguments. For C99-code "%zu"
should be used for size_t variables.
best regards,
Martin
--- a/libopendkim/dkim.c
+++ b/libopendkim/dkim.c
@@ -440,7 +440,7 @@ dkim_add_plist(DKIM *dkim, DKIM_SET *set
plist = (DKIM_PLIST *) DKIM_MALLOC(dkim, sizeof(DKIM_PLIST));
if (plist == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
sizeof(DKIM_PLIST));
return -1;
}
@@ -504,7 +504,7 @@ dkim_process_set(DKIM *dkim, dkim_set_t
hcopy = (u_char *) DKIM_MALLOC(dkim, len + 1);
if (hcopy == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)", len + 1);
+ dkim_error(dkim, "unable to allocate %zu byte(s)", len + 1);
return DKIM_STAT_INTERNAL;
}
strlcpy((char *) hcopy, (char *) str, len + 1);
@@ -513,7 +513,7 @@ dkim_process_set(DKIM *dkim, dkim_set_t
if (set == NULL)
{
DKIM_FREE(dkim, hcopy);
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
sizeof(DKIM_SET));
return DKIM_STAT_INTERNAL;
}
@@ -1146,7 +1146,7 @@ dkim_privkey_load(DKIM *dkim)
crypto = DKIM_MALLOC(dkim, sizeof(struct dkim_crypto));
if (crypto == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
sizeof(struct dkim_crypto));
return DKIM_STAT_NORESOURCE;
}
@@ -1939,7 +1939,7 @@ dkim_siglist_setup(DKIM *dkim)
dkim->dkim_siglist = DKIM_MALLOC(dkim, len);
if (dkim->dkim_siglist == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)", len);
+ dkim_error(dkim, "unable to allocate %zu byte(s)", len);
return DKIM_STAT_NORESOURCE;
}
@@ -1953,7 +1953,7 @@ dkim_siglist_setup(DKIM *dkim)
int n;
dkim_error(dkim,
- "unable to allocate %d byte(s)",
+ "unable to allocate %zu byte(s)",
sizeof(DKIM_SIGINFO));
for (n = 0; n < c; n++)
DKIM_FREE(dkim, dkim->dkim_siglist[n]);
@@ -2337,7 +2337,7 @@ dkim_siglist_setup(DKIM *dkim)
if (dkim->dkim_siglist[c]->sig_sig == NULL)
{
dkim_error(dkim,
- "unable to allocate %d byte(s)",
+ "unable to allocate %zu byte(s)",
b64siglen);
return DKIM_STAT_NORESOURCE;
}
@@ -2904,7 +2904,7 @@ dkim_get_key(DKIM *dkim, DKIM_SIGINFO *s
if (sig->sig_key == NULL)
{
dkim_error(dkim,
- "unable to allocate %d byte(s)",
+ "unable to allocate %zu byte(s)",
osig->sig_b64keylen);
return DKIM_STAT_NORESOURCE;
}
@@ -3086,7 +3086,7 @@ dkim_get_key(DKIM *dkim, DKIM_SIGINFO *s
sig->sig_key = DKIM_MALLOC(dkim, sig->sig_b64keylen);
if (sig->sig_key == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
sig->sig_b64keylen);
return DKIM_STAT_NORESOURCE;
}
@@ -3368,7 +3368,7 @@ dkim_eoh_sign(DKIM *dkim)
dkim->dkim_siglist = DKIM_MALLOC(dkim, sizeof(DKIM_SIGINFO **));
if (dkim->dkim_siglist == NULL)
{
- dkim_error(dkim, "failed to allocate %d byte(s)",
+ dkim_error(dkim, "failed to allocate %zu byte(s)",
sizeof(DKIM_SIGINFO *));
return DKIM_STAT_NORESOURCE;
}
@@ -3377,7 +3377,7 @@ dkim_eoh_sign(DKIM *dkim)
sizeof(struct dkim_siginfo));
if (dkim->dkim_siglist[0] == NULL)
{
- dkim_error(dkim, "failed to allocate %d byte(s)",
+ dkim_error(dkim, "failed to allocate %zu byte(s)",
sizeof(struct dkim_siginfo));
return DKIM_STAT_NORESOURCE;
}
@@ -3810,7 +3810,7 @@ dkim_eom_sign(DKIM *dkim)
{
sig->sig_error = DKIM_SIGERROR_KEYTOOSMALL;
dkim_error(dkim,
- "private key too small (%d bits, need at least %d)",
+ "private key too small (%u bits, need at least %u)",
sig->sig_keybits,
dkim->dkim_libhandle->dkiml_minkeybits);
return DKIM_STAT_SIGGEN;
@@ -3898,6 +3898,7 @@ dkim_eom_sign(DKIM *dkim)
int alg;
gnutls_datum_t dd;
struct dkim_crypto *crypto;
+ unsigned int ui_l = 0;
crypto = (struct dkim_crypto *) sig->sig_signature;
@@ -3952,7 +3953,7 @@ dkim_eom_sign(DKIM *dkim)
{
dkim_load_ssl_errors(dkim, 0);
dkim_error(dkim,
- "signature generation failed (status %d, length %d)",
+ "signature generation failed (status %d, length %zu)",
status, l);
RSA_free(crypto->crypto_key);
@@ -4003,7 +4004,7 @@ dkim_eom_sign(DKIM *dkim)
{
/* dkim_load_ssl_errors(dkim, 0); */
dkim_error(dkim,
- "signature generation failed (status %d, length %d, %s)",
+ "signature generation failed (status %d, length %zu, %s)",
status, l, ERR_error_string(ERR_get_error(), NULL));
RSA_free(crypto->crypto_key);
@@ -4034,7 +4035,7 @@ dkim_eom_sign(DKIM *dkim)
dkim->dkim_b64sig = DKIM_MALLOC(dkim, dkim->dkim_b64siglen);
if (dkim->dkim_b64sig == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
dkim->dkim_b64siglen);
#ifndef USE_GNUTLS
BIO_CLOBBER(crypto->crypto_keydata);
@@ -5445,7 +5446,7 @@ dkim_resign(DKIM *new, DKIM *old, _Bool
new->dkim_siglist = DKIM_MALLOC(new, sizeof(DKIM_SIGINFO *));
if (new->dkim_siglist == NULL)
{
- dkim_error(new, "failed to allocate %d byte(s)",
+ dkim_error(new, "failed to allocate %zu byte(s)",
sizeof(DKIM_SIGINFO *));
return DKIM_STAT_NORESOURCE;
}
@@ -5453,7 +5454,7 @@ dkim_resign(DKIM *new, DKIM *old, _Bool
new->dkim_siglist[0] = DKIM_MALLOC(new, sizeof(struct dkim_siginfo));
if (new->dkim_siglist[0] == NULL)
{
- dkim_error(new, "failed to allocate %d byte(s)",
+ dkim_error(new, "failed to allocate %zu byte(s)",
sizeof(struct dkim_siginfo));
return DKIM_STAT_NORESOURCE;
}
@@ -5640,7 +5641,7 @@ dkim_sig_process(DKIM *dkim, DKIM_SIGINF
if (crypto == NULL)
{
dkim_error(dkim,
- "unable to allocate %d byte(s)",
+ "unable to allocate %zu byte(s)",
sizeof(struct dkim_crypto));
#ifndef USE_GNUTLS
BIO_CLOBBER(key);
@@ -6085,7 +6086,7 @@ dkim_ohdrs(DKIM *dkim, DKIM_SIGINFO *sig
dkim->dkim_zdecode = DKIM_MALLOC(dkim, MAXHEADERS);
if (dkim->dkim_zdecode == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
strlen(z));
return DKIM_STAT_NORESOURCE;
}
@@ -6512,7 +6513,7 @@ dkim_header(DKIM *dkim, u_char *hdr, siz
if (h == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
sizeof(struct dkim_header));
return DKIM_STAT_NORESOURCE;
}
@@ -9369,7 +9370,7 @@ dkim_add_querymethod(DKIM *dkim, const c
sizeof(struct dkim_qmethod));
if (q == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
sizeof(struct dkim_qmethod));
return DKIM_STAT_NORESOURCE;
}
@@ -9378,7 +9379,7 @@ dkim_add_querymethod(DKIM *dkim, const c
if (q->qm_type == NULL)
{
DKIM_FREE(dkim, q);
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
strlen(type) + 1);
return DKIM_STAT_NORESOURCE;
}
@@ -9390,7 +9391,7 @@ dkim_add_querymethod(DKIM *dkim, const c
{
DKIM_FREE(dkim, q->qm_type);
DKIM_FREE(dkim, q);
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
strlen(options) + 1);
return DKIM_STAT_NORESOURCE;
}
@@ -9497,7 +9498,7 @@ dkim_add_xtag(DKIM *dkim, const char *ta
x = (struct dkim_xtag *) DKIM_MALLOC(dkim, sizeof(struct dkim_xtag));
if (x == NULL)
{
- dkim_error(dkim, "unable to allocate %d byte(s)",
+ dkim_error(dkim, "unable to allocate %zu byte(s)",
sizeof(struct dkim_xtag));
return DKIM_STAT_NORESOURCE;
}
@@ -9657,7 +9658,7 @@ dkim_signhdrs(DKIM *dkim, const char **h
if (dkim->dkim_hdrre == NULL)
{
- dkim_error(dkim, "could not allocate %d bytes",
+ dkim_error(dkim, "could not allocate %zu bytes",
sizeof(regex_t));
return DKIM_STAT_INTERNAL;
}
--- a/libopendkim/dkim.c
+++ b/libopendkim/dkim.c
@@ -3932,6 +3932,7 @@ dkim_eom_sign(DKIM *dkim)
{
int nid;
struct dkim_crypto *crypto;
+ unsigned int ui_l = 0;
crypto = (struct dkim_crypto *) sig->sig_signature;
@@ -3942,9 +3943,11 @@ dkim_eom_sign(DKIM *dkim)
sig->sig_hashtype == DKIM_HASHTYPE_SHA256)
nid = NID_sha256;
+ /* use variable ui_l to savely get the length (unsigned int *) out of RSA_sign and into size_t type l */
status = RSA_sign(nid, digest, diglen,
- crypto->crypto_out, (int *) &l,
+ crypto->crypto_out, &ui_l,
crypto->crypto_key);
+ l = ui_l;
if (status != 1 || l == 0)
{
dkim_load_ssl_errors(dkim, 0);