|
1 /* |
|
2 * Copyright (c) 2004-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 /** |
|
20 @file |
|
21 @internalComponent |
|
22 @released |
|
23 */ |
|
24 |
|
25 #include <iostream> |
|
26 #include <string> |
|
27 #include <fstream> |
|
28 #include <openssl/err.h> |
|
29 |
|
30 #include "parameter.h" |
|
31 #include "siscontents.h" |
|
32 #include "utility_interface.h" |
|
33 #include "siscontroller.h" |
|
34 #include "signsis.h" |
|
35 #include "certificateinfo.h" |
|
36 #include "sissignaturecertificatechain.h" |
|
37 |
|
38 const char* KMonthString[]= |
|
39 { |
|
40 "Jan", |
|
41 "Feb", |
|
42 "Mar", |
|
43 "Apr", |
|
44 "May", |
|
45 "Jun", |
|
46 "Jul", |
|
47 "Aug", |
|
48 "Sep", |
|
49 "Oct", |
|
50 "Nov", |
|
51 "Dec" |
|
52 }; |
|
53 |
|
54 void DeletePEMFiles(std::string& aDirectorypath) |
|
55 { |
|
56 int certNumber = 1; |
|
57 char intChain[2]; |
|
58 while(true) |
|
59 { |
|
60 std::string dirPath = aDirectorypath; |
|
61 itoa(certNumber,intChain,10); |
|
62 dirPath.append("/cert"); |
|
63 dirPath.append(intChain) ; |
|
64 dirPath.append(".pem"); |
|
65 if(remove(dirPath.c_str())==-1) |
|
66 { |
|
67 if(RemoveDirectoryA(dirPath.c_str())) |
|
68 { |
|
69 std::cout << "Cannot delete directory" << std::endl; |
|
70 } |
|
71 break; |
|
72 } |
|
73 certNumber++; |
|
74 } |
|
75 } |
|
76 |
|
77 |
|
78 inline void PrintWithIndent(std::ostream& aStream, const std::string& aString, int aIndent) |
|
79 { |
|
80 aStream.width(aIndent); |
|
81 aStream << ""; |
|
82 aStream << aString; |
|
83 } |
|
84 |
|
85 inline void PrintWithIndent(std::wostream& aStream, const std::wstring& aString, int aIndent) |
|
86 { |
|
87 aStream.width(aIndent); |
|
88 aStream << L""; |
|
89 aStream << aString; |
|
90 } |
|
91 |
|
92 void PrintExtensions(const std::vector<TExtension>& aExtensions, int aIndent) |
|
93 { |
|
94 if(aExtensions.size() > 0) |
|
95 { |
|
96 PrintWithIndent(std::cout, "X509v3 extensions:", aIndent); |
|
97 } |
|
98 for(int i = 0; i < aExtensions.size(); ++i) |
|
99 { |
|
100 std::cout << std::endl; |
|
101 PrintWithIndent(std::cout, aExtensions[i].iExtensionName, aIndent+4); |
|
102 std::cout << ": "; |
|
103 std::cout << (aExtensions[i].iIsCritical? "critical":"") << std::endl; |
|
104 if(aExtensions[i].iValue != "") |
|
105 { |
|
106 PrintWithIndent(std::cout, aExtensions[i].iValue, aIndent+4); |
|
107 std::cout << std::endl; |
|
108 } |
|
109 else |
|
110 { |
|
111 for(int j = 0; j < aExtensions[i].iValueList.size(); ++j) |
|
112 { |
|
113 if(0 != j) |
|
114 { |
|
115 if(aExtensions[i].iIsMultiLine) |
|
116 { |
|
117 std::cout << std::endl; |
|
118 PrintWithIndent(std::cout, "", aIndent+4); |
|
119 } |
|
120 else |
|
121 std::cout << ", "; |
|
122 } |
|
123 else |
|
124 { |
|
125 PrintWithIndent(std::cout, "", aIndent+4); |
|
126 } |
|
127 std::cout << aExtensions[i].iValueList[j].iName; |
|
128 if(aExtensions[i].iValueList[j].iName != "" && aExtensions[i].iValueList[j].iValue != "") |
|
129 { |
|
130 std::cout << ":"; |
|
131 } |
|
132 std::cout << aExtensions[i].iValueList[j].iValue; |
|
133 } |
|
134 } |
|
135 std::cout << ((aExtensions[i].iIsMultiLine)? "\n": "") ; |
|
136 } |
|
137 } |
|
138 |
|
139 void PrintDateTime(const CSISDateTime& aDateTime) |
|
140 { |
|
141 int year = aDateTime.Date().Year(); |
|
142 int month = aDateTime.Date().Month(); |
|
143 int day = aDateTime.Date().Day(); |
|
144 int hours = aDateTime.Time().Hours(); |
|
145 int mins = aDateTime.Time().Minutes(); |
|
146 int secs = aDateTime.Time().Seconds(); |
|
147 printf("%s %d %02d:%02d:%02d %d GMT", KMonthString[month], day, hours, mins, secs, year); |
|
148 } |
|
149 |
|
150 inline std::ostream& operator << (std::ostream& aStream, const CSISDate& aDate) |
|
151 { |
|
152 aStream << (int)aDate.Day() << "/" << (int)aDate.Month()+1 << "/" << (int)aDate.Year(); |
|
153 return aStream; |
|
154 } |
|
155 |
|
156 void PrintCertificateInfo(CCertificateInfo* aCertInfo) |
|
157 { |
|
158 std::wcout << L"Issued by : " << aCertInfo->IssuerName(false) << "." << std::endl; |
|
159 std::wcout << L"Issued to : " << aCertInfo->SubjectName(false) << "." << std::endl; |
|
160 std::cout << "Valid from " << aCertInfo->ValidFrom().Date() << " to " << aCertInfo->ValidTo().Date() << std::endl; |
|
161 } |
|
162 |
|
163 |
|
164 void PrintCertificateDetails(CCertificateInfo* aCertInfo) |
|
165 { |
|
166 std::cout << "Certificate: " << std::endl; |
|
167 PrintWithIndent(std::cout, "Data:", 4); |
|
168 std::cout << std::endl; |
|
169 int version = aCertInfo->Version(); |
|
170 PrintWithIndent(std::cout, "Version: ", 8); |
|
171 std::cout << version+1 << "(0x" << version << ")" << std::endl; |
|
172 PrintWithIndent(std::cout, "Serial Number: ", 8); |
|
173 std::cout << aCertInfo->SerialNumber(); |
|
174 std::cout << std::endl; |
|
175 PrintWithIndent(std::cout, "Signature Algorithm: ", 8); |
|
176 std::cout << aCertInfo->SignatureAlgo() << std::endl; |
|
177 PrintWithIndent(std::wcout, L"Issuer: ", 8); |
|
178 std::wcout << aCertInfo->IssuerName(true) << std::endl; |
|
179 PrintWithIndent(std::cout, "Validity", 8); |
|
180 std::cout << std::endl; |
|
181 PrintWithIndent(std::cout, "Not Before: ", 12); |
|
182 PrintDateTime(aCertInfo->ValidFrom()); |
|
183 std::cout << std::endl; |
|
184 PrintWithIndent(std::cout, "Not After : ", 12); |
|
185 PrintDateTime(aCertInfo->ValidTo()); |
|
186 std::cout << std::endl; |
|
187 PrintWithIndent(std::wcout, L"Subject: ", 8); |
|
188 std::wcout << aCertInfo->SubjectName(true) << std::endl; |
|
189 PrintWithIndent(std::cout, "Subject Public Key Info:", 8); |
|
190 std::cout << std::endl; |
|
191 PrintWithIndent(std::cout, "Public Key Algorithm: ", 12); |
|
192 std::cout << aCertInfo->PublicKeyAlgo() << std::endl; |
|
193 aCertInfo->PrintPublicKey(std::cout, 16); |
|
194 const std::vector<TExtension>& extList = aCertInfo->Extensions(); |
|
195 PrintExtensions(extList, 8); |
|
196 aCertInfo->PrintSignature(std::cout, 12); |
|
197 } |
|
198 |
|
199 void ReportSignatures(const CSISController& aController, bool aExtractCerts = false) |
|
200 { |
|
201 int signatureCount = aController.SignatureCount(); |
|
202 if(0 == signatureCount) |
|
203 { |
|
204 std::cout << "No primary signatures." << std::endl; |
|
205 return; |
|
206 } |
|
207 |
|
208 std::string directoryPath = "Chain"; |
|
209 if(aExtractCerts) |
|
210 { |
|
211 DeletePEMFiles(directoryPath); |
|
212 |
|
213 CreateDirectoryA(directoryPath.c_str(),NULL); |
|
214 } |
|
215 |
|
216 std::cout << std::endl << "Primary:" << std::endl; |
|
217 for(int i = 0; i < signatureCount; ++i) |
|
218 { |
|
219 CSignatureCertChainData& sigdata = const_cast<CSignatureCertChainData&>(aController.SignatureCertChain(i)); |
|
220 CSisSignatureCertificateChain certChain(sigdata); |
|
221 const std::vector<CCertificateInfo*>& certList = certChain.CertChain(); |
|
222 for(int j = 0; j < certList.size(); ++j) |
|
223 { |
|
224 if(aExtractCerts) |
|
225 { |
|
226 PrintCertificateDetails(certList[j]); |
|
227 } |
|
228 else |
|
229 { |
|
230 PrintCertificateInfo(certList[j]); |
|
231 std::cout << std::endl; |
|
232 } |
|
233 } |
|
234 if(aExtractCerts) |
|
235 { |
|
236 char intChain[2]; |
|
237 itoa(i+1,intChain,10); |
|
238 std::string certFullPath = directoryPath + "/cert"; |
|
239 certFullPath = certFullPath + intChain; |
|
240 certFullPath = certFullPath + ".pem"; |
|
241 certChain.ExtractCertificateChain(certFullPath); |
|
242 } |
|
243 } |
|
244 } |
|
245 |
|
246 int main(int argc, char *argv[]) |
|
247 { |
|
248 wchar_t **argv1 = CommandLineArgs(argc,argv); |
|
249 |
|
250 CParameter parameter; |
|
251 |
|
252 if (! parameter.CommandLine (argc, argv1)) |
|
253 { |
|
254 return 4; |
|
255 } |
|
256 if (parameter.Sis().empty()) |
|
257 { |
|
258 cleanup(argc,argv1); |
|
259 return 0; |
|
260 } |
|
261 |
|
262 ERR_load_crypto_strings (); |
|
263 OpenSSL_add_all_algorithms (); |
|
264 OpenSSL_add_all_ciphers (); |
|
265 OpenSSL_add_all_digests (); |
|
266 int retValue = 0; |
|
267 try |
|
268 { |
|
269 bool isSisFile = CSISContents::IsSisFile(parameter.Sis ()); |
|
270 |
|
271 if(isSisFile) |
|
272 { |
|
273 CSISContents content; |
|
274 content.Load (parameter.Sis ()); |
|
275 CSignSis signsis(parameter.Sis ()); |
|
276 if (parameter.Sign ()) |
|
277 { |
|
278 if (parameter.Verbose ()) |
|
279 { |
|
280 std::cout << "Signing" << std::endl; |
|
281 } |
|
282 signsis.SignSis(parameter.Output (), parameter.Certificate(), parameter.Key(), parameter.PassPhrase(), parameter.Algorithm()); |
|
283 } |
|
284 if (parameter.Unsign ()) |
|
285 { |
|
286 if (parameter.Verbose ()) |
|
287 { |
|
288 std::cout << "Removing signature" << std::endl; |
|
289 } |
|
290 signsis.RemoveSignature (parameter.Output ()); |
|
291 } |
|
292 if (parameter.Report() || parameter.ExtractCert()) |
|
293 { |
|
294 ReportSignatures(content.Controller(), parameter.ExtractCert()); |
|
295 } |
|
296 if (parameter.Dump ()) |
|
297 { |
|
298 content.Dump (std::cout, 0); |
|
299 } |
|
300 } |
|
301 else |
|
302 { |
|
303 if (parameter.Report ()||parameter.ExtractCert()) |
|
304 { |
|
305 std::cout<<"Reporting Stub Sis Controller"<<std::endl; |
|
306 CSISController ctrl; |
|
307 ctrl.Load (parameter.Sis ()); |
|
308 ReportSignatures(ctrl, parameter.ExtractCert()); |
|
309 } |
|
310 } |
|
311 } |
|
312 catch(const CSISException& oops) |
|
313 { |
|
314 std::wcout << oops.widewhat () << std::endl; |
|
315 retValue = 1; |
|
316 } |
|
317 catch (...) |
|
318 { |
|
319 std::wcout << L"Unexpected error." << std::endl; |
|
320 retValue = 1; |
|
321 } |
|
322 EVP_cleanup (); |
|
323 ERR_free_strings (); |
|
324 |
|
325 // cleanup the memory |
|
326 cleanup(argc,argv1); |
|
327 return retValue; |
|
328 } |
|
329 |