DevCertList.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. //////////////////////////////////////////////////////////////
  2. // DevcertList
  3. // Copyright 2008 Paul Todd
  4. //
  5. // This file is part of DevCertList.
  6. // DevcertList is free software: you can redistribute it and/or modify it under
  7. // the terms of the GNU General Public License as published by the Free Software
  8. // Foundation, either version 3 of the License, or (at your option) any later version.
  9. //
  10. // DevcertList is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12. // PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along with DevcertList.
  15. // If not, see http://www.gnu.org/licenses/.
  16. //////////////////////////////////////////////////////////////
  17. //
  18. //
  19. // Version 1.0 initial release
  20. // Version 1.2 support for binary encoded certificates
  21. // Version 1.3 support for IMEI verification
  22. // Version 1.4 support for UID's
  23. // Version 1.6 updated source and binary licence
  24. //////////////////////////////////////////////////////////////
  25. #include "stdafx.h"
  26. #define CAPABILITY_TCB (0)
  27. #define CAPABILITY_COMMDD (1)
  28. #define CAPABILITY_POWERMGMT (2)
  29. #define CAPABILITY_MULTIMEDIADD (3)
  30. #define CAPABILITY_READDEVICEDATA (4)
  31. #define CAPABILITY_WRITEDEVICEDATA (5)
  32. #define CAPABILITY_DRM (6)
  33. #define CAPABILITY_TRUSTEDUI (7)
  34. #define CAPABILITY_PROTSERV (8)
  35. #define CAPABILITY_DISKADMIN (9)
  36. #define CAPABILITY_NETWORKCONTROL (10)
  37. #define CAPABILITY_ALLFILES (11)
  38. #define CAPABILITY_SWEVENT (12)
  39. #define CAPABILITY_NETWORKSERVICES (13)
  40. #define CAPABILITY_TOCALSERVICES (14)
  41. #define CAPABILITY_READUSERDATA (15)
  42. #define CAPABILITY_WRITEUSERDATA (16)
  43. #define CAPABILITY_TOCATION (17)
  44. #define CAPABILITY_SURROUNDINGSDD (18)
  45. #define CAPABILITY_USERENVIRONMENT (19)
  46. BOOL IsSet(const DWORD dwBitArray, int iIndex)
  47. {
  48. const DWORD dwMap = 1 << (31 - iIndex);
  49. return (dwBitArray & dwMap) != 0;
  50. }
  51. void LogMessage(LPCTSTR lpszMessage, ...)
  52. {
  53. TCHAR buffer[512];
  54. va_list args;
  55. va_start(args, lpszMessage);
  56. // Returns the size of the created message
  57. _vsntprintf(buffer, sizeof(buffer), lpszMessage, args);
  58. _ftprintf(stderr, buffer);
  59. }
  60. void LogError(LPCTSTR lpszMessage, ...)
  61. {
  62. TCHAR buffer[512];
  63. va_list args;
  64. va_start(args, lpszMessage);
  65. // Returns the size of the created message
  66. _vsntprintf(buffer, sizeof(buffer), lpszMessage, args);
  67. _ftprintf(stderr, buffer);
  68. }
  69. void RemoveAllSubstrings(LPTSTR lpszString, LPCTSTR lpszStringToRemove)
  70. {
  71. const size_t length = strlen(lpszStringToRemove);
  72. LPSTR pos = NULL;
  73. do
  74. {
  75. pos = strstr(lpszString, lpszStringToRemove);
  76. if (pos != NULL)
  77. {
  78. LPSTR from = pos + length;
  79. LPSTR to = pos;
  80. while (*from)
  81. *to++ = *from++;
  82. *to = 0;
  83. }
  84. }
  85. while (pos != NULL);
  86. }
  87. LPBYTE ReadCertDataFromFile(LPCTSTR lpszFilename, DWORD& cbLength)
  88. {
  89. HANDLE hFile = CreateFile(lpszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
  90. if (hFile == INVALID_HANDLE_VALUE)
  91. {
  92. LogError(_T("STOPPING Failed to open certificate file (%d)"), GetLastError()); // failed to open file
  93. return NULL;
  94. }
  95. cbLength = GetFileSize(hFile, NULL);
  96. if (cbLength == INVALID_FILE_SIZE)
  97. {
  98. LogError(_T("STOPPING Failed to read file size (%d)"), GetLastError()); // failed to read file size
  99. CloseHandle(hFile);
  100. return NULL;
  101. }
  102. LPBYTE buf = new BYTE[cbLength];
  103. if (buf == NULL)
  104. {
  105. LogError(_T("STOPPING Failed to allocate memory for certificate file data")); // failed to allocate memory
  106. CloseHandle(hFile);
  107. return NULL;
  108. }
  109. DWORD cbActualRead = 0;
  110. if (ReadFile(hFile,buf,cbLength,&cbActualRead,NULL) == 0)
  111. {
  112. LogError(_T("STOPPING Failed to read certificate data from file (%d)"), GetLastError());
  113. delete buf;
  114. buf = NULL;
  115. CloseHandle(hFile);
  116. return NULL;
  117. }
  118. if (cbLength != cbActualRead)
  119. {
  120. LogError(_T("STOPPING Failed to read all the certificate data (%d)"), GetLastError());
  121. delete buf;
  122. buf = NULL;
  123. CloseHandle(hFile);
  124. return NULL;
  125. }
  126. CloseHandle(hFile);
  127. return buf;
  128. }
  129. PCCERT_CONTEXT CreateContextFromFileData(LPCTSTR lpszFilename)
  130. {
  131. DWORD cbFileLength = 0;
  132. LPBYTE lpszFileData = ReadCertDataFromFile(lpszFilename, cbFileLength);
  133. if (lpszFileData == NULL)
  134. {
  135. // we would have already logged the errors
  136. return NULL;
  137. }
  138. LPSTR lpszStringData = new CHAR[cbFileLength+1];
  139. if (lpszStringData == NULL)
  140. {
  141. LogError(_T("STOPPING Failed to allocate temporary string data"));
  142. delete lpszFileData;
  143. lpszFileData = NULL;
  144. return NULL;
  145. }
  146. // copy the suspected string data over and zero terminate it!
  147. memcpy(lpszStringData, lpszFileData, cbFileLength);
  148. lpszStringData[cbFileLength] = 0;
  149. if (strstr(lpszStringData, "-----BEGIN CERTIFICATE-----") != NULL && strstr(lpszStringData, "-----END CERTIFICATE-----") != NULL)
  150. {
  151. // this certifcate is base64 encoded
  152. RemoveAllSubstrings(lpszStringData, "-----BEGIN CERTIFICATE-----");
  153. RemoveAllSubstrings(lpszStringData, "-----END CERTIFICATE-----");
  154. delete [] lpszFileData;
  155. lpszFileData = NULL;
  156. cbFileLength = 0;
  157. cbFileLength = (DWORD)strlen(lpszStringData);
  158. lpszFileData = new BYTE[cbFileLength];
  159. if (lpszFileData == NULL)
  160. LogError(_T("STOPPING Failed to allocate buffer for base64 decoded data"));
  161. else
  162. {
  163. int actualLength = cbFileLength;
  164. if (!ATL::Base64Decode(lpszStringData, cbFileLength, lpszFileData, &actualLength))
  165. {
  166. LogError(_T("STOPPING Failed to base64 decode certificate"));
  167. delete [] lpszFileData;
  168. lpszFileData = NULL;
  169. }
  170. // remember to reset the length of the data to the decoded length
  171. cbFileLength = actualLength;
  172. }
  173. delete [] lpszStringData;
  174. lpszStringData = NULL;
  175. }
  176. else
  177. ; // this is binary encoded data so no transform needed
  178. PCCERT_CONTEXT pCertContext = NULL;
  179. if (lpszFileData != NULL)
  180. {
  181. // Now we read the file, get the certificate from the file
  182. pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, lpszFileData, cbFileLength);
  183. if (pCertContext == NULL)
  184. LogError(_T("STOPPING Failed to parse certificate data (%d)"), GetLastError());
  185. delete [] lpszFileData;
  186. lpszFileData = NULL;
  187. }
  188. return pCertContext;
  189. }
  190. PCERT_EXTENSION FindExtension(const PCERT_INFO lpInfo, const LPSTR lpszOidId)
  191. {
  192. for (int i=0; i < (int)lpInfo->cExtension; i++)
  193. {
  194. if (strcmp(lpInfo->rgExtension[i].pszObjId,lpszOidId) == 0)
  195. return &(lpInfo->rgExtension[i]);
  196. }
  197. return NULL;
  198. }
  199. void DumpIMEIs(const PCERT_INFO lpInfo, const BOOL bBare, const BOOL bValidate)
  200. {
  201. PCERT_EXTENSION ext = FindExtension(lpInfo, "1.2.826.0.1.1796587.1.1.1.1");
  202. if (ext == NULL)
  203. LogError(_T("STOPPING Failed to find extension field for IMEI\'s - is this a Symbian devcert?"));
  204. else
  205. {
  206. if (!bBare)
  207. LogMessage(_T("\nListing all IMEI\'s in devcert\n\n"));
  208. // now parse the fields
  209. LPBYTE lpExtData = ext->Value.pbData;
  210. int pos = 0;
  211. int i = 0;
  212. // skip the type of DER
  213. BYTE type = *lpExtData;
  214. if (type != 0x30)
  215. {
  216. LogError(_T("STOPPING Unexpected datatype in IMEI list structure was %x, expected 0x30"), (int)type);
  217. return;
  218. }
  219. pos++;
  220. int length = lpExtData[pos];
  221. pos++;
  222. // 0x80 means this is a custom variable data structure and is not part of our object
  223. if (length == 0x80)
  224. {
  225. LogError(_T("STOPPING Unxpected type in length field of IMEI blob, 0x80 is not a supported length at %d"), pos);
  226. return;
  227. }
  228. if (length > 0x80)
  229. {
  230. // the length is > 128 so
  231. // we look at the number of bytes
  232. // in the length and reset the length variable
  233. int lengthOfLength = (length & 0x7f);
  234. length=0;
  235. while (lengthOfLength > 0)
  236. {
  237. length <<= 8; // roll up the length
  238. length += lpExtData[pos];
  239. pos++;
  240. lengthOfLength--;
  241. }
  242. }
  243. else
  244. ; // length is already set and is < 128 bytes
  245. int base = pos;
  246. BOOL warnAboutSamsungIMEIs = FALSE;
  247. int errors = 0;
  248. while (pos < (base + length))
  249. {
  250. i++;
  251. // we now iterate through the list until we get to the end
  252. const BYTE type = lpExtData[pos];
  253. if (type != 0x0c)
  254. {
  255. LogError(_T("STOPPING Invalid IMEI field type found in data %x expected 0x0c at %d"), (int)type, pos);
  256. return;
  257. }
  258. pos++;
  259. const BYTE length = lpExtData[pos];
  260. if (length >= 0x80)
  261. {
  262. LogError(_T("STOPPING Invalid length parsing IMEI %d at %d"), i, pos);
  263. return;
  264. }
  265. pos++;
  266. const LPBYTE lpIMEI = lpExtData + pos;
  267. #ifdef _UNICODE
  268. if (bBare)
  269. _tprintf(_T("%.*S"), length, lpIMEI);
  270. else
  271. _tprintf(_T("%-4d %.*S"), i, length, lpIMEI);
  272. #else
  273. if (bBare)
  274. _tprintf(_T("%.*s"), length, lpIMEI);
  275. else
  276. _tprintf(_T("%-4d %.*s"), i, length, lpIMEI);
  277. #endif
  278. if (!bBare && bValidate)
  279. {
  280. // Now check the IMEI for validitity
  281. LPCSTR lpszIMEI = (LPCSTR)lpIMEI;
  282. if (length < 15)
  283. {
  284. LogError(_T(" STOPPING IMEI length (%d) is less than 15"), length);
  285. return;
  286. }
  287. if (length != 15)
  288. {
  289. LogError(_T(" *** invalid length (found %d, expected 15) *See note below ***"), length);
  290. errors++;
  291. warnAboutSamsungIMEIs = TRUE;
  292. }
  293. int checksum = 0;
  294. for (int i = 0; i < 14; i++)
  295. {
  296. int v = lpszIMEI[i] - '0';
  297. if (v < 0 || v > 9)
  298. {
  299. LogError(_T("\nSTOPPING Invalid digit at index %d\n"), i);
  300. return;
  301. }
  302. if (i % 2) v *= 2;
  303. checksum += (v % 10) + (v / 10);
  304. }
  305. if (checksum % 10 == 0)
  306. checksum = 0;
  307. else
  308. checksum = 10 - (checksum % 10);
  309. CHAR targetcs = lpszIMEI[14] - '0';
  310. if (targetcs != checksum)
  311. {
  312. LogError(_T(" **** 3GPP IMEI checksum mismatch (%d expected %d) ***"), checksum, targetcs);
  313. errors++;
  314. }
  315. }
  316. _tprintf(_T("\n"));
  317. pos += length;
  318. }
  319. if (!bBare)
  320. {
  321. _tprintf(_T("\n%d IMEI\'s in the certificate\n"), i);
  322. if (errors != 0 && bValidate)
  323. {
  324. _tprintf(_T("------------------------------------------------------------\n"));
  325. _tprintf(_T("!!!! %d CORRUPT OR SUSPICIOUS IMEI'S !!!!\n"), errors);
  326. _tprintf(_T("------------------------------------------------------------\n"));
  327. if (warnAboutSamsungIMEIs)
  328. _tprintf(_T("* Some devices may have up to 17 characters for an IMEI *BUT* this is normally an error"));
  329. }
  330. }
  331. }
  332. }
  333. void DumpUids(const PCERT_INFO lpInfo, const BOOL bBare, const BOOL bValidate)
  334. {
  335. PCERT_EXTENSION ext = FindExtension(lpInfo, "1.2.826.0.1.1796587.1.1.1.4");
  336. if (ext == NULL)
  337. LogError(_T("Failed to find extension field for UID\'s - is this an old Symbian devcert?"));
  338. else
  339. {
  340. if (!bBare)
  341. _tprintf(_T("\nListing all UID\'s in devcert\n\n"));
  342. LPBYTE lpUidData = ext->Value.pbData;
  343. const DWORD dwUidDataLength = ext->Value.cbData;
  344. int pos = 0;
  345. // skip the type of DER
  346. BYTE type = *lpUidData;
  347. if (type != 0x30)
  348. {
  349. LogError(_T("STOPPING Unexpected datatype in UID list structure was %x, expected 0x30"), (int)type);
  350. return;
  351. }
  352. pos++;
  353. int length = lpUidData[pos];
  354. pos++;
  355. // 0x80 means this is a custom variable data structure and is not part of our object
  356. if (length == 0x80)
  357. {
  358. LogError(_T("STOPPING Unxpected type in length field of UID blob, 0x80 is not a supported length at %d"), pos);
  359. return;
  360. }
  361. if (length > 0x80)
  362. {
  363. // the length is > 128 so
  364. // we look at the number of bytes
  365. // in the length and reset the length variable
  366. int lengthOfLength = (length & 0x7f);
  367. length=0;
  368. while (lengthOfLength > 0)
  369. {
  370. length <<= 8; // roll up the length
  371. length += lpUidData[pos];
  372. pos++;
  373. lengthOfLength--;
  374. }
  375. }
  376. else
  377. ; // length is already set and is < 128 bytes
  378. int base = pos;
  379. int errors = 0;
  380. int i = 0;
  381. while (pos < (base + length))
  382. {
  383. i++;
  384. // http://luca.ntop.org/Teaching/Appunti/asn1.html
  385. // this is a byte integer BER type - must be 2
  386. const BYTE type = lpUidData[pos];
  387. if (type != 0x02)
  388. {
  389. LogError(_T("Invalid type found for UID expected 0x02 at %d"), (int)type, pos);
  390. return;
  391. }
  392. pos++;
  393. // number of bytes
  394. const BYTE size = lpUidData[pos];
  395. if (size != 4)
  396. {
  397. LogError(_T("Invalid uid length found expected 4 but found (%d) at %d"), (int)size, pos);
  398. return;
  399. }
  400. pos++;
  401. BYTE one = lpUidData[pos];
  402. pos++;
  403. BYTE two = lpUidData[pos];
  404. pos++;
  405. BYTE three = lpUidData[pos];
  406. pos++;
  407. BYTE four = lpUidData[pos];
  408. pos++;
  409. const DWORD uid = one << 24 | two << 16 | three << 8 | four;
  410. if (bBare)
  411. _tprintf(_T("0x%x\n"), uid);
  412. else
  413. {
  414. _tprintf(_T("%-4d "), i);
  415. if ((uid & 0x20000000) == 0x20000000)
  416. _tprintf(_T("0x%x - PROTECTED\n"), uid);
  417. else
  418. if ((uid & 0xa0000000) == 0xa0000000)
  419. _tprintf(_T("0x%x UNPROTECTED\n"), uid);
  420. else
  421. {
  422. _tprintf(_T("0x%x **** UNKNOWN UID Type, expected UID to start with 0x2 or 0xA \n"), uid);
  423. errors++;
  424. }
  425. }
  426. }
  427. if (!bBare)
  428. {
  429. _tprintf(_T("\n%d UID\'s in the certificate\n"), i);
  430. if (errors != 0 && bValidate)
  431. {
  432. _tprintf(_T("------------------------------------------------------------\n"));
  433. _tprintf(_T("!!!! %d CORRUPT OR SUSPICIOUS UID'S !!!!\n"), errors);
  434. _tprintf(_T("------------------------------------------------------------\n"));
  435. }
  436. }
  437. }
  438. }
  439. void DumpCapabilities(const PCERT_INFO lpInfo, const BOOL bBare)
  440. {
  441. PCERT_EXTENSION ext = FindExtension(lpInfo, "1.2.826.0.1.1796587.1.1.1.6");
  442. if (ext == NULL)
  443. LogError(_T("Failed to find extension field for Capabilities field - is this a Symbian devcert?"));
  444. else
  445. {
  446. if (!bBare)
  447. _tprintf(_T("\nListing all Capabilities\'s in devcert\n\n"));
  448. LPBYTE lpCapabilityData = ext->Value.pbData;
  449. int pos = 0;
  450. // http://luca.ntop.org/Teaching/Appunti/asn1.html
  451. // this is a byte string BER type - must be 3
  452. const BYTE type = lpCapabilityData[pos];
  453. if (type != 0x03)
  454. {
  455. LogError(_T("Invalid type found for capability list %d, exepected 0x03 at %d"), (int)type, pos);
  456. return;
  457. }
  458. pos++;
  459. // number of bytes
  460. const BYTE size = lpCapabilityData[pos];
  461. if (size >= 0x80)
  462. {
  463. LogError(_T("Invalid length found in capabilities must be < 128 (%d) at %d"), (int)size, pos);
  464. return;
  465. }
  466. pos++;
  467. const BYTE remainingbits = lpCapabilityData[pos];
  468. pos++;
  469. // the next 4 bytes represent an array of bits
  470. // each 8 bits is left to right ordered but each byte is
  471. // right to left ordered
  472. BYTE one = lpCapabilityData[pos];
  473. pos++;
  474. BYTE two = lpCapabilityData[pos];
  475. pos++;
  476. BYTE three = lpCapabilityData[pos];
  477. pos++;
  478. BYTE four = lpCapabilityData[pos];
  479. pos++;
  480. // Now construct the binary string for items and parse out the
  481. // capabilities as a bit mask
  482. const DWORD dwCapabilties = one << 24 | two << 16 | three << 8 | four;
  483. if (IsSet(dwCapabilties, CAPABILITY_TCB))
  484. {
  485. if (bBare)
  486. _tprintf(_T("TCB\n"));
  487. else
  488. _tprintf(_T(" TCB\n"));
  489. }
  490. else
  491. {
  492. if (!bBare)
  493. _tprintf(_T("NO TCB\n"));
  494. }
  495. if (IsSet(dwCapabilties, CAPABILITY_COMMDD))
  496. {
  497. if (bBare)
  498. _tprintf(_T("CommDD\n"));
  499. else
  500. _tprintf(_T(" CommDD\n"));
  501. }
  502. else
  503. {
  504. if (!bBare)
  505. _tprintf(_T("NO CommDD\n"));
  506. }
  507. if (IsSet(dwCapabilties, CAPABILITY_POWERMGMT))
  508. {
  509. if (bBare)
  510. _tprintf(_T("Power Management\n"));
  511. else
  512. _tprintf(_T(" Power Management\n"));
  513. }
  514. else
  515. {
  516. if (!bBare)
  517. _tprintf(_T("NO Power Management\n"));
  518. }
  519. if (IsSet(dwCapabilties,CAPABILITY_MULTIMEDIADD))
  520. {
  521. if (bBare)
  522. _tprintf(_T("MultimediaDD\n"));
  523. else
  524. _tprintf(_T(" MultimediaDD\n"));
  525. }
  526. else
  527. {
  528. if (!bBare)
  529. _tprintf(_T("NO MultimediaDD\n"));
  530. }
  531. if (IsSet(dwCapabilties, CAPABILITY_READDEVICEDATA))
  532. {
  533. if (bBare)
  534. _tprintf(_T("Read Device Data\n"));
  535. else
  536. _tprintf(_T(" Read Device Data\n"));
  537. }
  538. else
  539. {
  540. if (!bBare)
  541. _tprintf(_T("NO Read Device Data\n"));
  542. }
  543. if (IsSet(dwCapabilties,CAPABILITY_WRITEDEVICEDATA))
  544. {
  545. if (bBare)
  546. _tprintf(_T("Write Device Data\n"));
  547. else
  548. _tprintf(_T(" Write Device Data\n"));
  549. }
  550. else
  551. {
  552. if (!bBare)
  553. _tprintf(_T("NO Write Device Data\n"));
  554. }
  555. if (IsSet(dwCapabilties, CAPABILITY_DRM))
  556. {
  557. if (bBare)
  558. _tprintf(_T("DRM\n"));
  559. else
  560. _tprintf(_T(" DRM\n"));
  561. }
  562. else
  563. {
  564. if (!bBare)
  565. _tprintf(_T("NO DRM\n"));
  566. }
  567. if (IsSet(dwCapabilties , CAPABILITY_TRUSTEDUI))
  568. {
  569. if (bBare)
  570. _tprintf(_T("Trusted UI\n"));
  571. else
  572. _tprintf(_T(" Trusted UI\n"));
  573. }
  574. else
  575. {
  576. if (!bBare)
  577. _tprintf(_T("NO Trusted UI\n"));
  578. }
  579. if (IsSet(dwCapabilties, CAPABILITY_PROTSERV))
  580. {
  581. if (bBare)
  582. _tprintf(_T("Protserv\n"));
  583. else
  584. _tprintf(_T(" Protserv\n"));
  585. }
  586. else
  587. {
  588. if (!bBare)
  589. _tprintf(_T("NO ProtServ\n"));
  590. }
  591. if (IsSet(dwCapabilties, CAPABILITY_DISKADMIN))
  592. {
  593. if (bBare)
  594. _tprintf(_T("DiskAdmin\n"));
  595. else
  596. _tprintf(_T(" DiskAdmin\n"));
  597. }
  598. else
  599. {
  600. if (!bBare)
  601. _tprintf(_T("NO DiskAdmin\n"));
  602. }
  603. if (IsSet(dwCapabilties, CAPABILITY_NETWORKCONTROL))
  604. {
  605. if (bBare)
  606. _tprintf(_T("Network Control\n"));
  607. else
  608. _tprintf(_T(" Network Control\n"));
  609. }
  610. else
  611. {
  612. if (!bBare)
  613. _tprintf(_T("NO Network Control\n"));
  614. }
  615. if (IsSet(dwCapabilties, CAPABILITY_ALLFILES))
  616. {
  617. if (bBare)
  618. _tprintf(_T("All Files\n"));
  619. else
  620. _tprintf(_T(" All Files\n"));
  621. }
  622. else
  623. {
  624. if (!bBare)
  625. _tprintf(_T("NO All Files\n"));
  626. }
  627. if (IsSet(dwCapabilties, CAPABILITY_SWEVENT))
  628. {
  629. if (bBare)
  630. _tprintf(_T("SWEvent\n"));
  631. else
  632. _tprintf(_T(" SWEvent\n"));
  633. }
  634. else
  635. {
  636. if (!bBare)
  637. _tprintf(_T("NO SWEvent\n"));
  638. }
  639. if (IsSet(dwCapabilties, CAPABILITY_NETWORKSERVICES))
  640. {
  641. if (bBare)
  642. _tprintf(_T("Network Services\n"));
  643. else
  644. _tprintf(_T(" Network Services\n"));
  645. }
  646. else
  647. {
  648. if (!bBare)
  649. _tprintf(_T("NO Network Services\n"));
  650. }
  651. if (IsSet(dwCapabilties, CAPABILITY_TOCALSERVICES))
  652. {
  653. if (bBare)
  654. _tprintf(_T("Local Services\n"));
  655. else
  656. _tprintf(_T(" Local Services\n"));
  657. }
  658. else
  659. {
  660. if (!bBare)
  661. _tprintf(_T("NO Local Services\n"));
  662. }
  663. if (IsSet(dwCapabilties, CAPABILITY_READUSERDATA))
  664. {
  665. if (bBare)
  666. _tprintf(_T("Read User Data\n"));
  667. else
  668. _tprintf(_T(" Read User Data\n"));
  669. }
  670. else
  671. {
  672. if (!bBare)
  673. _tprintf(_T("NO Read User Data\n"));
  674. }
  675. if (IsSet(dwCapabilties, CAPABILITY_WRITEUSERDATA))
  676. {
  677. if (bBare)
  678. _tprintf(_T("Write User Data\n"));
  679. else
  680. _tprintf(_T(" Write User Data\n"));
  681. }
  682. else
  683. {
  684. if (!bBare)
  685. _tprintf(_T("NO Write User Data\n"));
  686. }
  687. if (IsSet(dwCapabilties, CAPABILITY_TOCATION))
  688. {
  689. if (bBare)
  690. _tprintf(_T("Location\n"));
  691. else
  692. _tprintf(_T(" Location\n"));
  693. }
  694. else
  695. {
  696. if (!bBare)
  697. _tprintf(_T("NO Location\n"));
  698. }
  699. if (IsSet(dwCapabilties , CAPABILITY_SURROUNDINGSDD))
  700. {
  701. if (bBare)
  702. _tprintf(_T("SurroundingsDD\n"));
  703. else
  704. _tprintf(_T(" SurroundingsDD\n"));
  705. }
  706. else
  707. {
  708. if (!bBare)
  709. _tprintf(_T("NO SurroundingsDD\n"));
  710. }
  711. if ((dwCapabilties, CAPABILITY_USERENVIRONMENT))
  712. {
  713. if (bBare)
  714. _tprintf(_T("User Environment\n"));
  715. else
  716. _tprintf(_T(" User Environment\n"));
  717. }
  718. else
  719. {
  720. if (!bBare)
  721. _tprintf(_T("NO User Environment\n"));
  722. }
  723. }
  724. }
  725. void PrintHelp()
  726. {
  727. _tprintf(_T("\nDevCertList 1.6 \n"));
  728. _tprintf(_T("(c) 2009 Paul Todd\n"));
  729. _tprintf(_T("Lists IMEI's, UID's and Capabilities for a Symbian devcerts\n\n"));
  730. _tprintf(_T("This software is licenced under the GPL 3.0 licence and\n"));
  731. _tprintf(_T("is released as freeware, you should not have been charged for it.\n"));
  732. _tprintf(_T("\nFor source, help, updates visit\n"));
  733. _tprintf(_T("https://projects.developer.nokia.com/DevCertList\n\n"));
  734. _tprintf(_T("usage: devcertlist [/b] [/i] [/c] [/?] certificatefile.cer\n"));
  735. _tprintf(_T("/b - bare output, useful for grep\n"));
  736. _tprintf(_T("/i - list imei's in devcert\n"));
  737. _tprintf(_T("/nv - do not validate IMEI's and UID's in devcert\n"));
  738. _tprintf(_T("/c - list capabilties for devcert\n"));
  739. _tprintf(_T("/u - list uids for devcert (if present)\n"));
  740. _tprintf(_T("/? - help\n"));
  741. }
  742. BOOL FlagSet(const int argc, TCHAR* argv[], LPCTSTR lpszOption)
  743. {
  744. for (int i=0; i < argc; i++)
  745. {
  746. LPCTSTR lpszArguement = argv[i];
  747. if (strcmp(lpszArguement, lpszOption) == 0)
  748. return TRUE;
  749. }
  750. return FALSE;
  751. }
  752. int _tmain(int argc, _TCHAR* argv[])
  753. {
  754. const BOOL help = FlagSet(argc, argv, _T("/?"));
  755. const BOOL bare = FlagSet(argc, argv, _T("/b"));
  756. const BOOL novalidate = FlagSet(argc, argv, _T("/nv"));
  757. const BOOL dumpIMEIs = FlagSet(argc, argv, _T("/i"));
  758. const BOOL dumpCapabilities = FlagSet(argc, argv, _T("/c"));
  759. const BOOL dumpUIDs = FlagSet(argc, argv, _T("/u"));
  760. if (argc <= 1 || help)
  761. PrintHelp();
  762. else
  763. {
  764. if (dumpIMEIs && dumpCapabilities && bare)
  765. LogError(_T("dump IMEI\'s, dump Capabilties and bare all together are not allowed"));
  766. else
  767. {
  768. LPCTSTR lpszCertFileName = argv[argc-1];
  769. PCCERT_CONTEXT pCertContext = CreateContextFromFileData(lpszCertFileName);
  770. if (pCertContext != NULL)
  771. {
  772. if (dumpIMEIs || (!dumpIMEIs && !dumpCapabilities && !dumpUIDs))
  773. DumpIMEIs(pCertContext->pCertInfo, bare, !novalidate);
  774. if (dumpUIDs || (!dumpUIDs && !dumpIMEIs && !dumpCapabilities))
  775. DumpUids(pCertContext->pCertInfo, bare, !novalidate);
  776. if (dumpCapabilities || (!dumpIMEIs && !dumpCapabilities && !dumpUIDs))
  777. DumpCapabilities(pCertContext->pCertInfo, bare);
  778. CertFreeCertificateContext(pCertContext);
  779. }
  780. else
  781. ; // failed to create the context, don't log as we have already done it
  782. }
  783. }
  784. return 0;
  785. }