LCOV - code coverage report
Current view: top level - src - X509.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2 119 1.7 %
Date: 2010-12-13 Functions: 2 8 25.0 %
Branches: 2 48 4.2 %

           Branch data     Line data    Source code
       1                 :            : // $Id: X509.cc 6724 2009-06-07 09:23:03Z vern $
       2                 :            : 
       3                 :            : #include <openssl/err.h>
       4                 :            : 
       5                 :            : #include "X509.h"
       6                 :            : #include "config.h"
       7                 :            : 
       8                 :            : // ### NOTE: while d2i_X509 does not take a const u_char** pointer,
       9                 :            : // here we assume d2i_X509 does not write to <data>, so it is safe to
      10                 :            : // convert data to a non-const pointer.  Could some X509 guru verify
      11                 :            : // this?
      12                 :            : 
      13                 :          0 : X509* d2i_X509_(X509** px, const u_char** in, int len)
      14                 :            :         {
      15                 :            : #ifdef OPENSSL_D2I_X509_USES_CONST_CHAR
      16                 :          0 :           return d2i_X509(px, in, len);
      17                 :            : #else
      18                 :            :           return d2i_X509(px, (u_char**)in, len);
      19                 :            : #endif
      20                 :            :         }
      21                 :            : 
      22                 :            : X509_STORE* X509_Cert::ctx = 0;
      23                 :            : X509_LOOKUP* X509_Cert::lookup = 0;
      24                 :            : X509_STORE_CTX X509_Cert::csc;
      25                 :            : bool X509_Cert::bInited = false;
      26                 :            : 
      27                 :            : // TODO: Check if Key < 768 Bits => Weakness!
      28                 :            : // FIXME: Merge verify and verifyChain.
      29                 :            : 
      30                 :          0 : void X509_Cert::sslCertificateEvent(Contents_SSL* e, X509* pCert)
      31                 :            :         {
      32                 :          0 :         EventHandlerPtr event = ssl_certificate;
      33         [ #  # ]:          0 :         if ( ! event )
      34                 :          0 :                 return;
      35                 :            : 
      36                 :            :         char tmp[256];
      37                 :          0 :         RecordVal* pX509Cert = new RecordVal(x509_type);
      38                 :            : 
      39                 :          0 :         X509_NAME_oneline(X509_get_issuer_name(pCert), tmp, sizeof tmp);
      40                 :          0 :         pX509Cert->Assign(0, new StringVal(tmp));
      41                 :          0 :         X509_NAME_oneline(X509_get_subject_name(pCert), tmp, sizeof tmp);
      42                 :          0 :         pX509Cert->Assign(1, new StringVal(tmp));
      43                 :          0 :         pX509Cert->Assign(2, new AddrVal(e->Conn()->OrigAddr()));
      44                 :            : 
      45                 :          0 :         val_list* vl = new val_list;
      46                 :          0 :         vl->append(e->BuildConnVal());
      47                 :          0 :         vl->append(pX509Cert);
      48                 :          0 :         vl->append(new Val(e->IsOrig(), TYPE_BOOL));
      49                 :            : 
      50                 :          0 :         e->Conn()->ConnectionEvent(event, e, vl);
      51                 :            :         }
      52                 :            : 
      53                 :          0 : void X509_Cert::sslCertificateError(Contents_SSL* e, int error_numbe)
      54                 :            :         {
      55                 :          0 :         Val* err_str = new StringVal(X509_verify_cert_error_string(csc.error));
      56                 :          0 :         val_list* vl = new val_list;
      57                 :            : 
      58                 :          0 :         vl->append(e->BuildConnVal());
      59                 :          0 :         vl->append(new Val(csc.error, TYPE_INT));
      60                 :          0 :         vl->append(err_str);
      61                 :            : 
      62                 :          0 :         e->Conn()->ConnectionEvent(ssl_X509_error, e, vl);
      63                 :          0 :         }
      64                 :            : 
      65                 :          0 : int X509_Cert::init()
      66                 :            :         {
      67                 :            : #if 0
      68                 :            :         OpenSSL_add_all_algorithms();
      69                 :            : #endif
      70                 :            : 
      71                 :          0 :         ctx = X509_STORE_new();
      72                 :          0 :         int flag = 0;
      73                 :          0 :         int ret = 0;
      74                 :            : 
      75   [ #  #  #  # ]:          0 :         if ( x509_trusted_cert_path &&
                 [ #  # ]
      76                 :            :              x509_trusted_cert_path->AsString()->Len() > 0 )
      77                 :            :                 { // add the path(s) for the local CA's certificates
      78                 :          0 :                 const BroString* pString = x509_trusted_cert_path->AsString();
      79                 :            : 
      80                 :          0 :                 lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
      81         [ #  # ]:          0 :                 if ( ! lookup )
      82                 :            :                         {
      83                 :          0 :                         fprintf(stderr, "X509_Cert::init(): initing lookup failed\n");
      84                 :          0 :                         flag = 1;
      85                 :            :                         }
      86                 :            : 
      87                 :          0 :                 int i = X509_LOOKUP_add_dir(lookup,
      88                 :            :                                 (const char*) pString->Bytes(),
      89                 :            :                                 X509_FILETYPE_PEM);
      90         [ #  # ]:          0 :                 if ( ! i )
      91                 :            :                         {
      92                 :          0 :                         fprintf( stderr, "X509_Cert::init(): error adding lookup directory\n" );
      93                 :          0 :                         ret = 0;
      94                 :            :                         }
      95                 :            :                 }
      96                 :            :         else
      97                 :            :                 {
      98                 :          0 :                 printf("X509: Using the default trusted cert path.\n");
      99                 :          0 :                 X509_STORE_set_default_paths(ctx);
     100                 :            :                 }
     101                 :            : 
     102                 :            :         // Add crl functionality - will only add if defined and
     103                 :            :         // X509_STORE_add_lookup was successful.
     104 [ #  # ][ #  # ]:          0 :         if ( ! flag && x509_crl_file && x509_crl_file->AsString()->Len() > 0 )
         [ #  # ][ #  # ]
     105                 :            :                 {
     106                 :          0 :                 const BroString* rString = x509_crl_file->AsString();
     107                 :            : 
     108         [ #  # ]:          0 :                 if ( X509_load_crl_file(lookup, (const char*) rString->Bytes(),
     109                 :            :                                         X509_FILETYPE_PEM) != 1 )
     110                 :            :                         {
     111                 :          0 :                         fprintf(stderr, "X509_Cert::init(): error reading CRL file\n");
     112                 :          0 :                         ret = 1;
     113                 :            :                         }
     114                 :            : 
     115                 :            : #if 0
     116                 :            :                 // Note, openssl version must be > 0.9.7(a).
     117                 :            :                 X509_STORE_set_flags(ctx,
     118                 :            :                         X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
     119                 :            : #endif
     120                 :            :                 }
     121                 :            : 
     122                 :          0 :         bInited = true;
     123                 :          0 :         return ret;
     124                 :            :         }
     125                 :            : 
     126                 :          0 : int X509_Cert::verify(Contents_SSL* e, const u_char* data, uint32 len)
     127                 :            :         {
     128         [ #  # ]:          0 :         if ( ! bInited )
     129                 :          0 :                 init();
     130                 :            : 
     131                 :          0 :         X509* pCert = d2i_X509_(NULL, &data, len);
     132         [ #  # ]:          0 :         if ( ! pCert )
     133                 :            :                 {
     134                 :            :                 // 5 = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
     135                 :          0 :                 sslCertificateError(e, 5);
     136                 :          0 :                 return -1;
     137                 :            :                 }
     138                 :            : 
     139                 :          0 :         sslCertificateEvent(e, pCert);
     140                 :            : 
     141                 :          0 :         X509_STORE_CTX_init(&csc, ctx, pCert, 0);
     142                 :          0 :         X509_STORE_CTX_set_time(&csc, 0, (time_t) network_time);
     143                 :          0 :         int i = X509_verify_cert(&csc);
     144                 :          0 :         X509_STORE_CTX_cleanup(&csc);
     145                 :          0 :         int ret = 0;
     146                 :            : 
     147                 :          0 :         int ext = X509_get_ext_count(pCert);
     148                 :            : 
     149         [ #  # ]:          0 :         if ( ext > 0 )
     150                 :            :                 {
     151                 :          0 :                 TableVal* x509ex = new TableVal(x509_extension);
     152                 :          0 :                 val_list* vl = new val_list;
     153                 :            :                 char buf[256];
     154                 :            : 
     155         [ #  # ]:          0 :                 for ( int k = 0; k < ext; ++k )
     156                 :            :                         {
     157                 :          0 :                         X509_EXTENSION* ex = X509_get_ext(pCert, k);
     158                 :          0 :                         ASN1_OBJECT* obj = X509_EXTENSION_get_object(ex);
     159                 :          0 :                         i2t_ASN1_OBJECT(buf, sizeof(buf), obj);
     160                 :            : 
     161                 :          0 :                         Val* index = new Val(k+1, TYPE_COUNT);
     162                 :          0 :                         Val* value = new StringVal(strlen(buf), buf);
     163                 :          0 :                         x509ex->Assign(index, value);
     164                 :          0 :                         Unref(index);
     165                 :            :                         // later we can do critical extensions like:
     166                 :            :                         // X509_EXTENSION_get_critical(ex);
     167                 :            :                         }
     168                 :            : 
     169                 :          0 :                 vl->append(e->BuildConnVal());
     170                 :          0 :                 vl->append(x509ex);
     171                 :          0 :                 e->Conn()->ConnectionEvent(process_X509_extensions, e, vl);
     172                 :            :                 }
     173                 :            : 
     174         [ #  # ]:          0 :         if ( ! i )
     175                 :            :                 {
     176                 :          0 :                 sslCertificateError(e, csc.error);
     177                 :          0 :                 ret = csc.error;
     178                 :            :                 }
     179                 :            :         else
     180                 :          0 :                 ret = 0;
     181                 :            : 
     182                 :          0 :         delete pCert;
     183                 :          0 :         return ret;
     184                 :            :         }
     185                 :            : 
     186                 :          0 : int X509_Cert::verifyChain(Contents_SSL* e, const u_char* data, uint32 len)
     187                 :            :         {
     188         [ #  # ]:          0 :         if ( ! bInited )
     189                 :          0 :                 init();
     190                 :            : 
     191                 :            :         // Gets an ssl3x cert chain (could be one single cert, too,
     192                 :            :         // but in chain format).
     193                 :            : 
     194                 :            :         // Init the stack.
     195                 :          0 :         STACK_OF(X509)* untrustedCerts = sk_X509_new_null();
     196         [ #  # ]:          0 :         if ( ! untrustedCerts )
     197                 :            :                 {
     198                 :            :                 // Internal error allocating stack of untrusted certs.
     199                 :            :                 // 11 = X509_V_ERR_OUT_OF_MEM
     200                 :          0 :                 sslCertificateError(e, 11);
     201                 :          0 :                 return -1;
     202                 :            :                 }
     203                 :            : 
     204                 :            :         // NOT AGAIN!!!
     205                 :            :         // Extract certificates and put them into an OpenSSL Stack.
     206                 :          0 :         uint tempLength = 0;
     207                 :          0 :         int certCount = 0;
     208                 :          0 :         X509* pCert = 0; // base cert, this one is to be verified
     209                 :            : 
     210         [ #  # ]:          0 :         while ( tempLength < len )
     211                 :            :                 {
     212                 :          0 :                 ++certCount;
     213                 :            :                 uint32 certLength =
     214                 :            :                         uint32((data[tempLength + 0] << 16) |
     215                 :            :                                data[tempLength + 1] << 8) |
     216                 :          0 :                         data[tempLength + 2];
     217                 :            : 
     218                 :            :                 // Points to current cert.
     219                 :          0 :                 const u_char* pCurrentCert = &data[tempLength+3];
     220                 :            : 
     221                 :          0 :                 X509* pTemp = d2i_X509_(0, &pCurrentCert, certLength);
     222         [ #  # ]:          0 :                 if ( ! pTemp )
     223                 :            :                         { // error is somewhat of a misnomer
     224                 :            :                         // 5 = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
     225                 :          0 :                         sslCertificateError(e, 5);
     226                 :            :                         //FIXME: free ptrs
     227                 :          0 :                         return -1;
     228                 :            :                         }
     229                 :            : 
     230         [ #  # ]:          0 :                 if ( certCount == 1 )
     231                 :            :                         // The first certificate goes directly into the ctx.
     232                 :          0 :                         pCert = pTemp;
     233                 :            :                 else
     234                 :            :                         // The remaining certificates (if any) are put into
     235                 :            :                         // the list of untrusted certificates
     236                 :          0 :                         sk_X509_push(untrustedCerts, pTemp);
     237                 :            : 
     238                 :          0 :                 tempLength += certLength + 3;
     239                 :            :                 }
     240                 :            : 
     241                 :          0 :         sslCertificateEvent(e, pCert);
     242                 :            : 
     243                 :          0 :         X509_STORE_CTX_init(&csc, ctx, pCert, untrustedCerts);
     244                 :          0 :         X509_STORE_CTX_set_time(&csc, 0, (time_t) network_time);
     245                 :          0 :         int i = X509_verify_cert(&csc);
     246                 :          0 :         X509_STORE_CTX_cleanup(&csc);
     247                 :            :         //X509_STORE_CTX_free(&csc);
     248                 :          0 :         int ret = 0;
     249                 :            : 
     250         [ #  # ]:          0 :         if ( ! i )
     251                 :            :                 {
     252                 :          0 :                 sslCertificateError(e, csc.error);
     253                 :          0 :                 ret = csc.error;
     254                 :            :                 }
     255                 :            :         else
     256                 :          0 :                 ret = 0;
     257                 :            : 
     258                 :          0 :         delete pCert;
     259                 :            :         // Free the stack, incuding. contents.
     260                 :            : 
     261                 :            :         // FIXME: could this break Bro's memory tracking?
     262                 :          0 :         sk_X509_pop_free(untrustedCerts, X509_free);
     263                 :            : 
     264                 :          0 :         return ret;
     265 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8