os/security/cryptoservices/certificateandkeymgmt/pkcs7/cmssignerinfo.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) 2006-2009 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
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include <cmssignerinfo.h>
sl@0
    20
#include <asn1dec.h>
sl@0
    21
#include <asn1enc.h>
sl@0
    22
#include <x509cert.h>
sl@0
    23
#include <cmssigneridentifier.h>
sl@0
    24
#include <cmsdefs.h>
sl@0
    25
#include "cmsutils.h"
sl@0
    26
#include "pkcs7asn1.h"
sl@0
    27
sl@0
    28
//
sl@0
    29
// Implementation of CCmsSignerInfo
sl@0
    30
//
sl@0
    31
CCmsSignerInfo* CCmsSignerInfo::NewL(const TDesC8& aDataToBeSigned,
sl@0
    32
									TBool aIsHash,
sl@0
    33
									const CDSAPrivateKey& aKey,
sl@0
    34
									CCmsSignerIdentifier* aSignerIdentifier,
sl@0
    35
									CX509AlgorithmIdentifier* aDigestAlgorithm,
sl@0
    36
									CX509AlgorithmIdentifier* aSignatureAlgorithm)
sl@0
    37
	{
sl@0
    38
	CCmsSignerInfo* self = NewLC(aDataToBeSigned,
sl@0
    39
								 aIsHash,
sl@0
    40
								 aKey,
sl@0
    41
								 aSignerIdentifier,
sl@0
    42
								 aDigestAlgorithm,
sl@0
    43
								 aSignatureAlgorithm);
sl@0
    44
	CleanupStack::Pop(self);
sl@0
    45
	return self;
sl@0
    46
	}
sl@0
    47
										
sl@0
    48
CCmsSignerInfo* CCmsSignerInfo::NewLC(const TDesC8& aDataToBeSigned,
sl@0
    49
									TBool aIsHash,
sl@0
    50
									const CDSAPrivateKey& aKey,
sl@0
    51
									CCmsSignerIdentifier* aSignerIdentifier,
sl@0
    52
									CX509AlgorithmIdentifier* aDigestAlgorithm,
sl@0
    53
									CX509AlgorithmIdentifier* aSignatureAlgorithm)
sl@0
    54
	{
sl@0
    55
	if (!aSignerIdentifier||!aDigestAlgorithm||!aSignatureAlgorithm)
sl@0
    56
		{
sl@0
    57
		User::Leave(KErrArgument);	
sl@0
    58
		}
sl@0
    59
	CCmsSignerInfo* self = new (ELeave) CCmsSignerInfo();
sl@0
    60
	CleanupStack::PushL(self);
sl@0
    61
	self->ConstructL(aDataToBeSigned, aIsHash, aKey, aSignerIdentifier, aDigestAlgorithm, aSignatureAlgorithm);
sl@0
    62
	return self;
sl@0
    63
	}
sl@0
    64
sl@0
    65
CCmsSignerInfo* CCmsSignerInfo::NewL(const TDesC8& aDataToBeSigned,
sl@0
    66
									TBool aIsHash,
sl@0
    67
									const CRSAPrivateKey& aKey,
sl@0
    68
									CCmsSignerIdentifier* aSignerIdentifier,
sl@0
    69
									CX509AlgorithmIdentifier* aDigestAlgorithm,
sl@0
    70
									CX509AlgorithmIdentifier* aSignatureAlgorithm)
sl@0
    71
	{
sl@0
    72
	CCmsSignerInfo* self = NewLC(aDataToBeSigned,
sl@0
    73
								 aIsHash,
sl@0
    74
								 aKey,
sl@0
    75
								 aSignerIdentifier,
sl@0
    76
								 aDigestAlgorithm,
sl@0
    77
								 aSignatureAlgorithm);
sl@0
    78
	CleanupStack::Pop(self);
sl@0
    79
	return self;		
sl@0
    80
	}
sl@0
    81
sl@0
    82
CCmsSignerInfo* CCmsSignerInfo::NewLC(const TDesC8& aDataToBeSigned,
sl@0
    83
									TBool aIsHash,
sl@0
    84
									const CRSAPrivateKey& aKey,
sl@0
    85
									CCmsSignerIdentifier* aSignerIdentifier,
sl@0
    86
									CX509AlgorithmIdentifier* aDigestAlgorithm,
sl@0
    87
									CX509AlgorithmIdentifier* aSignatureAlgorithm)
sl@0
    88
	{
sl@0
    89
	if (!aSignerIdentifier||!aDigestAlgorithm||!aSignatureAlgorithm)
sl@0
    90
		{
sl@0
    91
		User::Leave(KErrArgument);	
sl@0
    92
		}
sl@0
    93
sl@0
    94
	CCmsSignerInfo* self = new (ELeave) CCmsSignerInfo();
sl@0
    95
	CleanupStack::PushL(self);
sl@0
    96
	self->ConstructL(aDataToBeSigned, aIsHash, aKey, aSignerIdentifier, aDigestAlgorithm, aSignatureAlgorithm);
sl@0
    97
	return self;
sl@0
    98
	}
sl@0
    99
sl@0
   100
CCmsSignerInfo* CCmsSignerInfo::NewL(const TDesC8& aRawData)
sl@0
   101
	{
sl@0
   102
	CCmsSignerInfo* self = NewLC(aRawData);
sl@0
   103
	CleanupStack::Pop(self);
sl@0
   104
	return self;
sl@0
   105
	}
sl@0
   106
	
sl@0
   107
CCmsSignerInfo* CCmsSignerInfo::NewLC(const TDesC8& aRawData)
sl@0
   108
	{
sl@0
   109
	CCmsSignerInfo* self = new (ELeave) CCmsSignerInfo();
sl@0
   110
	CleanupStack::PushL(self);
sl@0
   111
	self->ConstructL(aRawData);
sl@0
   112
	return self;
sl@0
   113
	}
sl@0
   114
sl@0
   115
CCmsSignerInfo::CCmsSignerInfo()
sl@0
   116
	{	
sl@0
   117
	}
sl@0
   118
	
sl@0
   119
CCmsSignerInfo::~CCmsSignerInfo()
sl@0
   120
	{
sl@0
   121
	delete iDigestAlgorithm;
sl@0
   122
	delete iSignatureAlgorithm;
sl@0
   123
	delete iSignatureValue;	
sl@0
   124
	delete iSignerIdentifier;
sl@0
   125
	}
sl@0
   126
sl@0
   127
void CCmsSignerInfo::ConstructL(const TDesC8& aDataToBeSigned, 	
sl@0
   128
								TBool aIsHash, 
sl@0
   129
								const CDSAPrivateKey& aKey,
sl@0
   130
								CCmsSignerIdentifier* aSignerIdentifier,
sl@0
   131
								CX509AlgorithmIdentifier* aDigestAlgorithm,
sl@0
   132
								CX509AlgorithmIdentifier* aSignatureAlgorithm)
sl@0
   133
								
sl@0
   134
	{
sl@0
   135
	if (aSignatureAlgorithm->Algorithm()!=EDSA)
sl@0
   136
		{
sl@0
   137
		User::Leave(KErrArgument);	
sl@0
   138
		}
sl@0
   139
	iSignatureValue=CmsUtils::CreateSignatureL(aDataToBeSigned, aIsHash, aDigestAlgorithm->Algorithm(), aKey);
sl@0
   140
	
sl@0
   141
	iSignerIdentifier=aSignerIdentifier;
sl@0
   142
	iDigestAlgorithm=aDigestAlgorithm;
sl@0
   143
	iSignatureAlgorithm=aSignatureAlgorithm;
sl@0
   144
	//find out the CMS signer info version
sl@0
   145
	if (iSignerIdentifier->SignerIdentifierType() == CCmsSignerIdentifier::EIssuerAndSerialNumber)
sl@0
   146
		{
sl@0
   147
		iVersion=EVersion_1;
sl@0
   148
		}
sl@0
   149
	else if (iSignerIdentifier->SignerIdentifierType() == CCmsSignerIdentifier::ESubjectKeyIdentifier)
sl@0
   150
		{
sl@0
   151
		iVersion=EVersion_3;	
sl@0
   152
		}	
sl@0
   153
	
sl@0
   154
	}
sl@0
   155
sl@0
   156
void CCmsSignerInfo::ConstructL(const TDesC8& aDataToBeSigned, 	
sl@0
   157
								TBool aIsHash, 
sl@0
   158
								const CRSAPrivateKey& aKey,
sl@0
   159
								CCmsSignerIdentifier* aSignerIdentifier,
sl@0
   160
								CX509AlgorithmIdentifier* aDigestAlgorithm,
sl@0
   161
								CX509AlgorithmIdentifier* aSignatureAlgorithm)								
sl@0
   162
	{
sl@0
   163
	if (aSignatureAlgorithm->Algorithm()!=ERSA)
sl@0
   164
		{
sl@0
   165
		User::Leave(KErrArgument);	
sl@0
   166
		}
sl@0
   167
	iSignatureValue=CmsUtils::CreateSignatureL(aDataToBeSigned, aIsHash, aDigestAlgorithm->Algorithm(), aKey);
sl@0
   168
	iSignerIdentifier=aSignerIdentifier;
sl@0
   169
	iDigestAlgorithm=aDigestAlgorithm;
sl@0
   170
	iSignatureAlgorithm=aSignatureAlgorithm;
sl@0
   171
	//find out the CMS signer info version
sl@0
   172
	if (iSignerIdentifier->SignerIdentifierType() == CCmsSignerIdentifier::EIssuerAndSerialNumber)
sl@0
   173
		{
sl@0
   174
		iVersion=EVersion_1;
sl@0
   175
		}
sl@0
   176
	else if (iSignerIdentifier->SignerIdentifierType() == CCmsSignerIdentifier::ESubjectKeyIdentifier)
sl@0
   177
		{
sl@0
   178
		iVersion=EVersion_3;	
sl@0
   179
		}
sl@0
   180
	}
sl@0
   181
sl@0
   182
void CCmsSignerInfo::ConstructL(const TDesC8& aRawData)
sl@0
   183
	{
sl@0
   184
	CArrayPtr<TASN1DecGeneric>* signerInfo = PKCS7ASN1::DecodeSequenceLC(aRawData, 5, 7);
sl@0
   185
	TASN1DecInteger decInt;
sl@0
   186
	TInt pos = 0;
sl@0
   187
	// decodes version
sl@0
   188
	iVersion = decInt.DecodeDERShortL(*signerInfo->At(pos++));
sl@0
   189
	if (iVersion<0 || iVersion>4)
sl@0
   190
		{
sl@0
   191
		User::Leave(KErrArgument);	
sl@0
   192
		}
sl@0
   193
sl@0
   194
	DecodeSignerIdentifierL(signerInfo->At(pos++)->Encoding());
sl@0
   195
	
sl@0
   196
	iDigestAlgorithm = CX509AlgorithmIdentifier::NewL(signerInfo->At(pos++)->Encoding());
sl@0
   197
sl@0
   198
	if(signerInfo->At(pos)->Tag() == 0 && signerInfo->At(pos)->Class() == EContextSpecific)
sl@0
   199
		{
sl@0
   200
		// authenticated attributes not supported at this time
sl@0
   201
		iSignedAttributesPresent=ETrue;
sl@0
   202
		pos++;
sl@0
   203
		}
sl@0
   204
	iSignatureAlgorithm = CX509AlgorithmIdentifier::NewL(signerInfo->At(pos++)->Encoding());
sl@0
   205
	DecodeEncryptedDigestL(signerInfo->At(pos++)->Encoding());
sl@0
   206
sl@0
   207
	if(pos < signerInfo->Count() && signerInfo->At(pos)->Tag() == 1 && signerInfo->At(pos)->Class() == EContextSpecific)
sl@0
   208
		{
sl@0
   209
		// unauthenticated attributes not supported at this time
sl@0
   210
		iUnsignedAttributesPresent=ETrue;
sl@0
   211
		pos++;		
sl@0
   212
		}
sl@0
   213
sl@0
   214
	CleanupStack::PopAndDestroy(signerInfo);
sl@0
   215
	}
sl@0
   216
	
sl@0
   217
CASN1EncSequence* CCmsSignerInfo::EncodeASN1DERLC() const
sl@0
   218
	{
sl@0
   219
	// the root sequence contains the signed object
sl@0
   220
	CASN1EncSequence* root = CASN1EncSequence::NewLC();
sl@0
   221
	
sl@0
   222
	//Encode the version
sl@0
   223
	CASN1EncInt* version=CASN1EncInt::NewLC(iVersion);	
sl@0
   224
	root->AddAndPopChildL(version);
sl@0
   225
	
sl@0
   226
	//Encode sid
sl@0
   227
	CASN1EncBase* sid=EncodeSignerIdentifierLC();
sl@0
   228
	root->AddAndPopChildL(sid);
sl@0
   229
	
sl@0
   230
	//Encode Digest Algoritm
sl@0
   231
	CASN1EncSequence* digAlg=iDigestAlgorithm->EncodeASN1DERLC();
sl@0
   232
	root->AddAndPopChildL(digAlg);
sl@0
   233
	
sl@0
   234
	//Encode signature Algoritm
sl@0
   235
	CASN1EncSequence* sigAlg=iSignatureAlgorithm->EncodeASN1DERLC();
sl@0
   236
	root->AddAndPopChildL(sigAlg);
sl@0
   237
	
sl@0
   238
	//Encode signature value
sl@0
   239
	CASN1EncOctetString* sigEnc=CASN1EncOctetString::NewLC(iSignatureValue->Des());
sl@0
   240
	root->AddAndPopChildL(sigEnc);
sl@0
   241
	
sl@0
   242
	return root;	
sl@0
   243
	}
sl@0
   244
	
sl@0
   245
void CCmsSignerInfo::DecodeEncryptedDigestL(const TDesC8& aRawData)
sl@0
   246
	{
sl@0
   247
	CmsUtils::DecodeOctetStringL(aRawData, iSignatureValue);
sl@0
   248
	}
sl@0
   249
sl@0
   250
void CCmsSignerInfo::DecodeSignerIdentifierL(const TDesC8& aRawData)
sl@0
   251
	{
sl@0
   252
	iSignerIdentifier=CCmsSignerIdentifier::NewL(aRawData);
sl@0
   253
	}
sl@0
   254
sl@0
   255
CASN1EncBase* CCmsSignerInfo::EncodeSignerIdentifierLC() const
sl@0
   256
	{
sl@0
   257
	return iSignerIdentifier->EncodeASN1DERLC();	
sl@0
   258
	}
sl@0
   259
sl@0
   260
EXPORT_C TInt CCmsSignerInfo::Version() const
sl@0
   261
	{
sl@0
   262
	return iVersion;
sl@0
   263
	}
sl@0
   264
sl@0
   265
EXPORT_C TBool CCmsSignerInfo::IsSignedAttributesPresent() const
sl@0
   266
	{
sl@0
   267
	return iSignedAttributesPresent;	
sl@0
   268
	}
sl@0
   269
sl@0
   270
EXPORT_C TBool CCmsSignerInfo::IsUnsignedAttributesPresent() const
sl@0
   271
	{
sl@0
   272
	return iUnsignedAttributesPresent;	
sl@0
   273
	}
sl@0
   274
	
sl@0
   275
EXPORT_C const CX509AlgorithmIdentifier& CCmsSignerInfo::DigestAlgorithm() const
sl@0
   276
	{
sl@0
   277
	return *iDigestAlgorithm;	
sl@0
   278
	}
sl@0
   279
sl@0
   280
EXPORT_C const CX509AlgorithmIdentifier& CCmsSignerInfo::SignatureAlgorithm() const	
sl@0
   281
	{
sl@0
   282
	return *iSignatureAlgorithm;	
sl@0
   283
	}
sl@0
   284
sl@0
   285
EXPORT_C const TPtrC8 CCmsSignerInfo::SignatureValue() const
sl@0
   286
	{
sl@0
   287
	return *iSignatureValue;	
sl@0
   288
	}
sl@0
   289
	
sl@0
   290
EXPORT_C const CCmsSignerIdentifier& CCmsSignerInfo::SignerIdentifier() const
sl@0
   291
	{
sl@0
   292
	return *iSignerIdentifier;
sl@0
   293
	}
sl@0
   294
sl@0
   295
sl@0
   296
sl@0
   297
sl@0
   298
sl@0
   299
	
sl@0
   300
	
sl@0
   301
	
sl@0
   302
	
sl@0
   303
sl@0
   304
sl@0
   305
sl@0
   306
sl@0
   307