--- /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
+