p≡p engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1090 lines
26 KiB

2 years ago
6 years ago
6 years ago
4 years ago
4 years ago
4 years ago
4 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
4 years ago
6 years ago
4 years ago
6 years ago
4 years ago
6 years ago
4 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
3 years ago
3 years ago
6 years ago
  1. /**
  2. * @file map_asn1.c
  3. * @brief map asn1 to pEp structs and back
  4. * @license GNU General Public License 3.0 - see LICENSE.txt
  5. */
  6. #include "pEp_internal.h"
  7. #include "map_asn1.h"
  8. Identity_t *Identity_from_Struct(
  9. const pEp_identity *ident,
  10. Identity_t *result
  11. )
  12. {
  13. bool allocated = !result;
  14. assert(ident);
  15. if (!ident)
  16. return NULL;
  17. if (allocated)
  18. result = (Identity_t *) calloc(1, sizeof(Identity_t));
  19. assert(result);
  20. if (!result)
  21. return NULL;
  22. if (ident->address) {
  23. int r = OCTET_STRING_fromBuf(&result->address, ident->address, -1);
  24. if (r)
  25. goto enomem;
  26. }
  27. if (ident->fpr) {
  28. if (OCTET_STRING_fromString(&result->fpr, ident->fpr))
  29. goto enomem;
  30. }
  31. if (ident->user_id) {
  32. int r = OCTET_STRING_fromBuf(&result->user_id, ident->user_id, -1);
  33. if (r)
  34. goto enomem;
  35. }
  36. if (ident->username) {
  37. int r = OCTET_STRING_fromBuf(&result->username, ident->username, -1);
  38. if (r)
  39. goto enomem;
  40. }
  41. if (ident->comm_type != PEP_ct_unknown) {
  42. result->comm_type = ident->comm_type;
  43. }
  44. if (ident->lang[0]) {
  45. int r = OCTET_STRING_fromBuf(&result->lang, ident->lang, 2);
  46. assert(r == 0);
  47. if(r != 0)
  48. goto enomem;
  49. }
  50. else {
  51. int r = OCTET_STRING_fromBuf(&result->lang, "en", 2);
  52. assert(r == 0);
  53. if(r != 0)
  54. goto enomem;
  55. }
  56. return result;
  57. enomem:
  58. if (allocated)
  59. ASN_STRUCT_FREE(asn_DEF_Identity, result);
  60. return NULL;
  61. }
  62. pEp_identity *Identity_to_Struct(Identity_t *ident, pEp_identity *result)
  63. {
  64. bool allocated = !result;
  65. assert(ident);
  66. if (!ident)
  67. return NULL;
  68. if (allocated)
  69. result = new_identity(NULL, NULL, NULL, NULL);
  70. if (!result)
  71. return NULL;
  72. result->address = strndup((char *) ident->address.buf,
  73. ident->address.size);
  74. assert(result->address);
  75. if (!result->address)
  76. goto enomem;
  77. result->fpr = strndup((char *) ident->fpr.buf, ident->fpr.size);
  78. assert(result->fpr);
  79. if (!result->fpr)
  80. goto enomem;
  81. result->user_id = strndup((char *) ident->user_id.buf,
  82. ident->user_id.size);
  83. assert(result->user_id);
  84. if (!result->user_id)
  85. goto enomem;
  86. result->username = strndup((char *) ident->username.buf,
  87. ident->username.size);
  88. assert(result->username);
  89. if (!result->username)
  90. goto enomem;
  91. result->comm_type = (PEP_comm_type) ident->comm_type;
  92. if (ident->lang.size == 2) {
  93. result->lang[0] = ident->lang.buf[0];
  94. result->lang[1] = ident->lang.buf[1];
  95. result->lang[2] = 0;
  96. }
  97. return result;
  98. enomem:
  99. if (allocated)
  100. free_identity(result);
  101. return NULL;
  102. }
  103. IdentityList_t *IdentityList_from_identity_list(
  104. const identity_list *list,
  105. IdentityList_t *result
  106. )
  107. {
  108. bool allocated = !result;
  109. if (!(list && list->ident))
  110. return NULL;
  111. if (allocated) {
  112. result = (IdentityList_t *) calloc(1, sizeof(IdentityList_t));
  113. assert(result);
  114. if (!result)
  115. return NULL;
  116. }
  117. else {
  118. asn_sequence_empty(result);
  119. }
  120. for (const identity_list *l = list; l && l->ident; l=l->next) {
  121. Identity_t *ident = Identity_from_Struct(l->ident, NULL);
  122. if (ASN_SEQUENCE_ADD(&result->list, ident)) {
  123. ASN_STRUCT_FREE(asn_DEF_Identity, ident);
  124. goto enomem;
  125. }
  126. }
  127. return result;
  128. enomem:
  129. if (allocated)
  130. ASN_STRUCT_FREE(asn_DEF_IdentityList, result);
  131. return NULL;
  132. }
  133. identity_list *IdentityList_to_identity_list(IdentityList_t *list, identity_list *result)
  134. {
  135. bool allocated = !result;
  136. assert(list);
  137. if (!list)
  138. return NULL;
  139. if (allocated)
  140. result = new_identity_list(NULL);
  141. if (!result)
  142. return NULL;
  143. identity_list *r = result;
  144. for (int i=0; i<list->list.count; i++) {
  145. pEp_identity *ident = Identity_to_Struct(list->list.array[i], NULL);
  146. r = identity_list_add(r, ident);
  147. if (!r)
  148. goto enomem;
  149. }
  150. return result;
  151. enomem:
  152. if (allocated)
  153. free_identity_list(result);
  154. return NULL;
  155. }
  156. PStringPair_t *PStringPair_from_Struct(
  157. const stringpair_t *value,
  158. PStringPair_t *result
  159. )
  160. {
  161. bool allocated = !result;
  162. assert(value);
  163. if (!value)
  164. return NULL;
  165. if (allocated)
  166. result = (PStringPair_t *) calloc(1, sizeof(PStringPair_t));
  167. assert(result);
  168. if (!result)
  169. return NULL;
  170. if (value->key) {
  171. int r = OCTET_STRING_fromBuf(&result->key, value->key, -1);
  172. if (r)
  173. goto enomem;
  174. }
  175. if (value->value) {
  176. int r = OCTET_STRING_fromBuf(&result->value, value->value, -1);
  177. if (r)
  178. goto enomem;
  179. }
  180. return result;
  181. enomem:
  182. if (allocated)
  183. ASN_STRUCT_FREE(asn_DEF_PStringPair, result);
  184. return NULL;
  185. }
  186. stringpair_t *PStringPair_to_Struct(PStringPair_t *value)
  187. {
  188. assert(value);
  189. if (!value)
  190. return NULL;
  191. stringpair_t *result = (stringpair_t *) calloc(1, sizeof(stringpair_t));
  192. assert(result);
  193. if (!result)
  194. goto enomem;
  195. result->key = strndup((char *) value->key.buf,
  196. value->key.size);
  197. assert(result->key);
  198. if (!result->key)
  199. goto enomem;
  200. result->value = strndup((char *) value->value.buf,
  201. value->value.size);
  202. assert(result->value);
  203. if (!result->value)
  204. goto enomem;
  205. return result;
  206. enomem:
  207. free_stringpair(result);
  208. return NULL;
  209. }
  210. PStringPairList_t *PStringPairList_from_stringpair_list(
  211. const stringpair_list_t *list,
  212. PStringPairList_t *result
  213. )
  214. {
  215. bool allocated = !result;
  216. assert(list);
  217. if (!(list && list->value))
  218. return NULL;
  219. if (allocated) {
  220. result = (PStringPairList_t *) calloc(1, sizeof(PStringPairList_t));
  221. assert(result);
  222. if (!result)
  223. return NULL;
  224. }
  225. else {
  226. asn_sequence_empty(result);
  227. }
  228. for (const stringpair_list_t *l = list; l && l->value; l=l->next) {
  229. PStringPair_t *value = PStringPair_from_Struct(l->value, NULL);
  230. if (ASN_SEQUENCE_ADD(&result->list, value)) {
  231. ASN_STRUCT_FREE(asn_DEF_PStringPair, value);
  232. goto enomem;
  233. }
  234. }
  235. return result;
  236. enomem:
  237. if (allocated)
  238. ASN_STRUCT_FREE(asn_DEF_PStringPairList, result);
  239. return NULL;
  240. }
  241. stringpair_list_t *PStringPairList_to_stringpair_list(
  242. PStringPairList_t *list,
  243. stringpair_list_t *result
  244. )
  245. {
  246. bool allocated = !result;
  247. assert(list);
  248. if (!list)
  249. return NULL;
  250. if (allocated)
  251. result = new_stringpair_list(NULL);
  252. if (!result)
  253. return NULL;
  254. stringpair_list_t *r = result;
  255. for (int i=0; i<list->list.count; i++) {
  256. stringpair_t *value = PStringPair_to_Struct(list->list.array[i]);
  257. r = stringpair_list_add(r, value);
  258. if (!r)
  259. goto enomem;
  260. }
  261. return result;
  262. enomem:
  263. if (allocated)
  264. free_stringpair_list(result);
  265. return NULL;
  266. }
  267. PStringList_t *PStringList_from_stringlist(
  268. const stringlist_t *list,
  269. PStringList_t *result
  270. )
  271. {
  272. bool allocated = !result;
  273. assert(list);
  274. if (!(list && list->value))
  275. return NULL;
  276. if (allocated) {
  277. result = (PStringList_t *) calloc(1, sizeof(PStringList_t));
  278. assert(result);
  279. if (!result)
  280. return NULL;
  281. }
  282. else {
  283. asn_sequence_empty(result);
  284. }
  285. for (const stringlist_t *l = list; l && l->value; l=l->next) {
  286. PString_t *element = (PString_t *) calloc(1, sizeof(PString_t));
  287. assert(element);
  288. if (!element)
  289. goto enomem;
  290. int r = OCTET_STRING_fromBuf(element, l->value, -1);
  291. if (r)
  292. goto enomem;
  293. if (ASN_SEQUENCE_ADD(&result->list, element)) {
  294. ASN_STRUCT_FREE(asn_DEF_PString, element);
  295. goto enomem;
  296. }
  297. }
  298. return result;
  299. enomem:
  300. if (allocated)
  301. ASN_STRUCT_FREE(asn_DEF_PStringList, result);
  302. return NULL;
  303. }
  304. stringlist_t *PStringList_to_stringlist(PStringList_t *list)
  305. {
  306. assert(list);
  307. if (!list)
  308. return NULL;
  309. stringlist_t *result = (stringlist_t *) calloc(1, sizeof(stringlist_t));
  310. assert(result);
  311. if (!result)
  312. goto enomem;
  313. stringlist_t *r = result;
  314. for (int i=0; i<list->list.count; i++) {
  315. char *s = strndup((char *) list->list.array[i]->buf,
  316. list->list.array[i]->size);
  317. assert(s);
  318. if (!s)
  319. goto enomem;
  320. r->value = s;
  321. if (i < list->list.count-1) {
  322. r->next = (stringlist_t *) calloc(1, sizeof(stringlist_t));
  323. assert(r->next);
  324. if (!r->next)
  325. goto enomem;
  326. r = r->next;
  327. }
  328. }
  329. return result;
  330. enomem:
  331. free_stringlist(result);
  332. return NULL;
  333. }
  334. PBlobList_t *PBlobList_from_bloblist(
  335. bloblist_t *list,
  336. PBlobList_t *result,
  337. bool copy,
  338. size_t max_blob_size
  339. )
  340. {
  341. bool allocated = !result;
  342. if (!max_blob_size)
  343. max_blob_size = SIZE_MAX;
  344. assert(list);
  345. if (!(list && list->value))
  346. return NULL;
  347. if (allocated) {
  348. result = (PBlobList_t *) calloc(1, sizeof(PBlobList_t));
  349. assert(result);
  350. if (!result)
  351. return NULL;
  352. }
  353. else {
  354. asn_sequence_empty(result);
  355. }
  356. size_t rest_blob_size = max_blob_size;
  357. for (bloblist_t *l = list; l && l->value; l=l->next) {
  358. PBlob_t *element = (PBlob_t *) calloc(1, sizeof(PBlob_t));
  359. assert(element);
  360. if (!element)
  361. goto enomem;
  362. int r = 0;
  363. if (l->size > rest_blob_size)
  364. goto enomem;
  365. rest_blob_size -= l->size;
  366. if (copy) {
  367. r = OCTET_STRING_fromBuf(&element->value, l->value, l->size);
  368. if (r)
  369. goto enomem;
  370. }
  371. else /* move */ {
  372. #if defined(__CHAR_BIT__) && __CHAR_BIT__ == 8
  373. element->value.buf = (uint8_t *) l->value;
  374. #else
  375. // FIXME: this is problematic on platforms with bytes != octets
  376. // we want this warning
  377. element->value.buf = l->value;
  378. #endif
  379. l->value = NULL;
  380. element->value.size = l->size;
  381. l->size = 0;
  382. }
  383. if (!EMPTYSTR(l->mime_type)) {
  384. PString_t *_mime_type = (PString_t *) calloc(1, sizeof(PString_t));
  385. assert(_mime_type);
  386. if (!_mime_type)
  387. goto enomem;
  388. r = OCTET_STRING_fromBuf(_mime_type, l->mime_type, -1);
  389. if (r)
  390. goto enomem;
  391. element->mime_type = _mime_type;
  392. }
  393. if (!EMPTYSTR(l->filename)) {
  394. PString_t *_filename = (PString_t *) calloc(1, sizeof(PString_t));
  395. assert(_filename);
  396. if (!_filename)
  397. goto enomem;
  398. r = OCTET_STRING_fromBuf(_filename, l->filename, -1);
  399. if (r)
  400. goto enomem;
  401. element->filename = _filename;
  402. }
  403. switch (l->disposition) {
  404. case PEP_CONTENT_DISP_ATTACHMENT:
  405. element->disposition = ContentDisposition_attachment;
  406. break;
  407. case PEP_CONTENT_DISP_INLINE:
  408. element->disposition = ContentDisposition_inline;
  409. break;
  410. case PEP_CONTENT_DISP_OTHER:
  411. element->disposition = ContentDisposition_other;
  412. break;
  413. default:
  414. assert(0); // should not happen; use default
  415. element->disposition = ContentDisposition_attachment;
  416. }
  417. if (ASN_SEQUENCE_ADD(&result->list, element)) {
  418. ASN_STRUCT_FREE(asn_DEF_PBlob, element);
  419. goto enomem;
  420. }
  421. }
  422. return result;
  423. enomem:
  424. if (allocated)
  425. ASN_STRUCT_FREE(asn_DEF_PBlobList, result);
  426. return NULL;
  427. }
  428. bloblist_t *PBlobList_to_bloblist(
  429. PBlobList_t *list,
  430. bloblist_t *result,
  431. bool copy,
  432. size_t max_blob_size
  433. )
  434. {
  435. bool allocated = !result;
  436. if (!max_blob_size)
  437. max_blob_size = SIZE_MAX;
  438. assert(list);
  439. if (!list)
  440. return NULL;
  441. if (allocated)
  442. result = new_bloblist(NULL, 0, NULL, NULL);
  443. if (!result)
  444. return NULL;
  445. size_t rest_blob_size = max_blob_size;
  446. bloblist_t *r = result;
  447. for (int i=0; i<list->list.count; i++) {
  448. // this should not happen
  449. assert(list->list.array[i]);
  450. if (!list->list.array[i])
  451. goto enomem;
  452. if (list->list.array[i]->value.size > rest_blob_size)
  453. goto enomem;
  454. rest_blob_size -= list->list.array[i]->value.size;
  455. char *_mime_type = NULL;
  456. if (list->list.array[i]->mime_type) {
  457. _mime_type = strndup((char *) list->list.array[i]->mime_type->buf,
  458. list->list.array[i]->mime_type->size);
  459. assert(_mime_type);
  460. if (!_mime_type)
  461. goto enomem;
  462. }
  463. char *_filename = NULL;
  464. if (list->list.array[i]->filename) {
  465. _filename = strndup((char *) list->list.array[i]->filename->buf,
  466. list->list.array[i]->filename->size);
  467. assert(_filename);
  468. if (!_filename)
  469. goto enomem;
  470. }
  471. #if defined(__CHAR_BIT__) && __CHAR_BIT__ == 8
  472. char *_data = (char *) list->list.array[i]->value.buf;
  473. #else
  474. // FIXME: this is problematic on platforms with bytes != octets
  475. // we want this warning
  476. char *_data = list->list.array[i]->value.buf;
  477. #endif
  478. if (copy) {
  479. _data = strndup(_data, list->list.array[i]->value.size);
  480. assert(_data);
  481. if (!_data)
  482. goto enomem;
  483. }
  484. // bloblist_add() has move semantics
  485. r = bloblist_add(r, _data, list->list.array[i]->value.size, _mime_type,
  486. _filename);
  487. if (!copy) {
  488. list->list.array[i]->value.buf = NULL;
  489. list->list.array[i]->value.size = 0;
  490. }
  491. if (!r)
  492. goto enomem;
  493. switch (list->list.array[i]->disposition) {
  494. case ContentDisposition_attachment:
  495. r->disposition = PEP_CONTENT_DISP_ATTACHMENT;
  496. break;
  497. case ContentDisposition_inline:
  498. r->disposition = PEP_CONTENT_DISP_INLINE;
  499. break;
  500. case ContentDisposition_other:
  501. r->disposition = PEP_CONTENT_DISP_OTHER;
  502. break;
  503. default:
  504. assert(0); // should not happen; use default
  505. r->disposition = PEP_CONTENT_DISP_ATTACHMENT;
  506. }
  507. }
  508. return result;
  509. enomem:
  510. if (allocated)
  511. free_bloblist(result);
  512. return NULL;
  513. }
  514. ASN1Message_t *ASN1Message_from_message(
  515. message *msg,
  516. ASN1Message_t *result,
  517. bool copy,
  518. size_t max_blob_size
  519. )
  520. {
  521. bool allocated = !result;
  522. if (!max_blob_size)
  523. max_blob_size = SIZE_MAX;
  524. assert(msg);
  525. if (!msg)
  526. return NULL;
  527. if (allocated) {
  528. result = (ASN1Message_t *) calloc(1, sizeof(ASN1Message_t));
  529. assert(result);
  530. if (!result)
  531. return NULL;
  532. }
  533. else {
  534. asn_sequence_empty(result);
  535. }
  536. // direction will be skipped on the line
  537. if (!EMPTYSTR(msg->id)) {
  538. PString_t *str = (PString_t *) calloc(1, sizeof(PString_t));
  539. assert(str);
  540. if (!str)
  541. goto enomem;
  542. int r = OCTET_STRING_fromBuf(str, msg->id, -1);
  543. if (r)
  544. goto enomem;
  545. result->id = str;
  546. }
  547. if (msg->sent) {
  548. GeneralizedTime_t *ts = asn_time2GT(NULL, msg->sent, 1);
  549. if (!ts)
  550. goto enomem;
  551. result->sent = ts;
  552. }
  553. if (msg->recv) {
  554. GeneralizedTime_t *ts = asn_time2GT(NULL, msg->recv, 1);
  555. if (!ts)
  556. goto enomem;
  557. result->recv = ts;
  558. }
  559. if (!msg->from) // from is not optional
  560. goto enomem;
  561. Identity_from_Struct(msg->from, &result->from);
  562. if (msg->to && msg->to->ident) {
  563. IdentityList_t *l = IdentityList_from_identity_list(msg->to, NULL);
  564. if (!l)
  565. goto enomem;
  566. result->to = l;
  567. }
  568. if (msg->cc && msg->cc->ident) {
  569. IdentityList_t *l = IdentityList_from_identity_list(msg->cc, NULL);
  570. if (!l)
  571. goto enomem;
  572. result->cc = l;
  573. }
  574. if (msg->bcc && msg->bcc->ident) {
  575. IdentityList_t *l = IdentityList_from_identity_list(msg->bcc, NULL);
  576. if (!l)
  577. goto enomem;
  578. result->bcc = l;
  579. }
  580. if (msg->recv_by) {
  581. Identity_t *i = Identity_from_Struct(msg->recv_by, NULL);
  582. if (!i)
  583. goto enomem;
  584. result->recv_by = i;
  585. }
  586. if (msg->reply_to && msg->reply_to->ident) {
  587. IdentityList_t *l = IdentityList_from_identity_list(msg->reply_to, NULL);
  588. if (!l)
  589. goto enomem;
  590. result->reply_to = l;
  591. }
  592. if (msg->in_reply_to && msg->in_reply_to->value) {
  593. PStringList_t *l = PStringList_from_stringlist(msg->in_reply_to, NULL);
  594. if (!l)
  595. goto enomem;
  596. result->in_reply_to = l;
  597. }
  598. if (msg->references && msg->references->value) {
  599. PStringList_t *l = PStringList_from_stringlist(msg->references, NULL);
  600. if (!l)
  601. goto enomem;
  602. result->references = l;
  603. }
  604. if (msg->keywords && msg->keywords->value) {
  605. PStringList_t *l = PStringList_from_stringlist(msg->keywords, NULL);
  606. if (!l)
  607. goto enomem;
  608. result->keywords = l;
  609. }
  610. if (!EMPTYSTR(msg->comments)) {
  611. PString_t *str = (PString_t *) calloc(1, sizeof(PString_t));
  612. assert(str);
  613. if (!str)
  614. goto enomem;
  615. int r = OCTET_STRING_fromBuf(str, msg->comments, -1);
  616. if (r)
  617. goto enomem;
  618. result->comments = str;
  619. }
  620. if (msg->opt_fields && msg->opt_fields->value) {
  621. PStringPairList_t *l = PStringPairList_from_stringpair_list(msg->opt_fields, NULL);
  622. if (!l)
  623. goto enomem;
  624. result->opt_fields = l;
  625. }
  626. if (!EMPTYSTR(msg->_sender_fpr)) {
  627. Hash_t *str = (Hash_t *) calloc(1, sizeof(Hash_t));
  628. assert(str);
  629. if (!str)
  630. goto enomem;
  631. int r = OCTET_STRING_fromBuf(str, msg->_sender_fpr, -1);
  632. if (r)
  633. goto enomem;
  634. result->sender_fpr = str;
  635. }
  636. if (!EMPTYSTR(msg->shortmsg)) {
  637. PString_t *str = (PString_t *) calloc(1, sizeof(PString_t));
  638. assert(str);
  639. if (!str)
  640. goto enomem;
  641. int r = OCTET_STRING_fromBuf(str, msg->shortmsg, -1);
  642. if (r)
  643. goto enomem;
  644. result->shortmsg = str;
  645. }
  646. size_t rest_blob_size = max_blob_size;
  647. if (!EMPTYSTR(msg->longmsg)) {
  648. PString_t *str = (PString_t *) calloc(1, sizeof(PString_t));
  649. assert(str);
  650. if (!str)
  651. goto enomem;
  652. if (copy) {
  653. int r = OCTET_STRING_fromBuf(str, msg->longmsg, -1);
  654. if (r)
  655. goto enomem;
  656. if (str->size > rest_blob_size)
  657. goto enomem;
  658. }
  659. else /* move */ {
  660. str->size = strlen(msg->longmsg);
  661. if (str->size > rest_blob_size)
  662. goto enomem;
  663. str->buf = (uint8_t *) msg->longmsg;
  664. msg->longmsg = NULL;
  665. }
  666. rest_blob_size -= str->size;
  667. result->longmsg = str;
  668. }
  669. if (!EMPTYSTR(msg->longmsg_formatted)) {
  670. PString_t *str = (PString_t *) calloc(1, sizeof(PString_t));
  671. assert(str);
  672. if (!str)
  673. goto enomem;
  674. if (copy) {
  675. int r = OCTET_STRING_fromBuf(str, msg->longmsg_formatted, -1);
  676. if (r)
  677. goto enomem;
  678. if (str->size > rest_blob_size)
  679. goto enomem;
  680. }
  681. else /* move */ {
  682. str->size = strlen(msg->longmsg_formatted);
  683. if (str->size > rest_blob_size)
  684. goto enomem;
  685. str->buf = (uint8_t *) msg->longmsg_formatted;
  686. msg->longmsg_formatted = NULL;
  687. }
  688. rest_blob_size -= str->size;
  689. result->longmsg_formatted = str;
  690. }
  691. if (msg->attachments && msg->attachments->value) {
  692. PBlobList_t *bl = PBlobList_from_bloblist(msg->attachments, NULL, copy,
  693. rest_blob_size);
  694. if (!bl)
  695. goto enomem;
  696. result->attachments = bl;
  697. }
  698. return result;
  699. enomem:
  700. if (allocated)
  701. ASN_STRUCT_FREE(asn_DEF_ASN1Message, result);
  702. return NULL;
  703. }
  704. message *ASN1Message_to_message(
  705. ASN1Message_t *msg,
  706. message *result,
  707. bool copy,
  708. size_t max_blob_size
  709. )
  710. {
  711. bool allocated = !result;
  712. if (!max_blob_size)
  713. max_blob_size = SIZE_MAX;
  714. assert(msg);
  715. if (!msg)
  716. return NULL;
  717. if (allocated) {
  718. result = new_message(PEP_dir_incoming);
  719. if (!result)
  720. goto enomem;
  721. }
  722. if (msg->direction) {
  723. switch (*msg->direction) {
  724. case MessageDirection_incoming:
  725. result->dir = PEP_dir_incoming;
  726. break;
  727. case MessageDirection_outgoing:
  728. result->dir = PEP_dir_outgoing;
  729. break;
  730. default:
  731. assert(0);
  732. }
  733. }
  734. if (msg->id) {
  735. result->id = strndup((char *) msg->id->buf, msg->id->size);
  736. assert(result->id);
  737. if (!result->id)
  738. goto enomem;
  739. }
  740. if (msg->sent) {
  741. timestamp *_sent = new_timestamp(0);
  742. if (!_sent)
  743. goto enomem;
  744. if (asn_GT2time(msg->sent, _sent, 1) == -1)
  745. goto enomem;
  746. result->sent = _sent;
  747. }
  748. if (msg->recv) {
  749. timestamp *_recv = new_timestamp(0);
  750. if (!_recv)
  751. goto enomem;
  752. if (asn_GT2time(msg->recv, _recv, 1) == -1)
  753. goto enomem;
  754. result->recv = _recv;
  755. }
  756. // from is mandatory
  757. result->from = Identity_to_Struct(&msg->from, NULL);
  758. if (!result->from)
  759. goto enomem;
  760. if (msg->to) {
  761. identity_list *il = IdentityList_to_identity_list(msg->to, NULL);
  762. if (!il)
  763. goto enomem;
  764. result->to = il;
  765. }
  766. if (msg->cc) {
  767. identity_list *il = IdentityList_to_identity_list(msg->cc, NULL);
  768. if (!il)
  769. goto enomem;
  770. result->cc = il;
  771. }
  772. if (msg->bcc) {
  773. identity_list *il = IdentityList_to_identity_list(msg->bcc, NULL);
  774. if (!il)
  775. goto enomem;
  776. result->bcc = il;
  777. }
  778. if (msg->recv_by) {
  779. pEp_identity *i = Identity_to_Struct(msg->recv_by, NULL);
  780. if (!i)
  781. goto enomem;
  782. result->recv_by = i;
  783. }
  784. if (msg->reply_to) {
  785. identity_list *il = IdentityList_to_identity_list(msg->reply_to, NULL);
  786. if (!il)
  787. goto enomem;
  788. result->reply_to = il;
  789. }
  790. if (msg->in_reply_to) {
  791. stringlist_t *l = PStringList_to_stringlist(msg->in_reply_to);
  792. if (!l)
  793. goto enomem;
  794. result->in_reply_to = l;
  795. }
  796. if (msg->references) {
  797. stringlist_t *l = PStringList_to_stringlist(msg->references);
  798. if (!l)
  799. goto enomem;
  800. result->references = l;
  801. }
  802. if (msg->keywords) {
  803. stringlist_t *l = PStringList_to_stringlist(msg->keywords);
  804. if (!l)
  805. goto enomem;
  806. result->keywords = l;
  807. }
  808. if (msg->comments) {
  809. char *s = strndup((char *) msg->comments->buf, msg->comments->size);
  810. assert(s);
  811. if (!s)
  812. goto enomem;
  813. result->comments = s;
  814. }
  815. if (msg->opt_fields) {
  816. stringpair_list_t *l =
  817. PStringPairList_to_stringpair_list(msg->opt_fields, NULL);
  818. if (!l)
  819. goto enomem;
  820. result->opt_fields = l;
  821. }
  822. if (msg->sender_fpr) {
  823. char *_sender_fpr = strndup((char *) msg->sender_fpr->buf,
  824. msg->sender_fpr->size);
  825. if (!_sender_fpr)
  826. goto enomem;
  827. result->_sender_fpr = _sender_fpr;
  828. }
  829. if (msg->shortmsg) {
  830. char *s = strndup((char *) msg->shortmsg->buf, msg->shortmsg->size);
  831. assert(s);
  832. if (!s)
  833. goto enomem;
  834. result->shortmsg = s;
  835. }
  836. size_t rest_blob_size = max_blob_size;
  837. if (msg->longmsg) {
  838. if (msg->longmsg->size > rest_blob_size)
  839. goto enomem;
  840. char *s = NULL;
  841. if (copy) {
  842. s = strndup((char *) msg->longmsg->buf, msg->longmsg->size);
  843. if (!s)
  844. goto enomem;
  845. rest_blob_size -= msg->longmsg->size;
  846. }
  847. else /* move */ {
  848. s = (char *) msg->longmsg->buf;
  849. msg->longmsg->buf = NULL;
  850. rest_blob_size -= msg->longmsg->size;
  851. msg->longmsg->size = 0;
  852. }
  853. result->longmsg = s;
  854. }
  855. if (msg->longmsg_formatted) {
  856. if (msg->longmsg_formatted->size > rest_blob_size)
  857. goto enomem;
  858. char *s = NULL;
  859. if (copy) {
  860. s = strndup((char *) msg->longmsg_formatted->buf,
  861. msg->longmsg_formatted->size);
  862. if (!s)
  863. goto enomem;
  864. rest_blob_size -= msg->longmsg_formatted->size;
  865. }
  866. else /* move */ {
  867. s = (char *) msg->longmsg_formatted->buf;
  868. msg->longmsg_formatted->buf = NULL;
  869. rest_blob_size -= msg->longmsg_formatted->size;
  870. msg->longmsg_formatted->size = 0;
  871. }
  872. result->longmsg_formatted = s;
  873. }
  874. if (msg->attachments) {
  875. bloblist_t *a = PBlobList_to_bloblist(msg->attachments, NULL, copy,
  876. rest_blob_size);
  877. if (!a)
  878. goto enomem;
  879. result->attachments = a;
  880. }
  881. return result;
  882. enomem:
  883. if (allocated)
  884. free_message(result);
  885. return NULL;
  886. }