sl@0
|
1 |
/*
|
sl@0
|
2 |
Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
|
sl@0
|
3 |
|
sl@0
|
4 |
Redistribution and use in source and binary forms, with or without
|
sl@0
|
5 |
modification, are permitted provided that the following conditions are met:
|
sl@0
|
6 |
|
sl@0
|
7 |
* Redistributions of source code must retain the above copyright notice, this
|
sl@0
|
8 |
list of conditions and the following disclaimer.
|
sl@0
|
9 |
* Redistributions in binary form must reproduce the above copyright notice,
|
sl@0
|
10 |
this list of conditions and the following disclaimer in the documentation
|
sl@0
|
11 |
and/or other materials provided with the distribution.
|
sl@0
|
12 |
* Neither the name of Nokia Corporation nor the names of its contributors
|
sl@0
|
13 |
may be used to endorse or promote products derived from this software
|
sl@0
|
14 |
without specific prior written permission.
|
sl@0
|
15 |
|
sl@0
|
16 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
sl@0
|
17 |
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
sl@0
|
18 |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
sl@0
|
19 |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
sl@0
|
20 |
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
sl@0
|
21 |
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
sl@0
|
22 |
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
sl@0
|
23 |
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
sl@0
|
24 |
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
sl@0
|
25 |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
sl@0
|
26 |
|
sl@0
|
27 |
Description:
|
sl@0
|
28 |
*/
|
sl@0
|
29 |
|
sl@0
|
30 |
|
sl@0
|
31 |
#include "createx509.h"
|
sl@0
|
32 |
|
sl@0
|
33 |
|
sl@0
|
34 |
X509* CX509_Initializer::CreateX509L(CX509Certificate* X509Cert)
|
sl@0
|
35 |
{
|
sl@0
|
36 |
X509* ret = X509_new();
|
sl@0
|
37 |
TBool serail = ETrue;
|
sl@0
|
38 |
|
sl@0
|
39 |
if(ret != NULL)
|
sl@0
|
40 |
{
|
sl@0
|
41 |
|
sl@0
|
42 |
//validity
|
sl@0
|
43 |
X509_VAL_free(ret->cert_info->validity);
|
sl@0
|
44 |
ret->cert_info->validity = CreateX509_VAL(X509Cert);
|
sl@0
|
45 |
|
sl@0
|
46 |
//issuer
|
sl@0
|
47 |
const CX500DistinguishedName& IssName = X509Cert->IssuerName();
|
sl@0
|
48 |
X509_NAME_free(ret->cert_info->issuer);
|
sl@0
|
49 |
ret->cert_info->issuer = CreateX509_NAMEL(IssName);
|
sl@0
|
50 |
|
sl@0
|
51 |
//subject
|
sl@0
|
52 |
const CX500DistinguishedName& SubName = X509Cert->SubjectName();
|
sl@0
|
53 |
X509_NAME_free(ret->cert_info->subject);
|
sl@0
|
54 |
ret->cert_info->subject = CreateX509_NAMEL(SubName);
|
sl@0
|
55 |
// const HBufC * name = SubName.DisplayNameL();
|
sl@0
|
56 |
|
sl@0
|
57 |
//signature
|
sl@0
|
58 |
const TPtrC8* sig_alg_ptr = X509Cert->DataElementEncoding(CX509Certificate::EAlgorithmId);
|
sl@0
|
59 |
X509_ALGOR_free(ret->cert_info->signature);
|
sl@0
|
60 |
ret->cert_info->signature = CreateX509_ALGORL(sig_alg_ptr);
|
sl@0
|
61 |
|
sl@0
|
62 |
//serialnumber
|
sl@0
|
63 |
const TPtrC8 sernum = X509Cert->SerialNumber();
|
sl@0
|
64 |
ASN1_INTEGER_free(ret->cert_info->serialNumber);
|
sl@0
|
65 |
ret->cert_info->serialNumber = CreateASN1_STRING(sernum.Length(),V_ASN1_INTEGER,(unsigned char *)sernum.Ptr(),0);
|
sl@0
|
66 |
if((sernum.Length()== 1) && sernum[0]==0)
|
sl@0
|
67 |
serail = EFalse;
|
sl@0
|
68 |
|
sl@0
|
69 |
//version
|
sl@0
|
70 |
|
sl@0
|
71 |
TInt ver = X509Cert->Version();
|
sl@0
|
72 |
unsigned char verVal = (unsigned char)(ver-1);
|
sl@0
|
73 |
ASN1_INTEGER_free(ret->cert_info->version);
|
sl@0
|
74 |
if( (verVal) || (!serail))// for X509 V1 certificates, version is null if any serial number present.
|
sl@0
|
75 |
ret->cert_info->version = CreateASN1_STRING(1,V_ASN1_INTEGER,&verVal,0);
|
sl@0
|
76 |
|
sl@0
|
77 |
|
sl@0
|
78 |
//issuerUID
|
sl@0
|
79 |
const TPtrC8* issUID_enc = X509Cert->DataElementEncoding(CX509Certificate::EIssuerUID);
|
sl@0
|
80 |
if(issUID_enc)
|
sl@0
|
81 |
ret->cert_info->issuerUID = CreateASN1_STRING(issUID_enc->Length(),V_ASN1_BIT_STRING,(unsigned char *)issUID_enc->Ptr(),0);
|
sl@0
|
82 |
|
sl@0
|
83 |
|
sl@0
|
84 |
//subjectUID
|
sl@0
|
85 |
const TPtrC8* subUID_enc = X509Cert->DataElementEncoding(CX509Certificate::ESubjectUID);
|
sl@0
|
86 |
if(subUID_enc)
|
sl@0
|
87 |
ret->cert_info->subjectUID = CreateASN1_STRING(subUID_enc->Length(),V_ASN1_BIT_STRING,(unsigned char *)subUID_enc->Ptr(),0);
|
sl@0
|
88 |
|
sl@0
|
89 |
//key
|
sl@0
|
90 |
X509_PUBKEY_free(ret->cert_info->key);
|
sl@0
|
91 |
ret->cert_info->key = CreateX509_PUBKEYL(X509Cert);
|
sl@0
|
92 |
|
sl@0
|
93 |
|
sl@0
|
94 |
//extension
|
sl@0
|
95 |
|
sl@0
|
96 |
|
sl@0
|
97 |
ret->cert_info->extensions = CreateSTACKOF_X509_EXTENSIONL(X509Cert);
|
sl@0
|
98 |
|
sl@0
|
99 |
|
sl@0
|
100 |
//name
|
sl@0
|
101 |
ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0);
|
sl@0
|
102 |
|
sl@0
|
103 |
//sig_alg
|
sl@0
|
104 |
X509_ALGOR_free(ret->sig_alg);
|
sl@0
|
105 |
ret->sig_alg = CreateX509_ALGORL(sig_alg_ptr);
|
sl@0
|
106 |
|
sl@0
|
107 |
//signature
|
sl@0
|
108 |
const TPtrC8 sig = X509Cert->Signature();
|
sl@0
|
109 |
ASN1_STRING_free(ret->signature);
|
sl@0
|
110 |
ret->signature = CreateASN1_STRING(sig.Length(), V_ASN1_BIT_STRING, (unsigned char *)sig.Ptr(), ASN1_STRING_FLAG_BITS_LEFT);
|
sl@0
|
111 |
}
|
sl@0
|
112 |
|
sl@0
|
113 |
return ret;
|
sl@0
|
114 |
}
|
sl@0
|
115 |
|
sl@0
|
116 |
|
sl@0
|
117 |
X509_ALGOR* CX509_Initializer::CreateX509_ALGORL(const TPtrC8* ptr)
|
sl@0
|
118 |
{
|
sl@0
|
119 |
X509_ALGOR* ret = X509_ALGOR_new();
|
sl@0
|
120 |
|
sl@0
|
121 |
TASN1DecGeneric dec((TDesC8 &)*ptr);
|
sl@0
|
122 |
dec.InitL();
|
sl@0
|
123 |
|
sl@0
|
124 |
TASN1DecSequence encSeq;
|
sl@0
|
125 |
CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC(dec);
|
sl@0
|
126 |
|
sl@0
|
127 |
TASN1DecGeneric& AlgorEncSeq = *(seq->At(0));
|
sl@0
|
128 |
|
sl@0
|
129 |
if (dec.LengthDERContent() > AlgorEncSeq.LengthDER()) // can also check for (seq->Count() > 1) alternatively
|
sl@0
|
130 |
{
|
sl@0
|
131 |
// parameter part is present in the encoding.
|
sl@0
|
132 |
TASN1DecGeneric& ParameterEncSeq = *(seq->At(1));
|
sl@0
|
133 |
|
sl@0
|
134 |
// if param = 5, ie. ASN1 type NULL, then create a NULL ASN1 STRING
|
sl@0
|
135 |
ret->parameter = ASN1_TYPE_new();
|
sl@0
|
136 |
ret->parameter->type = (TInt)ParameterEncSeq.Encoding()[0];
|
sl@0
|
137 |
|
sl@0
|
138 |
if(ret->parameter->type != V_ASN1_NULL)
|
sl@0
|
139 |
{
|
sl@0
|
140 |
// we have some parameter
|
sl@0
|
141 |
// add code to fill this stuff
|
sl@0
|
142 |
}
|
sl@0
|
143 |
}
|
sl@0
|
144 |
else
|
sl@0
|
145 |
{
|
sl@0
|
146 |
//encoding does not contain parameter at all
|
sl@0
|
147 |
//ret->parameter is anyway NULL when X509_ALGOR is created
|
sl@0
|
148 |
//Not sure if we need to create a NULL ASN1 string or just leave parameter = NULL
|
sl@0
|
149 |
}
|
sl@0
|
150 |
|
sl@0
|
151 |
|
sl@0
|
152 |
const TDesC8& algor_data = AlgorEncSeq.GetContentDER();
|
sl@0
|
153 |
char * ch_algor_data = (char *)algor_data.Ptr();
|
sl@0
|
154 |
|
sl@0
|
155 |
ret->algorithm = ASN1_OBJECT_new();
|
sl@0
|
156 |
ret->algorithm->length = AlgorEncSeq.LengthDERContent();
|
sl@0
|
157 |
ret->algorithm->data = (unsigned char *)OPENSSL_malloc(ret->algorithm->length);
|
sl@0
|
158 |
if(ret->algorithm->data)
|
sl@0
|
159 |
memcpy(ret->algorithm->data, ch_algor_data, ret->algorithm->length);
|
sl@0
|
160 |
//else log error- cannot malloc
|
sl@0
|
161 |
|
sl@0
|
162 |
ret->algorithm->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; // so that X509_ALGOR_free() frees all internally allocated data
|
sl@0
|
163 |
|
sl@0
|
164 |
CleanupStack::PopAndDestroy(); //seq
|
sl@0
|
165 |
|
sl@0
|
166 |
return ret;
|
sl@0
|
167 |
}
|
sl@0
|
168 |
|
sl@0
|
169 |
|
sl@0
|
170 |
|
sl@0
|
171 |
X509_NAME* CX509_Initializer::CreateX509_NAMEL(const CX500DistinguishedName& DistName)
|
sl@0
|
172 |
{
|
sl@0
|
173 |
X509_NAME* ret = X509_NAME_new();
|
sl@0
|
174 |
|
sl@0
|
175 |
CASN1EncSequence * Asn1Seq = DistName.EncodeASN1LC();
|
sl@0
|
176 |
|
sl@0
|
177 |
HBufC8* octetData = HBufC8::NewMaxLC(5000);
|
sl@0
|
178 |
TPtr8 oct(octetData->Des());
|
sl@0
|
179 |
oct.FillZ();
|
sl@0
|
180 |
oct.SetLength(KMaxNameLength);
|
sl@0
|
181 |
TUint writePos = 0;
|
sl@0
|
182 |
Asn1Seq->WriteDERL(oct, writePos);
|
sl@0
|
183 |
|
sl@0
|
184 |
TInt len = Fill_X509_NAME_ENTRYL(ret, octetData->Des());
|
sl@0
|
185 |
|
sl@0
|
186 |
char *p = (char *)oct.PtrZ();
|
sl@0
|
187 |
|
sl@0
|
188 |
ret->bytes->data = (char *)OPENSSL_malloc(len); // no need to free this. BUF_MEM_free will free if not NULL
|
sl@0
|
189 |
if(ret->bytes->data)
|
sl@0
|
190 |
memcpy(ret->bytes->data, p, len);
|
sl@0
|
191 |
//else log error- cannot malloc
|
sl@0
|
192 |
|
sl@0
|
193 |
ret->bytes->length = len;
|
sl@0
|
194 |
ret->bytes->max = len;
|
sl@0
|
195 |
|
sl@0
|
196 |
ret->hash = 0; // for now filling zero. Not sure.
|
sl@0
|
197 |
|
sl@0
|
198 |
CleanupStack::PopAndDestroy(2); // Asn1Seq, octetData
|
sl@0
|
199 |
|
sl@0
|
200 |
return ret;
|
sl@0
|
201 |
}
|
sl@0
|
202 |
|
sl@0
|
203 |
|
sl@0
|
204 |
// return the length of the encoded sequence
|
sl@0
|
205 |
TInt CX509_Initializer::Fill_X509_NAME_ENTRYL(X509_NAME * name, const TDesC8& aBinaryData)
|
sl@0
|
206 |
{
|
sl@0
|
207 |
TInt aPos = 0;
|
sl@0
|
208 |
TASN1DecGeneric dec(aBinaryData.Right(aBinaryData.Length() - aPos));
|
sl@0
|
209 |
dec.InitL();
|
sl@0
|
210 |
|
sl@0
|
211 |
TInt end = aPos + dec.LengthDER();
|
sl@0
|
212 |
aPos += dec.LengthDERHeader();
|
sl@0
|
213 |
|
sl@0
|
214 |
if (dec.Tag() != EASN1Sequence)
|
sl@0
|
215 |
{
|
sl@0
|
216 |
User::Leave(KErrArgument);
|
sl@0
|
217 |
}
|
sl@0
|
218 |
while (aPos < end)
|
sl@0
|
219 |
{
|
sl@0
|
220 |
TASN1DecGeneric rdn(aBinaryData.Right(aBinaryData.Length() - aPos));
|
sl@0
|
221 |
rdn.InitL();
|
sl@0
|
222 |
if (rdn.Tag() != EASN1Set)
|
sl@0
|
223 |
{
|
sl@0
|
224 |
User::Leave(KErrArgument);
|
sl@0
|
225 |
}
|
sl@0
|
226 |
TInt rdnEnd = rdn.LengthDER();
|
sl@0
|
227 |
TInt rdnPos = rdn.LengthDERHeader();//add on header
|
sl@0
|
228 |
while (rdnPos < rdnEnd)
|
sl@0
|
229 |
{
|
sl@0
|
230 |
const TDesC8& TypeValEnc = rdn.Encoding();
|
sl@0
|
231 |
|
sl@0
|
232 |
TASN1DecGeneric dec(TypeValEnc.Right(TypeValEnc.Length() - rdnPos));
|
sl@0
|
233 |
dec.InitL();
|
sl@0
|
234 |
TInt tvend = rdnPos + dec.LengthDER();
|
sl@0
|
235 |
rdnPos += dec.LengthDERHeader();
|
sl@0
|
236 |
|
sl@0
|
237 |
//first element must be the id
|
sl@0
|
238 |
TASN1DecObjectIdentifier encOID;
|
sl@0
|
239 |
//iType = encOID.DecodeDERL(TypeValEnc, rdnPos);
|
sl@0
|
240 |
TASN1DecGeneric first(TypeValEnc.Right(TypeValEnc.Length() - rdnPos));
|
sl@0
|
241 |
first.InitL();
|
sl@0
|
242 |
rdnPos += first.LengthDER();
|
sl@0
|
243 |
if (first.Tag() != EASN1ObjectIdentifier)
|
sl@0
|
244 |
{
|
sl@0
|
245 |
User::Leave(KErrArgument);
|
sl@0
|
246 |
}
|
sl@0
|
247 |
|
sl@0
|
248 |
const TDesC8& type = first.GetContentDER();
|
sl@0
|
249 |
char * ch_type = (char *)type.Ptr();
|
sl@0
|
250 |
|
sl@0
|
251 |
//second is the data
|
sl@0
|
252 |
TASN1DecGeneric second(TypeValEnc.Right(TypeValEnc.Length() - rdnPos));
|
sl@0
|
253 |
second.InitL();
|
sl@0
|
254 |
rdnPos += second.LengthDER();
|
sl@0
|
255 |
|
sl@0
|
256 |
const TDesC8& value = second.GetContentDER();
|
sl@0
|
257 |
char * ch_value = (char *)value.Ptr();
|
sl@0
|
258 |
|
sl@0
|
259 |
X509_NAME_ENTRY* new_entry = CreateX509_NAME_ENTRY(ch_type,first.LengthDERContent(), ch_value, second.LengthDERContent(), second.Tag());
|
sl@0
|
260 |
|
sl@0
|
261 |
X509_NAME_add_entry(name, new_entry, -1, 0);
|
sl@0
|
262 |
|
sl@0
|
263 |
//we can free this, since add_entry makes a copy and adds
|
sl@0
|
264 |
X509_NAME_ENTRY_free(new_entry);
|
sl@0
|
265 |
//
|
sl@0
|
266 |
|
sl@0
|
267 |
if (rdnPos != tvend)
|
sl@0
|
268 |
{
|
sl@0
|
269 |
User::Leave(KErrArgument);
|
sl@0
|
270 |
}
|
sl@0
|
271 |
|
sl@0
|
272 |
}
|
sl@0
|
273 |
aPos += rdnEnd;
|
sl@0
|
274 |
}
|
sl@0
|
275 |
if (aPos != end)
|
sl@0
|
276 |
{
|
sl@0
|
277 |
User::Leave(KErrArgument);
|
sl@0
|
278 |
}
|
sl@0
|
279 |
return end;
|
sl@0
|
280 |
}
|
sl@0
|
281 |
|
sl@0
|
282 |
|
sl@0
|
283 |
X509_NAME_ENTRY * CX509_Initializer::CreateX509_NAME_ENTRY(char* type, int typeLen, char * value, int valueLen, int stringType)
|
sl@0
|
284 |
{
|
sl@0
|
285 |
X509_NAME_ENTRY * newEntry = X509_NAME_ENTRY_new();
|
sl@0
|
286 |
|
sl@0
|
287 |
newEntry->object->length = typeLen;
|
sl@0
|
288 |
newEntry->object->data = (unsigned char *)OPENSSL_malloc(typeLen);
|
sl@0
|
289 |
if(newEntry->object->data)
|
sl@0
|
290 |
memcpy(newEntry->object->data, type, typeLen);
|
sl@0
|
291 |
//else log error- cannot malloc
|
sl@0
|
292 |
|
sl@0
|
293 |
ASN1_STRING_free(newEntry->value);
|
sl@0
|
294 |
newEntry->value = CreateASN1_STRING(valueLen, stringType, (unsigned char* )value, 0);
|
sl@0
|
295 |
|
sl@0
|
296 |
newEntry->object->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; // so that X509_NAME_ENTRY_free() frees all internally allocated data
|
sl@0
|
297 |
|
sl@0
|
298 |
return newEntry;
|
sl@0
|
299 |
|
sl@0
|
300 |
}
|
sl@0
|
301 |
|
sl@0
|
302 |
|
sl@0
|
303 |
X509_VAL * CX509_Initializer::CreateX509_VAL(CX509Certificate* X509Cert)
|
sl@0
|
304 |
{
|
sl@0
|
305 |
X509_VAL * ret = X509_VAL_new();
|
sl@0
|
306 |
|
sl@0
|
307 |
const CValidityPeriod& val = X509Cert->ValidityPeriod();
|
sl@0
|
308 |
|
sl@0
|
309 |
TBuf8<KCertMaxBuffer> numBuffer8;
|
sl@0
|
310 |
char* numPtr = (char*)numBuffer8.PtrZ();
|
sl@0
|
311 |
|
sl@0
|
312 |
//start date (notBefore)
|
sl@0
|
313 |
TDateTime dt = val.Start().DateTime();
|
sl@0
|
314 |
|
sl@0
|
315 |
numBuffer8.AppendNum(dt.Year());
|
sl@0
|
316 |
if(numBuffer8.Length() > 2)
|
sl@0
|
317 |
numBuffer8.Delete(0, numBuffer8.Length() - 2);
|
sl@0
|
318 |
|
sl@0
|
319 |
_LIT8(KCertTimeStampFormat, "%02d%02d%02d%02d%02dZ");
|
sl@0
|
320 |
numBuffer8.AppendFormat(KCertTimeStampFormat,dt.Month()+1,dt.Day()+1,dt.Hour(),dt.Minute(),dt.Second()); //Month and Day - offset from zero, so add 1
|
sl@0
|
321 |
numPtr[13]='\0';
|
sl@0
|
322 |
|
sl@0
|
323 |
ASN1_STRING_free(ret->notBefore);
|
sl@0
|
324 |
ret->notBefore = CreateASN1_STRING(13,V_ASN1_UTCTIME,(unsigned char *)numPtr,0);
|
sl@0
|
325 |
|
sl@0
|
326 |
//finish date (notAfter)
|
sl@0
|
327 |
dt = val.Finish().DateTime();
|
sl@0
|
328 |
|
sl@0
|
329 |
numBuffer8.Zero();
|
sl@0
|
330 |
numBuffer8.AppendNum(dt.Year());
|
sl@0
|
331 |
if(numBuffer8.Length() > 2)
|
sl@0
|
332 |
numBuffer8.Delete(0, numBuffer8.Length() - 2);
|
sl@0
|
333 |
|
sl@0
|
334 |
numBuffer8.AppendFormat(KCertTimeStampFormat,dt.Month()+1,dt.Day()+1,dt.Hour(),dt.Minute(),dt.Second()); //Month and Day - offset from zero, so add 1
|
sl@0
|
335 |
numPtr[13]='\0';
|
sl@0
|
336 |
|
sl@0
|
337 |
ASN1_STRING_free(ret->notAfter);
|
sl@0
|
338 |
ret->notAfter = CreateASN1_STRING(13,V_ASN1_UTCTIME,(unsigned char *)numPtr,0);
|
sl@0
|
339 |
|
sl@0
|
340 |
return ret;
|
sl@0
|
341 |
|
sl@0
|
342 |
}
|
sl@0
|
343 |
|
sl@0
|
344 |
|
sl@0
|
345 |
|
sl@0
|
346 |
ASN1_STRING* CX509_Initializer::CreateASN1_STRING(int len, int type, unsigned char* data, long flags)
|
sl@0
|
347 |
{
|
sl@0
|
348 |
ASN1_STRING* ret = ASN1_STRING_new();
|
sl@0
|
349 |
ret->length = len;
|
sl@0
|
350 |
ret->type = type;
|
sl@0
|
351 |
if(data!=NULL)
|
sl@0
|
352 |
{
|
sl@0
|
353 |
ret->data = (unsigned char *)OPENSSL_malloc(len);
|
sl@0
|
354 |
if(ret->data)
|
sl@0
|
355 |
memcpy(ret->data,data,len);
|
sl@0
|
356 |
//else log error- cannot malloc
|
sl@0
|
357 |
}
|
sl@0
|
358 |
else
|
sl@0
|
359 |
ret->data = NULL;
|
sl@0
|
360 |
|
sl@0
|
361 |
ret->flags |= flags;
|
sl@0
|
362 |
return ret;
|
sl@0
|
363 |
}
|
sl@0
|
364 |
|
sl@0
|
365 |
|
sl@0
|
366 |
|
sl@0
|
367 |
X509_PUBKEY* CX509_Initializer::CreateX509_PUBKEYL(CX509Certificate* X509Cert)
|
sl@0
|
368 |
{
|
sl@0
|
369 |
X509_PUBKEY* ret = X509_PUBKEY_new();
|
sl@0
|
370 |
|
sl@0
|
371 |
//algor
|
sl@0
|
372 |
const TPtrC8* ptr = X509Cert->DataElementEncoding(CX509Certificate::ESubjectPublicKeyInfo);
|
sl@0
|
373 |
|
sl@0
|
374 |
TInt aPos = 0;
|
sl@0
|
375 |
TASN1DecGeneric dec(ptr->Right(ptr->Length() - aPos));
|
sl@0
|
376 |
dec.InitL();
|
sl@0
|
377 |
|
sl@0
|
378 |
TInt end = aPos + dec.LengthDER();
|
sl@0
|
379 |
aPos += dec.LengthDERHeader();
|
sl@0
|
380 |
|
sl@0
|
381 |
if (dec.Tag() != EASN1Sequence)
|
sl@0
|
382 |
User::Leave(KErrArgument);
|
sl@0
|
383 |
|
sl@0
|
384 |
if (aPos < end)
|
sl@0
|
385 |
{
|
sl@0
|
386 |
TASN1DecGeneric rdn(ptr->Right(ptr->Length() - aPos));
|
sl@0
|
387 |
rdn.InitL();
|
sl@0
|
388 |
TPtrC8 newPtr = rdn.Encoding();
|
sl@0
|
389 |
|
sl@0
|
390 |
X509_ALGOR_free(ret->algor); // free the one allocated by X509_PUBKEY_new
|
sl@0
|
391 |
ret->algor = CreateX509_ALGORL(&newPtr);
|
sl@0
|
392 |
}
|
sl@0
|
393 |
|
sl@0
|
394 |
//public_key
|
sl@0
|
395 |
const CSubjectPublicKeyInfo& pubkey = X509Cert->PublicKey();
|
sl@0
|
396 |
const TPtrC8 keyDat = pubkey.KeyData();
|
sl@0
|
397 |
|
sl@0
|
398 |
ASN1_BIT_STRING_free(ret->public_key);
|
sl@0
|
399 |
ret->public_key = CreateASN1_STRING(keyDat.Size(),V_ASN1_BIT_STRING,(unsigned char*)keyDat.Ptr(),0);
|
sl@0
|
400 |
|
sl@0
|
401 |
//pkey
|
sl@0
|
402 |
ret->pkey = NULL; // we need not create this. Will be created later. Used to cache the computed data
|
sl@0
|
403 |
|
sl@0
|
404 |
return ret;
|
sl@0
|
405 |
}
|
sl@0
|
406 |
|
sl@0
|
407 |
|
sl@0
|
408 |
|
sl@0
|
409 |
|
sl@0
|
410 |
STACK_OF(X509_EXTENSION)* CX509_Initializer::CreateSTACKOF_X509_EXTENSIONL(CX509Certificate* X509Cert)
|
sl@0
|
411 |
{
|
sl@0
|
412 |
//STACK_OF(X509_EXTENSION) * ret = sk_X509_EXTENSION_new_null();
|
sl@0
|
413 |
STACK_OF(X509_EXTENSION) * ret = NULL;
|
sl@0
|
414 |
|
sl@0
|
415 |
const TPtrC8* ptr = X509Cert->DataElementEncoding(CX509Certificate::EExtensionList);
|
sl@0
|
416 |
|
sl@0
|
417 |
const CArrayPtrFlat<CX509CertExtension>& extlist = X509Cert->Extensions();
|
sl@0
|
418 |
|
sl@0
|
419 |
TASN1DecSequence encSeq;
|
sl@0
|
420 |
TInt pos = 0;
|
sl@0
|
421 |
|
sl@0
|
422 |
if(ptr != NULL) //There is an extension list
|
sl@0
|
423 |
{
|
sl@0
|
424 |
TASN1DecGeneric dec((TDesC8 &)*ptr);
|
sl@0
|
425 |
ret = sk_X509_EXTENSION_new_null();
|
sl@0
|
426 |
dec.InitL();
|
sl@0
|
427 |
|
sl@0
|
428 |
CArrayPtrFlat<TASN1DecGeneric>* seq = encSeq.DecodeDERLC( dec.GetContentDER(), pos);
|
sl@0
|
429 |
|
sl@0
|
430 |
TInt count = seq->Count(); // no of extensions in the ext list
|
sl@0
|
431 |
for (TInt i = 0; i < count; i++)
|
sl@0
|
432 |
{
|
sl@0
|
433 |
|
sl@0
|
434 |
X509_EXTENSION* ext = X509_EXTENSION_new();
|
sl@0
|
435 |
|
sl@0
|
436 |
ext->object = ASN1_OBJECT_new();
|
sl@0
|
437 |
|
sl@0
|
438 |
TASN1DecGeneric* gen = seq->At(i);
|
sl@0
|
439 |
TASN1DecGeneric oid(seq->At(i)->GetContentDER());
|
sl@0
|
440 |
oid.InitL();
|
sl@0
|
441 |
|
sl@0
|
442 |
const TDesC8& ext_obj_data = oid.GetContentDER();
|
sl@0
|
443 |
char * ch_ext_obj_data = (char *)ext_obj_data.Ptr();
|
sl@0
|
444 |
|
sl@0
|
445 |
ext->object->length = oid.LengthDERContent();
|
sl@0
|
446 |
ext->object->data = (unsigned char *)OPENSSL_malloc(ext->object->length);
|
sl@0
|
447 |
if(ext->object->data)
|
sl@0
|
448 |
memcpy(ext->object->data, ch_ext_obj_data, ext->object->length);
|
sl@0
|
449 |
//else log error- cannot malloc
|
sl@0
|
450 |
|
sl@0
|
451 |
ext->object->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; // so that X509_free() frees all internally allocated data
|
sl@0
|
452 |
|
sl@0
|
453 |
if(extlist.At(i)->Critical())
|
sl@0
|
454 |
ext->critical = extlist.At(i)->Critical();
|
sl@0
|
455 |
|
sl@0
|
456 |
const TPtrC8 data = extlist.At(i)->Data();
|
sl@0
|
457 |
TASN1DecGeneric value(data);
|
sl@0
|
458 |
value.InitL();
|
sl@0
|
459 |
|
sl@0
|
460 |
const TDesC8& ext_value = value.GetContentDER();
|
sl@0
|
461 |
char * ch_ext_value = (char *)ext_value.Ptr();
|
sl@0
|
462 |
ASN1_STRING_free(ext->value);
|
sl@0
|
463 |
ext->value = CreateASN1_STRING(value.LengthDERContent(), V_ASN1_OCTET_STRING, (unsigned char *)ch_ext_value, 0);
|
sl@0
|
464 |
|
sl@0
|
465 |
sk_X509_EXTENSION_push(ret,ext);
|
sl@0
|
466 |
|
sl@0
|
467 |
}
|
sl@0
|
468 |
|
sl@0
|
469 |
CleanupStack::PopAndDestroy();// seq
|
sl@0
|
470 |
}
|
sl@0
|
471 |
|
sl@0
|
472 |
return ret;
|
sl@0
|
473 |
}
|
sl@0
|
474 |
|