From 83cb7c46353b849b9511f1328a06a1ef33baf5c8 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 15 Feb 2012 14:04:00 +0000 Subject: [PATCH] An incompatibility has always existed between the format used for RSA signatures and MDC2 using EVP or RSA_sign. This has become more apparent when the dgst utility in OpenSSL 1.0.0 and later switched to using the EVP_DigestSign functions which call RSA_sign. This means that the signature format OpenSSL 1.0.0 and later used with dgst -sign and MDC2 is incompatible with previous versions. Add detection in RSA_verify so either format works. Note: MDC2 is disabled by default in OpenSSL and very rarely used in practice. --- CHANGES | 7 +++++++ crypto/rsa/rsa_sign.c | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/CHANGES b/CHANGES index 37124447a9..d4163ca955 100644 --- a/CHANGES +++ b/CHANGES @@ -267,6 +267,13 @@ Changes between 1.0.0f and 1.0.1 [xx XXX xxxx] + *) The format used for MDC2 RSA signatures is inconsistent between EVP + and the RSA_sign/RSA_verify functions. This was made more apparent when + OpenSSL used RSA_sign/RSA_verify for some RSA signatures in particular + those which went through EVP_PKEY_METHOD in 1.0.0 and later. Detect + the correct format in RSA_verify so both forms transparently work. + [Steve Henson] + *) Some servers which support TLS 1.0 can choke if we initially indicate support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA encrypted premaster secret. As a workaround use the maximum pemitted diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c index 0be4ec7fb0..fa3239ab30 100644 --- a/crypto/rsa/rsa_sign.c +++ b/crypto/rsa/rsa_sign.c @@ -182,6 +182,22 @@ int int_rsa_verify(int dtype, const unsigned char *m, i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); if (i <= 0) goto err; + /* Oddball MDC2 case: signature can be OCTET STRING. + * check for correct tag and length octets. + */ + if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) + { + if (rm) + { + memcpy(rm, s + 2, 16); + *prm_len = 16; + ret = 1; + } + else if(memcmp(m, s + 2, 16)) + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + else + ret = 1; + } /* Special case: SSL signature */ if(dtype == NID_md5_sha1) {