cryptoservices/certificateandkeymgmt/recog/CertRecog.cpp
changeset 8 35751d3474b7
parent 0 2c201484c85f
--- a/cryptoservices/certificateandkeymgmt/recog/CertRecog.cpp	Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/recog/CertRecog.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -1,373 +1,374 @@
-/*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "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: 
-*
-*/
-
-
-#include <apmrec.h>
-#include <apmstd.h>
-#include <asn1cons.h>
-#include <ecom/ecom.h>
-#include <ecom/implementationproxy.h>
-
-#include "CertRecog.h"
-#include "x509cert.h"
-#include "x509certext.h"
-
-
-
-const TInt KCertificateRecognizerValue = 0x101F4A71;
-const TUid KUidMimeCertRecognizer = { KCertificateRecognizerValue };
-
-// User certs
-_LIT8( KDataTypeWAPCertificateResponse, "application/vnd.wap.cert-response" );
-_LIT8( KDataTypeX509_USER_Certificate, "application/x-x509-user-cert" );
-
-// CA certs
-_LIT8( KDataTypeX509_CA_Certificate, "application/x-x509-ca-cert" );
-_LIT8( KDataTypeWAP_WTLS_CA_Certificate, "application/vnd.wap.wtls-ca-certificate" );
-
-const TInt KSupportedDataTypesTotal = 3;
-
-const TInt KX509MinBufferLength = 30;
-const TInt KCertRecMaxBufferLength = 80;
-
-const TInt KASN1SequenceTagValue = 0x30;
-const TInt KASN1SequenceTwoBytesLength = 0x82;
-const TInt KASN1SequenceThreeBytesLength = 0x83;
-const TInt KASN1VersionWrapperTagValue = 0xA0;
-const TInt KASN1VersionWrapperLengthValue = 0x03;
-const TInt KASN1VersionLengthValue = 0x01;
-enum { EX509VersionValue1 = 0x00, EX509VersionValue2 = 0x01, EX509VersionValue3 = 0x02 };
-const TInt KWTLSCertificateVersionValue = 0x01;
-
-
-
-// ----------------------------------------------------------------------------
-// CApaCertificateRecognizer
-//
-
-CApaCertificateRecognizer::CApaCertificateRecognizer()
-	: CApaDataRecognizerType( KUidMimeCertRecognizer, CApaDataRecognizerType::ENormal )
-	{
-	iCountDataTypes = KSupportedDataTypesTotal;
-	}
-
-
-
-TUint CApaCertificateRecognizer::PreferredBufSize()
-	{
-	return KCertRecMaxBufferLength;
-	}
-
-
-
-TDataType CApaCertificateRecognizer::SupportedDataTypeL( TInt aIndex ) const
-	{
-	__ASSERT_DEBUG( aIndex >= 0 && aIndex < KSupportedDataTypesTotal,
-					User::Panic( _L("RECCERT"), 0 ) );
-	switch ( aIndex )
-		{
-		case 0:
-			return TDataType( KDataTypeX509_CA_Certificate );
-		case 1:
-			return TDataType( KDataTypeWAP_WTLS_CA_Certificate );
-		// Used to prevent warning about return paths not all returning a value
-		default:
-			return TDataType( KDataTypeWAPCertificateResponse );
-		}
-	}
-
-
-
-void CApaCertificateRecognizer::DoRecognizeL( const TDesC& aName, const TDesC8& aBuffer )
-	{
- 	
- 	RFile* filePtr = FilePassedByHandleL();
- 	if (filePtr)
- 		{
- 		ReadFileAndRecognizeL(*filePtr);
- 		return;	
- 		}
- 	
- 	//Connect to file server
- 	RFs fs;
- 	User::LeaveIfError(fs.Connect());	
- 	CleanupClosePushL(fs);
- 	
- 	// See if the data is passed by filename
- 	RFile fileToRead;	
- 	TInt ret = fileToRead.Open(fs, aName, EFileRead | EFileShareReadersOnly | EFileStream);
- 	CleanupClosePushL(fileToRead);
- 	if (ret == KErrNone)
- 		{
- 		//Try the preferred buffer size first
- 		ReadFileAndRecognizeL(fileToRead);
- 		}
- 	else
- 		// If not passed by file name, can try to recognize buffer.
- 		{
- 		DoRecognizeBufferL(aBuffer, EFalse, fileToRead);
- 		}
- 	
- 	CleanupStack::PopAndDestroy(2); //fileToRead, fs		
- 	
- 	}
-
-void CApaCertificateRecognizer::ReadFileAndRecognizeL(RFile& aFileToRead)
- 	{
- 	TInt size=PreferredBufSize();
- 	HBufC8* memForFile = HBufC8::NewLC(size);
- 	TPtr8 preferredBuffer(memForFile->Des());
- 	User::LeaveIfError(aFileToRead.Read(preferredBuffer, size));
- 	DoRecognizeBufferL(preferredBuffer, ETrue, aFileToRead);		
- 	CleanupStack::PopAndDestroy(memForFile); //memForFile	
- 	}
- 
-void CApaCertificateRecognizer::DoRecognizeBufferL(const TDesC8& aBuffer,  TBool aIsFile, RFile& aFile)
-	{
-	// Ensure length is sufficient for checking type
-   	if ( aBuffer.Size() >= 1 )
-   		{
-   		// First byte of X.509 certificate is an ANS.1 SEQUENCE tag
-   		if ( aBuffer[0] == KASN1SequenceTagValue )
-   			{
-  			RecognizeX509CertL( aBuffer, aIsFile, aFile);
-   			}
-   		// First byte of WTLS certificate is version == 1
-   		else if ( aBuffer[0] == KWTLSCertificateVersionValue )
-   			{
-  			RecognizeWTLSCertOrCertResponse( aBuffer, aIsFile, aFile);
-   			}
-  		
- 		}						
-   	}
-
-void CApaCertificateRecognizer::RecognizeX509CertL( const TDesC8& aBuffer,  TBool aIsFile, RFile& aFile )
-		{
-
-	//Basic check if this is a X509 certificate
-	TBool isCertV1orV2(EFalse);
-	TInt bufferSize = aBuffer.Size();
-	if ( bufferSize < KX509MinBufferLength )
-		{
-		return;
-		}
-	TInt index = 1;
-	// Check first sequence length byte and skip over the length value bytes
-	if ( aBuffer[index] == KASN1SequenceTwoBytesLength )
-		{
-		index += 3;
-		}
-	else if ( aBuffer[index] == KASN1SequenceThreeBytesLength )
-		{
-		index += 4;
-		}
-	else
-		{
-		return;
-		}
-	// Check next byte that is another sequence start
-	if ( aBuffer[index] != KASN1SequenceTagValue )
-		{
-		return;
-		}
-	++index;
-	// Check second sequence length byte and skip over the length value bytes
-	if ( aBuffer[index] == KASN1SequenceTwoBytesLength )
-		{
-		index += 3;
-		}
-	else if ( aBuffer[index] == KASN1SequenceThreeBytesLength )
-		{
-		index += 4;
-		}
-	else
-		{
-		return;
-		}
-	// Check for VERSION field
-	if ( aBuffer[index] == KASN1VersionWrapperTagValue )
-		{
-		++index;
-		if ( aBuffer[index] != KASN1VersionWrapperLengthValue )
-			{
-			return;
-			}
-		++index;
-		if ( aBuffer[index] != EASN1Integer )
-			{
-			return;
-			}
-		++index;
-		if ( aBuffer[index] != KASN1VersionLengthValue )
-			{
-			return;
-			}
-		++index;
-
-		// The cert is X509 v1 or v2
- 		if (aBuffer[index] == EX509VersionValue1 ||
- 		    aBuffer[index] == EX509VersionValue2)
-		    {
-		    isCertV1orV2=ETrue;
-		    }
-		else
-	 	   // The cert is neither X509 v1 nor v2
- 		    {
- 		   // The cert is not v3 as well 
- 		   if (aBuffer[index] != EX509VersionValue3)
- 			{
- 			return;	
-			}
- 		    }		
-
-		++index;
-		}
-	else
-		{
-		isCertV1orV2=ETrue;	
-		}
-	// Check for SerialNumber field
-	if ( aBuffer[index] != EASN1Integer )
-		{
-		return;
-		}
-	++index;
-	TInt serialNumberSize = aBuffer[index];
-	++index;
-	index += serialNumberSize;
-	// 1 is added for the next increments of index
-	if((index + 1) >= bufferSize)
-		{
-		return;
-		}
-	// Check for SIGNATURE field
-	if ( aBuffer[index] != KASN1SequenceTagValue )
-		{
-		return;
-		}
-	++index;
-	TInt signatureSize = aBuffer[index];
-	++index;
-	index += signatureSize;
-	if(index >= bufferSize)
-		{
-		return;
-		}
-	 	
- 	// if the certificate is passed by the buffer, but not file name 
- 	if (!aIsFile)	
- 		{
- 		// Check only the starting TAG byte of the NAME field
- 		if ( aBuffer[index] == KASN1SequenceTagValue )
- 			{
- 			iDataType = TDataType( KDataTypeX509_CA_Certificate );
- 			iConfidence = EProbable;
- 			}			
- 		}
- 	else
- 		// if the certificate is passed by file name
-		{
-		if (!isCertV1orV2) // x509 V3 certificate
- 			{ 
- 			//Get the file size
- 			TInt size;
- 			User::LeaveIfError(aFile.Size(size));
- 			HBufC8* memForFile = HBufC8::NewLC(size);
- 			TPtr8 fileContent(memForFile->Des());
- 			TInt pos=0;
- 			aFile.Seek(ESeekStart, pos);
- 			User::LeaveIfError(aFile.Read(fileContent, size));
- 			RecognizeWholeX509CertificateL(fileContent);
- 			CleanupStack::PopAndDestroy(memForFile);//memForFile
-			}									
- 		else  // x509 V1 or V2 certificate
- 			{ 
- 			iDataType = TDataType( KDataTypeX509_CA_Certificate );
- 			iConfidence = EProbable;				
- 			}
-	
-		}
-	}
-
-void CApaCertificateRecognizer::RecognizeWholeX509CertificateL(const TDesC8& aBuffer)
- 	{
- 	CX509Certificate* cert = CX509Certificate::NewLC(aBuffer);
- 	if (cert)
- 		{
- 		const CX509CertExtension* certExt = cert->Extension(KBasicConstraints);
- 		if (certExt)
- 			{
- 			CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC(certExt->Data());
- 			if (basic->IsCA())
- 				{
- 				iDataType = TDataType( KDataTypeX509_CA_Certificate );
- 				iConfidence = EProbable;					
- 				}
- 			else
- 				{
- 				iDataType = TDataType( KDataTypeX509_USER_Certificate );
- 				iConfidence = EProbable;										
- 				}
- 			CleanupStack::PopAndDestroy(basic); //basic				
-			}
- 		else
- 			{
- 			iDataType = TDataType( KDataTypeX509_USER_Certificate );
- 			iConfidence = EProbable;														
- 			}
- 		}
- 	CleanupStack::PopAndDestroy(cert); //cert
- 	}
-
-
-
-void CApaCertificateRecognizer::RecognizeWTLSCertOrCertResponse( const TDesC8& aBuffer, TBool /*aIsFile*/, RFile& /*aFile*/ )
-	{
-	if ( aBuffer.Size() >= 3 )
-		{
-		// Check next byte is signature algorithm value from 0 - 2
-		if ( aBuffer[1] == 0x00 || aBuffer[1] == 0x01 || aBuffer[1] == 0x02 )
-			{
-			// Check Identifier Type for Issuer Identifier
-			if ( aBuffer[2] == 0x01 )
-				{
-				iDataType = TDataType( KDataTypeWAP_WTLS_CA_Certificate );
-				}
-			else
-				{
-				iDataType = TDataType( KDataTypeWAPCertificateResponse );
-				}
-			iConfidence = EPossible;
-			}
-		}
-	}
-
-CApaDataRecognizerType* CApaCertificateRecognizer::CreateRecognizerL()
-	{
-	return new (ELeave) CApaCertificateRecognizer();
-	}
-
-const TImplementationProxy ImplementationTable[] = 
-	{
-		IMPLEMENTATION_PROXY_ENTRY(0x102034A2, CApaCertificateRecognizer::CreateRecognizerL)
-	};
-
-EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
-	{
-	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
-	return ImplementationTable;
-	}	
+/*
+* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+*
+*/
+
+
+#include <apmrec.h>
+#include <apmstd.h>
+#include <asn1cons.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+
+#include "CertRecog.h"
+#include "x509cert.h"
+#include "x509certext.h"
+
+
+
+const TInt KCertificateRecognizerValue = 0x101F4A71;
+const TUid KUidMimeCertRecognizer = { KCertificateRecognizerValue };
+
+// User certs
+_LIT8( KDataTypeWAPCertificateResponse, "application/vnd.wap.cert-response" );
+_LIT8( KDataTypeX509_USER_Certificate, "application/x-x509-user-cert" );
+
+// CA certs
+_LIT8( KDataTypeX509_CA_Certificate, "application/x-x509-ca-cert" );
+_LIT8( KDataTypeWAP_WTLS_CA_Certificate, "application/vnd.wap.wtls-ca-certificate" );
+
+const TInt KSupportedDataTypesTotal = 3;
+
+const TInt KX509MinBufferLength = 30;
+const TInt KCertRecMaxBufferLength = 80;
+
+const TInt KASN1SequenceTagValue = 0x30;
+const TInt KASN1SequenceTwoBytesLength = 0x82;
+const TInt KASN1SequenceThreeBytesLength = 0x83;
+const TInt KASN1VersionWrapperTagValue = 0xA0;
+const TInt KASN1VersionWrapperLengthValue = 0x03;
+const TInt KASN1VersionLengthValue = 0x01;
+enum { EX509VersionValue1 = 0x00, EX509VersionValue2 = 0x01, EX509VersionValue3 = 0x02 };
+const TInt KWTLSCertificateVersionValue = 0x01;
+
+
+
+// ----------------------------------------------------------------------------
+// CApaCertificateRecognizer
+//
+
+CApaCertificateRecognizer::CApaCertificateRecognizer()
+	: CApaDataRecognizerType( KUidMimeCertRecognizer, CApaDataRecognizerType::ENormal )
+	{
+	iCountDataTypes = KSupportedDataTypesTotal;
+	}
+
+
+
+TUint CApaCertificateRecognizer::PreferredBufSize()
+	{
+	return KCertRecMaxBufferLength;
+	}
+
+
+
+TDataType CApaCertificateRecognizer::SupportedDataTypeL( TInt aIndex ) const
+	{
+	__ASSERT_DEBUG( aIndex >= 0 && aIndex < KSupportedDataTypesTotal,
+					User::Panic( _L("RECCERT"), 0 ) );
+	switch ( aIndex )
+		{
+		case 0:
+			return TDataType( KDataTypeX509_CA_Certificate );
+		case 1:
+			return TDataType( KDataTypeWAP_WTLS_CA_Certificate );
+		// Used to prevent warning about return paths not all returning a value
+		default:
+			return TDataType( KDataTypeWAPCertificateResponse );
+		}
+	}
+
+
+
+void CApaCertificateRecognizer::DoRecognizeL( const TDesC& aName, const TDesC8& aBuffer )
+	{
+ 	
+ 	RFile* filePtr = FilePassedByHandleL();
+ 	if (filePtr)
+ 		{
+ 		ReadFileAndRecognizeL(*filePtr);
+ 		return;	
+ 		}
+ 	
+ 	//Connect to file server
+ 	RFs fs;
+ 	User::LeaveIfError(fs.Connect());	
+ 	CleanupClosePushL(fs);
+ 	
+ 	// See if the data is passed by filename
+ 	RFile fileToRead;	
+ 	TInt ret = fileToRead.Open(fs, aName, EFileRead | EFileShareReadersOnly | EFileStream);
+ 	CleanupClosePushL(fileToRead);
+ 	if (ret == KErrNone)
+ 		{
+ 		//Try the preferred buffer size first
+ 		ReadFileAndRecognizeL(fileToRead);
+ 		}
+ 	else
+ 		// If not passed by file name, can try to recognize buffer.
+ 		{
+ 		DoRecognizeBufferL(aBuffer, EFalse, fileToRead);
+ 		}
+ 	
+ 	CleanupStack::PopAndDestroy(2); //fileToRead, fs		
+ 	
+ 	}
+
+void CApaCertificateRecognizer::ReadFileAndRecognizeL(RFile& aFileToRead)
+ 	{
+ 	TInt size=PreferredBufSize();
+ 	HBufC8* memForFile = HBufC8::NewLC(size);
+ 	TPtr8 preferredBuffer(memForFile->Des());
+ 	User::LeaveIfError(aFileToRead.Read(preferredBuffer, size));
+ 	DoRecognizeBufferL(preferredBuffer, ETrue, aFileToRead);		
+ 	CleanupStack::PopAndDestroy(memForFile); //memForFile	
+ 	}
+ 
+void CApaCertificateRecognizer::DoRecognizeBufferL(const TDesC8& aBuffer,  TBool aIsFile, RFile& aFile)
+	{
+	// Ensure length is sufficient for checking type
+   	if ( aBuffer.Size() >= 1 )
+   		{
+   		// First byte of X.509 certificate is an ANS.1 SEQUENCE tag
+   		if ( aBuffer[0] == KASN1SequenceTagValue )
+   			{
+  			RecognizeX509CertL( aBuffer, aIsFile, aFile);
+   			}
+   		// First byte of WTLS certificate is version == 1
+   		else if ( aBuffer[0] == KWTLSCertificateVersionValue )
+   			{
+  			RecognizeWTLSCertOrCertResponse( aBuffer, aIsFile, aFile);
+   			}
+  		
+ 		}						
+   	}
+
+void CApaCertificateRecognizer::RecognizeX509CertL( const TDesC8& aBuffer,  TBool aIsFile, RFile& aFile )
+		{
+
+	//Basic check if this is a X509 certificate
+	TBool isCertV1orV2(EFalse);
+	TInt bufferSize = aBuffer.Size();
+	if ( bufferSize < KX509MinBufferLength )
+		{
+		return;
+		}
+	TInt index = 1;
+	// Check first sequence length byte and skip over the length value bytes
+	if ( aBuffer[index] == KASN1SequenceTwoBytesLength )
+		{
+		index += 3;
+		}
+	else if ( aBuffer[index] == KASN1SequenceThreeBytesLength )
+		{
+		index += 4;
+		}
+	else
+		{
+		return;
+		}
+	// Check next byte that is another sequence start
+	if ( aBuffer[index] != KASN1SequenceTagValue )
+		{
+		return;
+		}
+	++index;
+	// Check second sequence length byte and skip over the length value bytes
+	if ( aBuffer[index] == KASN1SequenceTwoBytesLength )
+		{
+		index += 3;
+		}
+	else if ( aBuffer[index] == KASN1SequenceThreeBytesLength )
+		{
+		index += 4;
+		}
+	else
+		{
+		return;
+		}
+	// Check for VERSION field
+	if ( aBuffer[index] == KASN1VersionWrapperTagValue )
+		{
+		++index;
+		if ( aBuffer[index] != KASN1VersionWrapperLengthValue )
+			{
+			return;
+			}
+		++index;
+		if ( aBuffer[index] != EASN1Integer )
+			{
+			return;
+			}
+		++index;
+		if ( aBuffer[index] != KASN1VersionLengthValue )
+			{
+			return;
+			}
+		++index;
+
+		// The cert is X509 v1 or v2
+ 		if (aBuffer[index] == EX509VersionValue1 ||
+ 		    aBuffer[index] == EX509VersionValue2)
+		    {
+		    isCertV1orV2=ETrue;
+		    }
+		else
+	 	   // The cert is neither X509 v1 nor v2
+ 		    {
+ 		   // The cert is not v3 as well 
+ 		   if (aBuffer[index] != EX509VersionValue3)
+ 			{
+ 			return;	
+			}
+ 		    }		
+
+		++index;
+		}
+	else
+		{
+		isCertV1orV2=ETrue;	
+		}
+	// Check for SerialNumber field
+	if ( aBuffer[index] != EASN1Integer )
+		{
+		return;
+		}
+	++index;
+	TInt serialNumberSize = aBuffer[index];
+	++index;
+	index += serialNumberSize;
+	// 1 is added for the next increments of index
+	if((index + 1) >= bufferSize)
+		{
+		return;
+		}
+	// Check for SIGNATURE field
+	if ( aBuffer[index] != KASN1SequenceTagValue )
+		{
+		return;
+		}
+	++index;
+	TInt signatureSize = aBuffer[index];
+	++index;
+	index += signatureSize;
+	if(index >= bufferSize)
+		{
+		return;
+		}
+	 	
+ 	// if the certificate is passed by the buffer, but not file name 
+ 	if (!aIsFile)	
+ 		{
+ 		// Check only the starting TAG byte of the NAME field
+ 		if ( aBuffer[index] == KASN1SequenceTagValue )
+ 			{
+ 			iDataType = TDataType( KDataTypeX509_CA_Certificate );
+ 			iConfidence = EProbable;
+ 			}			
+ 		}
+ 	else
+ 		// if the certificate is passed by file name
+		{
+		if (!isCertV1orV2) // x509 V3 certificate
+ 			{ 
+ 			//Get the file size
+ 			TInt size;
+ 			User::LeaveIfError(aFile.Size(size));
+ 			HBufC8* memForFile = HBufC8::NewLC(size);
+ 			TPtr8 fileContent(memForFile->Des());
+ 			TInt pos=0;
+ 			aFile.Seek(ESeekStart, pos);
+ 			User::LeaveIfError(aFile.Read(fileContent, size));
+ 			RecognizeWholeX509CertificateL(fileContent);
+ 			CleanupStack::PopAndDestroy(memForFile);//memForFile
+			}									
+ 		else  // x509 V1 or V2 certificate
+ 			{ 
+ 			iDataType = TDataType( KDataTypeX509_CA_Certificate );
+ 			iConfidence = EProbable;				
+ 			}
+	
+		}
+	}
+
+void CApaCertificateRecognizer::RecognizeWholeX509CertificateL(const TDesC8& aBuffer)
+ 	{
+ 	CX509Certificate* cert = CX509Certificate::NewLC(aBuffer);
+ 	if (cert)
+ 		{
+ 		const CX509CertExtension* certExt = cert->Extension(KBasicConstraints);
+ 		if (certExt)
+ 			{
+ 			CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC(certExt->Data());
+ 			if (basic->IsCA())
+ 				{
+ 				iDataType = TDataType( KDataTypeX509_CA_Certificate );
+ 				iConfidence = EProbable;					
+ 				}
+ 			else
+ 				{
+ 				iDataType = TDataType( KDataTypeX509_USER_Certificate );
+ 				iConfidence = EProbable;										
+ 				}
+ 			CleanupStack::PopAndDestroy(basic); //basic				
+			}
+ 		else
+ 			{
+ 			iDataType = TDataType( KDataTypeX509_USER_Certificate );
+ 			iConfidence = EProbable;														
+ 			}
+ 		}
+ 	CleanupStack::PopAndDestroy(cert); //cert
+ 	}
+
+
+
+void CApaCertificateRecognizer::RecognizeWTLSCertOrCertResponse( const TDesC8& aBuffer, TBool /*aIsFile*/, RFile& /*aFile*/ )
+	{
+	if ( aBuffer.Size() >= 3 )
+		{
+		// Check next byte is signature algorithm value from 0 - 2
+		if ( aBuffer[1] == 0x00 || aBuffer[1] == 0x01 || aBuffer[1] == 0x02 )
+			{
+			// Check Identifier Type for Issuer Identifier
+			if ( aBuffer[2] == 0x01 )
+				{
+				iDataType = TDataType( KDataTypeWAP_WTLS_CA_Certificate );
+				}
+			else
+				{
+				iDataType = TDataType( KDataTypeWAPCertificateResponse );
+				}
+			iConfidence = EPossible;
+			}
+		}
+	}
+
+CApaDataRecognizerType* CApaCertificateRecognizer::CreateRecognizerL()
+	{
+	return new (ELeave) CApaCertificateRecognizer();
+	}
+
+const TImplementationProxy ImplementationTable[] = 
+	{
+		IMPLEMENTATION_PROXY_ENTRY(0x102034A2, CApaCertificateRecognizer::CreateRecognizerL)
+	};
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+	{
+	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+	return ImplementationTable;
+	}	
+