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.

2388 lines
76 KiB

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