parse_key_file.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. * Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. /**
  32. * File:
  33. * parse_key_file.cpp
  34. * Description:
  35. * Parse the RSA key file that user inputs
  36. * to get the key type and rsa structure.
  37. */
  38. #include "parse_key_file.h"
  39. #include "se_trace.h"
  40. #include "arch.h"
  41. #include "util_st.h"
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <assert.h>
  46. #include <string>
  47. #include <algorithm>
  48. #include <fstream>
  49. //N_SIZE+E_SIZE+D_SIZE+P_SIZE+Q_SIZE+DMP1_SIZE+DMQ1_SIZE+sizeof(inverseQ)
  50. #define PRI_COMPONENTS_SIZE (N_SIZE_IN_BYTES + E_SIZE_IN_BYTES + D_SIZE_IN_BYTES + P_SIZE_IN_BYTES *5)
  51. #define PUB_CONPONENTS_SIZE (N_SIZE_IN_BYTES + E_SIZE_IN_BYTES) //N_SIZE+E_SIZE
  52. #define CHECK_RETRUN(value) {if(0 == (value)) return 0;}
  53. //base64Decode
  54. // to decode the base64 string and put it to the result.
  55. //Parameters
  56. // [IN] aSrc: the source string coded in base64
  57. // srcLen: length of the source string
  58. // [OUT] result: point to the decoded string
  59. //Return Value
  60. // int---The length of the decoded string
  61. static int base64_decode(const unsigned char* aSrc, size_t srcLen, unsigned char* result)
  62. {
  63. static char index_64[256] = {
  64. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  65. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  66. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
  67. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
  68. 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  69. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
  70. 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  71. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
  72. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  73. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  74. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  75. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  76. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  77. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  78. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  79. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
  80. };
  81. CHECK_RETRUN(aSrc);
  82. CHECK_RETRUN(srcLen);
  83. CHECK_RETRUN(result);
  84. unsigned char ch1 = 0, ch2 = 0, ch3 = 0, ch4 = 0;
  85. unsigned char *ptr = result;
  86. for (unsigned int i = 0; i < srcLen; ++i)
  87. {
  88. ch1 = index_64[aSrc[i]];
  89. if(ch1 == 64)
  90. continue;
  91. ch2 = index_64[aSrc[++i]];
  92. if(ch2 == 64)
  93. continue;
  94. *(ptr++) = (unsigned char)(ch1<<2 | ch2>>4);
  95. ch3 = index_64[aSrc[++i]];
  96. if(aSrc[i] == '=' || ch3 == 64)
  97. continue;
  98. *(ptr++) = (unsigned char)(ch2<<4 | ch3>>2);
  99. ch4 = index_64[aSrc[++i]];
  100. if(aSrc[i] == '=' || ch4 == 64)
  101. continue;
  102. *(ptr++) = (unsigned char)(ch3<<6 | ch4);
  103. }
  104. return (int)(ptr - result);
  105. }
  106. static void convert_string(unsigned char *str, int len)
  107. {
  108. assert(str != NULL&&len>0);
  109. char temp = 0;
  110. for(int i=0; i<len/2; i++)
  111. {
  112. temp = str[i];
  113. str[i] = str[len-1-i];
  114. str[len-1-i] = temp;
  115. }
  116. }
  117. static bool convert_from_pri_key(const unsigned char *psrc, unsigned int slen, rsa_params_t *rsa)
  118. {
  119. assert(NULL != psrc && NULL != rsa);
  120. if(slen<PRI_COMPONENTS_SIZE)
  121. {
  122. return false;
  123. }
  124. int index = 0;
  125. if((int)psrc[index]== 0x30 &&(int)psrc[index+1] == 0x82)
  126. index += 4;
  127. else if((int)psrc[index] == 0x30 && (int)psrc[index+1] == 0x81)
  128. index += 3;
  129. else
  130. return false;
  131. if(!((int)psrc[index] == 0x02 && (int)psrc[index+1] == 0x01))// version number must be 0x0102
  132. {
  133. return false;
  134. }
  135. index += 2;
  136. if((int)psrc[index] != 0x00)
  137. return false;
  138. index += 6;
  139. memset(rsa, 0, sizeof(rsa_params_t));
  140. //get the module
  141. memcpy_s(rsa->n, sizeof(rsa->n), psrc+index, N_SIZE_IN_BYTES);
  142. convert_string((unsigned char *)rsa->n, sizeof(rsa->n));
  143. //get EXPONENT
  144. index += N_SIZE_IN_BYTES;
  145. if(!((unsigned int)psrc[index] == 0x02 &&(unsigned int)psrc[index+1] == 0x01)) //"0x01" indicates the size of e is 1 byte
  146. {
  147. se_trace(SE_TRACE_ERROR, "Only '3' is accepted as the Exponent value.\n");
  148. return false;
  149. }
  150. index += 2;
  151. unsigned int temp = *(psrc+index);
  152. if(temp != 0x03)
  153. {
  154. se_trace(SE_TRACE_ERROR, "Key Exponent is %#x. Only '3' is accepted as the Exponent value.\n", temp);
  155. return false;
  156. }
  157. temp = temp&0x0f;
  158. memcpy_s(rsa->e, sizeof(rsa->e), &temp, sizeof(unsigned int));
  159. //get D
  160. index += 1;
  161. if((unsigned int)psrc[index]!=0x02)
  162. {
  163. return false;
  164. }
  165. index = index+4;
  166. if((int)psrc[index] == 0)
  167. index += 1;
  168. memcpy_s(rsa->d, sizeof(rsa->d), psrc+index, D_SIZE_IN_BYTES);
  169. convert_string((unsigned char *)rsa->d, sizeof(rsa->d));
  170. //get P
  171. index += D_SIZE_IN_BYTES;
  172. if((unsigned int)psrc[index]!=0x02)
  173. {
  174. return false;
  175. }
  176. index = index+4;
  177. if((int)psrc[index] == 0)
  178. index += 1;
  179. memcpy_s(rsa->p, sizeof(rsa->p), psrc+index, P_SIZE_IN_BYTES);
  180. convert_string((unsigned char *)rsa->p, sizeof(rsa->p));
  181. //get Q
  182. index += P_SIZE_IN_BYTES;
  183. if((unsigned int)psrc[index]!=0x02)
  184. {
  185. return false;
  186. }
  187. index = index+4;
  188. if((int)psrc[index] == 0)
  189. index += 1;
  190. memcpy_s(rsa->q, sizeof(rsa->q), psrc+index, Q_SIZE_IN_BYTES);
  191. convert_string((unsigned char *)rsa->q, sizeof(rsa->q));
  192. //get DMP1
  193. index += Q_SIZE_IN_BYTES;
  194. if((unsigned int)psrc[index]!=0x02)
  195. {
  196. return false;
  197. }
  198. index += 4;
  199. if((int)psrc[index] == 0)
  200. index += 1;
  201. memcpy_s(rsa->dmp1, sizeof(rsa->dmp1), psrc+index, DMP1_SIZE_IN_BYTES);
  202. convert_string((unsigned char *)rsa->dmp1, sizeof(rsa->dmp1));
  203. //get DMQ1
  204. index += DMP1_SIZE_IN_BYTES;
  205. if((unsigned int)psrc[index]!=0x02)
  206. {
  207. return false;
  208. }
  209. index += 4;
  210. if((int)psrc[index] == 0)
  211. index += 1;
  212. memcpy_s(rsa->dmq1, sizeof(rsa->dmq1), psrc+index, DMQ1_SIZE_IN_BYTES);
  213. convert_string((unsigned char *)rsa->dmq1, sizeof(rsa->dmq1));
  214. //get IQMP
  215. index += DMQ1_SIZE_IN_BYTES;
  216. if((unsigned int)psrc[index]!=0x02)
  217. {
  218. return false;
  219. }
  220. index += 3;
  221. if((int)psrc[index] == 0)
  222. index += 1;
  223. memcpy_s(rsa->iqmp, sizeof(rsa->iqmp), psrc+index, IQMP_SIZE_IN_BYTES);
  224. convert_string((unsigned char *)rsa->iqmp, sizeof(rsa->iqmp));
  225. return true;
  226. }
  227. static bool convert_from_pub_key(const unsigned char *psrc, unsigned int slen, rsa_params_t *rsa)
  228. {
  229. assert(NULL != psrc && NULL != rsa);
  230. if(slen<PUB_CONPONENTS_SIZE)
  231. {
  232. return false;
  233. }
  234. //encoded OID sequence (OBJECT IDENTIFIER = 1.2.840.113549.1.1.1)
  235. unsigned char OID_str[] = {0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00};
  236. size_t index = 0;
  237. if((unsigned int)psrc[index]==0x30 && (unsigned int)psrc[index+1] == 0x82)
  238. index += 4;
  239. else if((unsigned int)psrc[index]==0x30 && (unsigned int)psrc[index+1] == 0x81)
  240. index += 3;
  241. else
  242. return false;
  243. unsigned int i=0;
  244. for(; i<sizeof(OID_str); i++)
  245. {
  246. if((unsigned int)psrc[index+i] != (unsigned int)OID_str[i])
  247. break;
  248. }
  249. if(i<sizeof(OID_str))
  250. {
  251. return false;
  252. }
  253. index += sizeof(OID_str);
  254. if((unsigned int)psrc[index] == 0x03 && (unsigned int)psrc[index+1] == 0x82)//0382
  255. index += 4;
  256. else if((unsigned int)psrc[index] == 0x03 && (unsigned int)psrc[index+1] == 0x81)//0381
  257. index += 3;
  258. else
  259. return false;
  260. if((unsigned int)psrc[index] != 0x00)
  261. return false;
  262. index++;
  263. if((unsigned int)psrc[index] == 0x30 &&(unsigned int)psrc[index+1] == 0x82)
  264. index += 4;
  265. else if((unsigned int)psrc[index] == 0x30 &&(unsigned int)psrc[index+1] == 0x81)
  266. index += 3;
  267. else return false;
  268. if((unsigned int)psrc[index] == 0x02 &&(unsigned int)psrc[index+1] == 0x82)
  269. index += 4;
  270. else if((unsigned int)psrc[index] == 0x02 && (unsigned int)psrc[index+1] == 0x81)
  271. index += 3;
  272. if((unsigned int)psrc[index] == 0x00)
  273. index ++;
  274. //get N
  275. memset(rsa, 0, sizeof(rsa_params_t));
  276. memcpy_s(rsa->n, sizeof(rsa->n), psrc+index, N_SIZE_IN_BYTES);
  277. convert_string((unsigned char *)rsa->n, sizeof(rsa->n));
  278. //get EXPONENT
  279. index += N_SIZE_IN_BYTES;
  280. if(!((unsigned int)psrc[index] == 0x02 &&(unsigned int)psrc[index+1] == 0x01)) //"0x01" indicates the size of e is 1 byte
  281. {
  282. se_trace(SE_TRACE_ERROR, "Only '3' is accepted as the Exponent value.\n");
  283. return false;
  284. }
  285. index += 2;
  286. unsigned int temp = *(psrc+index);
  287. if(temp != 0x03)
  288. {
  289. se_trace(SE_TRACE_ERROR, "Key Exponent is %#x. Only '3' is accepted as the Exponent value.\n", temp);
  290. return false;
  291. }
  292. temp = temp&0x0f;
  293. memcpy_s(rsa->e, sizeof(rsa->e), &temp, sizeof(unsigned int));
  294. return true;
  295. }
  296. static unsigned char* decode_key_body(unsigned char *buffer, size_t slen, int *key_type, int *rlen)
  297. {
  298. assert(buffer!=NULL && key_type!=NULL && rlen!=NULL);
  299. const char pri_key_header[] = "-----BEGINRSAPRIVATEKEY-----" ;
  300. const char pri_key_end[] = "-----ENDRSAPRIVATEKEY-----\n";
  301. const char pub_key_header[] = "-----BEGINPUBLICKEY-----";
  302. const char pub_key_end[] = "-----ENDPUBLICKEY-----\n";
  303. int ktype = UNIDENTIFIABLE_KEY;
  304. int offset_pri = (int)(slen - strlen(pri_key_end));
  305. int offset_pub = (int)(slen - strlen(pub_key_end));
  306. if(offset_pub<=0 || offset_pri<=0)
  307. {
  308. se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR);
  309. *key_type = UNIDENTIFIABLE_KEY;
  310. return NULL;
  311. }
  312. //check the file header and footer to get the key type
  313. if(!strncmp((const char *)buffer, pri_key_header, strlen(pri_key_header)))
  314. {
  315. //make sure the key file isn't an emcrypted PEM private key file.
  316. if((!strncmp((const char *)(buffer+offset_pri), pri_key_end, strlen(pri_key_end))) &&
  317. !strstr((const char *)buffer, "Proc-Type: 4, ENCRYPTED"))
  318. {
  319. *(buffer+offset_pri-1) = '\0'; //remove the pri_key_end string
  320. ktype = PRIVATE_KEY;
  321. }
  322. else
  323. {
  324. ktype = UNIDENTIFIABLE_KEY;
  325. }
  326. }
  327. else if(!strncmp((const char *)buffer, pub_key_header, strlen(pub_key_header)))
  328. {
  329. if(!strncmp((const char *)(buffer+offset_pub), pub_key_end, strlen(pub_key_end)))
  330. {
  331. *(buffer + offset_pub-1) = '\0';
  332. ktype = PUBLIC_KEY;
  333. }
  334. else
  335. {
  336. ktype = UNIDENTIFIABLE_KEY;
  337. }
  338. }
  339. else
  340. {
  341. ktype = UNIDENTIFIABLE_KEY;
  342. }
  343. //get the body contents of the key file
  344. size_t body_size = 0, body_offset = 0;
  345. if(ktype == PRIVATE_KEY)
  346. {
  347. body_size = strlen((const char *)buffer) - strlen(pri_key_header);
  348. body_offset = strlen(pri_key_header)+1;
  349. }
  350. else if(ktype == PUBLIC_KEY)
  351. {
  352. body_size = strlen((const char *)buffer) - strlen(pub_key_header);
  353. body_offset = strlen(pub_key_header)+1;
  354. }
  355. else
  356. {
  357. se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR);
  358. *key_type = ktype;
  359. return NULL;
  360. }
  361. unsigned char *decoded_string = (unsigned char *)malloc(sizeof(char)*body_size);
  362. if(!decoded_string)
  363. {
  364. se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR);
  365. *key_type = ktype;
  366. return NULL;
  367. }
  368. memset(decoded_string, 0, body_size);
  369. int retlen = base64_decode(buffer+body_offset, body_size, decoded_string);
  370. if(retlen == 0)
  371. {
  372. se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR);
  373. *key_type = ktype;
  374. free(decoded_string);
  375. return NULL;
  376. }
  377. *key_type = ktype;
  378. *rlen = retlen;
  379. return decoded_string;
  380. }
  381. //read_key_file
  382. // read the input file line by line and trim the blank characters for each line
  383. //Parameters
  384. // [IN] key_path: the file required to be read
  385. static std::string read_key_file(const char *key_path)
  386. {
  387. assert(key_path != NULL);
  388. std::ifstream ifs(key_path, std::ios::in | std::ios::binary);
  389. if(!ifs.good())
  390. {
  391. se_trace(SE_TRACE_ERROR, READ_FILE_ERROR, key_path);
  392. return "";
  393. }
  394. std::string file_content;
  395. std::string str;
  396. while(std::getline(ifs, str))
  397. {
  398. str.erase(std::remove_if(str.begin(), str.end(), ::isspace), str.end());
  399. if(str.length() != 0)
  400. {
  401. file_content += str;
  402. file_content += "\n"; // Add '\n' for each line
  403. }
  404. }
  405. ifs.close();
  406. return file_content;
  407. }
  408. //parse_key_file():
  409. // parse the RSA key file
  410. //Parameters:
  411. // [IN] key_path: the key file name user inputs
  412. // [OUT] prsa: the rsa structure parsed from the key file
  413. // pkey_type: the key type
  414. //Return Value:
  415. // true: success
  416. // false: fail
  417. bool parse_key_file(const char *key_path, rsa_params_t *prsa, int *pkey_type)
  418. {
  419. assert(prsa != NULL && pkey_type != NULL);
  420. if(key_path == NULL)
  421. {
  422. *pkey_type = NO_KEY;
  423. return false;
  424. }
  425. //read and trim the file content
  426. std::string file_content = read_key_file(key_path);
  427. if(file_content.empty() == true)
  428. {
  429. *pkey_type = UNIDENTIFIABLE_KEY;
  430. return false;
  431. }
  432. const unsigned char *buffer = (const unsigned char *)file_content.c_str();
  433. //decode the buffer to decoded_string
  434. size_t result = strlen((const char *)buffer);
  435. int retlen = 0;
  436. int key_type = UNIDENTIFIABLE_KEY;
  437. unsigned char *decoded_string = decode_key_body(const_cast<unsigned char*>(buffer), result, &key_type, &retlen);
  438. if(!decoded_string)
  439. {
  440. *pkey_type = key_type;
  441. return false;
  442. }
  443. //get RSA from the decoded string
  444. bool ret = false;
  445. if(key_type == PRIVATE_KEY)
  446. {
  447. ret = convert_from_pri_key(decoded_string, retlen, prsa);
  448. }
  449. else
  450. {
  451. ret = convert_from_pub_key(decoded_string, retlen, prsa);
  452. }
  453. if(ret == false)
  454. {
  455. se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR);
  456. free(decoded_string);
  457. *pkey_type = key_type;
  458. return false;
  459. }
  460. else
  461. {
  462. se_trace(SE_TRACE_DEBUG, "Parsing key file is OK.\n");
  463. }
  464. *pkey_type = key_type;
  465. free(decoded_string);
  466. return true;
  467. }