pkiutilities/PKCS12/CrPkcs12/Src/pkcs12.cpp
changeset 0 164170e6151a
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 /*
       
     2 * Copyright (c) 2004 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 the PKCS#12 parser API
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <securityerr.h>
       
    21 #include    "pkcs12.h"
       
    22 #include    "crpkcs12.h"
       
    23 //#include    <?include_file>
       
    24 
       
    25 // EXTERNAL DATA STRUCTURES
       
    26 //extern  ?external_data;
       
    27 
       
    28 // EXTERNAL FUNCTION PROTOTYPES  
       
    29 //extern ?external_function( ?arg_type,?arg_type );
       
    30 
       
    31 // CONSTANTS
       
    32 
       
    33 // ASN.1 tag values
       
    34 const TInt KASN1SequenceTagValue = 0x30;
       
    35 const TInt KASN1ImplicitConstructedTagValue = 0xA0;   // Implicit constructed tag
       
    36 const TInt KASN1OctetStringTagValue   = 0x04;     // Octet string tag
       
    37 const TInt KASN1BerConstructedBit = 0x20;
       
    38 
       
    39 _LIT8(KPKCS12Version3, "\x02\x01\x03");
       
    40 _LIT8(KPKCS7DataOID, "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x01");
       
    41 _LIT8(KPKC7EncryptedDataOID, "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x06");
       
    42 _LIT8(KSequenceTagInOctet,"\x04\x01\x30\x04\x01\x80");
       
    43 _LIT8(KMozillaPKCS7EncryptedDataOID, 
       
    44     "\x04\x01\x06\x04\x01\x09\x04\x09\x2a\x86\x48\x86\xf7\x0d\x01\x07\x06");
       
    45 _LIT8(KMozillaPKCS7DataOID, 
       
    46     "\x04\x01\x06\x04\x01\x09\x04\x09\x2a\x86\x48\x86\xf7\x0d\x01\x07\x01");
       
    47 
       
    48 // MACROS
       
    49 //#define ?macro ?macro_def
       
    50 
       
    51 // LOCAL CONSTANTS AND MACROS
       
    52 //const ?type ?constant_var = ?constant;
       
    53 //#define ?macro_name ?macro_def
       
    54 
       
    55 // MODULE DATA STRUCTURES
       
    56 //enum ?declaration
       
    57 //typedef ?declaration
       
    58 
       
    59 // LOCAL FUNCTION PROTOTYPES
       
    60 //?type ?function_name( ?arg_type, ?arg_type );
       
    61 
       
    62 // FORWARD DECLARATIONS
       
    63 //class ?FORWARD_CLASSNAME;
       
    64 
       
    65 // ============================ MEMBER FUNCTIONS ===============================
       
    66 
       
    67 // ---------------------------------------------------------
       
    68 // PKCS12Factory::CreateL
       
    69 // ---------------------------------------------------------
       
    70 //
       
    71 EXPORT_C MPKCS12* PKCS12Factory::CreateL()
       
    72     {
       
    73     return CPKCS12::NewL();
       
    74     }
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 // CPKCS12::CPKCS12
       
    78 // C++ default constructor can NOT contain any code, that
       
    79 // might leave.
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 CPKCS12::CPKCS12()
       
    83     {
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CPKCS12::ConstructL
       
    88 // Symbian 2nd phase constructor can leave.
       
    89 // -----------------------------------------------------------------------------
       
    90 //
       
    91 void CPKCS12::ConstructL()
       
    92     {        
       
    93     
       
    94     }
       
    95 
       
    96 // -----------------------------------------------------------------------------
       
    97 // CPKCS12::NewL
       
    98 // Two-phased constructor.
       
    99 // -----------------------------------------------------------------------------
       
   100 //
       
   101 CPKCS12* CPKCS12::NewL()
       
   102     {
       
   103     CPKCS12* self = new( ELeave ) CPKCS12();
       
   104     
       
   105     CleanupStack::PushL( self );
       
   106     self->ConstructL();
       
   107     CleanupStack::Pop();
       
   108 
       
   109     return self;
       
   110     }
       
   111 
       
   112 void CPKCS12::Release()
       
   113     {
       
   114     delete this;
       
   115     }
       
   116 
       
   117 // ---------------------------------------------------------
       
   118 // CPKCS12::IsPKCS12Data
       
   119 // ---------------------------------------------------------
       
   120 //    
       
   121 TBool CPKCS12::IsPKCS12Data(const TDesC8& aBinaryData)
       
   122      {     
       
   123     // We don't decode the data because we may only have the first few bytes -
       
   124 	// instead we check the ASN1 by hand.
       
   125 	ASSERT(aBinaryData.Length() >= KPKCS12DataMinLength);
       
   126 	TInt pos = 0;
       
   127 	
       
   128 	if (!IsASN1Tag(KASN1SequenceTagValue,aBinaryData, pos))
       
   129 	    {
       
   130 	    return EFalse;
       
   131 	    }
       
   132 	if (!IsExpectedData(aBinaryData, pos, KPKCS12Version3))
       
   133 	    {
       
   134 	    return EFalse;
       
   135 	    }
       
   136     if (!IsASN1Tag(KASN1SequenceTagValue, aBinaryData, pos))
       
   137 	    {
       
   138 	    return EFalse;
       
   139 	    } 
       
   140 	if (!IsExpectedData(aBinaryData, pos, KPKCS7DataOID))
       
   141 	    {
       
   142 	    return EFalse;
       
   143 	    } 
       
   144     if (!IsASN1Tag(KASN1ImplicitConstructedTagValue, aBinaryData, pos))
       
   145 	    {
       
   146 	    return EFalse;
       
   147 	    } 
       
   148 	// OpenSSL, IE and Opera type of PKCS#12 file    
       
   149     if (IsASN1Tag(KASN1OctetStringTagValue, aBinaryData, pos))
       
   150         {
       
   151         if (!IsASN1Tag(KASN1SequenceTagValue, aBinaryData, pos))
       
   152             {
       
   153             return EFalse;
       
   154             }
       
   155         if (!IsASN1Tag(KASN1SequenceTagValue, aBinaryData, pos))
       
   156             {
       
   157             return EFalse;
       
   158             }    
       
   159     	if  (IsExpectedData(aBinaryData, pos, KPKC7EncryptedDataOID) || 
       
   160     	     IsExpectedData(aBinaryData, pos, KPKCS7DataOID))    		
       
   161     	    {    	    
       
   162     	    return ETrue;
       
   163     	    }
       
   164     	else
       
   165     	    {
       
   166     	    return EFalse;
       
   167     	    }
       
   168         }
       
   169     // Netscape and Mozilla type of PKCS#12 file    
       
   170 	else if (IsASN1Tag(KASN1OctetStringTagValue + KASN1BerConstructedBit, aBinaryData, pos))
       
   171 	    {
       
   172 	    if (IsExpectedData(aBinaryData, pos, KSequenceTagInOctet))
       
   173             {
       
   174             if (!IsExpectedData(aBinaryData, pos, KSequenceTagInOctet))
       
   175                 {
       
   176                 return EFalse;
       
   177                 }    
       
   178         	if  (IsExpectedData(aBinaryData, pos, KMozillaPKCS7DataOID) ||
       
   179         		IsExpectedData(aBinaryData, pos, KMozillaPKCS7EncryptedDataOID))
       
   180         	    {    	    
       
   181         	    return ETrue;
       
   182         	    }
       
   183             }
       
   184         // Firefox version 1.5 type of PKCS#12 data    
       
   185         else if (IsASN1Tag(KASN1OctetStringTagValue, aBinaryData, pos))
       
   186             {
       
   187             if (!IsASN1Tag(KASN1SequenceTagValue, aBinaryData, pos))
       
   188                 {
       
   189                 return EFalse;
       
   190                 }
       
   191             if (!IsASN1Tag(KASN1SequenceTagValue, aBinaryData, pos))
       
   192                 {
       
   193                 return EFalse;
       
   194                 }    
       
   195     	    if (IsExpectedData(aBinaryData, pos, KPKC7EncryptedDataOID) || 
       
   196     	     IsExpectedData(aBinaryData, pos, KPKCS7DataOID))    		
       
   197     	        {    	    
       
   198     	        return ETrue;
       
   199     	        }
       
   200     	    else
       
   201     	        {
       
   202     	        return EFalse;
       
   203     	        }
       
   204             }
       
   205         else
       
   206             {
       
   207             return EFalse;
       
   208             }            
       
   209 	    }
       
   210     else
       
   211         {            
       
   212         return EFalse;
       
   213         }
       
   214     return EFalse;    
       
   215     }
       
   216     
       
   217 // ---------------------------------------------------------
       
   218 // CPKCS12Recognizer::IsASN1Tag
       
   219 // ---------------------------------------------------------
       
   220 //  
       
   221 TBool CPKCS12::IsASN1Tag(
       
   222     TInt aTag, 
       
   223     const TDesC8& aBinaryData, 
       
   224     TInt& aPos)
       
   225 	{	
       
   226 	// Check we have enough data
       
   227 	if ((aPos + 2) >= aBinaryData.Length())
       
   228 		{
       
   229 		return EFalse;
       
   230 		}
       
   231 	// Check the outermost sequence is valid
       
   232 	if (aBinaryData[aPos] != aTag)
       
   233 		{
       
   234 		return EFalse;
       
   235 		}
       
   236 	// Skip sequence length
       
   237 	aPos++;
       
   238 	TInt length0 = aBinaryData[aPos++];
       
   239 	if (length0 & 0x80)
       
   240 		{
       
   241 		aPos += length0 & 0x7f;
       
   242 		}
       
   243 	return ETrue;
       
   244 	}
       
   245 
       
   246 // ---------------------------------------------------------
       
   247 // CPKCS12Recognizer::IsExpectedData
       
   248 // ---------------------------------------------------------
       
   249 //  
       
   250 TBool CPKCS12::IsExpectedData(
       
   251     const TDesC8& aBinaryData, 
       
   252     TInt& aPos, 
       
   253     const TDesC8& aExpectedData)
       
   254 	{	
       
   255 	TInt length = aExpectedData.Length();
       
   256 	// Check we have enough data
       
   257 	if (aPos + length >= aBinaryData.Length())
       
   258 		{
       
   259 		return EFalse;
       
   260 		}
       
   261 	// Check data matches	
       
   262 	if (aBinaryData.Mid(aPos, length) != aExpectedData)
       
   263 		{
       
   264 		return EFalse;
       
   265 		}
       
   266 	aPos += length;
       
   267 	return ETrue;
       
   268 	}    
       
   269 
       
   270 // -----------------------------------------------------------------------------
       
   271 // CPKCS12::ParseL
       
   272 // 
       
   273 // -----------------------------------------------------------------------------
       
   274 //
       
   275 void CPKCS12::ParseL(const TDesC8& aPKCS12, const TDesC16& aPassword)
       
   276     {
       
   277     Reset();
       
   278     iCrPkcs12 = CCrPKCS12::NewL();
       
   279     iCrData = CCrData::NewL(EFalse);
       
   280     User::LeaveIfError(iCrData->Write(aPKCS12));
       
   281     TInt start = 0;
       
   282     iCrData->Seek( ESeekStart, start );
       
   283     HandleErrorL( iCrPkcs12->OpenL( *iCrData, aPassword ));
       
   284     }
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CPKCS12::HandleErrorL
       
   288 // 
       
   289 // -----------------------------------------------------------------------------
       
   290 //
       
   291 void CPKCS12::HandleErrorL( TUint16 aError ) const
       
   292     {
       
   293 
       
   294     switch ( aError & 0x00ff )
       
   295         {
       
   296         case KCrOK:
       
   297             return;
       
   298         case KCrNotValidPkcs12Object:
       
   299             User::Leave(KErrArgument);
       
   300         case KCrBerLibraryError:
       
   301             User::Leave(KErrGeneral);
       
   302         case KCrNotSupportedHMACalgorithm:
       
   303             User::Leave(KErrNotSupported);
       
   304         case KCrCancelled:
       
   305             User::Leave(KErrCancel);
       
   306         case KCrGeneralError:
       
   307             User::Leave(KErrGeneral);
       
   308         case KCrWrongPassWordOrCorruptedFile:
       
   309             User::Leave(KErrBadPassphrase);
       
   310         case KCrNotPasswordBasedEncryption:
       
   311             User::Leave(KErrNotSupported);
       
   312         case KCrNoMemory:
       
   313             User::Leave(KErrNoMemory);
       
   314         default:
       
   315             User::Leave(KErrGeneral);
       
   316         }
       
   317     }
       
   318     
       
   319 // Destructor
       
   320 CPKCS12::~CPKCS12()
       
   321     {
       
   322     Reset();
       
   323     }
       
   324 
       
   325 // -----------------------------------------------------------------------------
       
   326 // CPKCS12::Reset
       
   327 // ?implementation_description
       
   328 // (other items were commented in a header).
       
   329 // -----------------------------------------------------------------------------
       
   330 //
       
   331 void CPKCS12::Reset()
       
   332     {
       
   333     if (iCrData)
       
   334         {        
       
   335         iCrData->Close();
       
   336         delete iCrData;
       
   337         iCrData = NULL;
       
   338         }    
       
   339     delete iCrPkcs12;
       
   340     iCrPkcs12 = NULL;
       
   341     }
       
   342 
       
   343 // -----------------------------------------------------------------------------
       
   344 // CPKCS12::CACertificates
       
   345 // ?implementation_description
       
   346 // (other items were commented in a header).
       
   347 // -----------------------------------------------------------------------------
       
   348 //
       
   349 const CArrayPtr<CX509Certificate>& CPKCS12::CACertificates() const
       
   350     {
       
   351     return iCrPkcs12->CACertificates();
       
   352     }
       
   353 
       
   354 // -----------------------------------------------------------------------------
       
   355 // CPKCS12::UserCertificates
       
   356 // ?implementation_description
       
   357 // (other items were commented in a header).
       
   358 // -----------------------------------------------------------------------------
       
   359 //
       
   360 const CArrayPtr<CX509Certificate>& CPKCS12::UserCertificates() const
       
   361     {    
       
   362     return iCrPkcs12->UserCertificates();
       
   363     }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // CPKCS12::PrivateKeys
       
   367 // ?implementation_description
       
   368 // (other items were commented in a header).
       
   369 // -----------------------------------------------------------------------------
       
   370 //
       
   371 const CArrayPtr<HBufC8>& CPKCS12::PrivateKeys() const
       
   372     {    
       
   373     return iCrPkcs12->PrivateKeys();
       
   374     }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CPKCS12::SafeBagsCount
       
   378 // ?implementation_description
       
   379 // (other items were commented in a header).
       
   380 // -----------------------------------------------------------------------------
       
   381 //
       
   382 TUint CPKCS12::SafeBagsCount() const
       
   383     {
       
   384     return iCrPkcs12->SafeBagsCount();
       
   385     }
       
   386 
       
   387 // -----------------------------------------------------------------------------
       
   388 // CPKCS12::IterCount
       
   389 // ?implementation_description
       
   390 // (other items were commented in a header).
       
   391 // -----------------------------------------------------------------------------
       
   392 //     
       
   393 TUint CPKCS12::IterCount() const
       
   394     {
       
   395     return iCrPkcs12->Iter();
       
   396     }
       
   397 
       
   398 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   399                                                                                 
       
   400 // ---------------------------------------------------------
       
   401 // E32Dll
       
   402 // DLL entry point
       
   403 // ---------------------------------------------------------
       
   404 //
       
   405 #ifndef EKA2
       
   406 GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
       
   407     {
       
   408     return KErrNone;
       
   409     }
       
   410 #endif
       
   411 
       
   412 //  End of File