pkiutilities/CertSaver/src/certparser.cpp
changeset 0 164170e6151a
child 30 cc1cea6aabaf
child 49 09b1ac925e3f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkiutilities/CertSaver/src/certparser.cpp	Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,378 @@
+/*
+* Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   Implementation of CCertParser class
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <apmrec.h>
+#include <x509cert.h>
+#include <x509certext.h>
+#include <hash.h>
+#include <X509CertNameParser.h>
+#include <featmgr.h>
+#include <data_caging_path_literals.hrh>
+#include <AknQueryDialog.h>
+#include <CertSaver.rsg>
+#include <StringLoader.h>
+#include <securityerr.h>
+#include <aknnotewrappers.h>              // Note dialogs
+#include <apmrec.h>
+#include "certparser.h"
+
+// CONSTANTS
+_LIT( KPKCS12DllName, "crpkcs12.dll" );   // PKCS12 DLL name
+const TInt KX509Version3 = 3;
+const TInt KPwMaxLength = 32;
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// ==================== LOCAL FUNCTIONS ====================
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CCertParser::CCertParser()
+    {
+    }
+
+// EPOC default constructor can leave.
+void CCertParser::ConstructL()
+    {
+    }
+
+// Two-phased constructor.
+CCertParser* CCertParser::NewL()
+    {
+    CCertParser* self = new (ELeave) CCertParser;
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+
+// Destructor
+CCertParser::~CCertParser()
+    {
+    delete iCert;
+    if ( iPKCS12 )
+        {
+        iPKCS12->Release();
+        }
+    iLibrary.Close();
+    }
+
+// ----------------------------------------------------------
+// CCertParser::SetContentL()
+// Checks if given buffer is a WTLS or a X.509 certificate and
+// sets member data accordingly.
+// ----------------------------------------------------------
+//
+void CCertParser::SetContentL( RFile& aFile )
+    {
+    delete iCert;
+    iCert = NULL;
+    TInt fileSize = 0;
+    CleanupClosePushL( aFile );
+    User::LeaveIfError( aFile.Size( fileSize ) );
+
+    HBufC8* buffer = HBufC8::NewL( fileSize );
+    CleanupStack::PushL( buffer );
+
+    TPtr8 ptr8(buffer->Des());
+    User::LeaveIfError( aFile.Read( ptr8 ) );
+
+    if ( !CheckIfX509CertificateL( *buffer ) )
+        {
+        TFileName fileName;
+        User::LeaveIfError( aFile.Name( fileName ) );
+        if ( !CheckIfPKCS12L( *buffer, fileName ) )
+            {
+            iCertType = ETypeCorrupt;
+            }
+        }
+    CleanupStack::PopAndDestroy( buffer );
+    CleanupStack::PopAndDestroy( &aFile );
+    }
+
+// ----------------------------------------------------------
+// CCertParser::CreatePKCS12L()
+// Creates PKCS#12 DLL
+// ----------------------------------------------------------
+//
+void CCertParser::CreatePKCS12L()
+    {
+    // Load PKCS#12 dll
+#ifdef __WINS__
+    User::LeaveIfError ( iLibrary.Load( KPKCS12DllName ) );
+#else
+    User::LeaveIfError ( iLibrary.Load( KPKCS12DllName, KDC_SHARED_LIB_DIR ) );
+#endif
+
+    // Define the function that returns pointer to MPKCS12
+    typedef MPKCS12* ( *TLibraryFunc )();
+    // Find CreateL() method from pkcs12.dll that implements the function
+    TLibraryFunc createL =
+        reinterpret_cast<TLibraryFunc>( iLibrary.Lookup( 1 ) );
+    // Create new instance of MPKCS12
+    iPKCS12 = createL();
+    }
+
+// ----------------------------------------------------------
+// CCertParser::CheckIfPKCS12L()
+// Checks if PKCS#12 file
+// ----------------------------------------------------------
+//
+TBool CCertParser::CheckIfPKCS12L(
+    const TDesC8& aPKCS12,
+    const TDesC& aFileName )
+    {
+    CreatePKCS12L();
+
+    if ( !iPKCS12->IsPKCS12Data( aPKCS12 ) )
+        {
+        ShowErrorNoteL( R_CERTSAVER_PKCS12_FILE_CORRUPTED );
+        return EFalse;
+        }
+
+    TBool done = EFalse;
+    TBuf<KPwMaxLength> password;
+    HBufC* buffer = NULL;
+
+    if ( !iEikEnv )
+        {
+        iEikEnv = CEikonEnv::Static();
+        }
+
+    while ( !done )
+        {
+        if ( !GetPasswordL( password, aFileName ) )
+            {
+            buffer = iEikEnv->AllocReadResourceLC( R_CERTSAVER_PKCS12_DISCARDED );
+            CAknInformationNote* note = new (ELeave) CAknInformationNote( ETrue );
+            note->ExecuteLD(buffer->Des());
+            CleanupStack::PopAndDestroy( buffer );
+            User::Leave( KErrExitApp );
+            }
+        TRAPD( err, iPKCS12->ParseL( aPKCS12, password ) );
+        if ( err != KErrBadPassphrase )
+            {
+            switch ( err )
+                {
+                case KErrNone:
+                    {
+                    iCertType = ETypePKCS12;
+                    break;
+                    }
+                case KErrNoMemory:
+                    {
+                    User::Leave( KErrNoMemory );
+                    }
+                case KErrNotSupported:
+                    {
+                    ShowErrorNoteL( R_QTN_CM_PKCS12_FORMAT_NOT_SUPPORTED );
+                    break;
+                    }
+                default:
+                    {
+                    ShowErrorNoteL( R_CERTSAVER_PKCS12_FILE_CORRUPTED );
+                    break;
+                    }
+                }
+            if ( err != KErrNone )
+                {
+                return EFalse;
+                }
+            done = ETrue;
+            }
+        else
+            {
+            password.Zero();
+            // Show error note
+            ShowErrorNoteL( R_QTN_CM_INCORRECT_PASSWORD );
+            }
+        }
+    return ETrue;
+    }
+
+// ----------------------------------------------------------
+// CCertParser::GetPasswordL(...)
+//
+// ----------------------------------------------------------
+//
+TInt CCertParser::GetPasswordL( TDes& aPassword, const TDesC& aFileName )
+    {
+    CAknTextQueryDialog* query = CAknTextQueryDialog::NewL( aPassword );
+    CleanupStack::PushL( query );
+    HBufC* prompt =
+        StringLoader::LoadLC( R_QTN_CM_TITLE_P12_PASSWORD, aFileName );
+    query->SetPromptL( *prompt );
+    CleanupStack::PopAndDestroy( prompt );
+    CleanupStack::Pop( query );
+    return query->ExecuteLD( R_PKCS12_PW_QUERY_DIALOG );
+    }
+
+// ----------------------------------------------------------
+// CCertParser::CheckIfX509CertificateL()
+// Returns the type of the certificate.
+// ----------------------------------------------------------
+//
+TBool CCertParser::CheckIfX509CertificateL(const TDesC8& aCert)
+    {
+    TRAPD( err,
+           iCert = CX509Certificate::NewL(aCert);
+         );
+
+    if ( err != KErrNone )
+        {
+        iCertType = ETypeCorrupt;
+        if ( err == KErrNoMemory )
+            {
+            User::Leave( err );
+            }
+        else
+            {
+            return EFalse;
+            }
+        }
+
+  if ( iCert )
+      {
+      // Check certificate version
+      if ( iCert->Version() != KX509Version3 )
+          {
+          // X509 v1 or v2 certificate. Certificate type is CA
+          iCertType = ETypeX509CA;
+          }
+      else
+          {
+          // X509 v3 certificate. Check basicConstrains
+          const CX509CertExtension* certExt = iCert->Extension( KBasicConstraints );
+          if ( certExt )
+              {
+              CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC( certExt->Data() );
+              if ( basic->IsCA() )
+                  {
+                  iCertType = ETypeX509CA;
+                  }
+              else
+                  {
+                  iCertType = ETypeX509Peer;
+                  }
+              CleanupStack::PopAndDestroy( basic ); //basic
+              }
+           else
+              {
+              // No basicConstrains extension
+              iCertType = ETypeX509Peer;
+              }
+          }
+      }
+
+    return ETrue;
+    }
+
+// ----------------------------------------------------------
+// CCertParser::CACertificates()
+// ----------------------------------------------------------
+//
+const CArrayPtr<CX509Certificate>&  CCertParser::CACertificates() const
+    {
+    __ASSERT_ALWAYS( iPKCS12, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
+    return iPKCS12->CACertificates();
+    }
+
+// ----------------------------------------------------------
+// CCertParser::UserCertificates()
+// ----------------------------------------------------------
+//
+const CArrayPtr<CX509Certificate>&  CCertParser::UserCertificates() const
+    {
+    __ASSERT_ALWAYS( iPKCS12, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
+    return iPKCS12->UserCertificates();
+    }
+
+// ----------------------------------------------------------
+// CCertParser::Keys()
+// ----------------------------------------------------------
+//
+const CArrayPtr<HBufC8>& CCertParser::Keys() const
+    {
+    __ASSERT_ALWAYS( iPKCS12, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
+    return iPKCS12->PrivateKeys();
+    }
+
+// ----------------------------------------------------------
+// CCertParser::CertType()
+// ----------------------------------------------------------
+//
+ CCertParser::TCertType CCertParser::CertType() const
+    {
+    return iCertType;
+    }
+
+// ----------------------------------------------------------
+// CCertParser::CertificateBuf()
+// Returns the content of the certificate.
+// ----------------------------------------------------------
+//
+const TPtrC8 CCertParser::CertificateBuf() const
+    {
+    __ASSERT_ALWAYS( iCert, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
+    return iCert->Encoding();
+    }
+
+// ----------------------------------------------------------
+// CCertParser::Certificate()
+// Returns the X.509 certificate object.
+// ----------------------------------------------------------
+//
+const CX509Certificate& CCertParser::Certificate() const
+    {
+    __ASSERT_ALWAYS( iCert, User::Panic( KCertSaverPanic, KPanicNullPointer ) );
+    return *((CX509Certificate*)iCert);
+    }
+
+// ----------------------------------------------------------
+// CCertParser::ShowErrorNoteL() const
+// Creates and shows an error note.
+// ----------------------------------------------------------
+//
+void CCertParser::ShowErrorNoteL( TInt aResourceID )
+    {
+     if ( !iEikEnv )
+        {
+        iEikEnv = CEikonEnv::Static();
+        }
+    HBufC* buffer = iEikEnv->AllocReadResourceLC( aResourceID );
+    CAknErrorNote* note = new (ELeave) CAknErrorNote( ETrue );
+    note->ExecuteLD(buffer->Des());
+    CleanupStack::PopAndDestroy( buffer );
+    }
+
+//  End of File
+