|
1 /* |
|
2 * Copyright (c) 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 "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 #include "trustrootpolicy.h" |
|
18 #include <openssl/x509.h> |
|
19 #include <openssl/x509v3.h> |
|
20 #include <openssl/bio.h> |
|
21 #include "javasymbianoslayer.h" |
|
22 |
|
23 _LIT(KLegacyCertsPath, "z:\\private\\10203636\\security\\trustroots\\device\\certificates\\"); |
|
24 _LIT(KOmjCertsPath, "c:\\private\\200211dc\\security\\trustroots\\device\\certificates\\"); |
|
25 _LIT8(KOmjCertsPath8, "c:\\private\\200211dc\\security\\trustroots\\device\\certificates\\"); |
|
26 _LIT(KOmjCertsTmpPath, "c:\\private\\200211dc\\security\\trustroots\\device\\certificates\\tmp\\"); |
|
27 _LIT8(KOmjCertsTmpPath8, "c:\\private\\200211dc\\security\\trustroots\\device\\certificates\\tmp\\"); |
|
28 _LIT(KLegacyTrustRootPolicyPath, "z:\\private\\10203636\\security\\midp2_trp.xml"); |
|
29 _LIT(KLegacyCertsStatesPath, "c:\\private\\10203636\\security\\trustroots\\device\\state\\"); |
|
30 _LIT(KOmjCertsStatesPath, "c:\\private\\200211dc\\security\\trustroots\\device\\state\\"); |
|
31 |
|
32 static bool CertsCopyNeeded() |
|
33 { |
|
34 _LIT(KSystemAmsSid, "10203636"); |
|
35 return (KOmjCertsPath().Find(KSystemAmsSid) == -1); |
|
36 } |
|
37 |
|
38 static void MoveFileL(const TDesC& oldPath, const TDesC& newPath, RFs& fsSession) |
|
39 { |
|
40 CFileMan* fileMan = CFileMan::NewL(fsSession); |
|
41 CleanupStack::PushL(fileMan); |
|
42 fileMan->Move(oldPath, newPath); |
|
43 CleanupStack::PopAndDestroy(); |
|
44 } |
|
45 |
|
46 static void RemoveDirL(const TDesC& dirName, RFs& fsSession) |
|
47 { |
|
48 CFileMan* fileMan = CFileMan::NewL(fsSession); |
|
49 CleanupStack::PushL(fileMan); |
|
50 fileMan->RmDir(dirName); |
|
51 CleanupStack::PopAndDestroy(); |
|
52 } |
|
53 |
|
54 static string GetDomainName(string domainId) |
|
55 { |
|
56 string domainName = ""; |
|
57 if (domainId == "*MFD*" |
|
58 || domainId == "*MFDU*") |
|
59 { |
|
60 domainName = "Manufacturer"; |
|
61 } |
|
62 else if (domainId == "*OPD*" |
|
63 || domainId == "*OPDU*" |
|
64 || domainId == "*ODOPDU*" |
|
65 || domainId == "*ODOPD*") |
|
66 { |
|
67 domainName = "Operator"; |
|
68 } |
|
69 else if (domainId == "*TTPD*") |
|
70 { |
|
71 domainName = "IdentifiedThirdParty"; |
|
72 } |
|
73 return domainName; |
|
74 } |
|
75 |
|
76 static string GetDomainCategory(string domainId) |
|
77 { |
|
78 string domainCategory = ""; |
|
79 if (domainId == "*MFD*" |
|
80 || domainId == "*MFDU*") |
|
81 { |
|
82 domainCategory = "MFD"; |
|
83 } |
|
84 else if (domainId == "*OPD*" |
|
85 || domainId == "*ODOPD*" |
|
86 || domainId == "*OPDU*" |
|
87 || domainId == "*ODOPDU*") |
|
88 { |
|
89 domainCategory = "OPD"; |
|
90 } |
|
91 else if (domainId == "*TTPD*") |
|
92 { |
|
93 domainCategory = "ITPD"; |
|
94 } |
|
95 return domainCategory; |
|
96 } |
|
97 |
|
98 static string GetHash(string trustRootPath) |
|
99 { |
|
100 /* The length of the MD5 digest (32 digit hexadecimal number) */ |
|
101 const int MD5_DIGEST_LEN = 8; |
|
102 char trustRootHash[MD5_DIGEST_LEN + 1]; |
|
103 trustRootHash[0] = '\0'; |
|
104 |
|
105 FILE* trustRootDataFile = fopen(trustRootPath.c_str(), "r"); |
|
106 if (trustRootDataFile != NULL) |
|
107 { |
|
108 if (fseek(trustRootDataFile, 0L, SEEK_END) == 0) |
|
109 { |
|
110 long trustRootDataLen = ftell(trustRootDataFile); |
|
111 if (trustRootDataLen > 0) |
|
112 { |
|
113 if (fseek(trustRootDataFile, 0L, SEEK_SET) == 0) |
|
114 { |
|
115 char* trustRootData = new char[trustRootDataLen]; |
|
116 if (trustRootData != NULL) |
|
117 { |
|
118 fread(trustRootData, sizeof(char), trustRootDataLen, trustRootDataFile); |
|
119 if (!ferror(trustRootDataFile)) |
|
120 { |
|
121 BIO* bio = BIO_new_mem_buf((void *) trustRootData, trustRootDataLen); |
|
122 if ((bio)) |
|
123 { |
|
124 BIO_set_close(bio, BIO_CLOSE); |
|
125 X509* trustRootCert = d2i_X509_bio(bio,NULL); |
|
126 if (trustRootCert != NULL) |
|
127 { |
|
128 sprintf(trustRootHash,"%08lX",X509_issuer_name_hash(trustRootCert)); |
|
129 trustRootHash[MD5_DIGEST_LEN] = '\0'; |
|
130 delete trustRootCert; |
|
131 trustRootCert = NULL; |
|
132 } |
|
133 } |
|
134 BIO_free(bio); |
|
135 } |
|
136 delete[] trustRootData; |
|
137 } |
|
138 } |
|
139 } |
|
140 } |
|
141 fclose(trustRootDataFile); |
|
142 } |
|
143 return string(trustRootHash); |
|
144 } |
|
145 |
|
146 static void CopyFilesL(const TDesC& aSource, const TDesC& aDest, RFs& fsSession) |
|
147 { |
|
148 // Create file management object |
|
149 CFileMan* fileMan = CFileMan::NewL(fsSession); |
|
150 CleanupStack::PushL(fileMan); |
|
151 |
|
152 // Do copy (here synchronously) |
|
153 fileMan->Copy(aSource, aDest, CFileMan::EOverWrite|CFileMan::ERecurse); |
|
154 // clear the read-only attribute |
|
155 _LIT(KWildCards,"*"); |
|
156 HBufC* newDir = HBufC::NewLC(aDest.Length() + 1); |
|
157 TPtr ptr = newDir->Des(); |
|
158 ptr.Copy(aDest); |
|
159 ptr.Append(KWildCards); |
|
160 fileMan->Attribs(ptr,KEntryAttNormal, KEntryAttReadOnly, TTime(0),CFileMan::ERecurse); |
|
161 CleanupStack::PopAndDestroy(newDir); |
|
162 |
|
163 // Clean up |
|
164 CleanupStack::PopAndDestroy(); |
|
165 } |
|
166 |
|
167 static void HandleTrustRootsL(const std::vector<TrustRoot>& aConfiguredTrustRoots, RFs& fsSession) |
|
168 { |
|
169 string path((const char *)KOmjCertsPath8().Ptr(), KOmjCertsPath8().Length()); |
|
170 string tmpPath; |
|
171 if (!CertsCopyNeeded()) |
|
172 { |
|
173 tmpPath = path; |
|
174 } |
|
175 else |
|
176 { |
|
177 tmpPath = string((const char *)KOmjCertsTmpPath8().Ptr(), KOmjCertsTmpPath8().Length()); |
|
178 } |
|
179 for (int i=0; i<aConfiguredTrustRoots.size(); i++) |
|
180 { |
|
181 TrustRoot trustRoot = aConfiguredTrustRoots[i]; |
|
182 |
|
183 // check if the corresponding certificate exists |
|
184 string tmpBaseName = tmpPath + trustRoot.iName; |
|
185 string trustRootName = tmpBaseName + ".cer"; |
|
186 string rootName = trustRoot.iName + ".cer"; |
|
187 FILE* trustRootFile = fopen(trustRootName.c_str(), "r"); |
|
188 if (trustRootFile == NULL) |
|
189 { |
|
190 trustRootName.clear(); |
|
191 trustRootName = tmpBaseName + ".der"; |
|
192 trustRootFile = fopen(trustRootName.c_str(), "r"); |
|
193 } |
|
194 if (trustRootFile != NULL) |
|
195 { |
|
196 fclose(trustRootFile); |
|
197 string domainName = GetDomainName(trustRoot.iDomain); |
|
198 if (domainName == "") |
|
199 { |
|
200 continue; |
|
201 } |
|
202 string domainCategory = GetDomainCategory(trustRoot.iDomain); |
|
203 if (domainCategory == "") |
|
204 { |
|
205 continue; |
|
206 } |
|
207 string hash = GetHash(trustRootName); |
|
208 if (hash == "") |
|
209 { |
|
210 continue; |
|
211 } |
|
212 // generate the metadata |
|
213 string baseName = path + trustRoot.iName; |
|
214 FILE * metadataFile = fopen((baseName + ".metadata").c_str(), "w+"); |
|
215 if (metadataFile != NULL) |
|
216 { |
|
217 // copy the cert from tmp |
|
218 if (CertsCopyNeeded()) |
|
219 { |
|
220 HBufC* tmp = stringToDes(trustRootName.c_str()); |
|
221 CleanupStack::PushL(tmp); |
|
222 TPtr ptr = tmp->Des(); |
|
223 MoveFileL(ptr, KOmjCertsPath, fsSession); |
|
224 CleanupStack::PopAndDestroy(tmp); |
|
225 } |
|
226 |
|
227 // generate the metadatafile |
|
228 fprintf(metadataFile, "name=%s\n", domainName.c_str()); |
|
229 fprintf(metadataFile, "category=%s\n", domainCategory.c_str()); |
|
230 fprintf(metadataFile, "removable=%d\n", (trustRoot.iCanDelete == true)); |
|
231 fprintf(metadataFile, "disablable=%d\n", (trustRoot.iCanDisable == true)); |
|
232 fprintf(metadataFile, "hash=%s\n", hash.c_str()); |
|
233 fclose(metadataFile); |
|
234 } |
|
235 } |
|
236 } |
|
237 } |
|
238 |
|
239 |
|
240 static void ConvertTrustRootPolicyL(RFs& fsSession) |
|
241 { |
|
242 // read the trust root info |
|
243 CTrustRootPolicy* trustRootPolicy = CTrustRootPolicy::NewL(); |
|
244 CleanupStack::PushL(trustRootPolicy); |
|
245 std::vector<TrustRoot> trustRoots; |
|
246 trustRootPolicy->ReadFromFileL(KLegacyTrustRootPolicyPath, trustRoots); |
|
247 CleanupStack::PopAndDestroy(trustRootPolicy); |
|
248 |
|
249 // generate trust roots metadata |
|
250 HandleTrustRootsL(trustRoots, fsSession); |
|
251 } |
|
252 |
|
253 static void CleanupL(RFs& fsSession) |
|
254 { |
|
255 if (!CertsCopyNeeded()) |
|
256 { |
|
257 return; |
|
258 } |
|
259 // delete the tmp directory (together with the leftovers = certificates without metadata) |
|
260 RemoveDirL(KOmjCertsTmpPath, fsSession); |
|
261 } |
|
262 |
|
263 static void CopyCertsL(RFs& fsSession) |
|
264 { |
|
265 if (!CertsCopyNeeded()) |
|
266 { |
|
267 return; |
|
268 } |
|
269 |
|
270 // copy all the files from KLegacyCertsPath to KOmjCertsPath |
|
271 CopyFilesL(KLegacyCertsPath, KOmjCertsTmpPath, fsSession); |
|
272 // copy all the files from KLegacyCertsStatesPath to KOmjCertsStatesPath |
|
273 CopyFilesL(KLegacyCertsStatesPath, KOmjCertsStatesPath, fsSession); |
|
274 } |
|
275 |
|
276 static void DoL() |
|
277 { |
|
278 // open file server session |
|
279 RFs fsSession; |
|
280 User::LeaveIfError(fsSession.Connect()); |
|
281 |
|
282 // copy the certs and state infos from legacy to omj |
|
283 CopyCertsL(fsSession); |
|
284 |
|
285 // convert the trust root policy from KLegacyTrustRootPolicyPath to KOmjCertsPath |
|
286 ConvertTrustRootPolicyL(fsSession); |
|
287 |
|
288 // cleanup |
|
289 CleanupL(fsSession); |
|
290 |
|
291 // close file server session |
|
292 fsSession.Close(); |
|
293 } |
|
294 |
|
295 TInt E32Main() |
|
296 { |
|
297 //__UHEAP_MARK; |
|
298 CTrapCleanup* cleanupStack = CTrapCleanup::New(); |
|
299 TRAPD(error, DoL()); |
|
300 delete cleanupStack; |
|
301 //__UHEAP_MARKEND; |
|
302 return error; |
|
303 } |