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.

2363 lines
75 KiB

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