pkiutilities/CertSaver/src/certparser.cpp
changeset 0 164170e6151a
child 30 cc1cea6aabaf
child 49 09b1ac925e3f
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 /*
       
     2 * Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Implementation of CCertParser class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32std.h>
       
    21 #include <apmrec.h>
       
    22 #include <x509cert.h>
       
    23 #include <x509certext.h>
       
    24 #include <hash.h>
       
    25 #include <X509CertNameParser.h>
       
    26 #include <featmgr.h>
       
    27 #include <data_caging_path_literals.hrh>
       
    28 #include <AknQueryDialog.h>
       
    29 #include <CertSaver.rsg>
       
    30 #include <StringLoader.h>
       
    31 #include <securityerr.h>
       
    32 #include <aknnotewrappers.h>              // Note dialogs
       
    33 #include <apmrec.h>
       
    34 #include "certparser.h"
       
    35 
       
    36 // CONSTANTS
       
    37 _LIT( KPKCS12DllName, "crpkcs12.dll" );   // PKCS12 DLL name
       
    38 const TInt KX509Version3 = 3;
       
    39 const TInt KPwMaxLength = 32;
       
    40 
       
    41 // MACROS
       
    42 
       
    43 // LOCAL CONSTANTS AND MACROS
       
    44 
       
    45 // MODULE DATA STRUCTURES
       
    46 
       
    47 // LOCAL FUNCTION PROTOTYPES
       
    48 
       
    49 // ==================== LOCAL FUNCTIONS ====================
       
    50 
       
    51 // ================= MEMBER FUNCTIONS =======================
       
    52 
       
    53 // C++ default constructor can NOT contain any code, that
       
    54 // might leave.
       
    55 //
       
    56 CCertParser::CCertParser()
       
    57     {
       
    58     }
       
    59 
       
    60 // EPOC default constructor can leave.
       
    61 void CCertParser::ConstructL()
       
    62     {
       
    63     }
       
    64 
       
    65 // Two-phased constructor.
       
    66 CCertParser* CCertParser::NewL()
       
    67     {
       
    68     CCertParser* self = new (ELeave) CCertParser;
       
    69 
       
    70     CleanupStack::PushL( self );
       
    71     self->ConstructL();
       
    72     CleanupStack::Pop( self );
       
    73 
       
    74     return self;
       
    75     }
       
    76 
       
    77 
       
    78 // Destructor
       
    79 CCertParser::~CCertParser()
       
    80     {
       
    81     delete iCert;
       
    82     if ( iPKCS12 )
       
    83         {
       
    84         iPKCS12->Release();
       
    85         }
       
    86     iLibrary.Close();
       
    87     }
       
    88 
       
    89 // ----------------------------------------------------------
       
    90 // CCertParser::SetContentL()
       
    91 // Checks if given buffer is a WTLS or a X.509 certificate and
       
    92 // sets member data accordingly.
       
    93 // ----------------------------------------------------------
       
    94 //
       
    95 void CCertParser::SetContentL( RFile& aFile )
       
    96     {
       
    97     delete iCert;
       
    98     iCert = NULL;
       
    99     TInt fileSize = 0;
       
   100     CleanupClosePushL( aFile );
       
   101     User::LeaveIfError( aFile.Size( fileSize ) );
       
   102 
       
   103     HBufC8* buffer = HBufC8::NewL( fileSize );
       
   104     CleanupStack::PushL( buffer );
       
   105 
       
   106     TPtr8 ptr8(buffer->Des());
       
   107     User::LeaveIfError( aFile.Read( ptr8 ) );
       
   108 
       
   109     if ( !CheckIfX509CertificateL( *buffer ) )
       
   110         {
       
   111         TFileName fileName;
       
   112         User::LeaveIfError( aFile.Name( fileName ) );
       
   113         if ( !CheckIfPKCS12L( *buffer, fileName ) )
       
   114             {
       
   115             iCertType = ETypeCorrupt;
       
   116             }
       
   117         }
       
   118     CleanupStack::PopAndDestroy( buffer );
       
   119     CleanupStack::PopAndDestroy( &aFile );
       
   120     }
       
   121 
       
   122 // ----------------------------------------------------------
       
   123 // CCertParser::CreatePKCS12L()
       
   124 // Creates PKCS#12 DLL
       
   125 // ----------------------------------------------------------
       
   126 //
       
   127 void CCertParser::CreatePKCS12L()
       
   128     {
       
   129     // Load PKCS#12 dll
       
   130 #ifdef __WINS__
       
   131     User::LeaveIfError ( iLibrary.Load( KPKCS12DllName ) );
       
   132 #else
       
   133     User::LeaveIfError ( iLibrary.Load( KPKCS12DllName, KDC_SHARED_LIB_DIR ) );
       
   134 #endif
       
   135 
       
   136     // Define the function that returns pointer to MPKCS12
       
   137     typedef MPKCS12* ( *TLibraryFunc )();
       
   138     // Find CreateL() method from pkcs12.dll that implements the function
       
   139     TLibraryFunc createL =
       
   140         reinterpret_cast<TLibraryFunc>( iLibrary.Lookup( 1 ) );
       
   141     // Create new instance of MPKCS12
       
   142     iPKCS12 = createL();
       
   143     }
       
   144 
       
   145 // ----------------------------------------------------------
       
   146 // CCertParser::CheckIfPKCS12L()
       
   147 // Checks if PKCS#12 file
       
   148 // ----------------------------------------------------------
       
   149 //
       
   150 TBool CCertParser::CheckIfPKCS12L(
       
   151     const TDesC8& aPKCS12,
       
   152     const TDesC& aFileName )
       
   153     {
       
   154     CreatePKCS12L();
       
   155 
       
   156     if ( !iPKCS12->IsPKCS12Data( aPKCS12 ) )
       
   157         {
       
   158         ShowErrorNoteL( R_CERTSAVER_PKCS12_FILE_CORRUPTED );
       
   159         return EFalse;
       
   160         }
       
   161 
       
   162     TBool done = EFalse;
       
   163     TBuf<KPwMaxLength> password;
       
   164     HBufC* buffer = NULL;
       
   165 
       
   166     if ( !iEikEnv )
       
   167         {
       
   168         iEikEnv = CEikonEnv::Static();
       
   169         }
       
   170 
       
   171     while ( !done )
       
   172         {
       
   173         if ( !GetPasswordL( password, aFileName ) )
       
   174             {
       
   175             buffer = iEikEnv->AllocReadResourceLC( R_CERTSAVER_PKCS12_DISCARDED );
       
   176             CAknInformationNote* note = new (ELeave) CAknInformationNote( ETrue );
       
   177             note->ExecuteLD(buffer->Des());
       
   178             CleanupStack::PopAndDestroy( buffer );
       
   179             User::Leave( KErrExitApp );
       
   180             }
       
   181         TRAPD( err, iPKCS12->ParseL( aPKCS12, password ) );
       
   182         if ( err != KErrBadPassphrase )
       
   183             {
       
   184             switch ( err )
       
   185                 {
       
   186                 case KErrNone:
       
   187                     {
       
   188                     iCertType = ETypePKCS12;
       
   189                     break;
       
   190                     }
       
   191                 case KErrNoMemory:
       
   192                     {
       
   193                     User::Leave( KErrNoMemory );
       
   194                     }
       
   195                 case KErrNotSupported:
       
   196                     {
       
   197                     ShowErrorNoteL( R_QTN_CM_PKCS12_FORMAT_NOT_SUPPORTED );
       
   198                     break;
       
   199                     }
       
   200                 default:
       
   201                     {
       
   202                     ShowErrorNoteL( R_CERTSAVER_PKCS12_FILE_CORRUPTED );
       
   203                     break;
       
   204                     }
       
   205                 }
       
   206             if ( err != KErrNone )
       
   207                 {
       
   208                 return EFalse;
       
   209                 }
       
   210             done = ETrue;
       
   211             }
       
   212         else
       
   213             {
       
   214             password.Zero();
       
   215             // Show error note
       
   216             ShowErrorNoteL( R_QTN_CM_INCORRECT_PASSWORD );
       
   217             }
       
   218         }
       
   219     return ETrue;
       
   220     }
       
   221 
       
   222 // ----------------------------------------------------------
       
   223 // CCertParser::GetPasswordL(...)
       
   224 //
       
   225 // ----------------------------------------------------------
       
   226 //
       
   227 TInt CCertParser::GetPasswordL( TDes& aPassword, const TDesC& aFileName )
       
   228     {
       
   229     CAknTextQueryDialog* query = CAknTextQueryDialog::NewL( aPassword );
       
   230     CleanupStack::PushL( query );
       
   231     HBufC* prompt =
       
   232         StringLoader::LoadLC( R_QTN_CM_TITLE_P12_PASSWORD, aFileName );
       
   233     query->SetPromptL( *prompt );
       
   234     CleanupStack::PopAndDestroy( prompt );
       
   235     CleanupStack::Pop( query );
       
   236     return query->ExecuteLD( R_PKCS12_PW_QUERY_DIALOG );
       
   237     }
       
   238 
       
   239 // ----------------------------------------------------------
       
   240 // CCertParser::CheckIfX509CertificateL()
       
   241 // Returns the type of the certificate.
       
   242 // ----------------------------------------------------------
       
   243 //
       
   244 TBool CCertParser::CheckIfX509CertificateL(const TDesC8& aCert)
       
   245     {
       
   246     TRAPD( err,
       
   247            iCert = CX509Certificate::NewL(aCert);
       
   248          );
       
   249 
       
   250     if ( err != KErrNone )
       
   251         {
       
   252         iCertType = ETypeCorrupt;
       
   253         if ( err == KErrNoMemory )
       
   254             {
       
   255             User::Leave( err );
       
   256             }
       
   257         else
       
   258             {
       
   259             return EFalse;
       
   260             }
       
   261         }
       
   262 
       
   263   if ( iCert )
       
   264       {
       
   265       // Check certificate version
       
   266       if ( iCert->Version() != KX509Version3 )
       
   267           {
       
   268           // X509 v1 or v2 certificate. Certificate type is CA
       
   269           iCertType = ETypeX509CA;
       
   270           }
       
   271       else
       
   272           {
       
   273           // X509 v3 certificate. Check basicConstrains
       
   274           const CX509CertExtension* certExt = iCert->Extension( KBasicConstraints );
       
   275           if ( certExt )
       
   276               {
       
   277               CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC( certExt->Data() );
       
   278               if ( basic->IsCA() )
       
   279                   {
       
   280                   iCertType = ETypeX509CA;
       
   281                   }
       
   282               else
       
   283                   {
       
   284                   iCertType = ETypeX509Peer;
       
   285                   }
       
   286               CleanupStack::PopAndDestroy( basic ); //basic
       
   287               }
       
   288            else
       
   289               {
       
   290               // No basicConstrains extension
       
   291               iCertType = ETypeX509Peer;
       
   292               }
       
   293           }
       
   294       }
       
   295 
       
   296     return ETrue;
       
   297     }
       
   298 
       
   299 // ----------------------------------------------------------
       
   300 // CCertParser::CACertificates()
       
   301 // ----------------------------------------------------------
       
   302 //
       
   303 const CArrayPtr<CX509Certificate>&  CCertParser::CACertificates() const
       
   304     {
       
   305     __ASSERT_ALWAYS( iPKCS12, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
       
   306     return iPKCS12->CACertificates();
       
   307     }
       
   308 
       
   309 // ----------------------------------------------------------
       
   310 // CCertParser::UserCertificates()
       
   311 // ----------------------------------------------------------
       
   312 //
       
   313 const CArrayPtr<CX509Certificate>&  CCertParser::UserCertificates() const
       
   314     {
       
   315     __ASSERT_ALWAYS( iPKCS12, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
       
   316     return iPKCS12->UserCertificates();
       
   317     }
       
   318 
       
   319 // ----------------------------------------------------------
       
   320 // CCertParser::Keys()
       
   321 // ----------------------------------------------------------
       
   322 //
       
   323 const CArrayPtr<HBufC8>& CCertParser::Keys() const
       
   324     {
       
   325     __ASSERT_ALWAYS( iPKCS12, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
       
   326     return iPKCS12->PrivateKeys();
       
   327     }
       
   328 
       
   329 // ----------------------------------------------------------
       
   330 // CCertParser::CertType()
       
   331 // ----------------------------------------------------------
       
   332 //
       
   333  CCertParser::TCertType CCertParser::CertType() const
       
   334     {
       
   335     return iCertType;
       
   336     }
       
   337 
       
   338 // ----------------------------------------------------------
       
   339 // CCertParser::CertificateBuf()
       
   340 // Returns the content of the certificate.
       
   341 // ----------------------------------------------------------
       
   342 //
       
   343 const TPtrC8 CCertParser::CertificateBuf() const
       
   344     {
       
   345     __ASSERT_ALWAYS( iCert, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
       
   346     return iCert->Encoding();
       
   347     }
       
   348 
       
   349 // ----------------------------------------------------------
       
   350 // CCertParser::Certificate()
       
   351 // Returns the X.509 certificate object.
       
   352 // ----------------------------------------------------------
       
   353 //
       
   354 const CX509Certificate& CCertParser::Certificate() const
       
   355     {
       
   356     __ASSERT_ALWAYS( iCert, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
       
   357     return *((CX509Certificate*)iCert);
       
   358     }
       
   359 
       
   360 // ----------------------------------------------------------
       
   361 // CCertParser::ShowErrorNoteL() const
       
   362 // Creates and shows an error note.
       
   363 // ----------------------------------------------------------
       
   364 //
       
   365 void CCertParser::ShowErrorNoteL( TInt aResourceID )
       
   366     {
       
   367      if ( !iEikEnv )
       
   368         {
       
   369         iEikEnv = CEikonEnv::Static();
       
   370         }
       
   371     HBufC* buffer = iEikEnv->AllocReadResourceLC( aResourceID );
       
   372     CAknErrorNote* note = new (ELeave) CAknErrorNote( ETrue );
       
   373     note->ExecuteLD(buffer->Des());
       
   374     CleanupStack::PopAndDestroy( buffer );
       
   375     }
       
   376 
       
   377 //  End of File
       
   378