[NEWS] OpenCA Signature Verification Vulnerabilities

From: SecuriTeam (support_at_securiteam.com)
Date: 12/01/03

  • Next message: SecuriTeam: "[UNIX] CuteNews Information Disclosure"
    To: list@securiteam.com
    Date: 1 Dec 2003 12:29:29 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.
    http://www.securiteam.com/mailinglist.html

    - - - - - - - - -

      OpenCA Signature Verification Vulnerabilities
    ------------------------------------------------------------------------

    SUMMARY

    Multiple flaws in OpenCA before version 0.9.1.4 could cause OpenCA to use
    an incorrect certificate in the chain to determine the serial being
    checked which could lead to certificates that are revoked or expired being
    incorrectly accepted.

    Chris Covell and Gottfried Scheckenbach performed tests with OpenCA and CA
    hierarchies. They had problems to verify signatures with some functions in
    OpenCA which test the signer's certificate.

    Michael Bell of the OpenCA core team identified and fixed the problems for
    OpenCA 0.9.1 and the CVS HEAD.

    DETAILS

    Who is affected?
    All version of OpenCA including 0.9.1.3. A security risk is present for
    people who are using digital signatures to secure approved requests or
    role based access control (RBAC).

    Vulnerabilities:
    1. OpenCA has a library for common crypto operations - crypto-utils.lib.
    This library includes a function to determine the serial of the
    certificate which somebody used to create a PKCS#7 signature. The function
    uses this serial to load and return the certificate. The function used the
    interface of OpenCA::PKCS7 (the OpenCA PKCS#7 module) in a wrong way.

    2. The crypto library crypto-utils.lib uses all certificates which were
    included into the signature to create the X.509 object of the signer's
    certificate. The result is a object which was created from one of the
    certificates of the certificate chain. This means that the result is
    haphazard.

    3. OpenCA::PKCS7 includes a wrong regular expression to detect lines which
    have nothing to do with the parsing of the certificate chain.

    4. The serial in the certificate chain were parsed with a wrong regular
    expression in OpenCA::PKCS7. Big letters like A, C, B, D, E and F were
    ignored.

    Recommendations:
    Upgrade to 0.9.1.4 and use newer snapshots than
    openca-0.9-SNAP-20031125.tar.gz. You can fix the problem by yourself too
    with the included patches. The original files which we used to create the
    diffs are from OpenCA 0.9.1.3.

    -----BEGIN PATCH-----

    --- openca-0.9.1.3/src/modules/openca-pkcs7/PKCS7.pm 2002-09-10
    16:42:02.000000000 +0200
    +++ openca-0.9.1.4/src/modules/openca-pkcs7/PKCS7.pm 2003-11-26
    15:54:08.000000000 +0100
    @@ -69,7 +69,7 @@

      our ($errno, $errval);

    -($OpenCA::PKCS7::VERSION = '$Revision: 1.12 $' )=~ s/(?:^.*:
    (\d+))|(?:\s+\$$)/defined $1?"0\.9":""/eg;
    +($OpenCA::PKCS7::VERSION = '$Revision: 1.12.2.1 $' )=~ s/(?:^.*:
    (\d+))|(?:\s+\$$)/defined $1?"0\.9":""/eg;

      my %params = (
              inFile => undef,
    @@ -167,6 +167,8 @@

             my ( $ret, $tmp );

    + return $self->{parsed} if ($self->{parsed});
    +
             $tmp = $self->{backend}->verify( SIGNATURE=>$self->{signature},
                             DATA_FILE=>$self->{dataFile},
                             CA_CERT=>$self->{caCert},
    @@ -292,10 +294,10 @@
                             ($self->{status}) = ( $line =~
    /^\s*error:([^:]*):/ );
                     }

    - next if( $line != /^depth/i );
    + next if( $line !~ /^depth/i );

                     ( $currentDepth, $serial, $dn ) =
    - ( $line =~ /depth:([\d]+) serial:([a-f\d]+)
    subject:(.*)/ );
    + ( $line =~ /depth:([\d]+) serial:([a-fA-F\d]+)
    subject:(.*)/ );
                     $ret->{$currentDepth}->{SERIAL} = hex ($serial) ;
                     $ret->{$currentDepth}->{DN} = $dn;

    --- openca-0.9.1.3/src/common/lib/functions/crypto-utils.lib
    2002-12-22 13:08:19.000000000 +0100
    +++ openca-0.9.1.4/src/common/lib/functions/crypto-utils.lib
    2003-11-26 13:04:50.000000000 +0100
    @@ -176,19 +176,36 @@
                     return undef;
             }

    - ## Get signer certificate from the pkcs7 structure
    - $sigCert = new OpenCA::X509 ( SHELL => $cryptoShell,
    - DATA => $sig->getSigner()->{CERTIFICATE});
    -
    - if( not $sigCert ) {
    - $errno = 6103;
    - $errval = i18nGettext ("Signer's certificate is
    corrupt!\nOpenCA::X509 returns errorcode __ERRNO__ (__ERRVAL__).",
    - "__ERRNO__", $OpenCA::X509::errno,
    - "__ERRVAL__",
    $OpenCA::X509::errval);
    - return undef;
    + ## Get signer certificate chain from the pkcs7 structure
    + my @chain = split /-----END CERTIFICATE-----/,
    + $sig->getSigner()->{CERTIFICATE};
    + for (my $i=0; $i < scalar @chain; $i++)
    + {
    + if (not $chain[$i])
    + {
    + delete $chain[$i];
    + next;
    + }
    + $chain[$i] .= "-----END CERTIFICATE-----";
    + $chain[$i] =~ s/^.*-----BEGIN
    CERTIFICATE-----/-----BEGIN CERTIFICATE-----/s;
    + }
    + $sigCert = undef;
    + for (my $i=0; $i < scalar @chain; $i++)
    + {
    + $sigCert = new OpenCA::X509 ( SHELL => $cryptoShell,
    + DATA => $chain[$i]);
    + if( not $sigCert ) {
    + $errno = 6103;
    + $errval = i18nGettext ("Signer's certificate is
    corrupt!\nOpenCA::X509 returns errorcode __ERRNO__ (__ERRVAL__).",
    + "__ERRNO__",
    $OpenCA::X509::errno,
    + "__ERRVAL__",
    $OpenCA::X509::errval);
    + return undef;
    + }
    + last if ( $tmpCert->getSerial() eq $sigCert->getSerial()
    );
    + $sigCert = undef;
             }

    - if( $tmpCert->getSerial() ne $sigCert->getSerial() ) {
    + if( not $sigCert ) {
                     $errno = 6104;
                     $errval = gettext ("Signer's Certificate and DB's
    Certificate do not match");
                     return undef;
    @@ -281,19 +298,8 @@
                     return undef;
             }

    - my $sigCert = new OpenCA::X509 ( SHELL => $cryptoShell,
    - DATA =>
    $sig->getSigner()->{CERTIFICATE});
    -
    - if (not $sigCert) {
    - $errno = 6302;
    - $errval = i18nGettext ("Cannot create X509-object from
    the certificate of the signer! OpenCA::X509 returns errorcode __ERRNO__
    (__ERRVAL__).",
    - "__ERRNO__", $OpenCA::X509::errno,
    - "__ERRVAL__",
    $OpenCA::X509::errval);
    - return undef;
    - }
    -
             my $db_cert = $db->getItem( DATATYPE => 'CERTIFICATE',
    - KEY => $sigCert->getSerial() );
    + KEY => $sig->getSigner()->{SERIAL} );

             if( not $db_cert ) {
                     $errno = 6303;

    --- openca-0.9.1.3/src/common/lib/cmds/verifySignature 2003-03-31
    15:45:19.000000000 +0200
    +++ openca-0.9.1.4/src/common/lib/cmds/verifySignature 2003-11-26
    13:04:34.000000000 +0100
    @@ -11,7 +11,7 @@
      ## Get the Configuration parameters ...
      my ( $parsed, $lnk, $serLink, $sigInfo, $sigStatus, $signer,
    $signature);
      my ( $baseDoc, $info, $sigCertStatus, $def, $dbStatus, $dbMessage);
    -my ( $myCN, $myEmail, $mySerial, @sigCert, $tmpCert, $pCert );
    +my ( $myCN, $myEmail, $mySerial, $tmpCert, $pCert );

      ## Get Required Parameters from Configuration
      my $baseDoc = getRequired ('verifySignatureform');
    @@ -53,10 +53,7 @@
      $myDN = $signer->{DN};
      $myDN =~ s/^\///; $myDN =~ s/\//<BR>/g;

    -$sigCert = new OpenCA::X509 ( SHELL => $cryptoShell,
    - DATA => $sign->getSigner()->{CERTIFICATE});
    -
    -$issuerDN = $sigCert->getParsed()->{ISSUER};
    +$issuerDN = $sign->getParsed()->{CHAIN}->{1}->{DN};
      $issuerDN =~ s/^\///; $issuerDN =~ s/[\/\,]/<BR>/g;

      ## Check Signature Status
    @@ -71,7 +68,7 @@
                     $dbStatus = $errno;
                     $sigStatus = "<FONT
    COLOR=\"Red\">".gettext("Unknown")."</FONT>";

    - $serLink = $sigCert->getSerial();
    + $serLink = $sign->getSigner()->{SERIAL};
             } else {
                     $sigMessage = gettext("Signature correctly verified");
             }
    @@ -96,11 +93,7 @@
             $serLink = $tmpCert->getSerial();
      }

    -if( $sigCert ) {
    - $pCert = $sigCert->getParsed();
    -} elsif ( $tmpCert ) {
    - $pCert = $tmpCert->getParsed();
    -}
    +$pCert = $tmpCert->getParsed();

      ## View the Operator Used Certificate Data
      $page = $query->subVar( $page, '@DN@', ($myDN or "n/a" ) );

    --- openca-0.9.1.3/src/common/lib/cmds/viewSignature 2002-12-10
    16:18:15.000000000 +0100
    +++ openca-0.9.1.4/src/common/lib/cmds/viewSignature 2003-11-26
    13:04:34.000000000 +0100
    @@ -11,7 +11,7 @@
      ## Get the Configuration parameters ...
      my ( $parsed, $lnk, $serLink, $sigInfo, $sigStatus, $signer,
    $signature);
      my ( $baseDoc, $info, $sigCertStatus, $def, $dbStatus, $dbMessage);
    -my ( $myCN, $myEmail, $mySerial, @sigCert, $tmpCert, $pCert );
    +my ( $myCN, $myEmail, $mySerial, $tmpCert, $pCert );

      my $dataType = $query->param('dataType' );
      my $key = $query->param('key');
    @@ -54,9 +54,6 @@
                     name=>"EMAIL",
    value=>$signer->{DN_HASH}->{EMAILADDRESS}[0]} );
      $myEmail = $lnk->a({-href=>$lnk->self_url()},
    $signer->{DN_HASH}->{EMAILADDRESS}[0]);

    -$sigCert = new OpenCA::X509 ( SHELL => $cryptoShell,
    - DATA =>
    $signature->getSigner()->{CERTIFICATE});
    -
      ## Check Signature Status
      if( not libCheckSignature( SIGNATURE=>$signature ) ) {
             $sigStatus = "<FONT COLOR=\"Red\">".gettext("Error")."</FONT>";
    @@ -105,7 +102,7 @@
             $serLink = $lnk->a({-href=>$lnk->self_url()},
                             $tmpCert->getSerial() );

    - $decSerLink = "( " . hex( $sigCert->getSerial() ) . " )";
    + $decSerLink = "( " . hex( $tmpCert->getSerial() ) . " )";

          $lnk = new CGI({cmd => "search",
                          dataType => "CERTIFICATE",
    @@ -114,11 +111,7 @@
          $myEmail = $lnk->a({-href=>$lnk->self_url()},
    $tmpCert->getParsed()->{EMAILADDRESS});
      }

    -if( $sigCert ) {
    - $pCert = $sigCert->getParsed();
    -} elsif ( $tmpCert ) {
    - $pCert = $tmpCert->getParsed();
    -}
    +$pCert = $tmpCert->getParsed();

      ## View the Operator Used Certificate Data
      $page = $query->subVar( $page, '@CN@', ($myCN or "n/a" ) );
    -----END PATCH-----

    References:
    The Common Vulnerabilities and Exposures project (cve.mitre.org) has
    assigned the name
    <http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0960>
    CAN-2003-0960 to this issue.

    ADDITIONAL INFORMATION

    The original advisory is available from:
    <http://www.openca.org/news/CAN-2003-0960.txt>
    http://www.openca.org/news/CAN-2003-0960.txt.

    The information has been provided by
    <mailto:michael.bell@cms.hu-berlin.de> Michael Bell.

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[UNIX] CuteNews Information Disclosure"

    Relevant Pages

    • [UNIX] Vulnerability in OpenCA Signature Verification
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... OpenCA Project is "an open organization aimed to ... This means that a certificate from another PKI can authorize ... operations on the used PKI if the chain of the used signature certificate ...
      (Securiteam)
    • [Full-Disclosure] [OpenCA Advisory] Vulnerability in signature verification
      ... OpenCA Security Advisory ... Vulnerability in signature validation ... the chain directory of OpenCA. ... This means that a certificate from ...
      (Full-Disclosure)
    • [OpenCA Advisory] Vulnerability in signature verification
      ... OpenCA Security Advisory ... Vulnerability in signature validation ... the chain directory of OpenCA. ... This means that a certificate from ...
      (Full-Disclosure)
    • [OpenCA Advisory] Vulnerability in signature verification
      ... OpenCA Security Advisory ... Vulnerability in signature validation ... the chain directory of OpenCA. ... This means that a certificate from ...
      (Bugtraq)
    • Re: Soft signatures
      ... now, digital signature, typically just represents that you (in ... For some time there were arguments that if a certificate contained the ... certificate with your public key and the non-repudiation flag in it. ... for a number of different business purposes. ...
      (sci.crypt)