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