|
1 /* |
|
2 * Copyright (c) 2005-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 "swicertstore.h" |
|
20 #include "osinterface.h" |
|
21 #include <sstream> |
|
22 using namespace std; |
|
23 |
|
24 SWICertStore::SWICertStore() |
|
25 :iUnifiedCapabilities(0) , |
|
26 iMandatoryCertInfo (NULL), |
|
27 iCertstoreInfo (NULL) |
|
28 { |
|
29 } |
|
30 |
|
31 void SWICertStore::Run(const Options& aOptions) |
|
32 { |
|
33 char buf[KLength]; |
|
34 char mandatory[2]; |
|
35 const char* fileName = CCIFile.c_str(); |
|
36 string CertstoreFile = ".\\"; |
|
37 CertstoreFile.append(fileName); |
|
38 |
|
39 MandatoryCertInfo* iNext = NULL; |
|
40 MandatoryCertInfo* node = NULL ; |
|
41 MandatoryCertInfo* nextNode = NULL; |
|
42 |
|
43 CertstoreInfo* iNextNode = NULL; |
|
44 CertstoreInfo* certNode = NULL ; |
|
45 CertstoreInfo* certNextNode = NULL; |
|
46 |
|
47 FILE *fp = fopen(fileName , "r" ); |
|
48 if(fp == NULL) |
|
49 { |
|
50 #ifdef DUMPCHAINVALIDITYTOOL |
|
51 cout << "File containing Certificate and Capability Information from DumpSWICertstore :" << endl; |
|
52 #endif |
|
53 throw EUnableToOpenFile; |
|
54 } |
|
55 |
|
56 while(!feof(fp)) |
|
57 { |
|
58 X509* rootArray = PEM_read_X509 (fp, NULL, NULL, NULL); |
|
59 if(rootArray) |
|
60 { |
|
61 iRootCertVector.push_back(rootArray); |
|
62 X509_NAME_oneline (X509_get_issuer_name (rootArray) , buf , KLength); |
|
63 char* issued = strstr (buf, "/CN="); |
|
64 string certLabel; |
|
65 if (issued) |
|
66 { |
|
67 issued += 4; |
|
68 char* end = strchr (issued, '/'); |
|
69 if (end) |
|
70 { |
|
71 *end = 0; |
|
72 } |
|
73 certLabel = issued; |
|
74 } |
|
75 |
|
76 string iniSectionName = "MANDATORY" ; |
|
77 OSInterface::ReadPrivateProfile(iniSectionName , certLabel , CertstoreFile , mandatory); |
|
78 if(!strcmp(mandatory , "1" )) |
|
79 { |
|
80 node = new MandatoryCertInfo; |
|
81 node ->iMandatoryCertName = certLabel; |
|
82 node ->iSignature = rootArray->signature->data ; |
|
83 node ->iSignatureLength = rootArray->signature->length; |
|
84 node ->iNext = NULL; |
|
85 //when it is the first node in the list |
|
86 if(iMandatoryCertInfo == NULL) |
|
87 { |
|
88 iMandatoryCertInfo = node; |
|
89 } |
|
90 else |
|
91 { |
|
92 nextNode = iMandatoryCertInfo; |
|
93 while(nextNode -> iNext != NULL) |
|
94 { |
|
95 nextNode = nextNode->iNext; |
|
96 } |
|
97 |
|
98 nextNode -> iNext = node; |
|
99 } |
|
100 } |
|
101 //linked list holding the capabilities and signature of the root certs in certstore. |
|
102 //This is required for unifying capabilities of the validated chains. |
|
103 int rootCaps = GetRootCertCapabilities(certLabel); |
|
104 certNode = new CertstoreInfo; |
|
105 certNode -> iRootCertSignature = rootArray->signature->data ; |
|
106 certNode -> iSignatureLen = rootArray->signature->length; |
|
107 certNode -> iRootCapabilities = rootCaps; |
|
108 certNode -> iNextNode = NULL; |
|
109 //when it is the first node in the list |
|
110 if(iCertstoreInfo == NULL) |
|
111 { |
|
112 iCertstoreInfo = certNode; |
|
113 } |
|
114 else |
|
115 { |
|
116 certNextNode = iCertstoreInfo; |
|
117 while(certNextNode -> iNextNode != NULL) |
|
118 { |
|
119 certNextNode = certNextNode -> iNextNode; |
|
120 } |
|
121 |
|
122 certNextNode -> iNextNode = certNode; |
|
123 } |
|
124 } |
|
125 } |
|
126 |
|
127 fclose(fp); |
|
128 } |
|
129 |
|
130 int SWICertStore::GetRootCertCapabilities(const std::string& aRootLabel) |
|
131 { |
|
132 const char* fileName = CCIFile.c_str(); |
|
133 string CertstoreFile = ".\\"; |
|
134 CertstoreFile.append(fileName); |
|
135 int CertCapabilities = 0; |
|
136 char* capabilities = new char[KLength]; |
|
137 string iniSectionName = "CAPABILITIES"; |
|
138 OSInterface::ReadPrivateProfile(iniSectionName , aRootLabel , CertstoreFile , capabilities); |
|
139 std::istringstream stream(capabilities); |
|
140 stream >> CertCapabilities; |
|
141 delete [] capabilities; |
|
142 return CertCapabilities; |
|
143 } |
|
144 |
|
145 void SWICertStore::UnifyCapabilitiesList(const SISCertificateChain& aChain) |
|
146 { |
|
147 int devCertCaps = aChain.GetDevCertCapabilities(); |
|
148 StringVector validatingRoot = aChain.GetValidatedRootSignature(); |
|
149 StringVector devCertValidatingRoot = aChain.GetDevCertValidatedRootSignature(); |
|
150 StringVector::iterator start = validatingRoot.begin(); |
|
151 StringVector::iterator last = validatingRoot.end(); |
|
152 StringVector::iterator devCertIterStart = devCertValidatingRoot.begin(); |
|
153 StringVector::iterator devCertIterEnd = devCertValidatingRoot.end(); |
|
154 while(iCertstoreInfo) |
|
155 { |
|
156 if(validatingRoot.size()) |
|
157 { |
|
158 string signature((const char*)(iCertstoreInfo->iRootCertSignature) , (iCertstoreInfo->iSignatureLen)); |
|
159 StringVector::iterator iter = std::find(start , last , signature); |
|
160 if(iter != last) |
|
161 { |
|
162 iUnifiedCapabilities = (iUnifiedCapabilities | (iCertstoreInfo -> iRootCapabilities)) ; |
|
163 } |
|
164 } |
|
165 |
|
166 if(devCertValidatingRoot.size()) |
|
167 { |
|
168 string signature((const char*)(iCertstoreInfo->iRootCertSignature) , (iCertstoreInfo->iSignatureLen)); |
|
169 StringVector::iterator iter = std::find(devCertIterStart , devCertIterEnd , signature); |
|
170 if(iter != devCertIterEnd) |
|
171 { |
|
172 //if devcert has capability constraint |
|
173 if(devCertCaps > 0) |
|
174 { |
|
175 int capability = (iCertstoreInfo -> iRootCapabilities) & devCertCaps; |
|
176 iUnifiedCapabilities = (iUnifiedCapabilities | capability); |
|
177 } |
|
178 else |
|
179 { |
|
180 //in case devcert has no capabilitiy constraint. |
|
181 iUnifiedCapabilities = (iUnifiedCapabilities | (iCertstoreInfo -> iRootCapabilities)); |
|
182 } |
|
183 } |
|
184 } |
|
185 iCertstoreInfo = iCertstoreInfo ->iNextNode; |
|
186 } |
|
187 } |
|
188 |
|
189 void SWICertStore::DisplayUnifiedCapabilities(const SISCertificateChain& aChain) |
|
190 { |
|
191 int uniCaps = iUnifiedCapabilities; |
|
192 int i = 0; |
|
193 if(uniCaps == 0 ) |
|
194 { |
|
195 if(aChain.GetValidatedRootSignature().size() > 0) |
|
196 { |
|
197 #ifdef DUMPCHAINVALIDITYTOOL |
|
198 cout<<"Root Certificate used for validation doesn't grant any capabilities"<<endl<<endl; |
|
199 #endif |
|
200 } |
|
201 |
|
202 if(!aChain.GetDevCertValidatedRootSignature().size() && !aChain.GetValidatedRootSignature().size()) |
|
203 { |
|
204 #ifdef DUMPCHAINVALIDITYTOOL |
|
205 cout << "Either Certificate Chain/Chains are not validated by the CertStore\n or Certificate Chain is broken " << endl << endl; |
|
206 #endif |
|
207 } |
|
208 } |
|
209 else |
|
210 { |
|
211 while(uniCaps) |
|
212 { |
|
213 if(uniCaps & 0x01) |
|
214 { |
|
215 #ifdef DUMPCHAINVALIDITYTOOL |
|
216 cout << CapabilityList[i] << endl; |
|
217 #endif |
|
218 } |
|
219 i++; |
|
220 uniCaps = uniCaps >> 1; |
|
221 } |
|
222 } |
|
223 } |
|
224 |
|
225 |
|
226 SWICertStore::~SWICertStore() |
|
227 { |
|
228 for(vector <X509*>::iterator iter = iRootCertVector.begin() ; iter != iRootCertVector.end() ; ++iter) |
|
229 { |
|
230 X509_free(*iter); |
|
231 } |
|
232 |
|
233 for(MandatoryCertInfo* list = iMandatoryCertInfo ; list ; ) |
|
234 { |
|
235 MandatoryCertInfo* next = list -> iNext; |
|
236 delete list; |
|
237 list = next; |
|
238 } |
|
239 |
|
240 for(CertstoreInfo* certList = iCertstoreInfo ; certList ; ) |
|
241 { |
|
242 CertstoreInfo* nextNode = certList -> iNextNode; |
|
243 delete certList; |
|
244 certList = nextNode; |
|
245 } |
|
246 |
|
247 } |