1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! KeyIDs.
//!
//! A KeyID is a fingerprint fragment.  It identifies a public key,
//! but is easy to forge.  For more details about how a KeyID is
//! generated, see [Section 12.2 of RFC 4880].
//!
//!   [Section 12.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-12.2
//!
//! Wraps [`sequoia-openpgp::KeyID`].
//!
//! [`sequoia-openpgp::KeyID`]: sequoia_openpgp::KeyID

use std::slice;
use libc::{c_char};

use sequoia_openpgp as openpgp;

use crate::Maybe;
use crate::RefRaw;
use crate::MoveIntoRaw;

/// Holds a KeyID.
///
/// A KeyID is a fingerprint fragment.  It identifies a public key,
/// but is easy to forge.  For more details about how a KeyID is
/// generated, see [Section 12.2 of RFC 4880].
///
///   [Section 12.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-12.2
///
/// Wraps [`sequoia-openpgp::KeyID`].
///
/// [`sequoia-openpgp::KeyID`]: sequoia_openpgp::KeyID
#[crate::ffi_wrapper_type(prefix = "pgp_", name = "keyid",
                     derive = "Clone, Debug, Display, Hash, PartialEq")]
pub struct KeyID(openpgp::KeyID);

/// Reads a binary key ID.
///
/// # Examples
///
/// ```c
/// #include <assert.h>
/// #include <stdlib.h>
/// #include <string.h>
/// #include <sequoia/openpgp.h>
///
/// pgp_keyid_t mr_b =
///     pgp_keyid_from_bytes ((uint8_t *) "\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb");
///
/// char *mr_b_as_string = pgp_keyid_to_string (mr_b);
/// assert (strcmp (mr_b_as_string, "BBBBBBBBBBBBBBBB") == 0);
///
/// pgp_keyid_free (mr_b);
/// free (mr_b_as_string);
/// ```
#[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C"
fn pgp_keyid_from_bytes(id: *const u8) -> *mut KeyID {
    assert!(!id.is_null());
    let id = unsafe { slice::from_raw_parts(id, 8) };
    openpgp::KeyID::from_bytes(id).move_into_raw()
}

/// Reads a hex-encoded Key ID.
///
/// # Examples
///
/// ```c
/// #include <assert.h>
/// #include <stdlib.h>
/// #include <string.h>
/// #include <sequoia/openpgp.h>
///
/// pgp_keyid_t mr_b = pgp_keyid_from_hex ("bbbbbbbbbbbbbbbb");
///
/// char *mr_b_as_string = pgp_keyid_to_string (mr_b);
/// assert (strcmp (mr_b_as_string, "BBBBBBBBBBBBBBBB") == 0);
///
/// free (mr_b_as_string);
/// pgp_keyid_free (mr_b);
/// ```
#[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C"
fn pgp_keyid_from_hex(id: *const c_char) -> Maybe<KeyID> {
    let id = ffi_param_cstr!(id).to_string_lossy();
    id.parse::<openpgp::KeyID>().ok().move_into_raw()
}

/// Converts the KeyID to a hexadecimal number.
#[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C"
fn pgp_keyid_to_hex(id: *const KeyID) -> *mut c_char {
    ffi_return_string!(format!("{:X}", id.ref_raw()))
}