A backend for the p≡p Engine built on Sequoia.
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.

2402 lines
77 KiB

12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
  1. use std::cmp;
  2. use std::convert::TryInto;
  3. use std::env;
  4. use std::ffi::{
  5. CStr,
  6. OsStr,
  7. };
  8. use std::io::{
  9. Read,
  10. Write,
  11. };
  12. use std::mem;
  13. use std::path::Path;
  14. use std::ptr;
  15. use std::slice;
  16. use std::time::{
  17. Duration,
  18. SystemTime,
  19. UNIX_EPOCH,
  20. };
  21. use libc::{
  22. c_char,
  23. c_uint,
  24. size_t,
  25. time_t,
  26. };
  27. use chrono::Utc;
  28. use chrono::TimeZone;
  29. use memmem::{Searcher, TwoWaySearcher};
  30. use sequoia_openpgp as openpgp;
  31. use openpgp::Cert;
  32. use openpgp::cert::{
  33. amalgamation::ValidAmalgamation,
  34. CertBuilder,
  35. CertParser,
  36. ValidCert,
  37. };
  38. use openpgp::crypto::{
  39. Password,
  40. SessionKey,
  41. };
  42. use openpgp::Fingerprint;
  43. use openpgp::Packet;
  44. use openpgp::packet::{
  45. key,
  46. Key,
  47. PKESK,
  48. SKESK,
  49. UserID,
  50. };
  51. use openpgp::parse::{
  52. Parse,
  53. PacketParser,
  54. stream::{
  55. DecryptionHelper,
  56. DecryptorBuilder,
  57. DetachedVerifierBuilder,
  58. GoodChecksum,
  59. MessageLayer,
  60. MessageStructure,
  61. VerificationHelper,
  62. VerificationError,
  63. }
  64. };
  65. use openpgp::policy::NullPolicy;
  66. use openpgp::serialize::{
  67. stream::{
  68. Armorer,
  69. Encryptor,
  70. LiteralWriter,
  71. Message,
  72. Recipient,
  73. Signer,
  74. },
  75. Serialize,
  76. };
  77. use openpgp::types::{
  78. ReasonForRevocation,
  79. RevocationStatus,
  80. SignatureType,
  81. SymmetricAlgorithm,
  82. };
  83. #[macro_use] mod log;
  84. mod constants;
  85. #[macro_use] mod pep;
  86. use pep::{
  87. Error,
  88. ErrorCode,
  89. PepCipherSuite,
  90. PepCommType,
  91. PepEncFormat,
  92. PepIdentity,
  93. PepIdentityFlags,
  94. PepIdentityList,
  95. PepIdentityListItem,
  96. Result,
  97. Session,
  98. StringList,
  99. StringListItem,
  100. Timestamp,
  101. };
  102. #[macro_use] mod ffi;
  103. use ffi::{Malloc, Free};
  104. mod keystore;
  105. use keystore::Keystore;
  106. mod buffer;
  107. use crate::buffer::rust_bytes_to_c_str_lossy;
  108. // If the PEP_TRACE environment variable is set or we are built in
  109. // debug mode, then enable tracing.
  110. lazy_static::lazy_static! {
  111. static ref TRACE: bool = {
  112. if cfg!(debug_assertions) {
  113. true
  114. } else if let Ok(_) = env::var("PEP_TRACE") {
  115. true
  116. } else {
  117. false
  118. }
  119. };
  120. }
  121. pub const P: &NullPolicy = &NullPolicy::new();
  122. // Given the pEp cipher suite indicator enum, return the equivalent
  123. // sequoia cipher suite enum value
  124. //
  125. // PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
  126. // PEP_CIPHER_SUITE suite)
  127. ffi!(fn pgp_config_cipher_suite(session: *mut Session, suite: PepCipherSuite)
  128. -> Result<()>
  129. {
  130. let session = Session::as_mut(session);
  131. session.set_cipher_suite(suite)
  132. });
  133. // Decrypts the key.
  134. //
  135. // On success, returns the decrypted key.
  136. fn _pgp_get_decrypted_key(key: Key<key::SecretParts, key::UnspecifiedRole>,
  137. pass: Option<&Password>)
  138. -> Result<Key<key::SecretParts, key::UnspecifiedRole>>
  139. {
  140. tracer!(*crate::TRACE, "_pgp_get_decrypted_key");
  141. match key.secret() {
  142. key::SecretKeyMaterial::Unencrypted { .. } => Ok(key),
  143. key::SecretKeyMaterial::Encrypted { .. } => {
  144. let fpr = key.fingerprint();
  145. if let Some(pass) = pass {
  146. wrap_err!(
  147. key.decrypt_secret(pass),
  148. WrongPassphrase,
  149. format!("Decrypting secret key material for {}", fpr))
  150. } else {
  151. t!("Can't decrypt {}: no password configured", fpr);
  152. Err(Error::PassphraseRequired)
  153. }
  154. }
  155. }
  156. }
  157. // Returns the first key in iter that is already decrypted or can be
  158. // decrypted using `pass`.
  159. fn _pgp_get_decrypted_key_iter<'a, I>(iter: I, pass: Option<&Password>)
  160. -> Result<Key<key::SecretParts, key::UnspecifiedRole>>
  161. where I: Iterator<Item=&'a Key<key::SecretParts, key::UnspecifiedRole>>
  162. {
  163. // Return the "best" (most helpful to the user) error.
  164. let mut bad_pass = None;
  165. let mut missing_pass = false;
  166. let mut other_error = None;
  167. for key in iter {
  168. match _pgp_get_decrypted_key(key.clone(), pass) {
  169. Ok(key) => return Ok(key),
  170. Err(err @ Error::WrongPassphrase(_, _)) => bad_pass = Some(err),
  171. Err(Error::PassphraseRequired) => missing_pass = true,
  172. Err(err) => other_error = Some(err),
  173. }
  174. }
  175. if let Some(err) = bad_pass {
  176. Err(err)
  177. } else if missing_pass {
  178. Err(Error::PassphraseRequired)
  179. } else if let Some(err) = other_error {
  180. Err(err)
  181. } else {
  182. Err(Error::UnknownError(
  183. anyhow::anyhow!("decrypting secret key material"),
  184. "empty iterator".into()))
  185. }
  186. }
  187. // PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
  188. ffi!(fn pgp_init_(session: *mut Session, _in_first: bool,
  189. per_user_directory: *const c_char,
  190. malloc: Malloc,
  191. free: Free,
  192. session_size: c_uint,
  193. session_cookie_offset: c_uint,
  194. session_curr_passphrase_offset: c_uint,
  195. session_new_key_pass_enable: c_uint,
  196. session_generation_passphrase_offset: c_uint,
  197. session_cipher_suite_offset: c_uint,
  198. pep_status_size: c_uint,
  199. pep_comm_type_size: c_uint,
  200. pep_enc_format_size: c_uint,
  201. pep_identity_flags_size: c_uint,
  202. pep_cipher_suite_size: c_uint,
  203. string_list_item_size: c_uint,
  204. pep_identity_size: c_uint,
  205. pep_identity_list_item_size: c_uint,
  206. timestamp_size: c_uint,
  207. _stringpair_size: c_uint,
  208. _stringpair_list_size: c_uint,
  209. magic: c_uint)
  210. -> Result<()>
  211. {
  212. use std::mem::size_of;
  213. use memoffset::offset_of;
  214. assert_eq!(magic, 0xDEADBEEF);
  215. assert!(session_size as usize >= size_of::<Session>());
  216. assert_eq!(session_cookie_offset as usize,
  217. offset_of!(Session, state));
  218. assert_eq!(session_curr_passphrase_offset as usize,
  219. offset_of!(Session, curr_passphrase));
  220. assert_eq!(session_new_key_pass_enable as usize,
  221. offset_of!(Session, new_key_pass_enabled));
  222. assert_eq!(session_generation_passphrase_offset as usize,
  223. offset_of!(Session, generation_passphrase));
  224. assert_eq!(session_cipher_suite_offset as usize,
  225. offset_of!(Session, cipher_suite));
  226. assert_eq!(pep_status_size as usize, size_of::<ErrorCode>());
  227. assert_eq!(pep_comm_type_size as usize, size_of::<PepCommType>());
  228. assert_eq!(pep_enc_format_size as usize, size_of::<PepEncFormat>());
  229. assert_eq!(pep_identity_flags_size as usize, size_of::<PepIdentityFlags>());
  230. assert_eq!(pep_cipher_suite_size as usize, size_of::<PepCipherSuite>());
  231. assert_eq!(string_list_item_size as usize, size_of::<StringListItem>());
  232. assert_eq!(pep_identity_size as usize, size_of::<PepIdentity>());
  233. assert_eq!(pep_identity_list_item_size as usize, size_of::<PepIdentityListItem>());
  234. assert_eq!(timestamp_size as usize, size_of::<Timestamp>());
  235. // assert_eq!(stringpair_size as usize, size_of::<StringPair>());
  236. // assert_eq!(stringpair_list_size as usize, size_of::<StringPairList>());
  237. let session = Session::as_mut(session);
  238. if per_user_directory.is_null() {
  239. return Err(Error::IllegalValue(
  240. "per_user_directory may not be NULL".into()));
  241. }
  242. let per_user_directory = unsafe { CStr::from_ptr(per_user_directory) };
  243. #[cfg(not(windows))]
  244. let per_user_directory = {
  245. use std::os::unix::ffi::OsStrExt;
  246. OsStr::from_bytes(per_user_directory.to_bytes())
  247. };
  248. #[cfg(windows)]
  249. let per_user_directory = {
  250. use std::ffi::OsString;
  251. use std::os::windows::prelude::*;
  252. let os_string = OsString::from_wide(per_user_directory.as_bytes());
  253. os_string.as_os_str()
  254. };
  255. let ks = keystore::Keystore::init(Path::new(per_user_directory))?;
  256. session.init(ks, malloc, free);
  257. Ok(())
  258. });
  259. // void pgp_release(PEP_SESSION session, bool out_last)
  260. ffi!(fn pgp_release(session: *mut Session, _out_last: bool) -> Result<()> {
  261. Session::as_mut(session).deinit();
  262. Ok(())
  263. });
  264. // Cookie used by the decryption and verification logic.
  265. struct Helper<'a> {
  266. session: &'a mut Session,
  267. secret_keys_called: bool,
  268. recipient_keylist: StringList,
  269. signer_keylist: StringList,
  270. good_checksums: usize,
  271. malformed_signature: usize,
  272. missing_keys: usize,
  273. unbound_key: usize,
  274. revoked_key: usize,
  275. expired_key: usize,
  276. bad_key: usize,
  277. bad_checksums: usize,
  278. // Whether we decrypted anything.
  279. decrypted: bool,
  280. // The filename stored in the literal data packet. Note: this is
  281. // *not* protected by the signature and should not be trusted!!!
  282. filename: Option<Vec<u8>>,
  283. }
  284. impl<'a> Helper<'a> {
  285. fn new(session: &'a mut Session) -> Self {
  286. Helper {
  287. session: session,
  288. secret_keys_called: false,
  289. recipient_keylist: StringList::empty(),
  290. signer_keylist: StringList::empty(),
  291. good_checksums: 0,
  292. malformed_signature: 0,
  293. missing_keys: 0,
  294. unbound_key: 0,
  295. revoked_key: 0,
  296. expired_key: 0,
  297. bad_key: 0,
  298. bad_checksums: 0,
  299. decrypted: false,
  300. filename: None,
  301. }
  302. }
  303. }
  304. impl<'a> VerificationHelper for &mut Helper<'a> {
  305. fn get_certs(&mut self, ids: &[openpgp::KeyHandle])
  306. -> openpgp::Result<Vec<Cert>>
  307. {
  308. let mut certs = Vec::new();
  309. for id in ids {
  310. if let Ok((cert, _private))
  311. = self.session.keystore().cert_find_with_key(id.clone(), false)
  312. {
  313. certs.push(cert);
  314. }
  315. }
  316. Ok(certs)
  317. }
  318. fn check(&mut self, structure: MessageStructure)
  319. -> openpgp::Result<()>
  320. {
  321. tracer!(*crate::TRACE, "Helper::check");
  322. for layer in structure.into_iter() {
  323. if let MessageLayer::SignatureGroup { results } = layer {
  324. for result in results {
  325. match result {
  326. Ok(GoodChecksum { sig, ka }) => {
  327. // We need to add the fingerprint of
  328. // the primary key to signer_keylist.
  329. let primary_fpr = ka.cert().fingerprint();
  330. self.signer_keylist.add_unique(
  331. primary_fpr.to_hex());
  332. t!("Good signature ({:02X}{:02X}) from {}",
  333. sig.digest_prefix()[0],
  334. sig.digest_prefix()[1],
  335. primary_fpr);
  336. self.good_checksums += 1;
  337. }
  338. Err(VerificationError::MalformedSignature { sig, error }) => {
  339. t!("Malformed signature ({:02X}{:02X}) \
  340. allegedly from {:?}: {}",
  341. sig.digest_prefix()[0],
  342. sig.digest_prefix()[1],
  343. sig.issuers().next(),
  344. error);
  345. self.malformed_signature += 1;
  346. }
  347. Err(VerificationError::MissingKey { sig }) => {
  348. t!("No key to check signature ({:02X}{:02X}) \
  349. allegedly from {:?}",
  350. sig.digest_prefix()[0],
  351. sig.digest_prefix()[1],
  352. sig.issuers().next());
  353. self.missing_keys += 1;
  354. }
  355. Err(VerificationError::UnboundKey { sig, cert, error }) => {
  356. // This happens if the key doesn't have a binding
  357. // signature.
  358. t!("Certificate {} has no valid self-signature; \
  359. can't check signature ({:02X}{:02X}): {}",
  360. cert.fingerprint(),
  361. sig.digest_prefix()[0],
  362. sig.digest_prefix()[1],
  363. error);
  364. self.unbound_key += 1;
  365. }
  366. Err(VerificationError::BadKey { sig, ka, error }) => {
  367. // This happens if the certificate is not
  368. // alive or revoked, if the key is not
  369. // alive or revoked, of if the key is not
  370. // signing capable.
  371. t!("Can't check signature ({:02X}{:02X}): \
  372. key {} is bad: {}",
  373. sig.digest_prefix()[0],
  374. sig.digest_prefix()[1],
  375. ka.cert().fingerprint(),
  376. error);
  377. // Check if the key or certificate is revoked.
  378. if let RevocationStatus::Revoked(_)
  379. = ka.revocation_status()
  380. {
  381. t!("reason: key is revoked");
  382. self.revoked_key += 1;
  383. } else if let RevocationStatus::Revoked(_)
  384. = ka.cert().revocation_status()
  385. {
  386. t!("reason: cert is revoked");
  387. self.revoked_key += 1;
  388. }
  389. // Check if the key or certificate is expired.
  390. else if let Err(err) = ka.cert().alive() {
  391. t!("reason: cert is expired: {}", err);
  392. self.expired_key += 1;
  393. }
  394. else if let Err(err) = ka.alive() {
  395. // Key is expired.
  396. t!("reason: key is expired: {}", err);
  397. self.expired_key += 1;
  398. }
  399. // Wrong key flags or something similar.
  400. else {
  401. t!("reason: other");
  402. self.bad_key += 1;
  403. }
  404. }
  405. Err(VerificationError::BadSignature { sig, ka, error }) => {
  406. t!("Bad signature ({:02X}{:02X}) from {}: {}",
  407. sig.digest_prefix()[0],
  408. sig.digest_prefix()[1],
  409. ka.cert().fingerprint(),
  410. error);
  411. self.bad_checksums += 1;
  412. }
  413. }
  414. }
  415. }
  416. }
  417. Ok(())
  418. }
  419. // Save the filename in the literal data packet.
  420. fn inspect(&mut self, pp: &PacketParser<'_>) -> openpgp::Result<()> {
  421. if let Packet::Literal(ref lit) = pp.packet {
  422. if let Some(filename) = lit.filename() {
  423. self.filename = Some(filename.to_vec());
  424. }
  425. }
  426. Ok(())
  427. }
  428. }
  429. impl<'a> DecryptionHelper for &mut Helper<'a> {
  430. fn decrypt<D>(&mut self, pkesks: &[PKESK], _: &[SKESK],
  431. sym_algo: Option<SymmetricAlgorithm>,
  432. mut decrypt: D)
  433. -> openpgp::Result<Option<openpgp::Fingerprint>>
  434. where D: FnMut(SymmetricAlgorithm, &SessionKey) -> bool
  435. {
  436. tracer!(*crate::TRACE, "Helper::decrypt");
  437. let password = self.session.curr_passphrase();
  438. let keystore = self.session.keystore();
  439. // Whether there are any wildcard recipients.
  440. let mut have_wildcards = false;
  441. // The certificate that decrypted the message.
  442. let mut decryption_identity = None;
  443. let mut missing_passphrase = false;
  444. let mut bad_passphrase = None;
  445. if self.secret_keys_called {
  446. // Prevent iterations, which isn't needed since we don't
  447. // support SKESKs.
  448. return Err(anyhow::anyhow!("SKESKs not supported"));
  449. }
  450. self.secret_keys_called = true;
  451. t!("{} PKESKs", pkesks.len());
  452. for pkesk in pkesks.iter() {
  453. let keyid = pkesk.recipient();
  454. if keyid.is_wildcard() {
  455. // Initially ignore wildcards.
  456. have_wildcards = true;
  457. continue;
  458. }
  459. t!("Considering PKESK for {}", keyid);
  460. // Collect the recipients. Note: we must return the
  461. // primary key's fingerprint.
  462. let (cert, private)
  463. = match keystore.cert_find_with_key(keyid.clone(), false)
  464. {
  465. Err(Error::KeyNotFound(_)) => continue,
  466. Err(err) => {
  467. t!("Error looking up {}: {}", keyid, err);
  468. continue;
  469. }
  470. Ok((cert, private)) => (cert, private)
  471. };
  472. self.recipient_keylist.add_unique(cert.fingerprint().to_hex());
  473. if self.decrypted {
  474. // We already have the session key. We are just
  475. // trying to collect the alleged recipients now.
  476. continue;
  477. }
  478. // Try to decrypt this PKESK.
  479. if ! private {
  480. continue;
  481. }
  482. let ka = match cert.keys().filter(|ka| *keyid == ka.keyid()).next() {
  483. Some(ka) => ka,
  484. None => {
  485. t!("Inconsistent DB: cert {} doesn't contain a subkey with \
  486. keyid {}, but DB says it does!",
  487. cert.fingerprint(), keyid);
  488. continue;
  489. }
  490. };
  491. if let Ok(key) = ka.key().clone().parts_into_secret() {
  492. let fpr = key.fingerprint();
  493. let key = match _pgp_get_decrypted_key(key, password.as_ref()) {
  494. Ok(key) => key,
  495. Err(err @ Error::WrongPassphrase(_, _)) => {
  496. bad_passphrase = Some(err);
  497. continue;
  498. }
  499. Err(Error::PassphraseRequired) => {
  500. missing_passphrase = true;
  501. continue;
  502. }
  503. Err(err) => {
  504. t!("While decrypting {}: {}", fpr, err);
  505. continue;
  506. }
  507. };
  508. let mut keypair = match key.into_keypair() {
  509. Ok(keypair) => keypair,
  510. Err(err) => {
  511. t!("Creating keypair for {}: {}", fpr, err);
  512. continue;
  513. }
  514. };
  515. match pkesk.decrypt(&mut keypair, sym_algo) {
  516. Some((sym_algo, sk)) => {
  517. if decrypt(sym_algo, &sk) {
  518. decryption_identity = Some(cert.fingerprint());
  519. self.decrypted = true;
  520. }
  521. }
  522. None => {
  523. t!("Failed to decrypt PKESK for {}", fpr);
  524. }
  525. }
  526. }
  527. }
  528. let mut tsks = None;
  529. if have_wildcards && ! self.decrypted {
  530. for pkesk in pkesks.iter() {
  531. let keyid = pkesk.recipient();
  532. if ! keyid.is_wildcard() {
  533. // We're only considering the wildcard PKESKs.
  534. continue;
  535. }
  536. if tsks.is_none() {
  537. // Load all certificates with secret key material.
  538. tsks = Some(keystore.cert_all(true)?);
  539. if tsks.as_ref().unwrap().len() == 0 {
  540. // We don't have any keys with secret key
  541. // material. We're done.
  542. break;
  543. }
  544. }
  545. for (tsk, _private) in tsks.as_ref().unwrap().iter() {
  546. for ka in tsk.keys().secret() {
  547. let key = match _pgp_get_decrypted_key(
  548. ka.key().clone(), password.as_ref())
  549. {
  550. Ok(key) => key,
  551. Err(err @ Error::WrongPassphrase(_, _)) => {
  552. bad_passphrase = Some(err);
  553. continue;
  554. }
  555. Err(Error::PassphraseRequired) => {
  556. missing_passphrase = true;
  557. continue;
  558. }
  559. Err(err) => {
  560. t!("decrypting {}: {}",
  561. ka.fingerprint(), err);
  562. continue;
  563. }
  564. };
  565. let mut keypair = match key.into_keypair() {
  566. Ok(keypair) => keypair,
  567. Err(err) => {
  568. t!("Creating keypair for {}: {}",
  569. ka.fingerprint(), err);
  570. continue;
  571. }
  572. };
  573. // Note: for decryption to appear to succeed,
  574. // we must get a valid algorithm (8 of 256
  575. // values) and a 16-bit checksum must match.
  576. // Thus, we have about a 1 in 2**21 chance of
  577. // having a false positive here.
  578. match pkesk.decrypt(&mut keypair, sym_algo) {
  579. Some((sym_algo, sk)) => {
  580. // Add it to the recipient list.
  581. t!("wildcard recipient appears to be {}",
  582. ka.fingerprint());
  583. if decrypt (sym_algo, &sk) {
  584. decryption_identity
  585. = Some(tsk.fingerprint());
  586. self.recipient_keylist.add_unique(
  587. tsk.fingerprint().to_hex());
  588. self.decrypted = true;
  589. break;
  590. } else {
  591. t!("Failed to decrypt message \
  592. using ESK decrypted by {}",
  593. ka.fingerprint());
  594. continue;
  595. }
  596. }
  597. None => {
  598. t!("Failed to decrypt PKESK for {}",
  599. ka.fingerprint());
  600. continue;
  601. }
  602. };
  603. }
  604. }
  605. }
  606. }
  607. if self.decrypted {
  608. Ok(decryption_identity)
  609. } else {
  610. if let Some(err) = bad_passphrase.take() {
  611. Err(err.into())
  612. } else if missing_passphrase {
  613. Err(Error::PassphraseRequired.into())
  614. } else {
  615. Err(Error::DecryptNoKey(
  616. anyhow::anyhow!("No key")).into())
  617. }
  618. }
  619. }
  620. }
  621. // PEP_STATUS pgp_decrypt_and_verify(
  622. // PEP_SESSION session, const char *ctext, size_t csize,
  623. // const char *dsigtext, size_t dsigsize,
  624. // char **ptext, size_t *psize, stringlist_t **keylist,
  625. // char** filename_ptr)
  626. ffi!(fn pgp_decrypt_and_verify(session: *mut Session,
  627. ctext: *const c_char, csize: size_t,
  628. dsigtext: *const c_char, _dsigsize: size_t,
  629. ptext: *mut *mut c_char, psize: *mut size_t,
  630. keylistp: *mut *mut StringListItem,
  631. filename_ptr: *mut *mut c_char)
  632. -> Result<()>
  633. {
  634. let session = Session::as_mut(session);
  635. let malloc = session.malloc();
  636. if ctext.is_null() {
  637. return Err(Error::IllegalValue(
  638. "ctext may not be NULL".into()));
  639. }
  640. let ctext = unsafe {
  641. std::slice::from_raw_parts(ctext as *const u8, csize)
  642. };
  643. // XXX: We don't handle detached signatures over encrypted
  644. // messages (and never have).
  645. if ! dsigtext.is_null() {
  646. return Err(Error::IllegalValue(
  647. "detached signatures over encrypted data are not supported".into()));
  648. }
  649. unsafe {
  650. ptext.as_mut().map(|p| *p = ptr::null_mut());
  651. psize.as_mut().map(|p| *p = 0);
  652. }
  653. let mut h = Helper::new(session);
  654. let decryptor = wrap_err!(
  655. DecryptorBuilder::from_bytes(ctext),
  656. UnknownError,
  657. "DecryptorBuilder")?;
  658. let mut decryptor = match decryptor.with_policy(crate::P, None, &mut h) {
  659. Ok(decryptor) => decryptor,
  660. Err(err) => {
  661. match err.downcast::<Error>() {
  662. Ok(err) => return Err(err),
  663. Err(err) => return Err(Error::DecryptNoKey(err)),
  664. }
  665. }
  666. };
  667. let mut content = Vec::new();
  668. wrap_err!(decryptor.read_to_end(&mut content),
  669. UnknownError,
  670. "read_to_end")?;
  671. let h = decryptor.helper_mut();
  672. if ! h.decrypted {
  673. return Err(Error::DecryptNoKey(anyhow::anyhow!("decryption failed")));
  674. }
  675. // Add a terminating NUL for naive users.
  676. content.push(0);
  677. unsafe {
  678. if let Some(ptextp) = ptext.as_mut() {
  679. let buffer = malloc(content.len()) as *mut u8;
  680. if buffer.is_null() {
  681. return Err(Error::OutOfMemory(
  682. "content".into(), content.len()));
  683. }
  684. slice::from_raw_parts_mut(buffer, content.len())
  685. .copy_from_slice(&content);
  686. *ptextp = buffer as *mut _;
  687. }
  688. psize.as_mut().map(|p| {
  689. // Don't count the trailing NUL.
  690. *p = content.len() - 1
  691. });
  692. }
  693. if h.signer_keylist.len() == 0 {
  694. h.signer_keylist.add("");
  695. }
  696. h.signer_keylist.append(&mut h.recipient_keylist);
  697. unsafe { keylistp.as_mut() }.map(|p| {
  698. *p = mem::replace(&mut h.signer_keylist, StringList::empty()).to_c();
  699. });
  700. if ! filename_ptr.is_null() {
  701. unsafe { filename_ptr.as_mut() }.map(|p| {
  702. if let Some(filename) = h.filename.as_ref() {
  703. *p = rust_bytes_to_c_str_lossy(filename);
  704. } else {
  705. *p = ptr::null_mut();
  706. }
  707. });
  708. }
  709. // **********************************
  710. // Sync changes with pgp_verify_text.
  711. // **********************************
  712. if h.good_checksums > 0 {
  713. // If there is at least one signature that we can verify,
  714. // succeed.
  715. return Err(Error::DecryptedAndVerified);
  716. } else if h.revoked_key > 0 {
  717. // If there are any signatures from revoked keys, fail.
  718. return Err(Error::VerifySignerKeyRevoked);
  719. } else if h.expired_key > 0 {
  720. // If there are any signatures from expired keys, fail.
  721. return Err(Error::Decrypted);
  722. } else if h.bad_key > 0 {
  723. // If there are any signatures from invalid keys (keys
  724. // that are not signing capable), fail.
  725. return Err(Error::Decrypted);
  726. } else if h.bad_checksums > 0 {
  727. // If there are any bad signatures, fail.
  728. return Err(Error::DecryptSignatureDoesNotMatch);
  729. } else {
  730. // We couldn't verify any signatures (possibly because we
  731. // don't have the keys).
  732. return Err(Error::Decrypted);
  733. }
  734. });
  735. // PEP_STATUS pgp_verify_text(
  736. // PEP_SESSION session, const char *text, size_t size,
  737. // const char *signature, size_t sig_size, stringlist_t **keylist)
  738. ffi!(fn pgp_verify_text(session: *mut Session,
  739. text: *const c_char, size: size_t,
  740. signature: *const c_char, sig_size: size_t,
  741. keylistp: *mut *mut StringListItem)
  742. -> Result<()>
  743. {
  744. let session = Session::as_mut(session);
  745. if size == 0 || sig_size == 0 {
  746. return Err(Error::DecryptWrongFormat);
  747. }
  748. if text.is_null() {
  749. return Err(Error::IllegalValue(
  750. "text may not be NULL".into()));
  751. }
  752. let text = unsafe {
  753. std::slice::from_raw_parts(text as *const u8, size)
  754. };
  755. if signature.is_null() {
  756. return Err(Error::IllegalValue(
  757. "signature may not be NULL".into()));
  758. }
  759. let signature = unsafe {
  760. std::slice::from_raw_parts(signature as *const u8, sig_size)
  761. };
  762. // ASCII text is sometimes mangled in transport. Show some stats
  763. // to make detecting this easier.
  764. if *crate::TRACE {
  765. let mut cr = 0;
  766. let mut crlf = 0;
  767. let mut lf = 0;
  768. for i in 0..text.len() {
  769. // CR
  770. if text[i] == b'\r' {
  771. cr += 1;
  772. }
  773. // LF
  774. if text[i] == b'\n' {
  775. if i > 0 && text[i - 1] == b'\r' {
  776. cr -= 1;
  777. crlf += 1;
  778. } else {
  779. lf += 1;
  780. }
  781. }
  782. }
  783. t!("Text to verify: {} bytes with {} crlfs, {} bare crs and {} bare lfs",
  784. size, crlf, cr, lf);
  785. }
  786. let mut h = Helper::new(session);
  787. let verifier = wrap_err!(
  788. DetachedVerifierBuilder::from_bytes(&signature[..]),
  789. UnknownError,
  790. "Creating DetachedVerifierBuilder")?;
  791. let mut verifier = match verifier.with_policy(crate::P, None, &mut h) {
  792. Ok(verifier) => verifier,
  793. Err(err) => {
  794. match err.downcast::<Error>() {
  795. Ok(err) => return Err(err),
  796. Err(err) => return Err(Error::VerifyNoKey(err)),
  797. }
  798. }
  799. };
  800. wrap_err!(
  801. verifier.verify_bytes(text),
  802. UnknownError,
  803. "Verifying text")?;
  804. if h.signer_keylist.len() == 0 {
  805. h.signer_keylist.add("");
  806. }
  807. h.signer_keylist.append(&mut h.recipient_keylist);
  808. unsafe { keylistp.as_mut() }.map(|p| {
  809. *p = mem::replace(&mut h.signer_keylist, StringList::empty()).to_c();
  810. });
  811. // *****************************************
  812. // Sync changes with pgp_decrypt_and_verify.
  813. // *****************************************
  814. if h.good_checksums > 0 {
  815. // If there is at least one signature that we can verify,
  816. // succeed.
  817. return Err(Error::Verified);
  818. } else if h.revoked_key > 0 {
  819. // If there are any signatures from revoked keys, fail.
  820. return Err(Error::VerifySignerKeyRevoked);
  821. } else if h.expired_key > 0 {
  822. // If there are any signatures from expired keys, fail.
  823. return Err(Error::Decrypted);
  824. } else if h.bad_key > 0 {
  825. // If there are any signatures from invalid keys (keys
  826. // that are not signing capable), fail.
  827. return Err(Error::Decrypted);
  828. } else if h.bad_checksums > 0 {
  829. // If there are any bad signatures, fail.
  830. return Err(Error::DecryptSignatureDoesNotMatch);
  831. } else {
  832. // We couldn't verify any signatures (possibly because we
  833. // don't have the keys).
  834. return Err(Error::Unencrypted);
  835. }
  836. });
  837. // PEP_STATUS pgp_sign_only(
  838. // PEP_SESSION session, const char* fpr, const char *ptext,
  839. // size_t psize, char **stext, size_t *ssize)
  840. ffi!(fn pgp_sign_only(
  841. session: *mut Session,
  842. fpr: *const c_char,
  843. ptext: *const c_char, psize: size_t,
  844. stextp: *mut *mut c_char, ssizep: *mut size_t)
  845. -> Result<()>
  846. {
  847. let session = Session::as_mut(session);
  848. let malloc = session.malloc();
  849. if fpr.is_null() {
  850. return Err(Error::IllegalValue(
  851. "fpr may not be NULL".into()));
  852. }
  853. let fpr = unsafe { CStr::from_ptr(fpr) };
  854. let fpr = wrap_err!(
  855. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  856. UnknownError,
  857. "Not a fingerprint")?;
  858. if ptext.is_null() {
  859. return Err(Error::IllegalValue(
  860. "ptext may not be NULL".into()));
  861. }
  862. let ptext = unsafe {
  863. slice::from_raw_parts(ptext as *const u8, psize)
  864. };
  865. unsafe {
  866. stextp.as_mut().map(|p| *p = ptr::null_mut());
  867. ssizep.as_mut().map(|p| *p = 0);
  868. }
  869. let password = session.curr_passphrase();
  870. let keystore = session.keystore();
  871. let (cert, _private) = keystore.cert_find(fpr, true)?;
  872. let vc = wrap_err!(
  873. cert.with_policy(crate::P, None),
  874. KeyUnsuitable,
  875. format!("{} rejected by policy", cert.fingerprint()))?;
  876. let key =
  877. _pgp_get_decrypted_key_iter(
  878. vc.keys().alive().revoked(false).for_signing().secret()
  879. .map(|ka| ka.key()),
  880. password.as_ref())?;
  881. let signer_keypair = wrap_err!(
  882. key.into_keypair(),
  883. UnknownError,
  884. "Creating key pair from signing key")?;
  885. let mut stext = Vec::new();
  886. let message = Message::new(&mut stext);
  887. let message = wrap_err!(
  888. Armorer::new(message).build(),
  889. UnknownError,
  890. "Setting up armorer")?;
  891. let mut message = wrap_err!(
  892. Signer::new(message, signer_keypair).detached().build(),
  893. UnknownError,
  894. "Setting up signer")?;
  895. wrap_err!(
  896. message.write_all(ptext),
  897. UnknownError,
  898. "Signing message")?;
  899. wrap_err!(
  900. message.finalize(),
  901. UnknownError,
  902. "Finalizing message")?;
  903. // Add a trailing NUL.
  904. stext.push(0);
  905. // We need to store it in a buffer backed by the libc allocator.
  906. unsafe {
  907. if let Some(stextp) = stextp.as_mut() {
  908. let buffer = malloc(stext.len()) as *mut u8;
  909. if buffer.is_null() {
  910. return Err(Error::OutOfMemory("stext".into(), stext.len()));
  911. }
  912. slice::from_raw_parts_mut(buffer, stext.len())
  913. .copy_from_slice(&stext);
  914. *stextp = buffer as *mut _;
  915. }
  916. ssizep.as_mut().map(|p| {
  917. // Don't count the trailing NUL.
  918. *p = stext.len() - 1
  919. });
  920. }
  921. Ok(())
  922. });
  923. fn pgp_encrypt_sign_optional(
  924. session: *mut Session,
  925. keylist: *mut StringListItem,
  926. ptext: *const c_char, psize: size_t,
  927. ctextp: *mut *mut c_char, csizep: *mut size_t,
  928. sign: bool)
  929. -> Result<()>
  930. {
  931. tracer!(*crate::TRACE, "pgp_encrypt_sign_optional");
  932. let session = Session::as_mut(session);
  933. let malloc = session.malloc();
  934. if ptext.is_null() {
  935. return Err(Error::IllegalValue(
  936. "ptext may not be NULL".into()));
  937. }
  938. let ptext = unsafe {
  939. slice::from_raw_parts(ptext as *const u8, psize)
  940. };
  941. unsafe {
  942. ctextp.as_mut().map(|p| *p = ptr::null_mut());
  943. csizep.as_mut().map(|p| *p = 0);
  944. }
  945. let password = session.curr_passphrase();
  946. let keystore = session.keystore();
  947. let keylist = StringList::to_rust(keylist, false);
  948. t!("{} recipients.", keylist.len());
  949. for (i, v) in keylist.iter().enumerate() {
  950. t!(" {}. {}", i, String::from_utf8_lossy(v.to_bytes()));
  951. }
  952. if sign {
  953. t!("First recipient will sign the message");
  954. }
  955. // Get the keys for the recipients.
  956. let mut recipient_keys = Vec::new();
  957. let mut signer_keypair = None;
  958. for (i, item) in keylist.iter().enumerate() {
  959. let fpr = wrap_err!(
  960. Fingerprint::from_hex(&String::from_utf8_lossy(item.to_bytes())),
  961. UnknownError,
  962. "Not a fingerprint")?;
  963. let (cert, _private) = keystore.cert_find(fpr, false)?;
  964. let vc = wrap_err!(
  965. cert.with_policy(crate::P, None),
  966. KeyUnsuitable,
  967. format!("{} rejected by policy", cert.fingerprint()))?;
  968. // Collect all of the keys that have the encryption for
  969. // transport capability.
  970. // Note: there might not be any valid encryption-capable
  971. // subkeys. Normally this isn't a problem as we consider such
  972. // certificates to be "broken" (cf. _pgp_key_broken) and won't
  973. // use them. But there is a time of check, time of use race,
  974. // which we ignore.
  975. let mut have_one = false;
  976. for ka in vc.keys().alive().revoked(false).for_transport_encryption() {
  977. recipient_keys.push(ka.key().clone());
  978. have_one = true;
  979. }
  980. if ! have_one {
  981. t!("warning: {} doesn't have any valid encryption-capable subkeys",
  982. vc.fingerprint());
  983. }
  984. // The the first recipient is the signer.
  985. if sign && i == 0 {
  986. let key =
  987. _pgp_get_decrypted_key_iter(
  988. vc.keys().alive().revoked(false).for_signing().secret()
  989. .map(|ka| ka.key()),
  990. password.as_ref())?;
  991. let keypair = wrap_err!(
  992. key.into_keypair(),
  993. UnknownError,
  994. "Creating key pair from signing key")?;
  995. signer_keypair = Some(keypair);
  996. }
  997. }
  998. let recipients: Vec<Recipient> = recipient_keys
  999. .iter()
  1000. .map(|key| Recipient::new(key.keyid(), key))
  1001. .collect();
  1002. let mut ctext = Vec::new();
  1003. let message = Message::new(&mut ctext);
  1004. let message = wrap_err!(
  1005. Armorer::new(message).build(),
  1006. UnknownError,
  1007. "Setting up armorer")?;
  1008. let mut message = wrap_err!(
  1009. Encryptor::for_recipients(message, recipients).build(),
  1010. UnknownError,
  1011. "Setting up encryptor")?;
  1012. if let Some(keypair) = signer_keypair {
  1013. message = wrap_err!(
  1014. Signer::new(message, keypair).build(),
  1015. UnknownError,
  1016. "Setting up signer")?;
  1017. }
  1018. let mut message = wrap_err!(
  1019. LiteralWriter::new(message).build(),
  1020. UnknownError,
  1021. "Setting up literal writer")?;
  1022. wrap_err!(
  1023. message.write_all(ptext),
  1024. UnknownError,
  1025. "Encrypting message")?;
  1026. wrap_err!(
  1027. message.finalize(),
  1028. UnknownError,
  1029. "Finalizing message")?;
  1030. // Add a trailing NUL.
  1031. ctext.push(0);
  1032. // We need to store it in a buffer backed by the libc allocator.
  1033. unsafe {
  1034. if let Some(ctextp) = ctextp.as_mut() {
  1035. let buffer = malloc(ctext.len()) as *mut u8;
  1036. if buffer.is_null() {
  1037. return Err(Error::OutOfMemory("ctext".into(), ctext.len()));
  1038. }
  1039. slice::from_raw_parts_mut(buffer, ctext.len())
  1040. .copy_from_slice(&ctext);
  1041. *ctextp = buffer as *mut _;
  1042. }
  1043. csizep.as_mut().map(|p| {
  1044. // Don't count the trailing NUL.
  1045. *p = ctext.len() - 1
  1046. });
  1047. }
  1048. Ok(())
  1049. }
  1050. // PEP_STATUS pgp_encrypt_only(
  1051. // PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1052. // size_t psize, char **ctext, size_t *csize)
  1053. ffi!(fn pgp_encrypt_only(session: *mut Session,
  1054. keylist: *mut StringListItem,
  1055. ptext: *const c_char, psize: size_t,
  1056. ctextp: *mut *mut c_char, csizep: *mut size_t)
  1057. -> Result<()>
  1058. {
  1059. pgp_encrypt_sign_optional(
  1060. session, keylist, ptext, psize, ctextp, csizep, false)
  1061. });
  1062. // PEP_STATUS pgp_encrypt_and_sign(
  1063. // PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1064. // size_t psize, char **ctext, size_t *csize)
  1065. ffi!(fn pgp_encrypt_and_sign(session: *mut Session,
  1066. keylist: *mut StringListItem,
  1067. ptext: *const c_char, psize: size_t,
  1068. ctextp: *mut *mut c_char, csizep: *mut size_t)
  1069. -> Result<()>
  1070. {
  1071. pgp_encrypt_sign_optional(
  1072. session, keylist, ptext, psize, ctextp, csizep, true)
  1073. });
  1074. // PEP_STATUS _pgp_generate_keypair(PEP_SESSION session, pEp_identity *identity, time_t when)
  1075. ffi!(fn _pgp_generate_keypair(session: *mut Session,
  1076. identity: *mut PepIdentity,
  1077. when: time_t)
  1078. -> Result<()>
  1079. {
  1080. let session = Session::as_mut(session);
  1081. let identity = if let Some(i) = PepIdentity::as_mut(identity) {
  1082. i
  1083. } else {
  1084. return Err(Error::IllegalValue(
  1085. "identity must not be NULL".into()));
  1086. };
  1087. t!("identity: {:?}", identity);
  1088. let is_group_identity
  1089. = identity.identity_flag(PepIdentityFlags::GroupIdent);
  1090. // NOTE: FOR NOW, NO PASSPHRASE-BASED KEYS WILL BE GENERATED FOR
  1091. // GROUP ENCRYPTION. VOLKER HAS A PLAN TO FIX THIS.
  1092. let password = if is_group_identity {
  1093. None
  1094. } else if session.new_key_pass_enabled() {
  1095. if let Some(password) = session.generation_passphrase() {
  1096. Some(password)
  1097. } else {
  1098. return Err(Error::PassphraseForNewKeysRequired);
  1099. }
  1100. } else {
  1101. None
  1102. };
  1103. t!("password protected: {}",
  1104. if password.is_some() { "yes" } else { "no" });
  1105. let address = identity.address()
  1106. .ok_or_else(|| {
  1107. Error::IllegalValue(
  1108. "identity->address must be non-NULL".into())
  1109. })?
  1110. .to_str()
  1111. .map_err(|err| {
  1112. Error::IllegalValue(
  1113. format!("identity->address must be UTF-8 encoded: {}",
  1114. err))
  1115. })?;
  1116. t!("identity.address: {}", address);
  1117. let username = identity.username();
  1118. let username = if let Some(username) = username {
  1119. let username = username.to_str()
  1120. .map_err(|err| {
  1121. Error::IllegalValue(
  1122. format!("identity->username must be UTF-8 encoded: {}",
  1123. err))
  1124. })?;
  1125. if username == address {
  1126. // Ignore the username if it is the same as the address.
  1127. None
  1128. } else {
  1129. Some(username)
  1130. }
  1131. } else {
  1132. None
  1133. };
  1134. t!("identity.username: {:?}", username);
  1135. let userid = wrap_err!(
  1136. UserID::from_unchecked_address(username, None, address)
  1137. .or_else(|err| {
  1138. if let Some(username) = username {
  1139. // Replace parentheses in input string with
  1140. // brackets.
  1141. let username = &username
  1142. .replace("(", "[")
  1143. .replace(")", "]")[..];
  1144. t!("Invalid username, trying '{}'", username);
  1145. UserID::from_unchecked_address(
  1146. Some(username),
  1147. None,
  1148. address)
  1149. } else {
  1150. Err(err)
  1151. }
  1152. })
  1153. .or_else(|err| {
  1154. if let Some(username) = username {
  1155. // Replace everything but letters and numbers
  1156. // with _.
  1157. let username = &username.chars()
  1158. .map(|c| {
  1159. match c {
  1160. c @ '0'..='9' => c,
  1161. c @ 'a'..='z' => c,
  1162. c @ 'A'..='Z' => c,
  1163. _ => '_'
  1164. }
  1165. })
  1166. .collect::<String>()[..];
  1167. t!("Invalid username, trying '{}'", username);
  1168. UserID::from_unchecked_address(
  1169. Some(username),
  1170. None,
  1171. address)
  1172. } else {
  1173. Err(err)
  1174. }
  1175. }),
  1176. UnknownError,
  1177. "UserID::from_unchecked_address")?;
  1178. // Generate a key.
  1179. let mut certb = CertBuilder::general_purpose(
  1180. Some(session.cipher_suite().try_into().unwrap_or_default()),
  1181. Some(userid));
  1182. certb = certb.set_password(password);
  1183. if when > 0 {
  1184. certb = certb.set_creation_time(
  1185. Some(UNIX_EPOCH + Duration::new(when as u64, 0)));
  1186. }
  1187. let (cert, _) = wrap_err!(
  1188. certb.generate(),
  1189. CannotCreateKey,
  1190. "Generating a key pair")?;
  1191. let fpr = cert.fingerprint();
  1192. wrap_err!(
  1193. session.keystore().cert_save(cert),
  1194. CannotCreateKey,
  1195. "Saving new key")?;
  1196. identity.set_fingerprint(fpr);
  1197. Ok(())
  1198. });
  1199. // PEP_STATUS pgp_generate_keypair(PEP_SESSION session, pEp_identity *identity)
  1200. #[no_mangle] pub extern "C"
  1201. fn pgp_generate_keypair(session: *mut Session,
  1202. identity: *mut PepIdentity)
  1203. -> crate::ErrorCode
  1204. {
  1205. _pgp_generate_keypair(session, identity, 0)
  1206. }
  1207. // PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr_raw)
  1208. ffi!(fn pgp_delete_keypair(session: *mut Session,
  1209. fpr: *const c_char)
  1210. -> Result<()>
  1211. {
  1212. let session = Session::as_mut(session);
  1213. let keystore = session.keystore();
  1214. if fpr.is_null() {
  1215. return Err(Error::IllegalValue("fpr must not be NULL".into()));
  1216. }
  1217. let fpr = unsafe { CStr::from_ptr(fpr) };
  1218. let fpr = wrap_err!(
  1219. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  1220. UnknownError,
  1221. "Not a fingerprint")?;
  1222. t!("Deleting {}", fpr);
  1223. keystore.cert_delete(fpr)
  1224. });
  1225. // Imports the keyring. If keydata contains more than one
  1226. // ascii-armored keyring, this only imports the first ascii-armored
  1227. // keyring.
  1228. fn import_keydata(session: &mut Session,
  1229. keydata: &[u8],
  1230. private_idents: &mut PepIdentityList,
  1231. imported_keys: &mut StringList,
  1232. changed_bitvec: &mut u64)
  1233. -> Result<()>
  1234. {
  1235. tracer!(*crate::TRACE, "import_keydata");
  1236. let keystore = session.keystore();
  1237. // We need to look at the first packet to figure out what we
  1238. // should do.
  1239. let ppr = match PacketParser::from_bytes(keydata) {
  1240. Ok(ppr) => ppr,
  1241. Err(err) =>
  1242. return Err(Error::UnknownError(
  1243. err, "Creating packet parser".into())),
  1244. };
  1245. let packet = match ppr.as_ref() {
  1246. Ok(pp) => &pp.packet,
  1247. Err(_eof) => {
  1248. return Err(Error::UnknownError(
  1249. anyhow::anyhow!("Unexpected EOF").into(),
  1250. "No data".into()));
  1251. }
  1252. };
  1253. match packet {
  1254. Packet::Signature(sig) => {
  1255. // Check that we have a certificate revocation
  1256. // certification. If so, try to import it.
  1257. if sig.typ() != SignatureType::KeyRevocation {
  1258. t!("Can't import a {} signature", sig.typ());
  1259. return Err(Error::NoKeyImported);
  1260. }
  1261. for issuer in sig.get_issuers().into_iter() {
  1262. match keystore.cert_find_with_key(issuer.clone(), false) {
  1263. Err(err) => {
  1264. t!("Can't merge signature: \
  1265. no certificate for {} available: {}",
  1266. issuer, err);
  1267. }
  1268. Ok((cert, _)) => {
  1269. let fpr = cert.fingerprint();
  1270. if let Err(err)
  1271. = sig.clone().verify_primary_key_revocation(
  1272. &cert.primary_key(),
  1273. &cert.primary_key())
  1274. {
  1275. t!("Revocation certificate not issued by {}: {}",
  1276. fpr, err);
  1277. continue;
  1278. }
  1279. match cert.insert_packets(sig.clone()) {
  1280. Err(err) => {
  1281. t!("Merging signature with {} failed: {}",
  1282. fpr, err);
  1283. // This trumps any other error.
  1284. return wrap_err!(
  1285. Err(err),
  1286. UnknownError,
  1287. "inserting packets");
  1288. }
  1289. Ok(cert) => {
  1290. match keystore.cert_save(cert) {
  1291. Ok((_, changed)) => {
  1292. let count = imported_keys.len();
  1293. if changed && count < 64 {
  1294. *changed_bitvec |= 1 << count;
  1295. }
  1296. imported_keys.add(fpr.to_hex());
  1297. return Err(Error::KeyImported);
  1298. }
  1299. Err(err) => {
  1300. t!("Saving updated certificate {} \
  1301. failed: {}",
  1302. fpr, err);
  1303. // This trumps any other error.
  1304. return Err(err);
  1305. }
  1306. }
  1307. }
  1308. }
  1309. }
  1310. }
  1311. }
  1312. t!("Failed to import revocation certificate allegedly issued by {:?}.",
  1313. sig
  1314. .issuers().next()
  1315. .map(|kh| kh.to_hex())
  1316. .unwrap_or("<no issuer subpacket>".into()));
  1317. return Err(Error::NoKeyImported);
  1318. }
  1319. Packet::PublicKey(_) | Packet::SecretKey(_) => {
  1320. let mut got_one = false;
  1321. for certo in CertParser::from(ppr) {
  1322. match certo {
  1323. Ok(cert) => {
  1324. let fpr = cert.fingerprint();
  1325. t!("Importing certificate {}", fpr);
  1326. for ua in cert.userids() {
  1327. t!(" User ID: {}", ua.userid());
  1328. }
  1329. let is_tsk = cert.is_tsk();
  1330. let (ident, changed)
  1331. = session.keystore().cert_save(cert)?;
  1332. imported_keys.add(fpr.to_hex());
  1333. t!("Adding {} to imported_keys", fpr);
  1334. if let Some(ident) = ident {
  1335. if is_tsk {
  1336. t!("Adding {:?} to private_idents", ident);
  1337. private_idents.add(&ident);
  1338. }
  1339. }
  1340. if changed {
  1341. let i = imported_keys.len() - 1;
  1342. if i < 64 {
  1343. (*changed_bitvec) |= 1 << i;
  1344. }
  1345. }
  1346. got_one = true;
  1347. }
  1348. e @ Err(_) => {
  1349. wrap_err!(e,
  1350. UnknownError,
  1351. "Error reading keyring")?;
  1352. }
  1353. }
  1354. }
  1355. if !got_one {
  1356. Err(Error::NoKeyImported)
  1357. } else {
  1358. Err(Error::KeyImported)
  1359. }
  1360. }
  1361. packet => {
  1362. t!("Can't import a {} packet", packet.tag());
  1363. Err(Error::NoKeyImported)
  1364. }
  1365. }
  1366. }
  1367. // Imports the keydata and returns a PepIdentity and whether
  1368. // the certificate is changed relative to the copy on disk.
  1369. //
  1370. // Whether the certificate is changed is a heuristic. It may
  1371. // indicate that the certificate has changed when it hasn't (false
  1372. // positive), but it will never say that the certificate has not
  1373. // changed when it has (false negative).
  1374. //
  1375. // PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *keydata,
  1376. // size_t size, identity_list **private_idents,
  1377. // stringlist_t** imported_keys,
  1378. // uint64_t* changed_key_index)
  1379. ffi!(fn pgp_import_keydata(session: *mut Session,
  1380. keydata: *const c_char,
  1381. keydata_len: size_t,
  1382. identity_listp: *mut *mut PepIdentityListItem,
  1383. imported_keysp: *mut *mut StringListItem,
  1384. changed_key_indexp: *mut u64)
  1385. -> Result<()>
  1386. {
  1387. let session = Session::as_mut(session);
  1388. if imported_keysp.is_null() && ! changed_key_indexp.is_null() {
  1389. return Err(Error::IllegalValue(
  1390. "When changed_key_index is provided, \
  1391. import_keys must also be provided."
  1392. .into()));
  1393. }
  1394. if keydata.is_null() {
  1395. return Err(Error::IllegalValue(
  1396. "keydata may not be NULL".into()));
  1397. }
  1398. let keydata = unsafe {
  1399. std::slice::from_raw_parts(keydata as *const u8, keydata_len)
  1400. };
  1401. // We add(!) to the existing lists.
  1402. let mut identity_list = unsafe { identity_listp.as_mut() }
  1403. .map(|p| PepIdentityList::to_rust(*p, false))
  1404. .unwrap_or_else(|| PepIdentityList::empty());
  1405. let mut imported_keys = unsafe { imported_keysp.as_mut() }
  1406. .map(|p| StringList::to_rust(*p, false))
  1407. .unwrap_or_else(|| StringList::empty());
  1408. let mut changed_key_index: u64 = unsafe { changed_key_indexp.as_mut() }
  1409. .map(|p| *p)
  1410. .unwrap_or(0);
  1411. // Get the start of each ascii armor block.
  1412. let mut offsets = Vec::new();
  1413. let searcher = TwoWaySearcher::new(b"-----BEGIN PGP");
  1414. loop {
  1415. let start = offsets.iter().last().map(|&i| i + 1).unwrap_or(0);
  1416. if let Some(i) = searcher.search_in(&keydata[start..]) {
  1417. offsets.push(start + i);
  1418. } else {
  1419. break;
  1420. }
  1421. }
  1422. t!("armor block offsets: {:?}", offsets);
  1423. let retval = if offsets.len() == 0 {
  1424. import_keydata(session,
  1425. keydata,
  1426. &mut identity_list,
  1427. &mut imported_keys,
  1428. &mut changed_key_index)
  1429. } else if offsets.len() == 1 {
  1430. import_keydata(session,
  1431. &keydata[offsets[0]..],
  1432. &mut identity_list,
  1433. &mut imported_keys,
  1434. &mut changed_key_index)
  1435. } else {
  1436. let mut retval = Error::KeyImported;
  1437. offsets.push(keydata.len());
  1438. for offsets in offsets.windows(2) {
  1439. let keydata = &keydata[offsets[0]..offsets[1]];
  1440. let curr_status = import_keydata(session,
  1441. keydata,
  1442. &mut identity_list,
  1443. &mut imported_keys,
  1444. &mut changed_key_index);
  1445. // import_keydata should not return Ok; on success, it
  1446. // should return KeyImported.
  1447. let curr_status = match curr_status {
  1448. Err(err) => err,
  1449. Ok(()) => panic!("import_keydata returned Ok"),
  1450. };
  1451. if ErrorCode::from(&curr_status) != ErrorCode::from(&retval) {
  1452. match curr_status {
  1453. Error::NoKeyImported
  1454. | Error::KeyNotFound(_)
  1455. | Error::UnknownError(_, _) => {
  1456. match retval {
  1457. Error::KeyImported => retval = Error::SomeKeysImported,
  1458. Error::UnknownError(_, _) => retval = curr_status,
  1459. _ => (),
  1460. }
  1461. }
  1462. Error::KeyImported => retval = Error::SomeKeysImported,
  1463. _ => (),
  1464. }
  1465. }
  1466. }
  1467. Err(retval)
  1468. };
  1469. unsafe { identity_listp.as_mut() }.map(|p| {
  1470. *p = identity_list.to_c();
  1471. });
  1472. unsafe { imported_keysp.as_mut() }.map(|p| {
  1473. *p = imported_keys.to_c();
  1474. });
  1475. unsafe { changed_key_indexp.as_mut() }.map(|p| {
  1476. *p = changed_key_index;
  1477. });
  1478. retval
  1479. });
  1480. // PEP_STATUS pgp_export_keydata(
  1481. // PEP_SESSION session, const char *fpr, char **keydata, size_t *size,
  1482. // bool secret)
  1483. ffi!(fn pgp_export_keydata(session: *mut Session,
  1484. fpr: *const c_char,
  1485. keydatap: *mut *mut c_char,
  1486. keydata_lenp: *mut size_t,
  1487. secret: bool)
  1488. -> Result<()>
  1489. {
  1490. let session = Session::as_mut(session);
  1491. let malloc = session.malloc();
  1492. if fpr.is_null() {
  1493. return Err(Error::IllegalValue("fpr must not be NULL".into()));
  1494. }
  1495. let fpr = unsafe { CStr::from_ptr(fpr) };
  1496. let fpr = wrap_err!(
  1497. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  1498. UnknownError,
  1499. "Not a fingerprint")?;
  1500. t!("({}, {})", fpr, if secret { "secret" } else { "public" });
  1501. // If the caller asks for a secret key and we only have a
  1502. // public key, then we return an error.
  1503. let (cert, _private) = session.keystore().cert_find(fpr, secret)?;
  1504. let mut keydata = Vec::new();
  1505. if secret {
  1506. wrap_err!(
  1507. cert.as_tsk().armored().serialize(&mut keydata),
  1508. UnknownError,
  1509. format!("Serializing key: {}", cert.fingerprint()))?;
  1510. } else {
  1511. wrap_err!(
  1512. cert.armored().serialize(&mut keydata),
  1513. UnknownError,
  1514. format!("Serializing certificate: {}", cert.fingerprint()))?;
  1515. }
  1516. // We need a NUL byte at the end.
  1517. keydata.push(0);
  1518. // We need to store it in a buffer backed by the libc allocator.
  1519. unsafe {
  1520. if let Some(keydatap) = keydatap.as_mut() {
  1521. let buffer = malloc(keydata.len()) as *mut u8;
  1522. if buffer.is_null() {
  1523. return Err(Error::OutOfMemory("keydata".into(), keydata.len()));
  1524. }
  1525. slice::from_raw_parts_mut(buffer, keydata.len())
  1526. .copy_from_slice(&keydata);
  1527. *keydatap = buffer as *mut _;
  1528. }
  1529. keydata_lenp.as_mut().map(|p| {
  1530. // Don't count the trailing NUL.
  1531. *p = keydata.len() - 1
  1532. });
  1533. }
  1534. Ok(())
  1535. });
  1536. // PEP_STATUS pgp_list_keyinfo(PEP_SESSION session,
  1537. // const char* pattern,
  1538. // stringpair_list_t** keyinfo_list)
  1539. stub!(pgp_list_keyinfo);
  1540. // PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
  1541. stub!(pgp_recv_key);
  1542. fn list_keys(session: *mut Session,
  1543. pattern: *const c_char,
  1544. keylistp: *mut *mut StringListItem,
  1545. private_only: bool) -> Result<()>
  1546. {
  1547. tracer!(*crate::TRACE, "list_keys");
  1548. let session = Session::as_mut(session);
  1549. if pattern.is_null() {
  1550. return Err(Error::IllegalValue(
  1551. "pattern may not be NULL".into()));
  1552. }
  1553. let pattern = unsafe { CStr::from_ptr(pattern) };
  1554. // XXX: What should we do if pattern is not valid UTF-8?
  1555. let pattern = pattern.to_string_lossy();
  1556. let mut keylist = StringList::empty();
  1557. match session.keystore().list_keys(&pattern, private_only) {
  1558. Err(Error::KeyNotFound(_)) => {
  1559. // If no keys are found, don't return an error, return the
  1560. // empty set.
  1561. }
  1562. Err(err) => {
  1563. return Err(err);
  1564. }
  1565. Ok(listing) => {
  1566. // We return revoked keys.
  1567. for (fpr, _, _) in listing {
  1568. keylist.add(fpr.to_hex());
  1569. }
  1570. }
  1571. }
  1572. t!("Found {} certificates matching '{}'", keylist.len(), pattern);
  1573. unsafe { keylistp.as_mut() }.map(|p| {
  1574. *p = keylist.to_c();
  1575. });
  1576. Ok(())
  1577. }
  1578. // PEP_STATUS pgp_find_keys(
  1579. // PEP_SESSION session, const char *pattern, stringlist_t **keylist)
  1580. ffi!(fn pgp_find_keys(session: *mut Session,
  1581. pattern: *const c_char,
  1582. keylistp: *mut *mut StringListItem)
  1583. -> Result<()>
  1584. {
  1585. list_keys(session, pattern, keylistp, false)
  1586. });
  1587. // PEP_STATUS pgp_find_private_keys(
  1588. // PEP_SESSION session, const char *pattern, stringlist_t **keylist)
  1589. ffi!(fn pgp_find_private_keys(session: *mut Session,
  1590. pattern: *const c_char,
  1591. keylistp: *mut *mut StringListItem)
  1592. -> Result<()>
  1593. {
  1594. list_keys(session, pattern, keylistp, true)
  1595. });
  1596. // PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
  1597. stub!(pgp_send_key);
  1598. // PEP_STATUS pgp_renew_key(
  1599. // PEP_SESSION session, const char *fpr, const timestamp *ts)
  1600. ffi!(fn pgp_renew_key(session: *mut Session,
  1601. fpr: *const c_char,
  1602. expiration: *const Timestamp)
  1603. -> Result<()>
  1604. {
  1605. let session = Session::as_mut(session);
  1606. if fpr.is_null() {
  1607. return Err(Error::IllegalValue(
  1608. "fpr may not be NULL".into()));
  1609. }
  1610. let fpr = unsafe { CStr::from_ptr(fpr) };
  1611. let fpr = wrap_err!(
  1612. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  1613. UnknownError,
  1614. "Not a fingerprint")?;
  1615. let expiration = if let Some(expiration) = unsafe { expiration.as_ref() } {
  1616. expiration
  1617. } else {
  1618. return Err(Error::IllegalValue("expiration must not be NULL".into()));
  1619. };
  1620. let password = session.curr_passphrase();
  1621. let keystore = session.keystore();
  1622. let expiration = Utc.ymd(1900 + expiration.tm_year,
  1623. 1 + expiration.tm_mon as u32,
  1624. expiration.tm_mday as u32)
  1625. .and_hms(expiration.tm_hour as u32,
  1626. expiration.tm_min as u32,
  1627. expiration.tm_sec as u32);
  1628. let expiration: SystemTime = expiration.into();
  1629. let (cert, _private) = keystore.cert_find(fpr, true)?;
  1630. let creation_time = cert.primary_key().creation_time();
  1631. if creation_time >= expiration {
  1632. // The creation time is after the expiration time!
  1633. return Err(Error::UnknownError(
  1634. anyhow::anyhow!("creation time ({:?}) \
  1635. can't be after expiration time ({:?})",
  1636. creation_time, expiration),
  1637. "invalid expiration time".into()));
  1638. }
  1639. let vc = wrap_err!(
  1640. cert.with_policy(crate::P, None),
  1641. KeyUnsuitable,
  1642. format!("{} rejected by policy", cert.fingerprint()))?;
  1643. let key =
  1644. _pgp_get_decrypted_key_iter(
  1645. vc.keys().revoked(false).for_certification().secret()
  1646. .map(|ka| ka.key()),
  1647. password.as_ref())?;
  1648. let mut signer_keypair = wrap_err!(
  1649. key.into_keypair(),
  1650. UnknownError,
  1651. "Creating key pair from certification key")?;
  1652. // Set the expiration for all non-revoked keys.
  1653. let mut self_sigs = Vec::new();
  1654. for (i, ka) in vc.keys().revoked(false).enumerate() {
  1655. // Arrange for a backsig, if needed.
  1656. let mut self_sig = if i > 0 // subkey
  1657. && (ka.for_certification()
  1658. || ka.for_signing()
  1659. || ka.for_authentication())
  1660. {
  1661. let subkey = wrap_err!(
  1662. ka.key().clone().parts_into_secret(),
  1663. UnknownError,
  1664. "Can't extend signing-capable subkey's expiration: \
  1665. secret key material is not available")?;
  1666. let subkey = _pgp_get_decrypted_key(subkey, password.as_ref())?;
  1667. let mut subkey_keypair = wrap_err!(
  1668. subkey.into_keypair(),
  1669. UnknownError,
  1670. "Creating key pair from subkey")?;
  1671. wrap_err!(
  1672. ka.set_expiration_time(
  1673. &mut signer_keypair,
  1674. Some(&mut subkey_keypair),
  1675. Some(expiration)),
  1676. UnknownError,
  1677. "setting expiration (generating self signature and backsig)")?
  1678. } else {
  1679. wrap_err!(
  1680. ka.set_expiration_time(
  1681. &mut signer_keypair,
  1682. None,
  1683. Some(expiration)),
  1684. UnknownError,
  1685. "setting expiration (generating self signature)")?
  1686. };
  1687. self_sigs.append(&mut self_sig);
  1688. }
  1689. let cert = wrap_err!(
  1690. cert.insert_packets(self_sigs),
  1691. UnknownError,
  1692. "inserting new self signatures")?;
  1693. keystore.cert_save(cert)?;
  1694. Ok(())
  1695. });
  1696. // PEP_STATUS pgp_revoke_key(
  1697. // PEP_SESSION session, const char *fpr, const char *reason)
  1698. ffi!(fn pgp_revoke_key(session: *mut Session,
  1699. fpr: *const c_char,
  1700. reason: *const c_char)
  1701. -> Result<()>
  1702. {
  1703. let session = Session::as_mut(session);
  1704. if fpr.is_null() {
  1705. return Err(Error::IllegalValue(
  1706. "fpr may not be NULL".into()));
  1707. }
  1708. let fpr = unsafe { CStr::from_ptr(fpr) };
  1709. let fpr = wrap_err!(
  1710. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  1711. UnknownError,
  1712. "Not a fingerprint")?;
  1713. let reason = unsafe {
  1714. reason.as_ref()
  1715. .map(|reason| CStr::from_ptr(reason).to_bytes())
  1716. .unwrap_or(b"")
  1717. };
  1718. let password = session.curr_passphrase();
  1719. let keystore = session.keystore();
  1720. let (cert, _private) = keystore.cert_find(fpr, true)?;
  1721. let vc = wrap_err!(
  1722. cert.with_policy(crate::P, None),
  1723. KeyUnsuitable,
  1724. format!("{} rejected by policy", cert.fingerprint()))?;
  1725. let key =
  1726. _pgp_get_decrypted_key_iter(
  1727. vc.keys().alive().revoked(false).for_certification().secret()
  1728. .map(|ka| ka.key()),
  1729. password.as_ref())?;
  1730. let mut signer_keypair = wrap_err!(
  1731. key.into_keypair(),
  1732. UnknownError,
  1733. "Creating key pair from certification key")?;
  1734. let sig = wrap_err!(
  1735. cert.revoke(&mut signer_keypair,
  1736. ReasonForRevocation::Unspecified,
  1737. reason),
  1738. UnknownError,
  1739. "generating revocation certificate")?;
  1740. let cert = wrap_err!(
  1741. cert.insert_packets(sig),
  1742. UnknownError,
  1743. "merging revocation certificate")?;
  1744. assert!(matches!(
  1745. cert.revocation_status(crate::P, None),
  1746. RevocationStatus::Revoked(_)));
  1747. keystore.cert_save(cert)?;
  1748. Ok(())
  1749. });
  1750. // Check to see that key, at a minimum, even contains encryption and
  1751. // signing subkeys.
  1752. fn _pgp_key_broken(vc: &ValidCert) -> bool {
  1753. let mut has_enc = false;
  1754. let mut has_signing = false;
  1755. for ka in vc.keys() {
  1756. if ka.for_signing() {
  1757. has_signing = true;
  1758. }
  1759. if ka.for_transport_encryption() || ka.for_storage_encryption() {
  1760. has_enc = true;
  1761. }
  1762. if has_signing && has_enc {
  1763. return false;
  1764. }
  1765. }
  1766. return true;
  1767. }
  1768. fn _pgp_key_expired(vc: &ValidCert) -> bool
  1769. {
  1770. tracer!(*crate::TRACE, "_pgp_key_expired");
  1771. if ! vc.alive().is_ok() {
  1772. return true;
  1773. }
  1774. // Check to see if the key is broken. Ideally, we'd do this in one
  1775. // pass below, but givem the choice for how to check for expiry,
  1776. // this is the simplest solutiom.
  1777. if _pgp_key_broken(vc) {
  1778. return false; // still isn't expired. is broken. there's a difference and a different check.
  1779. }
  1780. // Why is this an indicator of just an expired key and not a
  1781. // broken one? This will also reject keys that are not expired,
  1782. // but rather missing subkeys.
  1783. // Are there at least one certification subkey, one signing subkey
  1784. // and one encryption subkey that are live?
  1785. let mut can_encrypt = false;
  1786. let mut can_sign = false;
  1787. for ka in vc.keys().alive().revoked(false) {
  1788. if ka.for_transport_encryption() || ka.for_storage_encryption() {
  1789. can_encrypt = true;
  1790. }
  1791. if ka.for_signing() {
  1792. can_sign = true;
  1793. }
  1794. if can_encrypt && can_sign {
  1795. break;
  1796. }
  1797. }
  1798. let expired = !(can_encrypt && can_sign);
  1799. t!("Key can{} encrypt, can{} sign => {} expired",
  1800. if can_encrypt { "" } else { "not" },
  1801. if can_sign { "" } else { "not" },
  1802. if expired { "" } else { "not" });
  1803. return expired;
  1804. }
  1805. // PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
  1806. // const time_t when, bool *expired)
  1807. ffi!(fn pgp_key_expired(session: *mut Session,
  1808. fpr: *const c_char,
  1809. when: time_t,
  1810. expiredp: *mut bool)
  1811. -> Result<()>
  1812. {
  1813. let session = Session::as_mut(session);
  1814. if fpr.is_null() {
  1815. return Err(Error::IllegalValue(
  1816. "fpr may not be NULL".into()));
  1817. }
  1818. let fpr = unsafe { &CStr::from_ptr(fpr) };
  1819. let fpr = wrap_err!(
  1820. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  1821. UnknownError,
  1822. "Not a fingerprint")?;
  1823. if when < 0 {
  1824. // when is before UNIX EPOCH. The key was not alive at
  1825. // this time (the first keys were create around 1990).
  1826. unsafe { expiredp.as_mut() }.map(|p| {
  1827. *p = true;
  1828. });
  1829. return Ok(());
  1830. }
  1831. let when = SystemTime::UNIX_EPOCH + Duration::new(when as u64, 0);
  1832. let (cert, _private) = session.keystore().cert_find(fpr.clone(), false)?;
  1833. let vc = wrap_err!(
  1834. cert.with_policy(crate::P, when),
  1835. UnknownError,
  1836. "Invalid certificate")?;
  1837. let expired = _pgp_key_expired(&vc);
  1838. unsafe { expiredp.as_mut() }.map(|p| {
  1839. *p = expired;
  1840. });
  1841. t!("{} is {}expired as of {:?}",
  1842. fpr,
  1843. if expired { "" } else { "not " },
  1844. when);
  1845. Ok(())
  1846. });
  1847. fn _pgp_key_revoked(vc: &ValidCert) -> bool
  1848. {
  1849. if let RevocationStatus::Revoked(_) = vc.revocation_status() {
  1850. return true;
  1851. }
  1852. // Ok, at this point, we need to know if for signing or encryption
  1853. // there is ONLY a revoked key available. If so, this key is also
  1854. // considered revoked
  1855. let mut has_non_revoked_sig_key = false;
  1856. let mut has_revoked_sig_key = false;
  1857. for ka in vc.keys().for_signing() {
  1858. if let RevocationStatus::Revoked(_) = ka.revocation_status() {
  1859. has_revoked_sig_key = true;
  1860. } else {
  1861. has_non_revoked_sig_key = true;
  1862. break;
  1863. }
  1864. }
  1865. if has_non_revoked_sig_key {
  1866. let mut has_non_revoked_enc_key = false;
  1867. let mut has_revoked_enc_key = false;
  1868. for ka in vc.keys().for_storage_encryption().for_transport_encryption() {
  1869. if let RevocationStatus::Revoked(_) = ka.revocation_status() {
  1870. has_revoked_enc_key = true;
  1871. } else {
  1872. has_non_revoked_enc_key = true;
  1873. break;
  1874. }
  1875. }
  1876. if !has_non_revoked_enc_key { // this does NOT mean revoked. it MAY mean broken.
  1877. if has_revoked_enc_key {
  1878. return true;
  1879. }
  1880. }
  1881. } else if has_revoked_sig_key {
  1882. return true;
  1883. }
  1884. false
  1885. }
  1886. // PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
  1887. ffi!(fn pgp_key_revoked(session: *mut Session,
  1888. fpr: *const c_char,
  1889. revokedp: *mut bool)
  1890. -> Result<()>
  1891. {
  1892. let session = Session::as_mut(session);
  1893. if fpr.is_null() {
  1894. return Err(Error::IllegalValue(
  1895. "fpr may not be NULL".into()));
  1896. }
  1897. let fpr = unsafe { &CStr::from_ptr(fpr) };
  1898. let fpr = wrap_err!(
  1899. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  1900. UnknownError,
  1901. "Not a fingerprint")?;
  1902. let (cert, _private) = session.keystore().cert_find(fpr.clone(), false)?;
  1903. let vc = wrap_err!(
  1904. cert.with_policy(crate::P, None),
  1905. UnknownError,
  1906. "Invalid certificate")?;
  1907. let revoked = _pgp_key_revoked(&vc);
  1908. unsafe { revokedp.as_mut() }.map(|p| {
  1909. *p = revoked;
  1910. });
  1911. t!("{} is {}revoked",
  1912. fpr,
  1913. if revoked { "" } else { "not " });
  1914. Ok(())
  1915. });
  1916. // PEP_STATUS pgp_get_key_rating(
  1917. // PEP_SESSION session, const char *fpr, PEP_comm_type *comm_type)
  1918. // PEP_STATUS pgp_contains_priv_key(PEP_SESSION session, const char *fpr,
  1919. // bool *has_private)
  1920. ffi!(fn pgp_get_key_rating(session: *mut Session, fpr: *const c_char,
  1921. comm_typep: *mut PepCommType)
  1922. -> Result<()>
  1923. {
  1924. let session = Session::as_mut(session);
  1925. if fpr.is_null() {
  1926. return Err(Error::IllegalValue(
  1927. "fpr may not be NULL".into()));
  1928. }
  1929. let fpr = unsafe { CStr::from_ptr(fpr) };
  1930. let fpr = wrap_err!(
  1931. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  1932. UnknownError,
  1933. "Not a fingerprint")?;
  1934. if comm_typep.is_null() {
  1935. return Err(Error::IllegalValue(
  1936. "comm_type may not be NULL".into()));
  1937. }
  1938. let comm_type = |ct| {
  1939. unsafe { comm_typep.as_mut() }.map(|p| {
  1940. *p = ct;
  1941. });
  1942. };
  1943. comm_type(PepCommType::Unknown);
  1944. let (cert, _private) = session.keystore().cert_find(fpr.clone(), false)?;
  1945. let vc = wrap_err!(
  1946. cert.with_policy(crate::P, None),
  1947. UnknownError,
  1948. "Invalid certificate")?;
  1949. comm_type(PepCommType::OpenPgpUnconfirmed);
  1950. if let RevocationStatus::Revoked(_) = vc.revocation_status() {
  1951. comm_type(PepCommType::KeyRevoked);
  1952. return Ok(());
  1953. }
  1954. if _pgp_key_revoked(&vc) {
  1955. comm_type(PepCommType::KeyRevoked);
  1956. return Ok(());
  1957. }
  1958. if _pgp_key_broken(&vc) {
  1959. comm_type(PepCommType::KeyB0rken);
  1960. return Ok(());
  1961. }
  1962. // MUST guarantee the same behaviour.
  1963. if _pgp_key_expired(&vc) {
  1964. comm_type(PepCommType::KeyExpired);
  1965. return Ok(());
  1966. }
  1967. let mut worst_enc = PepCommType::NoEncryption;
  1968. let mut worst_sign = PepCommType::NoEncryption;
  1969. for ka in vc.keys().alive().revoked(false) {
  1970. let curr;
  1971. use openpgp::types::PublicKeyAlgorithm::*;
  1972. match ka.pk_algo() {
  1973. #[allow(deprecated)]
  1974. RSAEncryptSign | RSAEncrypt | RSASign
  1975. | DSA | ElGamalEncrypt | ElGamalEncryptSign =>
  1976. {
  1977. let bits = ka.mpis().bits().unwrap_or(0);
  1978. if bits < 1024 {
  1979. curr = PepCommType::KeyTooShort;
  1980. } else if bits == 1024 {
  1981. curr = PepCommType::OpenPgpWeakUnconfirmed;
  1982. } else {
  1983. curr = PepCommType::OpenPgpUnconfirmed;
  1984. }
  1985. }
  1986. _ => {
  1987. curr = PepCommType::OpenPgpUnconfirmed;
  1988. }
  1989. }
  1990. if ka.for_transport_encryption() || ka.for_storage_encryption() {
  1991. worst_enc = if worst_enc == PepCommType::NoEncryption {
  1992. curr
  1993. } else {
  1994. cmp::min(worst_enc, curr)
  1995. };
  1996. }
  1997. if ka.for_signing() {
  1998. worst_sign = if worst_sign == PepCommType::NoEncryption {
  1999. curr
  2000. } else {
  2001. cmp::min(worst_sign, curr)
  2002. };
  2003. }
  2004. }
  2005. // This may be redundant because of the broken check above; we
  2006. // should revisit later. But because this case was falling under
  2007. // expired because of how that is written, this was probably never
  2008. // hiit here
  2009. t!("worse enc: {:?}, worst sig: {:?}", worst_enc, worst_sign);
  2010. if worst_enc == PepCommType::NoEncryption
  2011. || worst_sign == PepCommType::NoEncryption
  2012. {
  2013. comm_type(PepCommType::KeyB0rken);
  2014. } else {
  2015. comm_type(cmp::min(worst_enc, worst_sign));
  2016. }
  2017. t!("{}'s rating is {:?}",
  2018. fpr, unsafe { comm_typep.as_ref() }.unwrap());
  2019. Ok(())
  2020. });
  2021. // PEP_STATUS pgp_key_created(PEP_SESSION session, const char *fpr, time_t *created)
  2022. ffi!(fn pgp_key_created(session: *mut Session,
  2023. fpr: *const c_char,
  2024. createdp: *mut time_t)
  2025. -> Result<()>
  2026. {
  2027. let session = Session::as_mut(session);
  2028. if fpr.is_null() {
  2029. return Err(Error::IllegalValue(
  2030. "fpr may not be NULL".into()));
  2031. }
  2032. let fpr = unsafe { &CStr::from_ptr(fpr) };
  2033. let fpr = wrap_err!(
  2034. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  2035. UnknownError,
  2036. "Not a fingerprint")?;
  2037. if createdp.is_null() {
  2038. return Err(Error::IllegalValue(
  2039. "createdp may not be NULL".into()));
  2040. }
  2041. let (cert, _private) = session.keystore().cert_find(fpr, false)?;
  2042. let t = wrap_err!(
  2043. cert.primary_key().creation_time().duration_since(UNIX_EPOCH),
  2044. UnknownError,
  2045. "Creation time out of range")?.as_secs();
  2046. unsafe { createdp.as_mut() }.map(|p| {
  2047. *p = t as time_t;
  2048. });
  2049. Ok(())
  2050. });
  2051. // PEP_STATUS pgp_binary(const char **path)
  2052. ffi!(fn pgp_binary(path: *mut *mut c_char) -> Result<()> {
  2053. unsafe { path.as_mut() }.map(|p| *p = ptr::null_mut());
  2054. Ok(())
  2055. });
  2056. // PEP_STATUS pgp_contains_priv_key(PEP_SESSION session, const char *fpr,
  2057. // bool *has_private)
  2058. ffi!(fn pgp_contains_priv_key(session: *mut Session, fpr: *const c_char,
  2059. has_privatep: *mut bool)
  2060. -> Result<()>
  2061. {
  2062. let session = Session::as_mut(session);
  2063. if fpr.is_null() {
  2064. return Err(Error::IllegalValue(
  2065. "fpr may not be NULL".into()));
  2066. }
  2067. let fpr = unsafe { CStr::from_ptr(fpr) };
  2068. let fpr = wrap_err!(
  2069. Fingerprint::from_hex(&String::from_utf8_lossy(fpr.to_bytes())),
  2070. UnknownError,
  2071. "Not a fingerprint")?;
  2072. let has_private = match session.keystore().cert_find(fpr, true) {
  2073. Ok(_) => true,
  2074. Err(Error::KeyNotFound(_)) => false,
  2075. Err(err) => return Err(err),
  2076. };
  2077. unsafe { has_privatep.as_mut() }.map(|p| {
  2078. *p = has_private
  2079. });
  2080. Ok(())
  2081. });