summaryrefslogtreecommitdiffstats
path: root/openpgp-ffi/src/packet/key.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp-ffi/src/packet/key.rs')
-rw-r--r--openpgp-ffi/src/packet/key.rs159
1 files changed, 159 insertions, 0 deletions
diff --git a/openpgp-ffi/src/packet/key.rs b/openpgp-ffi/src/packet/key.rs
new file mode 100644
index 00000000..07f32753
--- /dev/null
+++ b/openpgp-ffi/src/packet/key.rs
@@ -0,0 +1,159 @@
+//! Public key, public subkey, private key and private subkey packets.
+//!
+//! See [Section 5.5 of RFC 4880] for details.
+//!
+//! [Section 5.5 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.5
+
+use libc::{c_int, time_t};
+
+extern crate sequoia_openpgp as openpgp;
+use self::openpgp::{
+ Fingerprint,
+ KeyID,
+ packet,
+};
+
+/// Clones the key.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_clone(key: *const packet::Key)
+ -> *mut packet::Key {
+ let key = ffi_param_ref!(key);
+ box_raw!(key.clone())
+}
+
+/// Computes and returns the key's fingerprint as per Section 12.2
+/// of RFC 4880.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_fingerprint(key: *const packet::Key)
+ -> *mut Fingerprint {
+ let key = ffi_param_ref!(key);
+ box_raw!(key.fingerprint())
+}
+
+/// Computes and returns the key's key ID as per Section 12.2 of RFC
+/// 4880.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_keyid(key: *const packet::Key)
+ -> *mut KeyID {
+ let key = ffi_param_ref!(key);
+ box_raw!(key.keyid())
+}
+
+/// Returns whether the key is expired according to the provided
+/// self-signature.
+///
+/// Note: this is with respect to the provided signature, which is not
+/// checked for validity. That is, we do not check whether the
+/// signature is a valid self-signature for the given key.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_expired(key: *const packet::Key,
+ sig: *const packet::Signature)
+ -> bool
+{
+ let key = ffi_param_ref!(key);
+ let sig = ffi_param_ref!(sig);
+
+ sig.key_expired(key)
+}
+
+/// Like pgp_key_expired, but at a specific time.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_expired_at(key: *const packet::Key,
+ sig: *const packet::Signature,
+ when: time_t)
+ -> bool
+{
+ let key = ffi_param_ref!(key);
+ let sig = ffi_param_ref!(sig);
+
+ sig.key_expired_at(key, time::at(time::Timespec::new(when as i64, 0)))
+}
+
+/// Returns whether the key is alive according to the provided
+/// self-signature.
+///
+/// A key is alive if the creation date is in the past, and the key
+/// has not expired.
+///
+/// Note: this is with respect to the provided signature, which is not
+/// checked for validity. That is, we do not check whether the
+/// signature is a valid self-signature for the given key.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_alive(key: *const packet::Key,
+ sig: *const packet::Signature)
+ -> bool
+{
+ let key = ffi_param_ref!(key);
+ let sig = ffi_param_ref!(sig);
+
+ sig.key_alive(key)
+}
+
+/// Like pgp_key_alive, but at a specific time.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_alive_at(key: *const packet::Key,
+ sig: *const packet::Signature,
+ when: time_t)
+ -> bool
+{
+ let key = ffi_param_ref!(key);
+ let sig = ffi_param_ref!(sig);
+
+ sig.key_alive_at(key, time::at(time::Timespec::new(when as i64, 0)))
+}
+
+/// Returns the key's creation time.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_creation_time(key: *const packet::Key)
+ -> u32
+{
+ let key = ffi_param_ref!(key);
+ let ct = key.creation_time();
+
+ ct.to_timespec().sec as u32
+}
+
+/// Returns the key's public key algorithm.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_public_key_algo(key: *const packet::Key)
+ -> c_int
+{
+ let key = ffi_param_ref!(key);
+ let pk_algo : u8 = key.pk_algo().into();
+ pk_algo as c_int
+}
+
+/// Returns the public key's size in bits.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_public_key_bits(key: *const packet::Key)
+ -> c_int
+{
+ use self::openpgp::crypto::mpis::PublicKey::*;
+
+ let key = ffi_param_ref!(key);
+ match key.mpis() {
+ RSA { e: _, n } => n.bits as c_int,
+ DSA { p: _, q: _, g: _, y } => y.bits as c_int,
+ Elgamal { p: _, g: _, y } => y.bits as c_int,
+ EdDSA { curve: _, q } => q.bits as c_int,
+ ECDSA { curve: _, q } => q.bits as c_int,
+ ECDH { curve: _, q, hash: _, sym: _ } => q.bits as c_int,
+ Unknown { mpis: _, rest: _ } => 0,
+ }
+}
+
+/// Creates a new key pair from a Key packet with an unencrypted
+/// secret key.
+///
+/// # Errors
+///
+/// Fails if the secret key is missing, or encrypted.
+#[::ffi_catch_abort] #[no_mangle]
+pub extern "system" fn pgp_key_into_key_pair(errp: Option<&mut *mut failure::Error>,
+ key: *mut packet::Key)
+ -> *mut self::openpgp::crypto::KeyPair
+{
+ ffi_make_fry_from_errp!(errp);
+ let key = ffi_param_move!(key);
+ ffi_try_box!(key.into_keypair())
+}