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.

1802 lines
43 KiB

  1. // This file is under GNU General Public License 3.0
  2. // see LICENSE.txt
  3. /*
  4. ** Check to see if this machine uses EBCDIC. (Yes, believe it or
  5. ** not, there are still machines out there that use EBCDIC.)
  6. */
  7. #if 'A' == '\301'
  8. # define NETPGP_EBCDIC 1
  9. #else
  10. # define NETPGP_ASCII 1
  11. #endif
  12. #include "pEp_internal.h"
  13. #include "pgp_netpgp.h"
  14. #include <limits.h>
  15. #include <ctype.h>
  16. #include "wrappers.h"
  17. #include <netpgp.h>
  18. #include <netpgp/config.h>
  19. #include <netpgp/memory.h>
  20. #include <netpgp/crypto.h>
  21. #include <netpgp/netpgpsdk.h>
  22. #include <netpgp/validate.h>
  23. #include <netpgp/readerwriter.h>
  24. #include <netpgp/netpgpdefs.h>
  25. #include <pthread.h>
  26. #include <regex.h>
  27. #if defined(NETPGP_EBCDIC)
  28. #include <unistd.h>
  29. #endif
  30. #if 0
  31. #define TRACE_FUNCS() printf("Trace fun: %s:%d, %s\n",__FILE__,__LINE__,__FUNCTION__);
  32. #else
  33. #define TRACE_FUNCS()
  34. #endif
  35. #define _ENDL "\\s*(\r\n|\r|\n)"
  36. inline char A(char c)
  37. {
  38. TRACE_FUNCS()
  39. #if defined(NETPGP_EBCDIC)
  40. __e2a_l(&c,1);
  41. #endif
  42. return c;
  43. }
  44. netpgp_t *netpgp;
  45. static pthread_mutex_t netpgp_mutex;
  46. static PEP_STATUS init_netpgp()
  47. {
  48. TRACE_FUNCS()
  49. PEP_STATUS status = PEP_STATUS_OK;
  50. const char *home = NULL;
  51. pgp_io_t *io;
  52. if(pthread_mutex_init(&netpgp_mutex, NULL)){
  53. return PEP_OUT_OF_MEMORY;
  54. }
  55. if(pthread_mutex_lock(&netpgp_mutex)){
  56. return PEP_UNKNOWN_ERROR;
  57. }
  58. if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
  59. setlocale(LC_ALL, "");
  60. netpgp=malloc(sizeof(netpgp_t));
  61. memset(netpgp, 0x0, sizeof(netpgp_t));
  62. //netpgp_setvar(netpgp, "max mem alloc", "4194304");
  63. netpgp_setvar(netpgp, "need seckey", "1");
  64. netpgp_setvar(netpgp, "need pubkey", "1");
  65. netpgp_setvar(netpgp, "batch", "1");
  66. //pgp_set_debug_level("keyring.c");
  67. //netpgp_setvar(netpgp, "need userid", "1");
  68. if (!home)
  69. home = getenv("HOME");
  70. if (!home)
  71. status = PEP_INIT_CRYPTO_LIB_INIT_FAILED;
  72. if(home){
  73. netpgp_set_homedir(netpgp,(char*)home, "/.netpgp", 0);
  74. }else{
  75. status = PEP_INIT_NO_CRYPTO_HOME;
  76. goto unlock_netpgp;
  77. }
  78. // pair with gpg's cert-digest-algo
  79. netpgp_setvar(netpgp, "hash", "SHA256");
  80. // subset of gpg's personal-cipher-preferences
  81. // here only one cipher can be selected
  82. netpgp_setvar(netpgp, "cipher", "CAST5");
  83. if (!netpgp_init(netpgp)) {
  84. status = PEP_INIT_CRYPTO_LIB_INIT_FAILED;
  85. free(netpgp);
  86. netpgp=NULL;
  87. goto unlock_netpgp;
  88. }
  89. //pgp_set_debug_level("packet-parse.c");
  90. //pgp_set_debug_level("openssl_crypto.c");
  91. //pgp_set_debug_level("crypto.c");
  92. unlock_netpgp:
  93. pthread_mutex_unlock(&netpgp_mutex);
  94. return status;
  95. }
  96. static void release_netpgp()
  97. {
  98. TRACE_FUNCS()
  99. if(pthread_mutex_lock(&netpgp_mutex)){
  100. return;
  101. }
  102. netpgp_end(netpgp);
  103. memset(netpgp, 0x0, sizeof(netpgp_t));
  104. pthread_mutex_destroy(&netpgp_mutex);
  105. return;
  106. }
  107. PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
  108. {
  109. TRACE_FUNCS()
  110. PEP_STATUS status = PEP_STATUS_OK;
  111. assert(session);
  112. if(!session) return PEP_ILLEGAL_VALUE;
  113. if (in_first) {
  114. if((status = init_netpgp()) != PEP_STATUS_OK)
  115. return status;
  116. }
  117. return PEP_STATUS_OK;
  118. }
  119. void pgp_release(PEP_SESSION session, bool out_last)
  120. {
  121. TRACE_FUNCS()
  122. assert(session);
  123. if(!session) return;
  124. if (out_last){
  125. release_netpgp();
  126. }
  127. }
  128. // return 1 if the file contains ascii-armoured text
  129. static unsigned
  130. _armoured(const char *buf, size_t size, const char *pattern)
  131. {
  132. TRACE_FUNCS()
  133. unsigned armoured = 0;
  134. regex_t r;
  135. if( regcomp(&r, pattern, REG_EXTENDED|REG_NOSUB) ) printf("_armoured error\n");
  136. if (regexec(&r, buf, size, 0, NULL) == 0) {
  137. armoured = 1;
  138. }
  139. regfree(&r);
  140. return armoured;
  141. }
  142. // Iterate through netpgp' reported valid signatures
  143. // fill a list of valid figerprints
  144. // returns PEP_STATUS_OK if all sig reported valid
  145. // error status otherwise.
  146. static PEP_STATUS _validation_results(
  147. netpgp_t *netpgp,
  148. pgp_validation_t *vresult,
  149. stringlist_t **keylist
  150. )
  151. {
  152. TRACE_FUNCS()
  153. time_t now;
  154. time_t t;
  155. *keylist = NULL;
  156. now = time(NULL);
  157. if (now < vresult->birthtime) {
  158. // signature is not valid yet
  159. return PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  160. }
  161. if (vresult->duration != 0 && now > vresult->birthtime + vresult->duration) {
  162. // signature has expired
  163. t = vresult->duration + vresult->birthtime;
  164. return PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  165. }
  166. if (vresult->validc && vresult->valid_sigs &&
  167. !vresult->invalidc && !vresult->unknownc ) {
  168. stringlist_t *_keylist;
  169. // caller responsible to free
  170. _keylist = new_stringlist(NULL);
  171. assert(_keylist);
  172. if (_keylist == NULL) {
  173. return PEP_OUT_OF_MEMORY;
  174. }
  175. stringlist_t *k = _keylist;
  176. unsigned c = 0;
  177. for (unsigned n = 0; n < vresult->validc; ++n) {
  178. unsigned from = 0;
  179. const pgp_key_t *signer;
  180. char *fprstr = NULL;
  181. const uint8_t *keyid = vresult->valid_sigs[n].signer_id;
  182. signer = pgp_getkeybyid(netpgp->io, netpgp->pubring,
  183. keyid, &from, NULL, NULL,
  184. 0, 0); /* check neither revocation nor expiry
  185. as is should be checked already */
  186. if(signer)
  187. uint_to_string(signer->pubkeyfpr.fingerprint, &fprstr, signer->pubkeyfpr.length);
  188. else
  189. continue;
  190. if (fprstr == NULL){
  191. free_stringlist(_keylist);
  192. return PEP_OUT_OF_MEMORY;
  193. }
  194. k = stringlist_add(k, fprstr);
  195. free(fprstr);
  196. if(!k){
  197. free_stringlist(_keylist);
  198. return PEP_OUT_OF_MEMORY;
  199. }
  200. c++;
  201. }
  202. if(c > 0) {
  203. *keylist = _keylist;
  204. return PEP_STATUS_OK;
  205. }
  206. free_stringlist(_keylist);
  207. return PEP_VERIFY_NO_KEY;
  208. }
  209. if (vresult->validc + vresult->invalidc + vresult->unknownc == 0) {
  210. // No signatures found - is this memory signed?
  211. return PEP_VERIFY_NO_KEY;
  212. }
  213. if (vresult->invalidc) {
  214. // some invalid signatures
  215. return PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  216. }
  217. // only unknown sigs
  218. return PEP_DECRYPTED;
  219. }
  220. #define ARMOR_HEAD "^-----BEGIN PGP MESSAGE-----"_ENDL
  221. PEP_STATUS pgp_decrypt_and_verify(
  222. PEP_SESSION session, const char *ctext, size_t csize,
  223. const char *dsigtext, size_t dsigsize,
  224. char **ptext, size_t *psize, stringlist_t **keylist,
  225. char** filename_ptr // will be ignored
  226. )
  227. {
  228. TRACE_FUNCS()
  229. char *_ptext = NULL;
  230. char* passphrase = NULL;
  231. PEP_STATUS result;
  232. stringlist_t *_keylist = NULL;
  233. assert(session);
  234. assert(ctext);
  235. assert(csize);
  236. assert(ptext);
  237. assert(psize);
  238. assert(keylist);
  239. passphrase = session->curr_passphrase;
  240. if(passphrase && passphrase[0]) {
  241. netpgp_set_validation_password(passphrase);
  242. }
  243. if(!session || !ctext || !csize || !ptext || !psize || !keylist)
  244. return PEP_ILLEGAL_VALUE;
  245. if(pthread_mutex_lock(&netpgp_mutex)){
  246. return PEP_UNKNOWN_ERROR;
  247. }
  248. *ptext = NULL;
  249. *psize = 0;
  250. *keylist = NULL;
  251. pgp_validation_t *vresult = malloc(sizeof(pgp_validation_t));
  252. memset(vresult, 0x0, sizeof(pgp_validation_t));
  253. key_id_t *recipients_key_ids = NULL;
  254. unsigned recipients_count = 0;
  255. pgp_memory_t *mem = pgp_decrypt_and_validate_buf(
  256. netpgp,
  257. vresult,
  258. ctext, csize,
  259. netpgp->secring, netpgp->pubring,
  260. _armoured(ctext, csize, ARMOR_HEAD),
  261. &recipients_key_ids, &recipients_count
  262. );
  263. if (mem == NULL) {
  264. result = PEP_OUT_OF_MEMORY;
  265. goto unlock_netpgp;
  266. }
  267. const size_t _psize = pgp_mem_len(mem);
  268. if (_psize){
  269. if ((_ptext = malloc(_psize + 1)) == NULL) {
  270. result = PEP_OUT_OF_MEMORY;
  271. goto free_pgp;
  272. }
  273. memcpy(_ptext, pgp_mem_data(mem), _psize);
  274. _ptext[_psize] = '\0'; // safeguard for naive users
  275. result = PEP_DECRYPTED;
  276. }else{
  277. result = PEP_DECRYPT_NO_KEY;
  278. goto free_pgp;
  279. }
  280. if (result == PEP_DECRYPTED) {
  281. result = _validation_results(netpgp, vresult, &_keylist);
  282. printf("result=%x\n",result);
  283. if (result == PEP_DECRYPTED || result == PEP_VERIFY_NO_KEY) {
  284. if((_keylist = new_stringlist("")) == NULL) {
  285. result = PEP_OUT_OF_MEMORY;
  286. goto free_ptext;
  287. }
  288. result = PEP_DECRYPTED;
  289. }else if (result != PEP_STATUS_OK) {
  290. goto free_ptext;
  291. }else{
  292. result = PEP_DECRYPTED_AND_VERIFIED;
  293. }
  294. }
  295. stringlist_t *k = _keylist;
  296. for (unsigned n = 0; n < recipients_count; ++n) {
  297. unsigned from = 0;
  298. const pgp_key_t *rcpt;
  299. char *fprstr = NULL;
  300. key_id_t *keyid = &recipients_key_ids[n];
  301. rcpt = pgp_getkeybyid(netpgp->io, netpgp->pubring,
  302. *keyid, &from, NULL, NULL,
  303. 0, 0); /* check neither revocation nor expiry*/
  304. if(rcpt)
  305. uint_to_string(rcpt->pubkeyfpr.fingerprint, &fprstr, rcpt->pubkeyfpr.length);
  306. else
  307. // if no key found put ID instead of fpr
  308. uint_to_string(*keyid, &fprstr, sizeof(key_id_t));
  309. if (fprstr == NULL){
  310. result = PEP_OUT_OF_MEMORY;
  311. goto free_keylist;
  312. }
  313. k = stringlist_add_unique(k, fprstr);
  314. free(fprstr);
  315. if(!k){
  316. result = PEP_OUT_OF_MEMORY;
  317. goto free_keylist;
  318. }
  319. }
  320. if (result == PEP_DECRYPTED_AND_VERIFIED || result == PEP_DECRYPTED) {
  321. *ptext = _ptext;
  322. *psize = _psize;
  323. (*ptext)[*psize] = 0; // safeguard for naive users
  324. *keylist = _keylist;
  325. /* _ptext and _keylist ownership transfer, don't free */
  326. goto free_pgp;
  327. }
  328. free_keylist:
  329. free_stringlist(_keylist);
  330. free_ptext:
  331. free(_ptext);
  332. free_pgp:
  333. pgp_memory_free(mem);
  334. pgp_validate_result_free(vresult);
  335. unlock_netpgp:
  336. free(recipients_key_ids);
  337. pthread_mutex_unlock(&netpgp_mutex);
  338. return result;
  339. }
  340. #define ARMOR_SIG_HEAD "^-----BEGIN PGP (SIGNATURE|SIGNED MESSAGE)-----"_ENDL
  341. PEP_STATUS pgp_verify_text(
  342. PEP_SESSION session, const char *text, size_t size,
  343. const char *signature, size_t sig_size, stringlist_t **keylist
  344. )
  345. {
  346. TRACE_FUNCS()
  347. pgp_memory_t *signedmem;
  348. pgp_memory_t *sig;
  349. pgp_validation_t *vresult;
  350. PEP_STATUS result;
  351. stringlist_t *_keylist;
  352. assert(session);
  353. assert(text);
  354. assert(size);
  355. assert(signature);
  356. assert(sig_size);
  357. assert(keylist);
  358. if(!session || !text || !size || !signature || !sig_size || !keylist)
  359. return PEP_ILLEGAL_VALUE;
  360. if(pthread_mutex_lock(&netpgp_mutex)){
  361. return PEP_UNKNOWN_ERROR;
  362. }
  363. *keylist = NULL;
  364. vresult = malloc(sizeof(pgp_validation_t));
  365. if (vresult == NULL) {
  366. result = PEP_OUT_OF_MEMORY;
  367. goto unlock_netpgp;
  368. }
  369. memset(vresult, 0x0, sizeof(pgp_validation_t));
  370. signedmem = pgp_memory_new();
  371. if (signedmem == NULL) {
  372. result = PEP_OUT_OF_MEMORY;
  373. goto unlock_netpgp;
  374. }
  375. pgp_memory_add(signedmem, (const uint8_t*)text, size);
  376. sig = pgp_memory_new();
  377. if (sig == NULL) {
  378. pgp_memory_free(signedmem);
  379. result = PEP_OUT_OF_MEMORY;
  380. goto unlock_netpgp;
  381. }
  382. pgp_memory_add(sig, (const uint8_t*)signature, sig_size);
  383. pgp_validate_mem_detached(netpgp->io, vresult, sig,
  384. NULL,/* output */
  385. _armoured(signature, sig_size, ARMOR_SIG_HEAD),
  386. netpgp->pubring,
  387. signedmem);
  388. result = _validation_results(netpgp, vresult, &_keylist);
  389. if (result != PEP_STATUS_OK) {
  390. goto free_pgp;
  391. }else{
  392. result = PEP_VERIFIED;
  393. }
  394. if (result == PEP_VERIFIED) {
  395. /* TODO : check trust level */
  396. result = PEP_VERIFIED_AND_TRUSTED;
  397. }
  398. if (result == PEP_VERIFIED || result == PEP_VERIFIED_AND_TRUSTED) {
  399. *keylist = _keylist;
  400. /* _keylist ownership transfer, don't free */
  401. goto free_pgp;
  402. }
  403. free_stringlist(_keylist);
  404. free_pgp:
  405. // free done by pgp_validate_mem_detached
  406. // pgp_memory_free(sig);
  407. // pgp_memory_free(signedmem);
  408. pgp_validate_result_free(vresult);
  409. unlock_netpgp:
  410. pthread_mutex_unlock(&netpgp_mutex);
  411. return result;
  412. }
  413. PEP_STATUS pgp_sign_only(
  414. PEP_SESSION session, const char* fpr, const char *ptext,
  415. size_t psize, char **stext, size_t *ssize
  416. )
  417. {
  418. TRACE_FUNCS()
  419. pgp_key_t *signer = NULL;
  420. pgp_seckey_t *seckey = NULL;
  421. pgp_memory_t *signedmem = NULL;
  422. pgp_memory_t *text = NULL;
  423. pgp_output_t *output;
  424. const char *hashalg;
  425. pgp_keyring_t *snrs;
  426. pgp_create_sig_t *sig;
  427. uint8_t keyid[PGP_KEY_ID_SIZE];
  428. PEP_STATUS result;
  429. assert(session);
  430. assert(fpr);
  431. assert(ptext);
  432. assert(psize);
  433. assert(stext);
  434. assert(ssize);
  435. if(!session || !ptext || !psize || !stext || !ssize || !fpr || !fpr[0])
  436. return PEP_ILLEGAL_VALUE;
  437. if(pthread_mutex_lock(&netpgp_mutex)){
  438. return PEP_UNKNOWN_ERROR;
  439. }
  440. *stext = NULL;
  441. *ssize = 0;
  442. if ((snrs = calloc(1, sizeof(*snrs))) == NULL) {
  443. result = PEP_OUT_OF_MEMORY;
  444. goto unlock_netpgp;
  445. }
  446. assert(fpr && fpr[0]);
  447. uint8_t *uint_fpr = NULL;
  448. size_t fprlen;
  449. unsigned from = 0;
  450. if (string_to_uint(fpr, &uint_fpr, &fprlen)) {
  451. if ((signer = (pgp_key_t *)pgp_getkeybyfpr(netpgp->io, netpgp->secring, uint_fpr, fprlen, &from, NULL, 1,1)) == NULL) {
  452. /* reject revoked and expired */
  453. result = PEP_KEY_NOT_FOUND;
  454. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  455. goto free_snrs;
  456. }
  457. } else{
  458. result = PEP_ILLEGAL_VALUE;
  459. goto free_snrs;
  460. }
  461. // add key to signers
  462. pgp_keyring_add(snrs, signer);
  463. if(snrs->keys == NULL){
  464. result = PEP_OUT_OF_MEMORY;
  465. goto free_snrs;
  466. }
  467. /* Empty keylist ?*/
  468. if(snrs->keyc == 0){
  469. result = PEP_ILLEGAL_VALUE;
  470. goto free_snrs;
  471. }
  472. seckey = pgp_key_get_certkey(signer);
  473. /* No signing key. Revoked ? */
  474. if(seckey == NULL){
  475. result = PEP_GET_KEY_FAILED;
  476. goto free_snrs;
  477. }
  478. hashalg = netpgp_getvar(netpgp, "hash");
  479. const char *_stext;
  480. size_t _ssize;
  481. text = pgp_memory_new();
  482. pgp_memory_add(text, (const uint8_t*)ptext, psize);
  483. pgp_setup_memory_write(&output, &signedmem, psize);
  484. pgp_writer_push_armor_msg(output);
  485. pgp_hash_alg_t hash_alg = pgp_str_to_hash_alg(hashalg);
  486. sig = pgp_create_sig_new();
  487. pgp_start_sig(sig, seckey, hash_alg, PGP_SIG_BINARY);
  488. pgp_sig_add_data(sig, pgp_mem_data(text), pgp_mem_len(text));
  489. pgp_memory_free(text);
  490. pgp_add_creation_time(sig, time(NULL));
  491. pgp_add_sig_expiration_time(sig, 0);
  492. pgp_keyid(keyid, sizeof(keyid), &seckey->pubkey, hash_alg);
  493. pgp_add_issuer_keyid(sig, keyid);
  494. pgp_end_hashed_subpkts(sig);
  495. pgp_write_sig(output, sig, &seckey->pubkey, seckey);
  496. pgp_writer_close(output);
  497. pgp_create_sig_delete(sig);
  498. if (!signedmem) {
  499. result = PEP_UNENCRYPTED;
  500. goto free_snrs;
  501. }
  502. _stext = (char*) pgp_mem_data(signedmem);
  503. _ssize = pgp_mem_len(signedmem);
  504. // Allocate transferable buffer
  505. char *_buffer = malloc(_ssize + 1);
  506. assert(_buffer);
  507. if (_buffer == NULL) {
  508. result = PEP_OUT_OF_MEMORY;
  509. goto free_signedmem;
  510. }
  511. memcpy(_buffer, _stext, _ssize);
  512. *stext = _buffer;
  513. *ssize = _ssize;
  514. (*stext)[*ssize] = 0; // safeguard for naive users
  515. result = PEP_STATUS_OK;
  516. free_signedmem :
  517. pgp_memory_free(signedmem);
  518. free_snrs :
  519. pgp_keyring_free(snrs);
  520. unlock_netpgp:
  521. pthread_mutex_unlock(&netpgp_mutex);
  522. return result;
  523. }
  524. PEP_STATUS pgp_encrypt_and_sign(
  525. PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  526. size_t psize, char **ctext, size_t *csize
  527. )
  528. {
  529. TRACE_FUNCS()
  530. PEP_STATUS result = PEP_STATUS_OK;
  531. stringlist_t *klp;
  532. int ret;
  533. uint8_t *fpr = NULL;
  534. unsigned from;
  535. size_t len = 0;
  536. pgp_memory_t *mem = NULL;
  537. pgp_keyring_t *rcpts = NULL;
  538. pgp_seckey_t *seckey = NULL;
  539. pgp_key_t *signer = NULL;
  540. pgp_key_t *key = NULL;
  541. assert(netpgp->secring);
  542. string_to_uint(keylist->value, &fpr, &len);
  543. from = 0;
  544. signer = pgp_getkeybyfpr(netpgp->io, netpgp->secring, fpr, len, &from, NULL, 0, 0 );
  545. if(!signer) return PEP_KEY_NOT_FOUND;
  546. rcpts = malloc(sizeof(pgp_keyring_t));
  547. memset(rcpts,0,sizeof(pgp_keyring_t));
  548. klp = keylist;
  549. while(klp) {
  550. string_to_uint(klp->value, &fpr, &len);
  551. from = 0;
  552. key = pgp_getkeybyfpr(netpgp->io, netpgp->pubring, fpr, len, &from, NULL, 0, 0 );
  553. if(key) {
  554. pgp_keyring_add(rcpts, key);
  555. }
  556. klp = klp->next;
  557. }
  558. mem = netpgp_encrypt_and_sign(netpgp, rcpts, seckey, ptext, psize, true, 1);
  559. free(rcpts);
  560. return result;
  561. }
  562. PEP_STATUS pgp_encrypt_only(
  563. PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  564. size_t psize, char **ctext, size_t *csize
  565. )
  566. {
  567. TRACE_FUNCS()
  568. PEP_STATUS result = PEP_STATUS_OK;
  569. pgp_memory_t *mem;
  570. pgp_keyring_t *rcpts = NULL;
  571. unsigned from;
  572. size_t len = 0;
  573. uint8_t *fpr = NULL;
  574. pgp_key_t *key = NULL;
  575. stringlist_t *klp;
  576. rcpts = malloc(sizeof(pgp_keyring_t));
  577. memset(rcpts,0,sizeof(pgp_keyring_t));
  578. klp = keylist;
  579. while(klp) {
  580. string_to_uint(klp->value, &fpr, &len);
  581. from = 0;
  582. key = pgp_getkeybyfpr(netpgp->io, netpgp->pubring, fpr, len, &from, NULL, 0, 0 );
  583. if(key) {
  584. pgp_keyring_add(rcpts, key);
  585. }
  586. klp = klp->next;
  587. }
  588. mem = netpgp_encrypt_and_sign(netpgp, rcpts, NULL, ptext, psize, false, 1);
  589. free(rcpts);
  590. return result;
  591. }
  592. PEP_STATUS pgp_generate_keypair(
  593. PEP_SESSION session, pEp_identity *identity
  594. )
  595. {
  596. TRACE_FUNCS()
  597. pgp_key_t newseckey;
  598. pgp_key_t *newpubkey;
  599. PEP_STATUS result;
  600. char newid[1024];
  601. const char *hashalg;
  602. const char *cipher;
  603. assert(session);
  604. assert(identity);
  605. assert(identity->address);
  606. assert(identity->fpr == NULL);
  607. assert(identity->username);
  608. if(!session || !identity ||
  609. !identity->address || identity->fpr || !identity->username)
  610. return PEP_ILLEGAL_VALUE;
  611. if(pthread_mutex_lock(&netpgp_mutex)){
  612. return PEP_UNKNOWN_ERROR;
  613. }
  614. if(snprintf(newid, sizeof(newid),
  615. "%s <%s>", identity->username, identity->address) >= sizeof(newid)){
  616. result = PEP_BUFFER_TOO_SMALL;
  617. goto unlock_netpgp;
  618. }
  619. hashalg = netpgp_getvar(netpgp, "hash");
  620. cipher = netpgp_getvar(netpgp, "cipher");
  621. bzero(&newseckey, sizeof(newseckey));
  622. // Generate the key
  623. if (!pgp_rsa_generate_keypair(&newseckey, 4096, 65537UL, hashalg, cipher,
  624. (const uint8_t *) "", (const size_t) 0))
  625. {
  626. result = PEP_CANNOT_CREATE_KEY;
  627. goto free_seckey;
  628. }
  629. /* make a public key out of generated secret key */
  630. if((newpubkey = pgp_ensure_pubkey(
  631. netpgp->pubring,
  632. &newseckey.key.seckey.pubkey,
  633. newseckey.pubkeyid))==NULL)
  634. {
  635. result = PEP_OUT_OF_MEMORY;
  636. goto free_seckey;
  637. }
  638. // "Expire-Date: 1y\n";
  639. if (!pgp_add_selfsigned_userid(&newseckey, newpubkey,
  640. (uint8_t *)newid, 365*24*3600))
  641. {
  642. result = PEP_CANNOT_CREATE_KEY;
  643. goto delete_pubkey;
  644. }
  645. if (newpubkey == NULL)
  646. {
  647. result = PEP_OUT_OF_MEMORY;
  648. goto delete_pubkey;
  649. }
  650. // Append key to netpgp's rings (key ownership transfered)
  651. if (!pgp_keyring_add(netpgp->secring, &newseckey)){
  652. result = PEP_OUT_OF_MEMORY;
  653. goto delete_pubkey;
  654. }
  655. // save rings
  656. if (netpgp_save_pubring(netpgp) && netpgp_save_secring(netpgp))
  657. {
  658. char *fprstr = NULL;
  659. uint_to_string(newseckey.pubkeyfpr.fingerprint, &fprstr, newseckey.pubkeyfpr.length);
  660. if (fprstr == NULL) {
  661. result = PEP_OUT_OF_MEMORY;
  662. goto pop_secring;
  663. }
  664. /* keys saved, pass fingerprint back */
  665. identity->fpr = fprstr;
  666. result = PEP_STATUS_OK;
  667. /* free nothing, everything transfered */
  668. goto unlock_netpgp;
  669. } else {
  670. /* XXX in case only pubring save succeed
  671. * pubring file is left as-is, but backup restore
  672. * could be attempted if such corner case matters */
  673. result = PEP_UNKNOWN_ERROR;
  674. }
  675. pop_secring:
  676. ((pgp_keyring_t *)netpgp->secring)->keyc--;
  677. delete_pubkey:
  678. pgp_deletekeybyfpr(netpgp->io,
  679. (pgp_keyring_t *)netpgp->pubring,
  680. newseckey.pubkeyfpr.fingerprint,
  681. newseckey.pubkeyfpr.length);
  682. free_seckey:
  683. pgp_key_free(&newseckey);
  684. unlock_netpgp:
  685. pthread_mutex_unlock(&netpgp_mutex);
  686. return result;
  687. }
  688. PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fprstr)
  689. {
  690. TRACE_FUNCS()
  691. uint8_t *fpr;
  692. size_t length;
  693. PEP_STATUS result;
  694. assert(session);
  695. assert(fprstr);
  696. if (!session || !fprstr)
  697. return PEP_ILLEGAL_VALUE;
  698. if(pthread_mutex_lock(&netpgp_mutex)){
  699. return PEP_UNKNOWN_ERROR;
  700. }
  701. if (string_to_uint(fprstr, &fpr, &length)) {
  702. unsigned insec = pgp_deletekeybyfpr(netpgp->io,
  703. (pgp_keyring_t *)netpgp->secring,
  704. (const uint8_t *)fpr, length);
  705. unsigned inpub = pgp_deletekeybyfpr(netpgp->io,
  706. (pgp_keyring_t *)netpgp->pubring,
  707. (const uint8_t *)fpr, length);
  708. if(!insec && !inpub){
  709. result = PEP_KEY_NOT_FOUND;
  710. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  711. goto unlock_netpgp;
  712. } else {
  713. result = PEP_STATUS_OK;
  714. }
  715. }else{
  716. result = PEP_OUT_OF_MEMORY;
  717. goto unlock_netpgp;
  718. }
  719. // save rings
  720. if (netpgp_save_pubring(netpgp) &&
  721. netpgp_save_secring(netpgp))
  722. {
  723. result = PEP_STATUS_OK;
  724. }else{
  725. result = PEP_UNKNOWN_ERROR;
  726. }
  727. unlock_netpgp:
  728. pthread_mutex_unlock(&netpgp_mutex);
  729. return result;
  730. }
  731. void stringlist_from_keyring(pgp_keyring_t* keyring, stringlist_t **list)
  732. {
  733. TRACE_FUNCS()
  734. int i;
  735. char *fpr;
  736. pgp_key_t key;
  737. for(i = 0; i < keyring->keyc; i++) {
  738. key = keyring->keys[i];
  739. if(uint_to_string(key.pubkeyfpr.fingerprint, &fpr, PGP_FINGERPRINT_SIZE)) {
  740. if(!*list) *list = new_stringlist(fpr);
  741. else stringlist_add(*list, fpr);
  742. }
  743. }
  744. }
  745. pEp_identity *ident_from_uid_fpr(char *uid, uint8_t *fpr)
  746. {
  747. char *address;
  748. char *user_id;
  749. char *username;
  750. pEp_identity *ident;
  751. ident = malloc(sizeof(pEp_identity));
  752. ident->fpr = NULL;
  753. uint_to_string(fpr, &ident->fpr, PGP_FINGERPRINT_SIZE);
  754. printf("FPR: %s\n",ident->fpr);
  755. username=strtok(uid, "<");
  756. if(username[strlen(username)-1]==' ') username[strlen(username)-1]=0;
  757. ident->username=malloc(strlen(username));
  758. strcpy(ident->username,username);
  759. printf("User name: %s\n",ident->username);
  760. address=strtok(NULL, ">");
  761. ident->address=malloc(strlen(address));
  762. strcpy(ident->address,address);
  763. printf("Address: %s\n",ident->address);
  764. user_id=strtok(address, "@");
  765. ident->user_id=malloc(strlen(user_id));
  766. strcpy(ident->user_id,user_id);
  767. printf("User ID: %s\n",ident->address);
  768. return ident;
  769. }
  770. identity_list *add_idents_from_keyring(pgp_keyring_t* keyring, identity_list *list)
  771. {
  772. TRACE_FUNCS()
  773. int i, j;
  774. pgp_key_t key;
  775. char *uid;
  776. pEp_identity *ident;
  777. for(i = 0; i < keyring->keyc; i++ ) {
  778. key = keyring->keys[i];
  779. for(j = 0; j < key.uidc; j++) {
  780. uid = strdup(key.uids[j]);
  781. ident = ident_from_uid_fpr(uid, key.pubkeyfpr.fingerprint);
  782. list = identity_list_add(list, ident);
  783. }
  784. }
  785. return list;
  786. }
  787. #define ARMOR_KEY_HEAD "^-----BEGIN PGP (PUBLIC|PRIVATE) KEY BLOCK-----"_ENDL
  788. PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
  789. size_t size, identity_list **private_idents,
  790. stringlist_t** imported_keys,
  791. uint64_t* changed_key_index)
  792. {
  793. TRACE_FUNCS()
  794. int ret;
  795. PEP_STATUS result = PEP_STATUS_OK;
  796. char* passphrase = NULL;
  797. if (!imported_keys && changed_key_index)
  798. return PEP_ILLEGAL_VALUE;
  799. stringlist_t* key_fprs = NULL;
  800. pgp_memory_t *mem = NULL;
  801. assert(session);
  802. assert(key_data);
  803. passphrase = session->curr_passphrase;
  804. if(passphrase && passphrase[0]) {
  805. netpgp_set_validation_password(passphrase);
  806. }
  807. //pgp_set_debug_level("validate.c");
  808. //pgp_set_debug_level("reader.c");
  809. if(!session || !key_data)
  810. return PEP_ILLEGAL_VALUE;
  811. if(pthread_mutex_lock(&netpgp_mutex)){
  812. return PEP_UNKNOWN_ERROR;
  813. }
  814. mem = pgp_memory_new();
  815. if (mem == NULL) {
  816. result = PEP_OUT_OF_MEMORY;
  817. goto unlock_netpgp;
  818. }
  819. pgp_memory_add(mem, (const uint8_t*)key_data, size);
  820. ret = pgp_keyring_read_from_mem(netpgp, netpgp->pubring, netpgp->secring, _armoured(key_data, size, ARMOR_KEY_HEAD), mem, 1);
  821. switch(ret) {
  822. case PGP_PASSWORD_REQUIRED:
  823. printf("Password required\n");
  824. result=PEP_PASSPHRASE_REQUIRED;
  825. goto unlock_netpgp;
  826. break;
  827. case PGP_WRONG_PASSWORD:
  828. printf("Wrong password\n");
  829. result=PEP_WRONG_PASSPHRASE;
  830. goto unlock_netpgp;
  831. break;
  832. default:
  833. result=PEP_KEY_IMPORTED;
  834. if(changed_key_index) {
  835. (*changed_key_index)=0;
  836. if (netpgp->pubring->keyc) {
  837. (*changed_key_index)=pow(2,netpgp->pubring->keyc)-1;
  838. }
  839. //(*changed_key_index)=pow(2,netpgp->secring->keyc+netpgp->pubring->keyc)-1;
  840. }
  841. break;
  842. }
  843. pgp_memory_free(mem);
  844. if(private_idents) {
  845. printf("Return private indents\n");
  846. (*private_idents) = NULL;
  847. (*private_idents) = add_idents_from_keyring(netpgp->secring, (*private_idents));
  848. //(*private_idents) = add_idents_from_keyring(netpgp->pubring, (*private_idents));
  849. }
  850. if(imported_keys) {
  851. printf("Return list of imported keys\n");
  852. stringlist_from_keyring(netpgp->pubring, imported_keys);
  853. }
  854. netpgp_save_pubring(netpgp);
  855. netpgp_save_secring(netpgp);
  856. // save rings
  857. //if ( !netpgp_save_pubring(netpgp) || !netpgp_save_secring(netpgp) )
  858. //{
  859. // result = PEP_UNKNOWN_ERROR;
  860. //}
  861. unlock_netpgp:
  862. pthread_mutex_unlock(&netpgp_mutex);
  863. return result;
  864. }
  865. static PEP_STATUS _export_keydata(
  866. pgp_key_t *key,
  867. char **buffer,
  868. size_t *buflen
  869. )
  870. {
  871. TRACE_FUNCS()
  872. PEP_STATUS result;
  873. pgp_output_t *output;
  874. pgp_memory_t *mem;
  875. pgp_setup_memory_write(&output, &mem, 128);
  876. if (mem == NULL || output == NULL) {
  877. return PEP_ILLEGAL_VALUE;
  878. }
  879. if (!pgp_write_xfer_key(output, key, 1)) {
  880. result = PEP_UNKNOWN_ERROR;
  881. goto free_mem;
  882. }
  883. *buffer = NULL;
  884. *buflen = pgp_mem_len(mem);
  885. // Allocate transferable buffer
  886. *buffer = malloc(*buflen + 1);
  887. assert(*buffer);
  888. if (*buffer == NULL) {
  889. result = PEP_OUT_OF_MEMORY;
  890. goto free_mem;
  891. }
  892. memcpy(*buffer, pgp_mem_data(mem), *buflen);
  893. (*buffer)[*buflen] = 0; // safeguard for naive users
  894. return PEP_STATUS_OK;
  895. free_mem :
  896. pgp_teardown_memory_write(output, mem);
  897. return result;
  898. }
  899. PEP_STATUS pgp_export_keydata(
  900. PEP_SESSION session, const char *fprstr, char **key_data, size_t *size,
  901. bool secret
  902. )
  903. {
  904. TRACE_FUNCS()
  905. pgp_key_t *key;
  906. uint8_t *fpr = NULL;
  907. size_t fprlen;
  908. PEP_STATUS result;
  909. char *buffer;
  910. size_t buflen;
  911. const pgp_keyring_t *srcring;
  912. assert(session);
  913. assert(fprstr);
  914. assert(key_data);
  915. assert(size);
  916. if (secret)
  917. srcring = netpgp->secring;
  918. else
  919. srcring = netpgp->pubring;
  920. if (!session || !fprstr || !key_data || !size)
  921. return PEP_ILLEGAL_VALUE;
  922. if(pthread_mutex_lock(&netpgp_mutex)) {
  923. return PEP_UNKNOWN_ERROR;
  924. }
  925. if (string_to_uint(fprstr, &fpr, &fprlen)) {
  926. unsigned from = 0;
  927. if ((key = (pgp_key_t *)pgp_getkeybyfpr(netpgp->io, srcring, fpr, fprlen, &from, NULL,0,0)) == NULL) {
  928. result = PEP_KEY_NOT_FOUND;
  929. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  930. goto unlock_netpgp;
  931. }
  932. }else{
  933. result = PEP_OUT_OF_MEMORY;
  934. goto unlock_netpgp;
  935. }
  936. result = _export_keydata(key, &buffer, &buflen);
  937. if(result == PEP_STATUS_OK)
  938. {
  939. *key_data = buffer;
  940. *size = buflen;
  941. result = PEP_STATUS_OK;
  942. }
  943. unlock_netpgp:
  944. pthread_mutex_unlock(&netpgp_mutex);
  945. return result;
  946. }
  947. struct HKP_answer {
  948. char *memory;
  949. size_t size;
  950. };
  951. PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
  952. {
  953. TRACE_FUNCS()
  954. assert(!"pgp_recv_key not implemented");
  955. return PEP_UNKNOWN_ERROR;
  956. }
  957. typedef PEP_STATUS (*find_key_cb_t)(void*, pgp_key_t *);
  958. static PEP_STATUS find_keys_do(pgp_keyring_t* keyring,
  959. const char *pattern, find_key_cb_t cb, void* cb_arg)
  960. {
  961. TRACE_FUNCS()
  962. uint8_t *fpr = NULL;
  963. size_t length;
  964. unsigned from;
  965. pgp_key_t *key;
  966. PEP_STATUS result;
  967. // Try find a fingerprint in pattern
  968. if (string_to_uint(pattern, &fpr, &length)) {
  969. // Only one fingerprint can match
  970. from = 0;
  971. key = pgp_getkeybyfpr(netpgp->io, keyring, fpr, length, &from, NULL, 0, 0);
  972. if ( key == NULL) {
  973. return PEP_KEY_NOT_FOUND;
  974. }
  975. result = cb(cb_arg, key);
  976. } else {
  977. TRACE_FUNCS()
  978. // Search by name for pattern. Can match many.
  979. from = 0;
  980. result = PEP_KEY_NOT_FOUND;
  981. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  982. while((key = (pgp_key_t *)pgp_getnextkeybyname(netpgp->io, keyring, (const char *)pattern, &from)) != NULL) {
  983. result = cb(cb_arg, key);
  984. if (result != PEP_STATUS_OK)
  985. break;
  986. from++;
  987. }
  988. }
  989. return result;
  990. }
  991. static PEP_STATUS add_key_uint_to_stringinglist(void *arg, pgp_key_t *key)
  992. {
  993. TRACE_FUNCS()
  994. stringlist_t **keylist = arg;
  995. char *newfprstr = NULL;
  996. uint_to_string(key->pubkeyfpr.fingerprint, &newfprstr, key->pubkeyfpr.length);
  997. if (newfprstr == NULL) {
  998. return PEP_OUT_OF_MEMORY;
  999. } else {
  1000. stringlist_add(*keylist, newfprstr);
  1001. free(newfprstr);
  1002. if (*keylist == NULL) {
  1003. return PEP_OUT_OF_MEMORY;
  1004. }
  1005. }
  1006. return PEP_STATUS_OK;
  1007. }
  1008. static PEP_STATUS add_secret_key_uint_to_stringinglist(void *arg, pgp_key_t *key)
  1009. {
  1010. TRACE_FUNCS()
  1011. if (pgp_is_key_secret(key)) {
  1012. stringlist_t **keylist = arg;
  1013. char *newfprstr = NULL;
  1014. uint_to_string(key->pubkeyfpr.fingerprint, &newfprstr, key->pubkeyfpr.length);
  1015. if (newfprstr == NULL) {
  1016. return PEP_OUT_OF_MEMORY;
  1017. } else {
  1018. stringlist_add(*keylist, newfprstr);
  1019. free(newfprstr);
  1020. if (*keylist == NULL) {
  1021. return PEP_OUT_OF_MEMORY;
  1022. }
  1023. }
  1024. }
  1025. return PEP_STATUS_OK;
  1026. }
  1027. static PEP_STATUS add_keyinfo_to_stringpair_list(void* arg, pgp_key_t *key) {
  1028. TRACE_FUNCS()
  1029. stringpair_list_t** keyinfo_list = (stringpair_list_t**)arg;
  1030. stringpair_t* pair = NULL;
  1031. char* id_fpr = NULL;
  1032. char* primary_userid = (char*)pgp_key_get_primary_userid(key);
  1033. // Unused:
  1034. // bool key_revoked = false;
  1035. // PEP_STATUS key_status = pgp_key_revoked(session, id_fpr, &key_revoked);
  1036. // if (key_revoked || key_status == PEP_GET_KEY_FAILED)
  1037. // return PEP_STATUS_OK; // we just move on
  1038. uint_to_string(key->pubkeyfpr.fingerprint, &id_fpr, key->pubkeyfpr.length);
  1039. pair = new_stringpair(id_fpr, primary_userid);
  1040. if (pair == NULL)
  1041. return PEP_OUT_OF_MEMORY;
  1042. *keyinfo_list = stringpair_list_add(*keyinfo_list, pair);
  1043. free(id_fpr);
  1044. if (*keyinfo_list == NULL)
  1045. return PEP_OUT_OF_MEMORY;
  1046. return PEP_STATUS_OK;
  1047. }
  1048. PEP_STATUS pgp_find_keys(
  1049. PEP_SESSION session, const char *pattern, stringlist_t **keylist
  1050. )
  1051. {
  1052. TRACE_FUNCS()
  1053. stringlist_t *_keylist, *_k;
  1054. PEP_STATUS result;
  1055. assert(session);
  1056. assert(pattern);
  1057. assert(keylist);
  1058. if (!session || !pattern || !keylist )
  1059. {
  1060. return PEP_ILLEGAL_VALUE;
  1061. }
  1062. if (pthread_mutex_lock(&netpgp_mutex))
  1063. {
  1064. return PEP_UNKNOWN_ERROR;
  1065. }
  1066. *keylist = NULL;
  1067. _keylist = new_stringlist(NULL);
  1068. if (_keylist == NULL) {
  1069. result = PEP_OUT_OF_MEMORY;
  1070. goto unlock_netpgp;
  1071. }
  1072. _k = _keylist;
  1073. result = find_keys_do(netpgp->pubring, pattern, &add_key_uint_to_stringinglist, &_k);
  1074. if (result == PEP_STATUS_OK) {
  1075. *keylist = _keylist;
  1076. // Transfer ownership, no free
  1077. goto unlock_netpgp;
  1078. }
  1079. free_stringlist(_keylist);
  1080. unlock_netpgp:
  1081. pthread_mutex_unlock(&netpgp_mutex);
  1082. return result;
  1083. }
  1084. #define HKP_REQ_PREFIX "keytext="
  1085. #define HKP_REQ_PREFIX_LEN 8
  1086. PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
  1087. {
  1088. TRACE_FUNCS()
  1089. assert(!"pgp_send_key not implemented");
  1090. return PEP_UNKNOWN_ERROR;
  1091. }
  1092. PEP_STATUS pgp_get_key_rating(
  1093. PEP_SESSION session, const char *fprstr, PEP_comm_type *comm_type)
  1094. {
  1095. TRACE_FUNCS()
  1096. pgp_key_t *key;
  1097. uint8_t *fpr = NULL;
  1098. unsigned from = 0;
  1099. size_t length;
  1100. int rating;
  1101. PEP_STATUS status = PEP_STATUS_OK;
  1102. assert(session);
  1103. assert(fprstr);
  1104. assert(comm_type);
  1105. if (!session || !fprstr || !comm_type )
  1106. return PEP_ILLEGAL_VALUE;
  1107. *comm_type = PEP_ct_unknown;
  1108. if(pthread_mutex_lock(&netpgp_mutex)){
  1109. return PEP_UNKNOWN_ERROR;
  1110. }
  1111. if (!string_to_uint(fprstr, &fpr, &length)) {
  1112. status = PEP_ILLEGAL_VALUE;
  1113. goto unlock_netpgp;
  1114. }
  1115. key = pgp_getkeybyfpr(netpgp->io, netpgp->pubring, fpr, length, &from, NULL, 0, 0);
  1116. if(key == NULL)
  1117. {
  1118. status = PEP_KEY_NOT_FOUND;
  1119. goto unlock_netpgp;
  1120. }
  1121. rating = pgp_key_get_rating(key);
  1122. switch(rating){
  1123. case PGP_VALID:
  1124. *comm_type = PEP_ct_OpenPGP_unconfirmed;
  1125. break;
  1126. case PGP_WEAK:
  1127. *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
  1128. break;
  1129. case PGP_TOOSHORT:
  1130. *comm_type = PEP_ct_key_too_short;
  1131. break;
  1132. case PGP_INVALID:
  1133. *comm_type = PEP_ct_key_b0rken;
  1134. break;
  1135. case PGP_EXPIRED:
  1136. *comm_type = PEP_ct_key_expired;
  1137. break;
  1138. case PGP_REVOKED:
  1139. *comm_type = PEP_ct_key_revoked;
  1140. break;
  1141. default:
  1142. break;
  1143. }
  1144. unlock_netpgp:
  1145. pthread_mutex_unlock(&netpgp_mutex);
  1146. return status;
  1147. }
  1148. PEP_STATUS pgp_renew_key(
  1149. PEP_SESSION session,
  1150. const char *fprstr,
  1151. const timestamp *ts
  1152. )
  1153. {
  1154. TRACE_FUNCS()
  1155. pgp_key_t *pkey;
  1156. pgp_key_t *skey;
  1157. uint8_t fpr[PGP_FINGERPRINT_SIZE];
  1158. size_t length;
  1159. unsigned from = 0;
  1160. time_t duration;
  1161. const uint8_t *primid;
  1162. PEP_STATUS status = PEP_STATUS_OK;
  1163. assert(session);
  1164. assert(fprstr);
  1165. if (!session || !fprstr )
  1166. return PEP_ILLEGAL_VALUE;
  1167. if(ts)
  1168. {
  1169. time_t now, when;
  1170. now = time(NULL);
  1171. when = mktime((struct tm*)ts);
  1172. if(now && when && when > now){
  1173. duration = when - now;
  1174. }else{
  1175. return PEP_ILLEGAL_VALUE;
  1176. }
  1177. }else{
  1178. /* Default 1 year from now */
  1179. duration = 365*24*3600;
  1180. }
  1181. if(pthread_mutex_lock(&netpgp_mutex)){
  1182. return PEP_UNKNOWN_ERROR;
  1183. }
  1184. if (!string_to_uint(fprstr, &fpr, &length)) {
  1185. status = PEP_ILLEGAL_VALUE;
  1186. goto unlock_netpgp;
  1187. }
  1188. pkey = pgp_getkeybyfpr(netpgp->io, netpgp->pubring, fpr, length, &from, NULL, 1, 0); /* reject revoked, accept expired */
  1189. if(pkey == NULL)
  1190. {
  1191. status = PEP_KEY_NOT_FOUND;
  1192. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  1193. goto unlock_netpgp;
  1194. }
  1195. from = 0;
  1196. skey = pgp_getkeybyfpr( netpgp->io, netpgp->secring, fpr, length, &from, NULL, 1, 0); /* reject revoked, accept expired */
  1197. if(skey == NULL)
  1198. {
  1199. status = PEP_KEY_NOT_FOUND;
  1200. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  1201. goto unlock_netpgp;
  1202. }
  1203. if((primid = pgp_key_get_primary_userid(skey)) == NULL)
  1204. {
  1205. status = PEP_KEY_HAS_AMBIG_NAME;
  1206. goto unlock_netpgp;
  1207. }
  1208. // FIXME : renew in a more gentle way
  1209. if (!pgp_add_selfsigned_userid(skey, pkey, primid, duration))
  1210. {
  1211. status = PEP_CANNOT_CREATE_KEY;
  1212. goto unlock_netpgp;
  1213. }
  1214. // save rings
  1215. if (netpgp_save_pubring(netpgp) &&
  1216. netpgp_save_secring(netpgp))
  1217. {
  1218. status = PEP_STATUS_OK;
  1219. }else{
  1220. status = PEP_UNKNOWN_ERROR;
  1221. }
  1222. unlock_netpgp:
  1223. pthread_mutex_unlock(&netpgp_mutex);
  1224. return status;
  1225. }
  1226. PEP_STATUS pgp_revoke_key(
  1227. PEP_SESSION session,
  1228. const char *fprstr,
  1229. const char *reason
  1230. )
  1231. {
  1232. TRACE_FUNCS()
  1233. uint8_t *fpr = NULL;
  1234. size_t length;
  1235. unsigned from = 0;
  1236. PEP_STATUS status = PEP_STATUS_OK;
  1237. assert(session);
  1238. assert(fprstr);
  1239. if (!session || !fprstr)
  1240. return PEP_UNKNOWN_ERROR;
  1241. if(pthread_mutex_lock(&netpgp_mutex)){
  1242. return PEP_UNKNOWN_ERROR;
  1243. }
  1244. // FIXME : deduplicate that code w/ renew
  1245. if (!string_to_uint(fprstr, &fpr, &length)) {
  1246. status = PEP_ILLEGAL_VALUE;
  1247. goto unlock_netpgp;
  1248. }
  1249. pgp_key_t *pkey = pgp_getkeybyfpr( netpgp->io, netpgp->pubring, fpr, length, &from, NULL, 1, 0); /* reject revoked, accept expired */
  1250. if(pkey == NULL)
  1251. {
  1252. status = PEP_KEY_NOT_FOUND;
  1253. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  1254. goto unlock_netpgp;
  1255. }
  1256. from = 0;
  1257. pgp_key_t *skey = pgp_getkeybyfpr( netpgp->io, netpgp->secring, fpr, length, &from, NULL, 1, 0); /* reject revoked, accept expired */
  1258. if(skey == NULL)
  1259. {
  1260. status = PEP_KEY_NOT_FOUND;
  1261. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  1262. goto unlock_netpgp;
  1263. }
  1264. pgp_key_revoke(skey, pkey,
  1265. 0, /* no reason code specified */
  1266. reason);
  1267. unlock_netpgp:
  1268. pthread_mutex_unlock(&netpgp_mutex);
  1269. return status;
  1270. }
  1271. PEP_STATUS pgp_key_expired(
  1272. PEP_SESSION session,
  1273. const char *fprstr,
  1274. const time_t when,
  1275. bool *expired
  1276. )
  1277. {
  1278. TRACE_FUNCS()
  1279. PEP_STATUS status = PEP_STATUS_OK;
  1280. PEP_comm_type comm_type;
  1281. assert(session);
  1282. assert(fprstr);
  1283. assert(expired);
  1284. if (!session || !fprstr || !expired)
  1285. return PEP_UNKNOWN_ERROR;
  1286. // TODO : take "when" in account
  1287. *expired = false;
  1288. status = pgp_get_key_rating(session, fprstr, &comm_type);
  1289. if (status != PEP_STATUS_OK)
  1290. return status;
  1291. if (comm_type == PEP_ct_key_expired){
  1292. *expired = true;
  1293. }
  1294. return PEP_STATUS_OK;
  1295. }
  1296. PEP_STATUS pgp_key_revoked(
  1297. PEP_SESSION session,
  1298. const char *fprstr,
  1299. bool *revoked
  1300. )
  1301. {
  1302. TRACE_FUNCS()
  1303. PEP_STATUS status = PEP_STATUS_OK;
  1304. PEP_comm_type comm_type;
  1305. assert(session);
  1306. assert(fprstr);
  1307. assert(revoked);
  1308. *revoked = false;
  1309. status = pgp_get_key_rating(session, fprstr, &comm_type);
  1310. if (status != PEP_STATUS_OK)
  1311. return status;
  1312. if (comm_type == PEP_ct_key_revoked){
  1313. *revoked = true;
  1314. }
  1315. return PEP_STATUS_OK;
  1316. }
  1317. PEP_STATUS pgp_key_created(
  1318. PEP_SESSION session,
  1319. const char *fprstr,
  1320. time_t *created
  1321. )
  1322. {
  1323. TRACE_FUNCS()
  1324. uint8_t *fpr;
  1325. pgp_key_t *key;
  1326. size_t length;
  1327. unsigned from = 0;
  1328. PEP_STATUS status = PEP_STATUS_OK;
  1329. assert(session);
  1330. assert(fprstr);
  1331. assert(created);
  1332. if (!session || !fprstr || !created)
  1333. return PEP_UNKNOWN_ERROR;
  1334. *created = 0;
  1335. if(pthread_mutex_lock(&netpgp_mutex)){
  1336. return PEP_UNKNOWN_ERROR;
  1337. }
  1338. if (!string_to_uint(fprstr, &fpr, &length)) {
  1339. status = PEP_ILLEGAL_VALUE;
  1340. goto unlock_netpgp;
  1341. }
  1342. key = pgp_getkeybyfpr( netpgp->io, netpgp->pubring, fpr, length, &from, NULL,0,0);
  1343. if (key)
  1344. {
  1345. *created = (time_t) key->key.pubkey.birthtime;
  1346. }
  1347. else
  1348. {
  1349. status = PEP_KEY_NOT_FOUND;
  1350. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  1351. goto unlock_netpgp;
  1352. }
  1353. unlock_netpgp:
  1354. pthread_mutex_unlock(&netpgp_mutex);
  1355. return status;
  1356. }
  1357. PEP_STATUS pgp_list_keyinfo(
  1358. PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list)
  1359. {
  1360. TRACE_FUNCS()
  1361. if (!session || !keyinfo_list)
  1362. return PEP_UNKNOWN_ERROR;
  1363. if (pthread_mutex_lock(&netpgp_mutex))
  1364. {
  1365. return PEP_UNKNOWN_ERROR;
  1366. }
  1367. // Unused:
  1368. // pgp_key_t *key;
  1369. PEP_STATUS result;
  1370. result = find_keys_do(netpgp->pubring, pattern, &add_keyinfo_to_stringpair_list, (void*)keyinfo_list);
  1371. if (!keyinfo_list)
  1372. result = PEP_KEY_NOT_FOUND;
  1373. printf("%s:%d, Key not found\n",__FILE__,__LINE__);
  1374. pthread_mutex_unlock(&netpgp_mutex);
  1375. return result;
  1376. }
  1377. PEP_STATUS pgp_find_private_keys(
  1378. PEP_SESSION session, const char *pattern, stringlist_t **keylist
  1379. )
  1380. {
  1381. TRACE_FUNCS()
  1382. stringlist_t *_keylist, *_k;
  1383. PEP_STATUS result;
  1384. assert(session);
  1385. assert(keylist);
  1386. //if (!session || !keylist )
  1387. //{
  1388. // return PEP_ILLEGAL_VALUE;
  1389. //}
  1390. if (pthread_mutex_lock(&netpgp_mutex))
  1391. {
  1392. return PEP_UNKNOWN_ERROR;
  1393. }
  1394. *keylist = NULL;
  1395. _keylist = new_stringlist(NULL);
  1396. if (_keylist == NULL) {
  1397. result = PEP_OUT_OF_MEMORY;
  1398. goto unlock_netpgp;
  1399. }
  1400. _k = _keylist;
  1401. result = find_keys_do(netpgp->secring, pattern, &add_secret_key_uint_to_stringinglist, &_k);
  1402. if (result == PEP_STATUS_OK) {
  1403. *keylist = _keylist;
  1404. // Transfer ownership, no free
  1405. goto unlock_netpgp;
  1406. }
  1407. free_stringlist(_keylist);
  1408. unlock_netpgp:
  1409. pthread_mutex_unlock(&netpgp_mutex);
  1410. return result;
  1411. }
  1412. PEP_STATUS pgp_contains_priv_key(
  1413. PEP_SESSION session,
  1414. const char *fpr,
  1415. bool *has_private)
  1416. {
  1417. TRACE_FUNCS()
  1418. stringlist_t* keylist = NULL;
  1419. PEP_STATUS status = pgp_find_private_keys(session, fpr, &keylist);
  1420. if (status == PEP_STATUS_OK && keylist) {
  1421. free_stringlist(keylist);
  1422. *has_private = true;
  1423. }
  1424. else {
  1425. *has_private = false;
  1426. }
  1427. return status;
  1428. }
  1429. PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session) {
  1430. // Not implemented - netpgp doesn't appear to keep track of trust status in
  1431. // a meaningful way, though there is space for it in the structs.
  1432. TRACE_FUNCS()
  1433. return PEP_STATUS_OK;
  1434. }
  1435. PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session, PEP_CIPHER_SUITE suite) {
  1436. TRACE_FUNCS()
  1437. if (suite == PEP_CIPHER_SUITE_DEFAULT) {
  1438. return PEP_STATUS_OK;
  1439. } else {
  1440. return PEP_CANNOT_CONFIG;
  1441. }
  1442. }