os/security/cryptoservices/certificateandkeymgmt/x509/x509cert.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 1998-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
* -- FingerPrint Note:
sl@0
    16
* Developers have to be aware that if they are going to change the fingerprint for this certificate
sl@0
    17
* for a different hash, then there are other places that need to reflect this change
sl@0
    18
* -- Location
sl@0
    19
* void CX509Certificate::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
    20
* EXPORT_C void CX509Certificate::InternalizeL(RReadStream& aStream)
sl@0
    21
* Also change the CWTLSCertificate and search for other occurences of the current
sl@0
    22
* hash.
sl@0
    23
* -- TeletexString type support Note:
sl@0
    24
* If the certificate has decoded the members from TeletexString then the return value 
sl@0
    25
* may be incorrect because TeletexString type is not fully supported by this library.
sl@0
    26
* Instead the decode methods perform a direct conversion from 8 to 16bits by adding 
sl@0
    27
* null characters in the second byte of each character. This will work as expected 
sl@0
    28
* for cases where the string contains ASCII data.
sl@0
    29
*
sl@0
    30
*/
sl@0
    31
sl@0
    32
sl@0
    33
sl@0
    34
sl@0
    35
#include <x509cert.h>
sl@0
    36
#include <x509certext.h>
sl@0
    37
#include "X509time.h"
sl@0
    38
#include <x509keys.h>
sl@0
    39
#include <keyidentifierutil.h>
sl@0
    40
#include <asn1enc.h>
sl@0
    41
#include <asn1dec.h>
sl@0
    42
sl@0
    43
EXPORT_C CPKCS1SignatureResult* CPKCS1SignatureResult::NewL(const CAlgorithmIdentifier& aDigestAlgorithm, const TDesC8& aDigest)
sl@0
    44
	{
sl@0
    45
	CPKCS1SignatureResult* self = CPKCS1SignatureResult::NewLC(aDigestAlgorithm, aDigest);
sl@0
    46
	CleanupStack::Pop();
sl@0
    47
	return self;
sl@0
    48
	}
sl@0
    49
sl@0
    50
EXPORT_C CPKCS1SignatureResult* CPKCS1SignatureResult::NewLC(const CAlgorithmIdentifier& aDigestAlgorithm, const TDesC8& aDigest)
sl@0
    51
	{
sl@0
    52
	CPKCS1SignatureResult* self = new(ELeave) CPKCS1SignatureResult;
sl@0
    53
	CleanupStack::PushL(self);
sl@0
    54
	self->ConstructL(aDigestAlgorithm, aDigest);
sl@0
    55
	return self;
sl@0
    56
	}
sl@0
    57
sl@0
    58
void CPKCS1SignatureResult::ConstructL(const CAlgorithmIdentifier& aDigestAlgorithm, const TDesC8& aDigest)
sl@0
    59
	{
sl@0
    60
	iDigestAlgorithm = CAlgorithmIdentifier::NewL(aDigestAlgorithm);
sl@0
    61
	iDigest = aDigest.AllocL();
sl@0
    62
	}
sl@0
    63
sl@0
    64
EXPORT_C TBool CPKCS1SignatureResult::VerifyL(const TDesC8& aResult)
sl@0
    65
	{
sl@0
    66
sl@0
    67
	TBool res = EFalse;
sl@0
    68
	TRAPD(err, res = DoVerifyL(aResult));
sl@0
    69
	if ((err != KErrNone) && (err != KErrArgument))
sl@0
    70
		{
sl@0
    71
		User::Leave(err);
sl@0
    72
		}
sl@0
    73
	return res;
sl@0
    74
	}
sl@0
    75
sl@0
    76
TBool CPKCS1SignatureResult::DoVerifyL(const TDesC8& aResult)
sl@0
    77
	{
sl@0
    78
	TBool res = EFalse;
sl@0
    79
	TASN1DecSequence decSeq;
sl@0
    80
	TInt pos = 0;
sl@0
    81
	TInt len = aResult.Length();
sl@0
    82
sl@0
    83
	const CArrayPtrFlat<TASN1DecGeneric>* seq = decSeq.DecodeDERLC(aResult, pos);
sl@0
    84
	if (seq->Count() == 2)
sl@0
    85
		{
sl@0
    86
		const TASN1DecGeneric* gen1 = seq->At(0);
sl@0
    87
		const TASN1DecGeneric* gen2 = seq->At(1);
sl@0
    88
		CAlgorithmIdentifier* algId = CX509AlgorithmIdentifier::NewLC(gen1->Encoding());
sl@0
    89
		HBufC8* digest = gen2->GetContentDER().AllocL();
sl@0
    90
		if ((*algId == *iDigestAlgorithm) && (*digest == *iDigest)  && (pos == len))
sl@0
    91
			{
sl@0
    92
			res = ETrue;
sl@0
    93
			}
sl@0
    94
		delete digest;
sl@0
    95
		CleanupStack::PopAndDestroy();
sl@0
    96
		}
sl@0
    97
	CleanupStack::PopAndDestroy();
sl@0
    98
	return res;
sl@0
    99
	}
sl@0
   100
sl@0
   101
sl@0
   102
EXPORT_C CRSAPublicKey* TX509KeyFactory::RSAPublicKeyL(const TDesC8& aEncoding) const
sl@0
   103
	{
sl@0
   104
	return CX509RSAPublicKey::NewL(aEncoding);
sl@0
   105
	}
sl@0
   106
sl@0
   107
EXPORT_C CRSASignatureResult* TX509KeyFactory::RSASignatureResultL(const CAlgorithmIdentifier& aDigestAlgorithm, TDesC8& aDigest) const
sl@0
   108
	{
sl@0
   109
	return CPKCS1SignatureResult::NewL(aDigestAlgorithm, aDigest);
sl@0
   110
	}
sl@0
   111
sl@0
   112
EXPORT_C CDSAPublicKey* TX509KeyFactory::DSAPublicKeyL(const TDesC8& aParamsEncoding, const TDesC8& aEncoding) const
sl@0
   113
	{
sl@0
   114
	return CX509DSAPublicKey::NewL(aParamsEncoding, aEncoding);
sl@0
   115
	}
sl@0
   116
sl@0
   117
EXPORT_C CDSAPublicKey* TX509KeyFactory::DSAPublicKeyL(const CDSAParameters& aParams, const TDesC8& aEncoding) const
sl@0
   118
	{
sl@0
   119
	return CX509DSAPublicKey::NewL(aParams, aEncoding);
sl@0
   120
	}
sl@0
   121
sl@0
   122
sl@0
   123
EXPORT_C CDSASignature* TX509KeyFactory::DSASignatureL(const TDesC8& aEncoding) const
sl@0
   124
	{
sl@0
   125
	return CX509DSASignature::NewL(aEncoding);
sl@0
   126
	}
sl@0
   127
sl@0
   128
EXPORT_C CDSAParameters* TX509KeyFactory::DSAParametersL(const TDesC8& aParamsEncoding) const
sl@0
   129
{
sl@0
   130
	return (CX509DSAPublicKey::DSAParametersL(aParamsEncoding));
sl@0
   131
}
sl@0
   132
sl@0
   133
//CX509ValidityPeriod
sl@0
   134
EXPORT_C CX509ValidityPeriod* CX509ValidityPeriod::NewL(const TDesC8& aBinaryData)
sl@0
   135
	{
sl@0
   136
	TInt pos = 0;
sl@0
   137
	return CX509ValidityPeriod::NewL(aBinaryData, pos);
sl@0
   138
	}
sl@0
   139
sl@0
   140
EXPORT_C CX509ValidityPeriod* CX509ValidityPeriod::NewLC(const TDesC8& aBinaryData)
sl@0
   141
	{
sl@0
   142
	TInt pos = 0;
sl@0
   143
	return CX509ValidityPeriod::NewLC(aBinaryData, pos);
sl@0
   144
	}
sl@0
   145
sl@0
   146
EXPORT_C CX509ValidityPeriod* CX509ValidityPeriod::NewL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   147
	{
sl@0
   148
	CX509ValidityPeriod* self = CX509ValidityPeriod::NewLC(aBinaryData, aPos);
sl@0
   149
	CleanupStack::Pop();
sl@0
   150
	return self;
sl@0
   151
	}
sl@0
   152
sl@0
   153
EXPORT_C CX509ValidityPeriod* CX509ValidityPeriod::NewLC(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   154
	{
sl@0
   155
	CX509ValidityPeriod* self = new(ELeave) CX509ValidityPeriod;
sl@0
   156
	CleanupStack::PushL(self);
sl@0
   157
	self->ConstructL(aBinaryData, aPos);
sl@0
   158
	return self;
sl@0
   159
	}
sl@0
   160
sl@0
   161
CX509ValidityPeriod::CX509ValidityPeriod()
sl@0
   162
	{
sl@0
   163
	}
sl@0
   164
sl@0
   165
void CX509ValidityPeriod::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   166
	{
sl@0
   167
	TASN1DecSequence encSeq;
sl@0
   168
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos);
sl@0
   169
	if (seq->Count() != 2)
sl@0
   170
		{
sl@0
   171
		User::Leave(KErrArgument);
sl@0
   172
		}
sl@0
   173
	TASN1DecX509Time decTime;
sl@0
   174
	iStart = decTime.DecodeDERL(*(seq->At(0)));
sl@0
   175
	iFinish = decTime.DecodeDERL(*(seq->At(1)));
sl@0
   176
	CleanupStack::PopAndDestroy();//seq + contents
sl@0
   177
	}
sl@0
   178
sl@0
   179
//algorithm id
sl@0
   180
EXPORT_C CX509AlgorithmIdentifier* CX509AlgorithmIdentifier::NewL(const TDesC8& aBinaryData)
sl@0
   181
	{
sl@0
   182
	TInt pos = 0;
sl@0
   183
	return CX509AlgorithmIdentifier::NewL(aBinaryData, pos);
sl@0
   184
	}
sl@0
   185
sl@0
   186
EXPORT_C CX509AlgorithmIdentifier* CX509AlgorithmIdentifier::NewLC(const TDesC8& aBinaryData)
sl@0
   187
	{
sl@0
   188
	TInt pos = 0;
sl@0
   189
	return CX509AlgorithmIdentifier::NewLC(aBinaryData, pos);
sl@0
   190
	}
sl@0
   191
sl@0
   192
EXPORT_C CX509AlgorithmIdentifier* CX509AlgorithmIdentifier::NewL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   193
	{
sl@0
   194
	CX509AlgorithmIdentifier* self = CX509AlgorithmIdentifier::NewLC(aBinaryData, aPos);
sl@0
   195
	CleanupStack::Pop();
sl@0
   196
	return self;
sl@0
   197
	}
sl@0
   198
sl@0
   199
EXPORT_C CX509AlgorithmIdentifier* CX509AlgorithmIdentifier::NewLC(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   200
	{
sl@0
   201
	CX509AlgorithmIdentifier* self = new(ELeave) CX509AlgorithmIdentifier;
sl@0
   202
	CleanupStack::PushL(self);
sl@0
   203
	self->InitializeL(aBinaryData, aPos);
sl@0
   204
	return self;
sl@0
   205
	}
sl@0
   206
sl@0
   207
EXPORT_C CX509AlgorithmIdentifier* CX509AlgorithmIdentifier::NewL(TAlgorithmId aAlgorithmId, const TDesC8& aEncodedParams)
sl@0
   208
 	{
sl@0
   209
	CX509AlgorithmIdentifier* self = CX509AlgorithmIdentifier::NewLC(aAlgorithmId, aEncodedParams);
sl@0
   210
 	CleanupStack::Pop();
sl@0
   211
 	return self;	
sl@0
   212
 	}
sl@0
   213
 	
sl@0
   214
EXPORT_C CX509AlgorithmIdentifier* CX509AlgorithmIdentifier::NewLC(TAlgorithmId aAlgorithmId, const TDesC8& aEncodedParams)
sl@0
   215
 	{
sl@0
   216
 	CX509AlgorithmIdentifier* self = new(ELeave) CX509AlgorithmIdentifier(aAlgorithmId);
sl@0
   217
 	CleanupStack::PushL(self);
sl@0
   218
 	self->ConstructL(aEncodedParams);
sl@0
   219
 	return self;				
sl@0
   220
 	}
sl@0
   221
sl@0
   222
CX509AlgorithmIdentifier::CX509AlgorithmIdentifier(TAlgorithmId& aAlgorithmId):CAlgorithmIdentifier(aAlgorithmId)
sl@0
   223
 	{
sl@0
   224
 	}
sl@0
   225
sl@0
   226
sl@0
   227
CX509AlgorithmIdentifier::CX509AlgorithmIdentifier()
sl@0
   228
	{
sl@0
   229
	}
sl@0
   230
sl@0
   231
void CX509AlgorithmIdentifier::InitializeL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   232
	{
sl@0
   233
	TASN1DecSequence encSeq;
sl@0
   234
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 1, KMaxTInt);
sl@0
   235
	TInt count = seq->Count();
sl@0
   236
	TASN1DecObjectIdentifier encOID;
sl@0
   237
	HBufC* oid = encOID.DecodeDERL(*(seq->At(0)));
sl@0
   238
	CleanupStack::PushL(oid);
sl@0
   239
	TPtrC oidDes(oid->Des()); 
sl@0
   240
	if (oidDes == KDSA)
sl@0
   241
		{
sl@0
   242
		//optional params
sl@0
   243
		if (count > 1)//if we still have stuff left
sl@0
   244
			{
sl@0
   245
			TASN1DecGeneric* gen = seq->At(1);
sl@0
   246
			iEncodedParams = gen->Encoding().AllocL();
sl@0
   247
			}
sl@0
   248
		else
sl@0
   249
			{
sl@0
   250
			iEncodedParams = HBufC8::NewL(1);
sl@0
   251
			*iEncodedParams = KNullDesC8;
sl@0
   252
			}
sl@0
   253
		iAlgorithmId = EDSA;
sl@0
   254
		CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   255
		return;
sl@0
   256
		}
sl@0
   257
	if (count > 1)
sl@0
   258
		{
sl@0
   259
		TASN1DecGeneric* gen = seq->At(1);
sl@0
   260
		if (oidDes == KDH)
sl@0
   261
			{
sl@0
   262
			iEncodedParams = gen->Encoding().AllocL();
sl@0
   263
			iAlgorithmId = EDH;
sl@0
   264
			CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   265
			return;
sl@0
   266
			}
sl@0
   267
		if (oidDes == KRSA)
sl@0
   268
			{
sl@0
   269
			iAlgorithmId = ERSA;
sl@0
   270
			TASN1DecNull null;
sl@0
   271
			null.DecodeDERL(*gen);//just to check the syntax is OK
sl@0
   272
			iEncodedParams = HBufC8::NewL(1);
sl@0
   273
			*iEncodedParams = KNullDesC8;
sl@0
   274
			CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   275
			return;
sl@0
   276
			}
sl@0
   277
		if (oidDes == KMD5)
sl@0
   278
			{
sl@0
   279
			iAlgorithmId = EMD5;
sl@0
   280
			TASN1DecNull null;
sl@0
   281
			null.DecodeDERL(*gen);//just to check the syntax is OK
sl@0
   282
			iEncodedParams = HBufC8::NewL(1);
sl@0
   283
			*iEncodedParams = KNullDesC8;
sl@0
   284
			CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   285
			return;
sl@0
   286
			}
sl@0
   287
		if (oidDes == KMD2)
sl@0
   288
			{
sl@0
   289
			iAlgorithmId = EMD2;
sl@0
   290
			TASN1DecNull null;
sl@0
   291
			null.DecodeDERL(*gen);//just to check the syntax is OK
sl@0
   292
			iEncodedParams = HBufC8::NewL(1);
sl@0
   293
			*iEncodedParams = KNullDesC8;
sl@0
   294
			CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   295
			return;
sl@0
   296
			}
sl@0
   297
		if (oidDes == KSHA1)
sl@0
   298
			{
sl@0
   299
			iAlgorithmId = ESHA1;
sl@0
   300
			TASN1DecNull null;
sl@0
   301
			null.DecodeDERL(*gen);//just to check the syntax is OK
sl@0
   302
			iEncodedParams = HBufC8::NewL(1);
sl@0
   303
			*iEncodedParams = KNullDesC8;
sl@0
   304
			CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   305
			return;
sl@0
   306
			}
sl@0
   307
sl@0
   308
        if (oidDes == KSHA224)
sl@0
   309
            {
sl@0
   310
            iAlgorithmId = ESHA224;
sl@0
   311
            TASN1DecNull null;
sl@0
   312
            null.DecodeDERL(*gen);//just to check the syntax is OK
sl@0
   313
            iEncodedParams = HBufC8::NewL(1);
sl@0
   314
            *iEncodedParams = KNullDesC8;
sl@0
   315
            CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   316
            return;
sl@0
   317
            }
sl@0
   318
        if (oidDes == KSHA256)
sl@0
   319
            {
sl@0
   320
            iAlgorithmId = ESHA256;
sl@0
   321
            TASN1DecNull null;
sl@0
   322
            null.DecodeDERL(*gen);//just to check the syntax is OK
sl@0
   323
            iEncodedParams = HBufC8::NewL(1);
sl@0
   324
            *iEncodedParams = KNullDesC8;
sl@0
   325
            CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   326
            return;
sl@0
   327
            }      
sl@0
   328
        if (oidDes == KSHA384)
sl@0
   329
            {
sl@0
   330
            iAlgorithmId = ESHA384;
sl@0
   331
            TASN1DecNull null;
sl@0
   332
            null.DecodeDERL(*gen);//just to check the syntax is OK
sl@0
   333
            iEncodedParams = HBufC8::NewL(1);
sl@0
   334
            *iEncodedParams = KNullDesC8;
sl@0
   335
            CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   336
            return;
sl@0
   337
            }        
sl@0
   338
        if (oidDes == KSHA512)
sl@0
   339
            {
sl@0
   340
            iAlgorithmId = ESHA512;
sl@0
   341
            TASN1DecNull null;
sl@0
   342
            null.DecodeDERL(*gen);//just to check the syntax is OK
sl@0
   343
            iEncodedParams = HBufC8::NewL(1);
sl@0
   344
            *iEncodedParams = KNullDesC8;
sl@0
   345
            CleanupStack::PopAndDestroy(2);//seq, oid
sl@0
   346
            return;
sl@0
   347
            }         
sl@0
   348
	
sl@0
   349
		}
sl@0
   350
	User::Leave(KErrNotSupported);
sl@0
   351
	}
sl@0
   352
	
sl@0
   353
EXPORT_C CASN1EncSequence* CX509AlgorithmIdentifier::EncodeASN1DERLC() const
sl@0
   354
	{
sl@0
   355
	// the root sequence contains the signed object
sl@0
   356
	CASN1EncSequence* root = CASN1EncSequence::NewLC();
sl@0
   357
	
sl@0
   358
	//encode the oid
sl@0
   359
	CASN1EncObjectIdentifier* oid(NULL);
sl@0
   360
	switch (iAlgorithmId)
sl@0
   361
		{
sl@0
   362
	case EDSA:
sl@0
   363
		oid=CASN1EncObjectIdentifier::NewLC(KDSA);
sl@0
   364
		break;
sl@0
   365
		
sl@0
   366
	case EDH:
sl@0
   367
		oid=CASN1EncObjectIdentifier::NewLC(KDH);
sl@0
   368
		break;
sl@0
   369
		
sl@0
   370
	case ERSA:
sl@0
   371
		oid=CASN1EncObjectIdentifier::NewLC(KRSA);
sl@0
   372
		break;
sl@0
   373
		
sl@0
   374
	case EMD5:
sl@0
   375
		oid=CASN1EncObjectIdentifier::NewLC(KMD5);
sl@0
   376
		break;
sl@0
   377
		
sl@0
   378
	case EMD2:
sl@0
   379
		oid=CASN1EncObjectIdentifier::NewLC(KMD2);
sl@0
   380
		break;
sl@0
   381
		
sl@0
   382
	case ESHA1:
sl@0
   383
		oid=CASN1EncObjectIdentifier::NewLC(KSHA1);
sl@0
   384
		break;
sl@0
   385
sl@0
   386
	case ESHA224:
sl@0
   387
		oid=CASN1EncObjectIdentifier::NewLC(KSHA224);
sl@0
   388
		break;
sl@0
   389
sl@0
   390
	case ESHA256:
sl@0
   391
		oid=CASN1EncObjectIdentifier::NewLC(KSHA256);
sl@0
   392
		break;
sl@0
   393
sl@0
   394
	case ESHA384:
sl@0
   395
		oid=CASN1EncObjectIdentifier::NewLC(KSHA384);
sl@0
   396
		break;
sl@0
   397
sl@0
   398
	case ESHA512:
sl@0
   399
		oid=CASN1EncObjectIdentifier::NewLC(KSHA512);
sl@0
   400
		break;
sl@0
   401
		
sl@0
   402
	default:
sl@0
   403
		User::Leave(KErrNotSupported);
sl@0
   404
		}
sl@0
   405
	
sl@0
   406
	root->AddAndPopChildL(oid);
sl@0
   407
	
sl@0
   408
	//Encode parameters
sl@0
   409
	if (*iEncodedParams!=KNullDesC8)
sl@0
   410
		{
sl@0
   411
		CASN1EncEncoding* enc=CASN1EncEncoding::NewLC(*iEncodedParams);
sl@0
   412
		root->AddAndPopChildL(enc);
sl@0
   413
		}
sl@0
   414
	else
sl@0
   415
		{
sl@0
   416
		if (iAlgorithmId!=EDSA)
sl@0
   417
			{
sl@0
   418
			CASN1EncNull* enc=CASN1EncNull::NewLC();
sl@0
   419
			root->AddAndPopChildL(enc);				
sl@0
   420
			}
sl@0
   421
		}
sl@0
   422
		
sl@0
   423
	return root;		
sl@0
   424
	}
sl@0
   425
	
sl@0
   426
sl@0
   427
//signing algorithm id
sl@0
   428
EXPORT_C CX509SigningAlgorithmIdentifier* CX509SigningAlgorithmIdentifier::NewL(const TDesC8& aBinaryData)
sl@0
   429
	{
sl@0
   430
	TInt pos = 0;
sl@0
   431
	return CX509SigningAlgorithmIdentifier::NewL(aBinaryData, pos);
sl@0
   432
	}
sl@0
   433
sl@0
   434
EXPORT_C CX509SigningAlgorithmIdentifier* CX509SigningAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData)
sl@0
   435
	{
sl@0
   436
	TInt pos = 0;
sl@0
   437
	return CX509SigningAlgorithmIdentifier::NewLC(aBinaryData, pos);
sl@0
   438
	}
sl@0
   439
sl@0
   440
EXPORT_C CX509SigningAlgorithmIdentifier* CX509SigningAlgorithmIdentifier::NewL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   441
	{
sl@0
   442
	CX509SigningAlgorithmIdentifier* self = CX509SigningAlgorithmIdentifier::NewLC(aBinaryData, aPos);
sl@0
   443
	CleanupStack::Pop();
sl@0
   444
	return self;
sl@0
   445
	}
sl@0
   446
sl@0
   447
EXPORT_C CX509SigningAlgorithmIdentifier* CX509SigningAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   448
	{
sl@0
   449
	CX509SigningAlgorithmIdentifier* self = new(ELeave) CX509SigningAlgorithmIdentifier;
sl@0
   450
	CleanupStack::PushL(self);
sl@0
   451
	self->ConstructL(aBinaryData, aPos);
sl@0
   452
	return self;
sl@0
   453
	}
sl@0
   454
sl@0
   455
EXPORT_C CX509SigningAlgorithmIdentifier* CX509SigningAlgorithmIdentifier::NewL(const CAlgorithmIdentifier& aAsymmetricAlgorithm, const CAlgorithmIdentifier& aDigestAlgorithm)
sl@0
   456
 	{
sl@0
   457
 	CX509SigningAlgorithmIdentifier* self = CX509SigningAlgorithmIdentifier::NewLC(aAsymmetricAlgorithm, aDigestAlgorithm);
sl@0
   458
 	CleanupStack::Pop();
sl@0
   459
 	return self;
sl@0
   460
 	}
sl@0
   461
 
sl@0
   462
EXPORT_C CX509SigningAlgorithmIdentifier* CX509SigningAlgorithmIdentifier::NewLC(const CAlgorithmIdentifier& aAsymmetricAlgorithm, const CAlgorithmIdentifier& aDigestAlgorithm)
sl@0
   463
 	{
sl@0
   464
 	CX509SigningAlgorithmIdentifier* self = new(ELeave) CX509SigningAlgorithmIdentifier;
sl@0
   465
 	CleanupStack::PushL(self);
sl@0
   466
 	self->ConstructL(aAsymmetricAlgorithm, aDigestAlgorithm);
sl@0
   467
 	return self;
sl@0
   468
 	}
sl@0
   469
sl@0
   470
CX509SigningAlgorithmIdentifier::CX509SigningAlgorithmIdentifier()
sl@0
   471
	{
sl@0
   472
	}
sl@0
   473
sl@0
   474
void CX509SigningAlgorithmIdentifier::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   475
	{
sl@0
   476
	TASN1DecSequence encSeq;
sl@0
   477
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 1, KMaxTInt);
sl@0
   478
	TInt count = seq->Count();
sl@0
   479
	TASN1DecObjectIdentifier encOID;
sl@0
   480
	HBufC* oid = encOID.DecodeDERL(*(seq->At(0)));
sl@0
   481
	CleanupStack::PushL(oid);
sl@0
   482
	TPtrC oidDes(oid->Des()); 
sl@0
   483
	//none of the signing algorithms we support have parameters here...
sl@0
   484
	HBufC8* encodedParams = HBufC8::NewLC(1);
sl@0
   485
	*encodedParams = KNullDesC8;
sl@0
   486
sl@0
   487
	if (oidDes == KDSAWithSHA1)
sl@0
   488
		{
sl@0
   489
		//should be no params, but we allow params encoded as NULL for interop reasons
sl@0
   490
		TAlgorithmId algId = EDSA;
sl@0
   491
		TAlgorithmId digestId = ESHA1;
sl@0
   492
		iDigestAlgorithm = CAlgorithmIdentifier::NewL(digestId, encodedParams->Des());
sl@0
   493
		iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(algId, encodedParams->Des());
sl@0
   494
		if (count == 1)
sl@0
   495
			{			
sl@0
   496
			CleanupStack::PopAndDestroy(3);//seq, oid, encodedParams
sl@0
   497
			return;
sl@0
   498
			}
sl@0
   499
		}
sl@0
   500
sl@0
   501
	if (oidDes == KMD2WithRSA)
sl@0
   502
		{
sl@0
   503
		TAlgorithmId algId = ERSA;
sl@0
   504
		TAlgorithmId digestId = EMD2;
sl@0
   505
		iDigestAlgorithm = CAlgorithmIdentifier::NewL(digestId, encodedParams->Des());
sl@0
   506
		iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(algId, encodedParams->Des());
sl@0
   507
		}
sl@0
   508
sl@0
   509
	if (oidDes == KMD5WithRSA)
sl@0
   510
		{
sl@0
   511
		TAlgorithmId algId = ERSA;
sl@0
   512
		TAlgorithmId digestId = EMD5;
sl@0
   513
		iDigestAlgorithm = CAlgorithmIdentifier::NewL(digestId, encodedParams->Des());
sl@0
   514
		iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(algId, encodedParams->Des());
sl@0
   515
		}
sl@0
   516
sl@0
   517
	if (oidDes == KSHA1WithRSA  || oidDes == KSHA1WithRSASignature)
sl@0
   518
		{
sl@0
   519
		TAlgorithmId algId = ERSA;
sl@0
   520
		TAlgorithmId digestId = ESHA1;
sl@0
   521
		iDigestAlgorithm = CAlgorithmIdentifier::NewL(digestId, encodedParams->Des());
sl@0
   522
		iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(algId, encodedParams->Des());
sl@0
   523
		}
sl@0
   524
sl@0
   525
	if (oidDes == KSHA224WithRSA)
sl@0
   526
         {
sl@0
   527
         TAlgorithmId algId = ERSA;
sl@0
   528
         TAlgorithmId digestId = ESHA224;
sl@0
   529
         iDigestAlgorithm = CAlgorithmIdentifier::NewL(digestId, encodedParams->Des());
sl@0
   530
         iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(algId, encodedParams->Des());
sl@0
   531
         }
sl@0
   532
	
sl@0
   533
	if (oidDes == KSHA256WithRSA)
sl@0
   534
         {
sl@0
   535
         TAlgorithmId algId = ERSA;
sl@0
   536
         TAlgorithmId digestId = ESHA256;
sl@0
   537
         iDigestAlgorithm = CAlgorithmIdentifier::NewL(digestId, encodedParams->Des());
sl@0
   538
         iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(algId, encodedParams->Des());
sl@0
   539
         }
sl@0
   540
sl@0
   541
	if (oidDes == KSHA384WithRSA)
sl@0
   542
         {
sl@0
   543
         TAlgorithmId algId = ERSA;
sl@0
   544
         TAlgorithmId digestId = ESHA384;
sl@0
   545
         iDigestAlgorithm = CAlgorithmIdentifier::NewL(digestId, encodedParams->Des());
sl@0
   546
         iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(algId, encodedParams->Des());
sl@0
   547
         }
sl@0
   548
sl@0
   549
	if (oidDes == KSHA512WithRSA)
sl@0
   550
         {
sl@0
   551
         TAlgorithmId algId = ERSA;
sl@0
   552
         TAlgorithmId digestId = ESHA512;
sl@0
   553
         iDigestAlgorithm = CAlgorithmIdentifier::NewL(digestId, encodedParams->Des());
sl@0
   554
         iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(algId, encodedParams->Des());
sl@0
   555
         }
sl@0
   556
sl@0
   557
		//???not sure if we should just leave here...
sl@0
   558
	if (iDigestAlgorithm == NULL)
sl@0
   559
		{	
sl@0
   560
		User::Leave(KErrNotSupported);
sl@0
   561
		}
sl@0
   562
	else
sl@0
   563
		{
sl@0
   564
		if (count != 2)
sl@0
   565
			{
sl@0
   566
			// Shouldn't ever get here, since RFC2459 mandates having 2
sl@0
   567
			// data items.  However, some people miss out the second
sl@0
   568
			// when it's NULL, so we'll not report and error here
sl@0
   569
			}
sl@0
   570
		else
sl@0
   571
			{
sl@0
   572
			TASN1DecGeneric* gen = seq->At(1);
sl@0
   573
			TASN1DecNull null;
sl@0
   574
			null.DecodeDERL(*gen);//just to check the syntax is OK
sl@0
   575
			}
sl@0
   576
		}
sl@0
   577
	CleanupStack::PopAndDestroy(3);//seq, oid, encodedParams
sl@0
   578
	}
sl@0
   579
sl@0
   580
void CX509SigningAlgorithmIdentifier::ConstructL(const CAlgorithmIdentifier& aAsymmetricAlgorithm, const CAlgorithmIdentifier& aDigestAlgorithm)
sl@0
   581
 	{
sl@0
   582
 	iDigestAlgorithm = CAlgorithmIdentifier::NewL(aDigestAlgorithm);
sl@0
   583
 	iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(aAsymmetricAlgorithm);
sl@0
   584
 	};
sl@0
   585
sl@0
   586
//subject public key info
sl@0
   587
EXPORT_C CX509SubjectPublicKeyInfo* CX509SubjectPublicKeyInfo::NewL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   588
	{
sl@0
   589
	CX509SubjectPublicKeyInfo* self = CX509SubjectPublicKeyInfo::NewLC(aBinaryData, aPos);
sl@0
   590
	CleanupStack::Pop();
sl@0
   591
	return self;
sl@0
   592
	}
sl@0
   593
sl@0
   594
EXPORT_C CX509SubjectPublicKeyInfo* CX509SubjectPublicKeyInfo::NewLC(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   595
	{
sl@0
   596
	CX509SubjectPublicKeyInfo* self = new(ELeave) CX509SubjectPublicKeyInfo;
sl@0
   597
	CleanupStack::PushL(self);
sl@0
   598
	self->ConstructL(aBinaryData, aPos);
sl@0
   599
	return self;
sl@0
   600
	}
sl@0
   601
sl@0
   602
EXPORT_C CX509SubjectPublicKeyInfo* CX509SubjectPublicKeyInfo::NewL(const TDesC8& aBinaryData)
sl@0
   603
	{
sl@0
   604
	TInt pos = 0;
sl@0
   605
	return CX509SubjectPublicKeyInfo::NewL(aBinaryData, pos);
sl@0
   606
	}
sl@0
   607
sl@0
   608
EXPORT_C CX509SubjectPublicKeyInfo* CX509SubjectPublicKeyInfo::NewLC(const TDesC8& aBinaryData)
sl@0
   609
	{
sl@0
   610
	TInt pos = 0;
sl@0
   611
	return CX509SubjectPublicKeyInfo::NewLC(aBinaryData, pos);
sl@0
   612
	}
sl@0
   613
sl@0
   614
CX509SubjectPublicKeyInfo::CX509SubjectPublicKeyInfo()
sl@0
   615
	{
sl@0
   616
	}
sl@0
   617
sl@0
   618
void CX509SubjectPublicKeyInfo::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   619
	{
sl@0
   620
	TASN1DecSequence encSeq;
sl@0
   621
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 2, KMaxTInt);
sl@0
   622
	iAlgId = CX509AlgorithmIdentifier::NewL(seq->At(0)->Encoding());
sl@0
   623
	TASN1DecBitString encBS;
sl@0
   624
	iEncodedKeyData = encBS.ExtractOctetStringL(*(seq->At(1)));
sl@0
   625
	CleanupStack::PopAndDestroy();//seq
sl@0
   626
	}
sl@0
   627
sl@0
   628
//generic X 509 extension syntax
sl@0
   629
EXPORT_C CX509CertExtension* CX509CertExtension::NewL(const CX509CertExtension& aExtension)
sl@0
   630
	{
sl@0
   631
	CX509CertExtension* self = CX509CertExtension::NewLC(aExtension);
sl@0
   632
	CleanupStack::Pop();
sl@0
   633
	return self;
sl@0
   634
	}
sl@0
   635
sl@0
   636
EXPORT_C CX509CertExtension* CX509CertExtension::NewLC(const CX509CertExtension& aExtension)
sl@0
   637
	{
sl@0
   638
	CX509CertExtension* self = new(ELeave) CX509CertExtension;
sl@0
   639
	CleanupStack::PushL(self);
sl@0
   640
	self->ConstructL(aExtension);
sl@0
   641
	return self;
sl@0
   642
	}
sl@0
   643
sl@0
   644
EXPORT_C CX509CertExtension* CX509CertExtension::NewL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   645
	{
sl@0
   646
	CX509CertExtension* self = CX509CertExtension::NewLC(aBinaryData, aPos);
sl@0
   647
	CleanupStack::Pop();
sl@0
   648
	return self;
sl@0
   649
	}
sl@0
   650
sl@0
   651
EXPORT_C CX509CertExtension* CX509CertExtension::NewLC(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   652
	{
sl@0
   653
	CX509CertExtension* self = new(ELeave) CX509CertExtension;
sl@0
   654
	CleanupStack::PushL(self);
sl@0
   655
	self->ConstructL(aBinaryData, aPos);
sl@0
   656
	return self;
sl@0
   657
	}
sl@0
   658
sl@0
   659
EXPORT_C CX509CertExtension* CX509CertExtension::NewL(const TDesC8& aBinaryData)
sl@0
   660
	{
sl@0
   661
	TInt pos = 0;
sl@0
   662
	return CX509CertExtension::NewL(aBinaryData, pos);
sl@0
   663
	}
sl@0
   664
sl@0
   665
EXPORT_C CX509CertExtension* CX509CertExtension::NewLC(const TDesC8& aBinaryData)
sl@0
   666
	{
sl@0
   667
	TInt pos = 0;
sl@0
   668
	return CX509CertExtension::NewLC(aBinaryData, pos);
sl@0
   669
	}
sl@0
   670
sl@0
   671
EXPORT_C CX509CertExtension* CX509CertExtension::NewL(const TDesC& aCertExtOID, 
sl@0
   672
							const TBool aCritical,
sl@0
   673
							const TDesC8& aCertExtValue)
sl@0
   674
	{
sl@0
   675
	CX509CertExtension* self = CX509CertExtension::NewLC(aCertExtOID, aCritical, aCertExtValue);
sl@0
   676
	CleanupStack::Pop();
sl@0
   677
	return self;
sl@0
   678
	}
sl@0
   679
sl@0
   680
EXPORT_C CX509CertExtension* CX509CertExtension::NewLC(const TDesC& aCertExtOID, 
sl@0
   681
							const TBool aCritical,
sl@0
   682
							const TDesC8& aCertExtValue)
sl@0
   683
	{
sl@0
   684
	CX509CertExtension* self = new(ELeave) CX509CertExtension;
sl@0
   685
	CleanupStack::PushL(self);
sl@0
   686
	self->ConstructL(aCertExtOID, aCritical, aCertExtValue);
sl@0
   687
	return self;
sl@0
   688
	}
sl@0
   689
sl@0
   690
void CX509CertExtension::ConstructL(const CX509CertExtension& aExtension)
sl@0
   691
	{
sl@0
   692
	iCritical = aExtension.iCritical;
sl@0
   693
	iId = aExtension.iId->Des().AllocL();
sl@0
   694
	iData = aExtension.iData->Des().AllocL();
sl@0
   695
	}
sl@0
   696
sl@0
   697
void CX509CertExtension::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   698
	{
sl@0
   699
	TASN1DecSequence encSeq;
sl@0
   700
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, aPos, 2, KMaxTInt);
sl@0
   701
sl@0
   702
	TASN1DecObjectIdentifier encOID;
sl@0
   703
	iId = encOID.DecodeDERL(*(seq->At(0)));
sl@0
   704
	//second is either critical flag, or the ext
sl@0
   705
	TASN1DecGeneric* second = seq->At(1);
sl@0
   706
	if (second->Tag() != EASN1Boolean)
sl@0
   707
		{
sl@0
   708
		iData = second->Encoding().AllocL();
sl@0
   709
		aPos += second->LengthDER();
sl@0
   710
		}
sl@0
   711
	else
sl@0
   712
		{
sl@0
   713
		TASN1DecBoolean encBool;
sl@0
   714
		iCritical = encBool.DecodeDERL(*second);
sl@0
   715
		if (seq->Count() != 3)
sl@0
   716
			{
sl@0
   717
			User::Leave(KErrArgument);
sl@0
   718
			}
sl@0
   719
sl@0
   720
		TASN1DecGeneric* third = seq->At(2);
sl@0
   721
		iData = third->Encoding().AllocL();
sl@0
   722
		}
sl@0
   723
	CleanupStack::PopAndDestroy();//seq
sl@0
   724
	}
sl@0
   725
sl@0
   726
void CX509CertExtension::ConstructL(const TDesC& aCertExtOID, 
sl@0
   727
									const TBool aCritical,
sl@0
   728
									const TDesC8& aCertExtValue)
sl@0
   729
	{
sl@0
   730
	iId = aCertExtOID.AllocL();
sl@0
   731
	iCritical = aCritical;
sl@0
   732
	iData = aCertExtValue.AllocL();
sl@0
   733
	}
sl@0
   734
sl@0
   735
EXPORT_C CX509CertExtension::~CX509CertExtension()
sl@0
   736
	{
sl@0
   737
	delete iData;
sl@0
   738
	delete iId;
sl@0
   739
	}
sl@0
   740
sl@0
   741
EXPORT_C TBool CX509CertExtension::Critical() const
sl@0
   742
	{
sl@0
   743
	return iCritical;
sl@0
   744
	}
sl@0
   745
sl@0
   746
EXPORT_C TPtrC CX509CertExtension::Id() const	//OID for the extension
sl@0
   747
	{
sl@0
   748
	return iId->Des();
sl@0
   749
	}
sl@0
   750
sl@0
   751
EXPORT_C TPtrC8 CX509CertExtension::Data() const	 //the extension itself
sl@0
   752
	{
sl@0
   753
	return iData->Des();
sl@0
   754
	}
sl@0
   755
sl@0
   756
EXPORT_C CASN1EncSequence* CX509CertExtension::EncodeASN1DERLC() const
sl@0
   757
	{
sl@0
   758
	CASN1EncSequence *result = CASN1EncSequence::NewLC();
sl@0
   759
	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(*iId);
sl@0
   760
	result->AddAndPopChildL(oid);
sl@0
   761
	// Encode critical flag only if true
sl@0
   762
	if (iCritical)
sl@0
   763
		{
sl@0
   764
		CASN1EncBoolean *critical = CASN1EncBoolean::NewLC(iCritical);
sl@0
   765
		result->AddAndPopChildL(critical);
sl@0
   766
		}	
sl@0
   767
	CASN1EncOctetString *data = CASN1EncOctetString::NewLC(*iData);
sl@0
   768
	result->AddAndPopChildL(data);
sl@0
   769
	return result;
sl@0
   770
	}
sl@0
   771
sl@0
   772
CX509CertExtension::CX509CertExtension()
sl@0
   773
	:iCritical(EFalse)
sl@0
   774
	{
sl@0
   775
	}
sl@0
   776
sl@0
   777
//CX509Certificate
sl@0
   778
EXPORT_C CX509Certificate* CX509Certificate::NewL(const CX509Certificate& aCert)
sl@0
   779
	{
sl@0
   780
	CX509Certificate* self = CX509Certificate::NewLC(aCert);
sl@0
   781
	CleanupStack::Pop();//self
sl@0
   782
	return self;
sl@0
   783
	}
sl@0
   784
sl@0
   785
EXPORT_C CX509Certificate* CX509Certificate::NewLC(const CX509Certificate& aCert)
sl@0
   786
	{
sl@0
   787
	CX509Certificate* self = new(ELeave) CX509Certificate;
sl@0
   788
	CleanupStack::PushL(self);
sl@0
   789
	self->ConstructL(aCert);
sl@0
   790
	return self;
sl@0
   791
	}
sl@0
   792
sl@0
   793
EXPORT_C CX509Certificate* CX509Certificate::NewL(const TDesC8& aBinaryData)
sl@0
   794
	{
sl@0
   795
	TInt pos = 0;
sl@0
   796
	return CX509Certificate::NewL(aBinaryData, pos);
sl@0
   797
	}
sl@0
   798
sl@0
   799
EXPORT_C CX509Certificate* CX509Certificate::NewLC(const TDesC8& aBinaryData)
sl@0
   800
	{	
sl@0
   801
	TInt pos = 0;
sl@0
   802
	return CX509Certificate::NewLC(aBinaryData, pos);
sl@0
   803
	}
sl@0
   804
sl@0
   805
EXPORT_C CX509Certificate* CX509Certificate::NewL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   806
	{
sl@0
   807
	CX509Certificate* self = CX509Certificate::NewLC(aBinaryData, aPos);
sl@0
   808
	CleanupStack::Pop();
sl@0
   809
	return self;
sl@0
   810
	}
sl@0
   811
sl@0
   812
EXPORT_C CX509Certificate* CX509Certificate::NewLC(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   813
	{	
sl@0
   814
	CX509Certificate* self = new(ELeave) CX509Certificate();
sl@0
   815
	CleanupStack::PushL(self);
sl@0
   816
	self->ConstructL(aBinaryData, aPos);
sl@0
   817
	return self;
sl@0
   818
	}
sl@0
   819
sl@0
   820
EXPORT_C CX509Certificate* CX509Certificate::NewL(RReadStream& aStream)
sl@0
   821
	{
sl@0
   822
	CX509Certificate* self = CX509Certificate::NewLC(aStream);
sl@0
   823
	CleanupStack::Pop();//self
sl@0
   824
	return self;
sl@0
   825
	}
sl@0
   826
sl@0
   827
EXPORT_C CX509Certificate* CX509Certificate::NewLC(RReadStream& aStream)
sl@0
   828
	{
sl@0
   829
	CX509Certificate* self = new(ELeave) CX509Certificate;
sl@0
   830
	CleanupStack::PushL(self);
sl@0
   831
	self->InternalizeL(aStream);
sl@0
   832
	return self;
sl@0
   833
	}
sl@0
   834
sl@0
   835
void CX509Certificate::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   836
	{
sl@0
   837
	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
sl@0
   838
	gen.InitL();
sl@0
   839
	
sl@0
   840
	// The outermost tag for X509 certificates is always a sequence.
sl@0
   841
	// Since this tag does not form part of the signed data it is possible
sl@0
   842
	// to corrupt the tag by changing it to any other ASN.1 tag and process
sl@0
   843
	// the rest of the certificate as normal.
sl@0
   844
	// However, we still reject the certificate anyway to avoid 
sl@0
   845
	// confusion because the data does not match the X.509 specification.	
sl@0
   846
	if (gen.Tag() != EASN1Sequence)
sl@0
   847
		{
sl@0
   848
		User::Leave(KErrArgument);
sl@0
   849
		}
sl@0
   850
	
sl@0
   851
	aPos += gen.LengthDER();
sl@0
   852
	iKeyFactory = new(ELeave) TX509KeyFactory;
sl@0
   853
sl@0
   854
	iEncoding = gen.Encoding().AllocL();
sl@0
   855
sl@0
   856
	TASN1DecSequence encSeq;
sl@0
   857
	TInt pos = 0;
sl@0
   858
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(*iEncoding, pos, 3, 3);	
sl@0
   859
	TASN1DecGeneric* encSigAlg = seq->At(1);
sl@0
   860
	iSigningAlgorithm = CX509SigningAlgorithmIdentifier::NewL(encSigAlg->Encoding());
sl@0
   861
	TASN1DecBitString encBS;
sl@0
   862
	iSignature = encBS.ExtractOctetStringL(*(seq->At(2)));
sl@0
   863
	CleanupStack::PopAndDestroy();//seq
sl@0
   864
sl@0
   865
	CSHA1* hash = CSHA1::NewL();
sl@0
   866
	CleanupStack::PushL(hash);
sl@0
   867
	iFingerprint = hash->Final(Encoding()).AllocL();
sl@0
   868
	CleanupStack::PopAndDestroy();//hash
sl@0
   869
	ConstructCertL();
sl@0
   870
	}
sl@0
   871
sl@0
   872
void CX509Certificate::ConstructL(const CX509Certificate& aCertificate)
sl@0
   873
	{
sl@0
   874
	iKeyFactory = new(ELeave) TX509KeyFactory;
sl@0
   875
sl@0
   876
	iEncoding = aCertificate.iEncoding->AllocL();
sl@0
   877
	iSignature = aCertificate.iSignature->AllocL();
sl@0
   878
	iFingerprint = aCertificate.iFingerprint->AllocL();
sl@0
   879
	iSigningAlgorithm = CSigningAlgorithmIdentifier::NewL(aCertificate.SigningAlgorithm());	
sl@0
   880
	iSerialNumber = aCertificate.iSerialNumber->Des().AllocL();
sl@0
   881
	iIssuerName = CX500DistinguishedName::NewL(*(aCertificate.iIssuerName));
sl@0
   882
	iValidityPeriod = new(ELeave) CValidityPeriod(*(aCertificate.iValidityPeriod));
sl@0
   883
	iSubjectName = CX500DistinguishedName::NewL(*(aCertificate.iSubjectName));
sl@0
   884
	iSubjectPublicKeyInfo = CSubjectPublicKeyInfo::NewL(*(aCertificate.iSubjectPublicKeyInfo));
sl@0
   885
	iIssuerUid = aCertificate.iIssuerUid->Des().AllocL();
sl@0
   886
	iSubjectUid = aCertificate.iSubjectUid->Des().AllocL();
sl@0
   887
	iExtensions = new(ELeave) CArrayPtrFlat<CX509CertExtension> (1);
sl@0
   888
	TInt count = aCertificate.iExtensions->Count();
sl@0
   889
	for (TInt i = 0; i < count; i++)
sl@0
   890
		{
sl@0
   891
		CX509CertExtension* ext = CX509CertExtension::NewLC(*aCertificate.iExtensions->At(i));
sl@0
   892
		iExtensions->AppendL(ext);
sl@0
   893
		CleanupStack::Pop();//ext
sl@0
   894
		}
sl@0
   895
	iVersion = aCertificate.Version();
sl@0
   896
	InitDataElementsL(aCertificate);
sl@0
   897
	}
sl@0
   898
sl@0
   899
void CX509Certificate::InitDataElementsL(const CX509Certificate& aCertificate)
sl@0
   900
	{
sl@0
   901
	iDataElements = new(ELeave) TFixedArray<TPtrC8*, KX509MaxDataElements>;
sl@0
   902
	iDataElements->Reset();
sl@0
   903
	TPtrC8 signedData = SignedDataL();
sl@0
   904
	TASN1DecSequence encSeq;
sl@0
   905
	TInt pos = 0;
sl@0
   906
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(signedData, pos, 6, KMaxTInt);//6 is the minimum number of elements in an x509 cert
sl@0
   907
	pos = 0;
sl@0
   908
sl@0
   909
	TPtrC8** pElement = iDataElements->Begin();
sl@0
   910
	*pElement++ = aCertificate.DataElementEncoding(CX509Certificate::EVersionNumber)? new(ELeave) TPtrC8(seq->At(pos++)->Encoding()):NULL;
sl@0
   911
	for (TInt i = 0; i < 6; i++)	//init all the non-optional elements
sl@0
   912
		{
sl@0
   913
		*pElement++ = new(ELeave) TPtrC8(seq->At(pos++)->Encoding());
sl@0
   914
		}
sl@0
   915
	*pElement++ = aCertificate.DataElementEncoding(CX509Certificate::EIssuerUID)? new(ELeave) TPtrC8(seq->At(pos++)->Encoding()):NULL;
sl@0
   916
	*pElement++ = aCertificate.DataElementEncoding(CX509Certificate::ESubjectUID)? new(ELeave) TPtrC8(seq->At(pos++)->Encoding()):NULL;
sl@0
   917
	*pElement++ = aCertificate.DataElementEncoding(CX509Certificate::EExtensionList)? new(ELeave) TPtrC8(seq->At(pos++)->Encoding()):NULL;
sl@0
   918
	CleanupStack::PopAndDestroy();
sl@0
   919
	}
sl@0
   920
sl@0
   921
void CX509Certificate::ConstructCertL()
sl@0
   922
	{
sl@0
   923
	TPtrC8 signedData = SignedDataL();
sl@0
   924
	TASN1DecSequence encSeq;
sl@0
   925
	TInt pos = 0;
sl@0
   926
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(signedData, pos, 6, KMaxTInt);//6 is the minimum number of elements in an x509 cert
sl@0
   927
	TInt count = seq->Count();
sl@0
   928
	pos = 0;
sl@0
   929
	TASN1DecGeneric* curr = seq->At(pos);
sl@0
   930
	pos++;
sl@0
   931
	iDataElements = new(ELeave) TFixedArray<TPtrC8*, KX509MaxDataElements>;
sl@0
   932
	iDataElements->Reset();
sl@0
   933
	TPtrC8** pElement = iDataElements->Begin();
sl@0
   934
	if ((curr->Class() == EContextSpecific) && (curr->Tag() == 0))
sl@0
   935
		{
sl@0
   936
		//version!
sl@0
   937
		TASN1DecGeneric ver(curr->GetContentDER());
sl@0
   938
		ver.InitL();
sl@0
   939
		TPtrC8 pVer8 = ver.GetContentDER();
sl@0
   940
		if(pVer8.Length() != 1)
sl@0
   941
			{
sl@0
   942
			User::Leave(KErrArgument);
sl@0
   943
			}
sl@0
   944
		iVersion = (pVer8[0]) + 1;
sl@0
   945
		if ((iVersion < 1) || (iVersion > 3) || (count < 7))
sl@0
   946
			{
sl@0
   947
			User::Leave(KErrArgument);
sl@0
   948
			}
sl@0
   949
		*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
   950
		curr = seq->At(pos);
sl@0
   951
		pos++;
sl@0
   952
		}
sl@0
   953
	else
sl@0
   954
		{
sl@0
   955
		*pElement++ = NULL;
sl@0
   956
		}
sl@0
   957
	if (curr->Tag() != EASN1Integer)
sl@0
   958
		{
sl@0
   959
		User::Leave(KErrArgument);
sl@0
   960
		}
sl@0
   961
	iSerialNumber = (curr->GetContentDER()).AllocL();
sl@0
   962
	*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
   963
	curr = seq->At(pos);
sl@0
   964
	pos++;
sl@0
   965
	CX509SigningAlgorithmIdentifier* algorithmId = CX509SigningAlgorithmIdentifier::NewLC(curr->Encoding());
sl@0
   966
	if (!(SigningAlgorithm() == *(algorithmId)))
sl@0
   967
		{
sl@0
   968
		User::Leave(KErrArgument);
sl@0
   969
		}
sl@0
   970
	CleanupStack::PopAndDestroy();//algorithmId
sl@0
   971
	*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
   972
sl@0
   973
	curr = seq->At(pos);
sl@0
   974
	pos++;
sl@0
   975
	iIssuerName = CX500DistinguishedName::NewL(curr->Encoding());
sl@0
   976
	*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
   977
	curr = seq->At(pos);
sl@0
   978
	pos++;
sl@0
   979
	iValidityPeriod = CX509ValidityPeriod::NewL(curr->Encoding());
sl@0
   980
	*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
   981
	curr = seq->At(pos);
sl@0
   982
	pos++;
sl@0
   983
	iSubjectName = CX500DistinguishedName::NewL(curr->Encoding());
sl@0
   984
	*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
   985
	curr = seq->At(pos);
sl@0
   986
	pos++;
sl@0
   987
	iSubjectPublicKeyInfo = CX509SubjectPublicKeyInfo::NewL(curr->Encoding());
sl@0
   988
	*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
   989
	//do issuer uid, subject uid, exts
sl@0
   990
	//these are all optional
sl@0
   991
	TBool hasIssuerUid = EFalse;
sl@0
   992
	TBool hasSubjectUid = EFalse;
sl@0
   993
	TBool hasExts = EFalse;
sl@0
   994
	iExtensions = new(ELeave)CArrayPtrFlat<CX509CertExtension> (1);
sl@0
   995
	if (pos < count)//otherwise there aren't any of 'em
sl@0
   996
		{
sl@0
   997
		curr = seq->At(pos);
sl@0
   998
		pos++;
sl@0
   999
		if (curr->Class() != EContextSpecific)
sl@0
  1000
			{
sl@0
  1001
			User::Leave(KErrArgument);
sl@0
  1002
			}
sl@0
  1003
		switch(curr->Tag())
sl@0
  1004
			{
sl@0
  1005
			case 1:
sl@0
  1006
				{
sl@0
  1007
				iIssuerUid = DecodeUidL(curr->GetContentDER(), hasIssuerUid);
sl@0
  1008
				*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
  1009
				break;
sl@0
  1010
				}
sl@0
  1011
			case 2:
sl@0
  1012
				{
sl@0
  1013
				iSubjectUid = DecodeUidL(curr->GetContentDER(), hasSubjectUid);
sl@0
  1014
				*pElement++ = NULL;
sl@0
  1015
				*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
  1016
				break;
sl@0
  1017
				}
sl@0
  1018
			case 3:
sl@0
  1019
				{
sl@0
  1020
				DecodeExtsL(curr->GetContentDER(), hasExts);
sl@0
  1021
				*pElement++ = NULL;
sl@0
  1022
				*pElement++ = NULL;
sl@0
  1023
				*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
  1024
				break;
sl@0
  1025
				}
sl@0
  1026
			default:
sl@0
  1027
				{
sl@0
  1028
				User::Leave(KErrArgument);
sl@0
  1029
				}
sl@0
  1030
			}
sl@0
  1031
		if (pos < count)
sl@0
  1032
			{
sl@0
  1033
			curr = seq->At(pos);
sl@0
  1034
			pos++;
sl@0
  1035
			switch(curr->Tag())
sl@0
  1036
				{
sl@0
  1037
				case 2:
sl@0
  1038
					{
sl@0
  1039
					iSubjectUid = DecodeUidL(curr->GetContentDER(), hasSubjectUid);
sl@0
  1040
					*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
  1041
					break;
sl@0
  1042
					}
sl@0
  1043
				case 3:
sl@0
  1044
					{
sl@0
  1045
					DecodeExtsL(curr->GetContentDER(), hasExts);
sl@0
  1046
					*pElement++ = NULL;
sl@0
  1047
					*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
  1048
					break;
sl@0
  1049
					}
sl@0
  1050
				default:
sl@0
  1051
					{
sl@0
  1052
					User::Leave(KErrArgument);
sl@0
  1053
					}
sl@0
  1054
				}
sl@0
  1055
			if (pos < count)
sl@0
  1056
				{
sl@0
  1057
				curr = seq->At(pos);
sl@0
  1058
				pos++;
sl@0
  1059
				if (curr->Tag() == 3)
sl@0
  1060
					{
sl@0
  1061
					DecodeExtsL(curr->GetContentDER(), hasExts);
sl@0
  1062
					*pElement++ = new(ELeave) TPtrC8(curr->Encoding());
sl@0
  1063
					}
sl@0
  1064
				else
sl@0
  1065
					{
sl@0
  1066
					User::Leave(KErrArgument);
sl@0
  1067
					}
sl@0
  1068
				}
sl@0
  1069
			}
sl@0
  1070
		}
sl@0
  1071
	if (pos != count)
sl@0
  1072
		{
sl@0
  1073
		User::Leave(KErrArgument);
sl@0
  1074
		}
sl@0
  1075
	if (!iIssuerUid)
sl@0
  1076
		{
sl@0
  1077
		iIssuerUid = HBufC8::NewL(1);
sl@0
  1078
		*iIssuerUid = KNullDesC8;
sl@0
  1079
		}
sl@0
  1080
	if (!iSubjectUid)
sl@0
  1081
		{
sl@0
  1082
		iSubjectUid = HBufC8::NewL(1);
sl@0
  1083
		*iSubjectUid = KNullDesC8;
sl@0
  1084
		}
sl@0
  1085
		
sl@0
  1086
	// we have not checked for the certificate version number based on 
sl@0
  1087
	// the certificate contents. This is primarily done to avoid BC for 
sl@0
  1088
	// clients who are still using malformed certificates.
sl@0
  1089
	
sl@0
  1090
	CleanupStack::PopAndDestroy();//seq
sl@0
  1091
	}
sl@0
  1092
sl@0
  1093
CX509Certificate::CX509Certificate()
sl@0
  1094
	:iVersion(1)
sl@0
  1095
	{
sl@0
  1096
	}
sl@0
  1097
sl@0
  1098
EXPORT_C CX509Certificate::~CX509Certificate()
sl@0
  1099
	{
sl@0
  1100
	delete iIssuerName;
sl@0
  1101
	delete iSubjectName;
sl@0
  1102
	delete iIssuerUid;
sl@0
  1103
	delete iSubjectUid;
sl@0
  1104
	
sl@0
  1105
	if (iDataElements != NULL)
sl@0
  1106
		{
sl@0
  1107
		for (TInt i = 0; i < KX509MaxDataElements; i++)
sl@0
  1108
			{
sl@0
  1109
			delete iDataElements->At(i);
sl@0
  1110
			}
sl@0
  1111
		delete iDataElements;
sl@0
  1112
		}
sl@0
  1113
	if (iExtensions != NULL)
sl@0
  1114
		{
sl@0
  1115
		iExtensions->ResetAndDestroy();
sl@0
  1116
		}
sl@0
  1117
	delete iExtensions;
sl@0
  1118
	}
sl@0
  1119
sl@0
  1120
EXPORT_C TBool CX509Certificate::IsEqualL(const CX509Certificate& aCert) const
sl@0
  1121
	{
sl@0
  1122
	return	(	(*(iSerialNumber) == *(aCert.iSerialNumber)) && 
sl@0
  1123
				(iIssuerName->ExactMatchL(*(aCert.iIssuerName)))	);
sl@0
  1124
	}
sl@0
  1125
sl@0
  1126
EXPORT_C void CX509Certificate::InternalizeL(RReadStream& aStream)
sl@0
  1127
	{
sl@0
  1128
	if (iIssuerName != NULL) //just to check cert is uninitialised
sl@0
  1129
		{
sl@0
  1130
		User::Leave(KErrArgument);
sl@0
  1131
		}
sl@0
  1132
	iKeyFactory = new(ELeave) TX509KeyFactory;
sl@0
  1133
	
sl@0
  1134
	TInt len = aStream.ReadInt32L(); //Read the length of the streamed encoding
sl@0
  1135
	HBufC8* temp= HBufC8::NewLC(len);	
sl@0
  1136
	TPtr8 ptr=temp->Des();
sl@0
  1137
	aStream.ReadL(ptr,len);
sl@0
  1138
	iEncoding=temp->AllocL();
sl@0
  1139
	CleanupStack::PopAndDestroy(); // temp
sl@0
  1140
sl@0
  1141
	TASN1DecSequence encSeq;
sl@0
  1142
	TInt pos = 0;
sl@0
  1143
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(*iEncoding, pos, 3, 3);	
sl@0
  1144
	TASN1DecGeneric* encSigAlg = seq->At(1);
sl@0
  1145
	iSigningAlgorithm = CX509SigningAlgorithmIdentifier::NewL(encSigAlg->Encoding());
sl@0
  1146
	TASN1DecBitString encBS;
sl@0
  1147
	iSignature = encBS.ExtractOctetStringL(*(seq->At(2)));
sl@0
  1148
	CleanupStack::PopAndDestroy();//seq	
sl@0
  1149
sl@0
  1150
	CSHA1* hash = CSHA1::NewL();
sl@0
  1151
	CleanupStack::PushL(hash);
sl@0
  1152
	iFingerprint = hash->Final(Encoding()).AllocL();
sl@0
  1153
	CleanupStack::PopAndDestroy();//hash
sl@0
  1154
sl@0
  1155
	ConstructCertL();
sl@0
  1156
	}
sl@0
  1157
sl@0
  1158
void CX509Certificate::DecodeExtsL(const TDesC8& aBinaryData, TBool& aHasElementAlready)
sl@0
  1159
	{
sl@0
  1160
	TASN1DecSequence encSeq;
sl@0
  1161
	TInt pos = 0;
sl@0
  1162
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(aBinaryData, pos);
sl@0
  1163
	TInt count = seq->Count();
sl@0
  1164
	for (TInt i = 0; i < count; i++)
sl@0
  1165
		{
sl@0
  1166
		TASN1DecGeneric* gen = seq->At(i);
sl@0
  1167
		CX509CertExtension* ext = CX509CertExtension::NewLC(gen->Encoding());
sl@0
  1168
		iExtensions->AppendL(ext);
sl@0
  1169
		CleanupStack::Pop();//ext
sl@0
  1170
		}
sl@0
  1171
	CleanupStack::PopAndDestroy();//
sl@0
  1172
	aHasElementAlready = ETrue;
sl@0
  1173
	}
sl@0
  1174
sl@0
  1175
HBufC8* CX509Certificate::DecodeUidL(const TDesC8& aBinaryData, TBool& aHasElementAlready)
sl@0
  1176
	{
sl@0
  1177
	if ((aHasElementAlready) || (iVersion ==1))
sl@0
  1178
		{
sl@0
  1179
		User::Leave(KErrArgument);
sl@0
  1180
		}
sl@0
  1181
	aHasElementAlready = ETrue;
sl@0
  1182
	return aBinaryData.AllocL();
sl@0
  1183
	}
sl@0
  1184
sl@0
  1185
//***************************************************************************************//
sl@0
  1186
//extra accessors
sl@0
  1187
EXPORT_C const TPtrC8 CX509Certificate::SignedDataL() const
sl@0
  1188
	{
sl@0
  1189
	TASN1DecSequence encSeq;
sl@0
  1190
	TInt pos = 0;
sl@0
  1191
	CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(*iEncoding, pos, 3, 3);
sl@0
  1192
	TASN1DecGeneric* gen = seq->At(0);
sl@0
  1193
	TPtrC8 res = gen->Encoding();
sl@0
  1194
	CleanupStack::PopAndDestroy();
sl@0
  1195
	return res;
sl@0
  1196
	}
sl@0
  1197
sl@0
  1198
EXPORT_C TInt CX509Certificate::Version() const
sl@0
  1199
	{
sl@0
  1200
	return iVersion;
sl@0
  1201
	}
sl@0
  1202
sl@0
  1203
/**
sl@0
  1204
* If the certificate has decoded the members from TeletexString then the return value 
sl@0
  1205
* may be incorrect because TeletexString type is not fully supported by this library.
sl@0
  1206
* Instead the decode methods perform a direct conversion from 8 to 16bits by adding 
sl@0
  1207
* null characters in the second byte of each character. This will work as expected 
sl@0
  1208
* for cases where the string contains ASCII data.
sl@0
  1209
*/
sl@0
  1210
EXPORT_C const CX500DistinguishedName& CX509Certificate::IssuerName() const
sl@0
  1211
	{
sl@0
  1212
	return *iIssuerName;
sl@0
  1213
	}
sl@0
  1214
sl@0
  1215
/**
sl@0
  1216
* If the certificate has decoded the members from TeletexString then the return value 
sl@0
  1217
* may be incorrect because TeletexString type is not fully supported by this library.
sl@0
  1218
* Instead the decode methods perform a direct conversion from 8 to 16bits by adding 
sl@0
  1219
* null characters in the second byte of each character. This will work as expected 
sl@0
  1220
* for cases where the string contains ASCII data.
sl@0
  1221
*/
sl@0
  1222
EXPORT_C const CX500DistinguishedName& CX509Certificate::SubjectName() const
sl@0
  1223
	{
sl@0
  1224
	return *iSubjectName;
sl@0
  1225
	}
sl@0
  1226
sl@0
  1227
EXPORT_C const CArrayPtrFlat<CX509CertExtension>& CX509Certificate::Extensions() const
sl@0
  1228
	{
sl@0
  1229
	return *iExtensions;
sl@0
  1230
	}
sl@0
  1231
sl@0
  1232
EXPORT_C const CX509CertExtension* CX509Certificate::Extension(const TDesC& aExtensionName) const
sl@0
  1233
	{
sl@0
  1234
	TInt count = iExtensions->Count();
sl@0
  1235
	for (TInt i = 0; i < count; i++)
sl@0
  1236
		{
sl@0
  1237
		CX509CertExtension* ext = iExtensions->At(i);
sl@0
  1238
		if (ext->Id() == aExtensionName)
sl@0
  1239
			return ext;
sl@0
  1240
		}
sl@0
  1241
	return NULL;
sl@0
  1242
	}
sl@0
  1243
sl@0
  1244
EXPORT_C const TPtrC8* CX509Certificate::DataElementEncoding(const TUint aIndex) const
sl@0
  1245
	{
sl@0
  1246
	return iDataElements->At(aIndex);
sl@0
  1247
	}
sl@0
  1248
sl@0
  1249
/**
sl@0
  1250
* If the certificate has decoded the members from TeletexString then the return value 
sl@0
  1251
* may be incorrect because TeletexString type is not fully supported by this library.
sl@0
  1252
* Instead the decode methods perform a direct conversion from 8 to 16bits by adding 
sl@0
  1253
* null characters in the second byte of each character. This will work as expected 
sl@0
  1254
* for cases where the string contains ASCII data.
sl@0
  1255
*/
sl@0
  1256
EXPORT_C HBufC* CX509Certificate::IssuerL() const
sl@0
  1257
	{
sl@0
  1258
	return iIssuerName->DisplayNameL();
sl@0
  1259
	}
sl@0
  1260
sl@0
  1261
/**
sl@0
  1262
* If the certificate has decoded the members from TeletexString then the return value 
sl@0
  1263
* may be incorrect because TeletexString type is not fully supported by this library.
sl@0
  1264
* Instead the decode methods perform a direct conversion from 8 to 16bits by adding 
sl@0
  1265
* null characters in the second byte of each character. This will work as expected 
sl@0
  1266
* for cases where the string contains ASCII data.
sl@0
  1267
*/
sl@0
  1268
EXPORT_C HBufC* CX509Certificate::SubjectL() const
sl@0
  1269
	{
sl@0
  1270
	return iSubjectName->DisplayNameL();
sl@0
  1271
	}
sl@0
  1272
sl@0
  1273
EXPORT_C TBool CX509Certificate::IsSelfSignedL() const
sl@0
  1274
	{
sl@0
  1275
	if (iSubjectName->Count() > 0)
sl@0
  1276
		{
sl@0
  1277
		return iSubjectName->ExactMatchL(*iIssuerName);
sl@0
  1278
		}
sl@0
  1279
	else
sl@0
  1280
		{
sl@0
  1281
		TBool res = EFalse;
sl@0
  1282
		const CX509CertExtension* subjectExt = Extension(KIssuerAltName);
sl@0
  1283
		const CX509CertExtension* issuerExt = Extension(KSubjectAltName);
sl@0
  1284
		if ((subjectExt) && (issuerExt))
sl@0
  1285
			{
sl@0
  1286
			const CX509AltNameExt* issuerAltName = CX509AltNameExt::NewLC(subjectExt->Data());
sl@0
  1287
			const CX509AltNameExt* subjectAltName = CX509AltNameExt::NewLC(issuerExt->Data());
sl@0
  1288
			if (subjectAltName->Match(*issuerAltName))
sl@0
  1289
				{
sl@0
  1290
				res = ETrue;
sl@0
  1291
				}
sl@0
  1292
			CleanupStack::PopAndDestroy(2);//subjectAltName, issuerAltName
sl@0
  1293
			}
sl@0
  1294
		return res;
sl@0
  1295
		} 
sl@0
  1296
	}
sl@0
  1297
sl@0
  1298
sl@0
  1299
EXPORT_C TKeyIdentifier CX509Certificate::KeyIdentifierL() const	
sl@0
  1300
	{
sl@0
  1301
	if (iSubjectPublicKeyInfo->AlgorithmId() != EDSA)
sl@0
  1302
		{
sl@0
  1303
		// The base class handles the RSA case and leaves with KErrNotSupported if
sl@0
  1304
		// it is not RSA.
sl@0
  1305
		return CCertificate::KeyIdentifierL();
sl@0
  1306
		}
sl@0
  1307
	else
sl@0
  1308
		{
sl@0
  1309
		// This handles the DSA case
sl@0
  1310
		CDSAPublicKey* dsaKey = 
sl@0
  1311
						iKeyFactory->DSAPublicKeyL(iSubjectPublicKeyInfo->EncodedParams(), 
sl@0
  1312
													iSubjectPublicKeyInfo->KeyData());
sl@0
  1313
		CleanupStack::PushL(dsaKey);
sl@0
  1314
		TKeyIdentifier retVal;
sl@0
  1315
		KeyIdentifierUtil::DSAKeyIdentifierL(*dsaKey, retVal);
sl@0
  1316
		CleanupStack::PopAndDestroy(dsaKey);
sl@0
  1317
		return retVal;
sl@0
  1318
		}
sl@0
  1319
	}
sl@0
  1320
sl@0
  1321
EXPORT_C TKeyIdentifier CX509Certificate::SubjectKeyIdentifierL() const
sl@0
  1322
	{	
sl@0
  1323
	const CX509CertExtension* subjectKeyIdExtStr = this->Extension(KSubjectKeyId);
sl@0
  1324
	if (subjectKeyIdExtStr)
sl@0
  1325
		{
sl@0
  1326
		TKeyIdentifier ret;
sl@0
  1327
		CX509SubjectKeyIdExt *subjectKeyIdExt = CX509SubjectKeyIdExt::NewLC(subjectKeyIdExtStr->Data());
sl@0
  1328
		// Currently, we do not support key identifiers larger than 160 bits - make sure not to overflow the descriptor
sl@0
  1329
		if (subjectKeyIdExt->KeyId().Length() <= ret.MaxLength())
sl@0
  1330
			{
sl@0
  1331
			ret.Copy(subjectKeyIdExt->KeyId());
sl@0
  1332
			CleanupStack::PopAndDestroy(subjectKeyIdExt);
sl@0
  1333
			return ret;
sl@0
  1334
			}
sl@0
  1335
		CleanupStack::PopAndDestroy(subjectKeyIdExt);
sl@0
  1336
		}
sl@0
  1337
		
sl@0
  1338
	return KeyIdentifierL();
sl@0
  1339
	}
sl@0
  1340
sl@0
  1341
sl@0
  1342
EXPORT_C TKeyIdentifier CX509Certificate::SubjectKeyIdL() const
sl@0
  1343
	{
sl@0
  1344
	// if it is a v1 or v2 type then there is no way of knowing which is a CA, treat all certs as CA as done in the certificate recognizer.
sl@0
  1345
	if (Version() < 3 )
sl@0
  1346
		{
sl@0
  1347
		return SubjectKeyIdentifierL();
sl@0
  1348
		}
sl@0
  1349
	
sl@0
  1350
	// if it is x509 v3 certificate then check for the basic constraint extension.
sl@0
  1351
	const CX509CertExtension* ext = Extension(KBasicConstraints);
sl@0
  1352
	if (ext)
sl@0
  1353
		{
sl@0
  1354
		CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC(ext->Data());
sl@0
  1355
		TBool markedAsCA = basic->IsCA();
sl@0
  1356
		CleanupStack::PopAndDestroy(basic);
sl@0
  1357
		// it can be an intermediate as well as root CA
sl@0
  1358
		if ( markedAsCA )
sl@0
  1359
			{
sl@0
  1360
			return SubjectKeyIdentifierL();
sl@0
  1361
			}
sl@0
  1362
		}
sl@0
  1363
	// For non-CA certs, use the recommended method of computing it from RFC5280, section 4.2.1.2
sl@0
  1364
	return KeyIdentifierL();									
sl@0
  1365
		
sl@0
  1366
	}
sl@0
  1367