xorl %eax, %eax

CVE-2009-0591: OpenSSL Signed Attributes Security Bypass

leave a comment »

First of all this issue affects OpenSSL from 0.9.8h up to 0.9.8j release. Here I’ll be using 0.9.8j to describe the vulnerability. This bug was disclosed on 25 March 2009 and it was reported by Ivan Nestlerode of IBM. The buggy routine is under crypto/cms/cms_smime.c. You only have to worry if you’re using a CMS (Cryptographic Message Syntax) enabled OpenSSL library. Here is the function:

321
322 int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
323                  X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
324         {
325         CMS_SignerInfo *si;
        ...
331         BIO *cmsbio = NULL, *tmpin = NULL;
        ...
346         for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
347                 {
348                 si = sk_CMS_SignerInfo_value(sinfos, i);
        ...
379         /* Attempt to verify all SignerInfo signed attribute signatures */
380
381         if (!(flags & CMS_NO_ATTR_VERIFY))
382                 {
383                 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
384                         {
385                         si = sk_CMS_SignerInfo_value(sinfos, i);
        ...
416         cmsbio=CMS_dataInit(cms, tmpin);
417         if (!cmsbio)
        ...
427                         si = sk_CMS_SignerInfo_value(sinfos, i);
428                         if (!CMS_SignerInfo_verify_content(si, cmsbio))
429                                 {
430                                 CMSerr(CMS_F_CMS_VERIFY,
431                                         CMS_R_CONTENT_VERIFY_ERROR);
432                                 goto err;
433                                 }
        ...
451         return ret;
452         }

By having a quick look at CMS_SignerInfo_verify_content() which can be found at crypto/cms/cms_sd.c you can easily locate the above missing check. Take a look at this:

872 int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
873         {
          ...
876         int r = -1;
          ...
879         if (CMS_signed_get_attr_count(si) >= 0)
880                 {
          ...
884                 if (!os)
885                         {
886                         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
887                                 CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
888                         goto err;
889                         }890                 }
891
892         if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
893                 goto err;
          ...
901                 if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
          ...
905                         goto err;
          ...
907                 if (mlen != (unsigned int)os->length)
          ...
911                         goto err;
          ...
936         err:
937         EVP_MD_CTX_cleanup(&mctx);
938         return r;
939
940         }


Clearly there are many ways to make this function return -1 since conditions at lines 884, 892, 901 and 907 are directly calling err label without setting the value of r variable to 0. This means that the check at line 428 of CMS_verify() can be bypassed if any of the those conditions is reached and r has value of -1. The patch for this bug was this:

                        {
                        si = sk_CMS_SignerInfo_value(sinfos, i);
-                       if (!CMS_SignerInfo_verify_content(si, cmsbio))
+                       if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0)
                                {
                                CMSerr(CMS_F_CMS_VERIFY,

In order to check for both 0 and negative values. Using this you can construct malformed signature attributes and make them appear like verified, valid ones.

Written by xorl

April 2, 2009 at 17:13

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s