-
-
Save wiktor-k/124a84513d5f31b50c89e22eda8a7bc1 to your computer and use it in GitHub Desktop.
C++ Wrapper functions for sequoia
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Crypto.hpp | |
////////////////////////////// | |
#include "spdlog/spdlog.h" | |
#include "spdlog/sinks/stdout_color_sinks.h" | |
#include "spdlog/sinks/rotating_file_sink.h" | |
#define SPDLOG_STR_H(x) #x | |
#define SPDLOG_STR_HELPER(x) SPDLOG_STR_H(x) | |
#define DEBUG(...) spdlog::log(spdlog::level::debug, "[" + fmt::format(__FILE__) + "::" + SPDLOG_STR_HELPER(__LINE__) + "::" + std::string(__func__) + "] " + fmt::format(__VA_ARGS__)) | |
#define INFO(...) spdlog::log(spdlog::level::info, "[" + fmt::format(__FILE__) + "::" + SPDLOG_STR_HELPER(__LINE__) + "::" + std::string(__func__) + "] " + fmt::format(__VA_ARGS__)) | |
#define WARN(...) spdlog::log(spdlog::level::warn, "[" + fmt::format(__FILE__) + "::" + SPDLOG_STR_HELPER(__LINE__) + "::" + std::string(__func__) + "] " + fmt::format(__VA_ARGS__)) | |
#define ERROR(...) spdlog::log( spdlog::level::err, "[" + fmt::format(__FILE__) + "::" + SPDLOG_STR_HELPER(__LINE__) + "::" + std::string(__func__) + "] " + fmt::format(__VA_ARGS__)) | |
extern std::string privateKeyString; | |
extern std::string publicKeyString; | |
namespace gpg { | |
void Init(); | |
bool GetFingerprint(char* fingerprint, std::string_view publicKeyStringView, bool checkLiving=false); | |
bool ValidateKey(char* fingerprint, std::string_view publicKeyStringView); | |
bool Verify(std::string_view publicKey, std::string_view signature, std::string_view data); | |
bool Sign(std::string& signature, std::string_view inpustString); | |
bool Encrypt(std::string_view publicKeyStringView, std::string_view inputString, std::string& encryptedData); | |
bool Decrypt(std::string& decryptedData, std::string_view inputString); | |
} | |
///////////////////////////////////////////////////////////////////////////////////// | |
// Crypto.cpp | |
// this file handles the gpg and cryptography functions | |
#include "Crypto.hpp" | |
#if defined (__cplusplus) | |
extern "C" { | |
#endif | |
#include <sequoia/openpgp.h> | |
#if defined (__cplusplus) | |
} | |
#endif | |
std::string privateKeyString = ""; | |
std::string publicKeyString = ""; | |
namespace gpg{ | |
pgp_cert_t publicKey; | |
pgp_cert_t privateKey; | |
void Init(){ | |
pgp_error_t err = NULL; | |
publicKey = pgp_cert_from_bytes(&err, (const uint8_t*)publicKeyString.data(), (size_t)publicKeyString.length()); | |
if(err){ | |
ERROR("problem getting cert from bytes: {}", pgp_error_to_string(err)); | |
exit(1); | |
} | |
err = NULL; | |
privateKey = pgp_cert_from_bytes(&err, (const uint8_t*)privateKeyString.data(), (size_t)privateKeyString.length()); | |
if(err){ | |
ERROR("problem getting cert from bytes: {}", pgp_error_to_string(err)); | |
exit(1); | |
} | |
} | |
bool GetFingerprint(char* fingerprintHex, std::string_view publicKeyStringView, bool checkLiving){ | |
pgp_error_t err = NULL; | |
pgp_cert_t cert = pgp_cert_from_bytes(&err, (const uint8_t*)publicKeyStringView.data(), (size_t)publicKeyStringView.length()); | |
if (!cert){ | |
pgp_error_free(err); | |
return false; | |
} | |
//if (checkLiving){ | |
// std::string certString = pgp_cert_to_string(cert); | |
// DEBUG("cert string:\n{}", certString); | |
// pgp_cert_valid_key_iter_next(iter_signer, NULL, NULL); | |
//} | |
pgp_fingerprint_t fingerprint = pgp_cert_fingerprint(cert); | |
if (!fingerprint){ | |
pgp_cert_free(cert); | |
pgp_error_free(err); | |
return false; | |
} | |
fingerprintHex = pgp_fingerprint_to_hex(fingerprint); | |
DEBUG("finerpring hex{}", fingerprintHex); | |
pgp_fingerprint_free(fingerprint); | |
pgp_cert_free(cert); | |
pgp_error_free(err); | |
return true; | |
} | |
bool Sign(std::string& signature, std::string_view inputString){ | |
//INFO("SIGNING"); | |
pgp_error_t err = NULL; | |
pgp_policy_t policy = pgp_standard_policy(); | |
//signing iterator | |
pgp_cert_valid_key_iter_t iter_signer = pgp_cert_valid_key_iter(privateKey, policy, 0); | |
if(!iter_signer){ | |
ERROR("unable to get signer iterator"); | |
pgp_policy_free(policy); | |
return false; | |
} | |
pgp_cert_valid_key_iter_for_certification(iter_signer); | |
if(!iter_signer){ | |
ERROR("unable to get signer iterator for certification"); | |
pgp_policy_free(policy); | |
return false; | |
} | |
pgp_cert_valid_key_iter_for_signing(iter_signer); | |
if(!iter_signer){ | |
ERROR("unable to get signer iterator for signing"); | |
pgp_policy_free(policy); | |
return false; | |
} | |
pgp_key_t key = pgp_cert_valid_key_iter_next(iter_signer, NULL, NULL); | |
if(!key){ | |
ERROR("unable to get key from iter_signer"); | |
pgp_cert_valid_key_iter_free(iter_signer); | |
pgp_policy_free(policy); | |
return false; | |
} | |
pgp_key_pair_t signing_key_pair = pgp_key_into_key_pair(&err, pgp_key_clone(key)); | |
if (err){ | |
ERROR("unable to get signing keypair, {}", pgp_error_to_string(err)); | |
pgp_error_free(err); | |
pgp_cert_valid_key_iter_free(iter_signer); | |
pgp_policy_free(policy); | |
return false; | |
} | |
pgp_signer_t signer = pgp_key_pair_as_signer(signing_key_pair); | |
pgp_writer_t writer = pgp_writer_from_bytes((uint8_t*)signature.data(), signature.capacity()); | |
writer = pgp_armor_writer_new(&err, writer, PGP_ARMOR_KIND_SIGNATURE, | |
NULL, 0); | |
if (err){ | |
ERROR("unable to create writer, {}", pgp_error_to_string(err)); | |
pgp_error_free(err); | |
pgp_cert_valid_key_iter_free(iter_signer); | |
pgp_policy_free(policy); | |
return false; | |
} | |
// pgp_armor_writer_finalize | |
pgp_writer_stack_t writer_stack = pgp_writer_stack_message(writer); | |
writer_stack = pgp_signer_new_detached(&err, writer_stack, | |
&signer, 1, 0); | |
if (err){ | |
ERROR("unable to create writer, {}", pgp_error_to_string(err)); | |
pgp_error_free(err); | |
pgp_cert_valid_key_iter_free(iter_signer); | |
pgp_policy_free(policy); | |
return false; | |
} | |
pgp_status_t write_status = | |
pgp_writer_stack_write_all(&err, writer_stack, | |
(uint8_t*)inputString.data(), (size_t)inputString.length()); | |
if (write_status || err){ | |
ERROR("pgp_writer_stack_write: {}", pgp_error_to_string (err)); | |
pgp_error_free(err); | |
pgp_cert_valid_key_iter_free(iter_signer); | |
pgp_policy_free(policy); | |
return false; | |
} | |
pgp_writer_stack_finalize(&err, writer_stack); | |
if (err){ | |
ERROR("unable to finalize writer, {}", pgp_error_to_string(err)); | |
ERROR("response string, {}", signature); | |
pgp_error_free(err); | |
pgp_cert_valid_key_iter_free(iter_signer); | |
pgp_policy_free(policy); | |
return false; | |
} | |
//INFO("FINISHED SIGNING"); | |
return true; | |
} | |
bool Encrypt(std::string_view publicKeyStringView, std::string_view inputString, std::string& encryptedData){ | |
//INFO("ENCRYPTING"); | |
pgp_status_t rc; | |
pgp_error_t err; | |
pgp_cert_t cert; | |
pgp_writer_t writer; | |
pgp_writer_stack_t writer_stack = NULL; | |
pgp_policy_t policy = pgp_standard_policy (); | |
//cert = pgp_cert_from_file (&err, argv[1]); | |
cert = pgp_cert_from_bytes(&err, (const uint8_t*)publicKeyStringView.data(), (size_t)publicKeyStringView.length()); | |
if (!cert){ | |
ERROR("pgp_cert_from_bytes, {}", pgp_error_to_string(err)); | |
pgp_error_free(err); | |
pgp_policy_free(policy); | |
return false; | |
} | |
pgp_cert_valid_key_iter_t iter = pgp_cert_valid_key_iter (cert, policy, 0); | |
if (!iter){ | |
ERROR("no iter from cert and policy"); | |
pgp_cert_free(cert); | |
pgp_policy_free(policy); | |
return false; | |
} | |
//DEBUG("recipient cert: \n{}", pgp_cert_debug(cert)); | |
pgp_cert_valid_key_iter_alive (iter); | |
pgp_cert_valid_key_iter_revoked (iter, false); | |
pgp_cert_valid_key_iter_for_storage_encryption (iter); | |
pgp_cert_valid_key_iter_for_transport_encryption (iter); | |
size_t recipients_len; | |
pgp_recipient_t *recipients = | |
pgp_recipients_from_valid_key_iter (iter, &recipients_len); | |
//DEBUG("recipient length: {}", recipients_len); | |
writer = pgp_writer_from_bytes((uint8_t *)encryptedData.data(), (size_t)encryptedData.capacity()); | |
writer = pgp_armor_writer_new (&err, writer, PGP_ARMOR_KIND_MESSAGE, | |
NULL, 0); | |
writer_stack = pgp_writer_stack_message (writer); | |
writer_stack = pgp_encryptor_new (&err, | |
writer_stack, | |
NULL, 0, /* no passwords */ | |
recipients, recipients_len, | |
9 /* AES256 */, | |
0 /* No AEAD */); | |
//INFO("written"); | |
if (writer_stack == NULL){ | |
ERROR("pgp_encryptor_new: {}", pgp_error_to_string (err)); | |
pgp_error_free(err); | |
pgp_cert_free(cert); | |
pgp_cert_valid_key_iter_free(iter); | |
pgp_policy_free(policy); | |
return false; | |
} | |
writer_stack = pgp_literal_writer_new (&err, writer_stack); | |
ssize_t written; | |
//DEBUG("inputString crypto\n{}", inputString); | |
written = pgp_writer_stack_write_all(&err, writer_stack, (uint8_t*)inputString.data(), (size_t)inputString.length()); | |
if (written < 0){ | |
ERROR("pgp_writer_stack_write: {}", pgp_error_to_string (err)); | |
pgp_error_free(err); | |
pgp_cert_free(cert); | |
pgp_cert_valid_key_iter_free(iter); | |
pgp_policy_free(policy); | |
return false; | |
} | |
//DEBUG("encryptedData crypto\n{}", encryptedData); | |
rc = pgp_writer_stack_finalize (&err, writer_stack); | |
writer_stack = NULL; | |
encryptedData.resize(strlen(encryptedData.c_str())); | |
if (rc){ | |
ERROR("pgp_writer_stack_write: {}", pgp_error_to_string (err)); | |
pgp_error_free(err); | |
pgp_cert_free(cert); | |
pgp_cert_valid_key_iter_free(iter); | |
pgp_policy_free(policy); | |
return false; | |
} | |
//for (size_t i = 0; i < recipients_len; i++) | |
// pgp_recipient_free (recipients[i]); | |
free (recipients); | |
pgp_cert_free (cert); | |
pgp_policy_free (policy); | |
//INFO("FINISHED ENCRYPTING"); | |
return true; | |
} | |
struct decrypt_cookie { | |
pgp_cert_t key; | |
int decrypt_called; | |
}; | |
static pgp_status_t | |
decrypt_get_public_keys_cb (void *cookie_raw, | |
pgp_keyid_t *keyids, size_t keyids_len, | |
pgp_cert_t **certs, size_t *cert_len, | |
void (**our_free)(void *)) | |
{ | |
/* Feed the Certs to the verifier here. */ | |
*certs = NULL; | |
*cert_len = 0; | |
*our_free = free; | |
return PGP_STATUS_SUCCESS; | |
} | |
static pgp_status_t | |
decrypt_check_cb (void *cookie_opaque, pgp_message_structure_t structure) | |
{ | |
pgp_message_structure_iter_t iter = pgp_message_structure_iter (structure); | |
for (pgp_message_layer_t layer = pgp_message_structure_iter_next (iter); | |
layer; | |
layer = pgp_message_structure_iter_next (iter)) { | |
uint8_t algo; | |
uint8_t aead_algo; | |
pgp_verification_result_iter_t results; | |
switch (pgp_message_layer_variant (layer)) { | |
case PGP_MESSAGE_LAYER_COMPRESSION: | |
pgp_message_layer_compression (layer, &algo); | |
//fprintf (stderr, "Compressed using %d\n", algo); | |
break; | |
case PGP_MESSAGE_LAYER_ENCRYPTION: | |
pgp_message_layer_encryption (layer, &algo, &aead_algo); | |
if (aead_algo) { | |
//fprintf (stderr, "Encrypted and protected using %d/%d\n", | |
// algo, aead_algo); | |
} else { | |
//fprintf (stderr, "Encrypted using %d\n", algo); | |
} | |
break; | |
case PGP_MESSAGE_LAYER_SIGNATURE_GROUP: | |
pgp_message_layer_signature_group (layer, &results); | |
for (pgp_verification_result_t result = | |
pgp_verification_result_iter_next (results); | |
result; | |
result = pgp_verification_result_iter_next (results)) { | |
pgp_signature_t sig = NULL; | |
pgp_key_t key = NULL; | |
pgp_keyid_t keyid; | |
char *keyid_str = NULL; | |
switch (pgp_verification_result_variant (result)) { | |
case PGP_VERIFICATION_RESULT_GOOD_CHECKSUM: | |
pgp_verification_result_good_checksum (result, NULL, NULL, | |
&key, NULL, NULL); | |
keyid = pgp_key_keyid (key); | |
keyid_str = pgp_keyid_to_string (keyid); | |
//fprintf (stderr, "Good signature from %s\n", keyid_str); | |
break; | |
case PGP_VERIFICATION_RESULT_NOT_ALIVE: | |
pgp_verification_result_not_alive (result, NULL, NULL, | |
&key, NULL, NULL); | |
keyid = pgp_key_keyid (key); | |
keyid_str = pgp_keyid_to_string (keyid); | |
//fprintf (stderr, "Good checksum, but not alive signature from %s\n", | |
// keyid_str); | |
break; | |
case PGP_VERIFICATION_RESULT_MISSING_KEY: | |
pgp_verification_result_missing_key (result, &sig); | |
keyid = pgp_signature_issuer (sig); | |
keyid_str = pgp_keyid_to_string (keyid); | |
//fprintf (stderr, "No key to check signature from %s\n", keyid_str); | |
break; | |
case PGP_VERIFICATION_RESULT_ERROR: { | |
pgp_error_t err; | |
pgp_verification_result_error (result, NULL, &err); | |
char *err_str = pgp_error_to_string (err); | |
//fprintf (stderr, "Bad signature: %s\n", err_str); | |
free (err_str); | |
pgp_error_free (err); | |
break; | |
} | |
default: | |
assert (! "reachable"); | |
} | |
free (keyid_str); | |
pgp_signature_free (sig); | |
pgp_key_free (key); | |
pgp_verification_result_free (result); | |
} | |
pgp_verification_result_iter_free (results); | |
break; | |
default: | |
assert (! "reachable"); | |
} | |
pgp_message_layer_free (layer); | |
} | |
pgp_message_structure_iter_free (iter); | |
pgp_message_structure_free (structure); | |
/* Implement your verification policy here. */ | |
return PGP_STATUS_SUCCESS; | |
} | |
static pgp_status_t | |
decrypt_cb (void *cookie_opaque, | |
pgp_pkesk_t *pkesks, size_t pkesk_count, | |
pgp_skesk_t *skesks, size_t skesk_count, | |
uint8_t sym_algo_hint, | |
pgp_decryptor_do_decrypt_cb_t *decrypt, | |
void *decrypt_cookie, | |
pgp_fingerprint_t *identity_out) | |
{ | |
pgp_status_t rc; | |
pgp_error_t err; | |
struct decrypt_cookie *cookie = (struct decrypt_cookie*)cookie_opaque; | |
/* Prevent iterations, we only have one key to offer. */ | |
(!cookie->decrypt_called); | |
cookie->decrypt_called = 1; | |
for (int i = 0; i < pkesk_count; i++) { | |
pgp_pkesk_t pkesk = pkesks[i]; | |
pgp_keyid_t keyid = pgp_pkesk_recipient (pkesk); | |
pgp_cert_key_iter_t key_iter = pgp_cert_key_iter (cookie->key); | |
pgp_key_t key; | |
while ((key = pgp_cert_key_iter_next (key_iter))) { | |
pgp_keyid_t this_keyid = pgp_key_keyid (key); | |
int match = pgp_keyid_equal (this_keyid, keyid); | |
pgp_keyid_free (this_keyid); | |
if (match) | |
break; | |
pgp_key_free (key); | |
} | |
pgp_cert_key_iter_free (key_iter); | |
pgp_keyid_free (keyid); | |
if (! key) | |
continue; | |
uint8_t algo; | |
uint8_t session_key[1024]; | |
size_t session_key_len = sizeof session_key; | |
if (pgp_pkesk_decrypt (&err, | |
pkesk, key, &algo, | |
session_key, &session_key_len)) { | |
ERROR("Error - pgp_pkesk_decrypt: {}", pgp_error_to_string (err)); | |
} | |
pgp_key_free (key); | |
pgp_session_key_t sk = pgp_session_key_from_bytes (session_key, | |
session_key_len); | |
rc = decrypt (decrypt_cookie, algo, sk); | |
pgp_session_key_free (sk); | |
*identity_out = pgp_cert_fingerprint (cookie->key); | |
return rc; | |
} | |
return PGP_STATUS_UNKNOWN_ERROR; | |
} | |
bool Decrypt(std::string& decryptedData, std::string_view inputString){ | |
pgp_error_t err; | |
pgp_cert_t cert; | |
pgp_reader_t source; | |
pgp_reader_t plaintext; | |
ssize_t nread; | |
pgp_policy_t policy = pgp_standard_policy (); | |
///cert = pgp_cert_from_bytes (&err, argv[1]); | |
//publicKey = pgp_cert_from_bytes(&err, (const uint8_t*)publicKeyString.data(), (size_t)publicKeyString.length()); | |
//privateKey = pgp_cert_from_bytes(&err, (const uint8_t*)privateKeyString.data(), (size_t)privateKeyString.length()); | |
if (privateKey == NULL){ | |
ERROR("publicKey is null:"); | |
pgp_policy_free(policy); | |
return false; | |
} | |
source = pgp_reader_from_bytes ((const uint8_t*)inputString.data(), inputString.length()); | |
if (!source){ | |
ERROR("Could not create reader from bytes"); | |
pgp_policy_free(policy); | |
return false; | |
} | |
struct decrypt_cookie cookie = { | |
.key = privateKey, | |
.decrypt_called = 0, | |
}; | |
plaintext = pgp_decryptor_new (&err, policy, source, | |
decrypt_get_public_keys_cb, decrypt_cb, | |
decrypt_check_cb, NULL, &cookie, 0); | |
if (!plaintext){ | |
ERROR("pgp_decryptor_new: {}", pgp_error_to_string (err)); | |
pgp_reader_free(source); | |
pgp_policy_free(policy); | |
return false; | |
} | |
unsigned int offset = 0; | |
nread = pgp_reader_read(&err, plaintext, (uint8_t*)decryptedData.data(), decryptedData.capacity()); | |
if (nread < 0){ | |
ERROR("bad read to decrypted data: {}, pgp_reader_read: {}", pgp_error_to_string (err)); | |
pgp_reader_free(source); | |
pgp_policy_free(policy); | |
pgp_reader_free (plaintext); | |
return false; | |
} | |
decryptedData.resize(nread); | |
pgp_reader_free (plaintext); | |
pgp_reader_free (source); | |
pgp_policy_free (policy); | |
return true; | |
} | |
struct verify_cookie { | |
pgp_cert_t public_key; | |
bool get_secret_keys_called; | |
bool good_checksum; | |
bool good_but_expired; | |
bool not_alive; | |
bool good_but_revoked; | |
bool missing_keys; | |
bool bad_checksums; | |
}; | |
static pgp_status_t | |
verify_get_public_keys_cb (void *cookie_opaque, | |
pgp_keyid_t *keyids, size_t keyids_len, | |
pgp_cert_t **certs, size_t *certs_len, | |
void (**our_free)(void *)) | |
{ | |
/* Feed the Certs to the verifier here. */ | |
struct verify_cookie *cookie = (struct verify_cookie*)cookie_opaque; | |
*certs = (pgp_cert_t*)malloc(sizeof(pgp_cert_t)); | |
//assert (*certs); | |
if (!*certs) | |
return PGP_STATUS_UNKNOWN_ERROR; | |
*certs[0] = cookie->public_key; | |
*certs_len = 1; | |
*our_free = free; | |
return PGP_STATUS_SUCCESS; | |
} | |
static pgp_status_t | |
verify_check_cb (void *cookie_opaque, pgp_message_structure_t structure) | |
{ | |
struct verify_cookie *cookie = (struct verify_cookie*)cookie_opaque; | |
pgp_message_structure_iter_t iter = pgp_message_structure_iter (structure); | |
pgp_message_layer_t layer = pgp_message_structure_iter_next (iter); | |
if (!layer){ | |
pgp_message_structure_iter_free (iter); | |
pgp_message_structure_free (structure); | |
return PGP_STATUS_SUCCESS; | |
} | |
pgp_verification_result_iter_t results; | |
if (pgp_message_layer_signature_group (layer, &results)) { | |
pgp_verification_result_t result = pgp_verification_result_iter_next (results); | |
if (!result){ | |
pgp_verification_result_iter_free (results); | |
pgp_message_layer_free (layer); | |
pgp_message_structure_iter_free (iter); | |
pgp_message_structure_free (structure); | |
return PGP_STATUS_SUCCESS; | |
} | |
switch (pgp_verification_result_variant (result)) { | |
case PGP_VERIFICATION_RESULT_GOOD_CHECKSUM: | |
cookie->good_checksum = true; | |
break; | |
case PGP_VERIFICATION_RESULT_NOT_ALIVE: | |
cookie->not_alive = true; | |
break; | |
case PGP_VERIFICATION_RESULT_MISSING_KEY: | |
cookie->missing_keys = true; | |
break; | |
case PGP_VERIFICATION_RESULT_ERROR: | |
cookie->bad_checksums = true; | |
break; | |
default: | |
assert (! "reachable"); | |
} | |
pgp_verification_result_free (result); | |
} else { | |
assert (! "reachable"); | |
} | |
pgp_verification_result_iter_free (results); | |
pgp_message_layer_free (layer); | |
pgp_message_structure_iter_free (iter); | |
pgp_message_structure_free (structure); | |
return PGP_STATUS_SUCCESS; | |
} | |
bool Verify(std::string_view publicKeyStringView, std::string_view signatureStringView, std::string_view sourceStringView){ | |
pgp_error_t err; | |
pgp_reader_t signature; | |
pgp_reader_t source; | |
pgp_reader_t verifier; | |
pgp_policy_t policy = pgp_standard_policy (); | |
//publicKey = pgp_cert_from_bytes(&err, (const uint8_t*)publicKeyStringView.data(), (size_t)publicKeyStringView.length()); | |
if (!publicKey){ | |
ERROR("Could not create publicKey from bytes"); | |
pgp_policy_free(policy); | |
return false; | |
} | |
signature = pgp_reader_from_bytes((const uint8_t*)signatureStringView.data(), (size_t)signatureStringView.length()); | |
if (!signature){ | |
ERROR("Could not create signature from bytes"); | |
pgp_policy_free(policy); | |
return false; | |
} | |
source = pgp_reader_from_bytes((const uint8_t*)sourceStringView.data(), (size_t)sourceStringView.length()); | |
if (!source){ | |
ERROR("Could not create source from bytes"); | |
pgp_reader_free(signature); | |
pgp_policy_free(policy); | |
return false; | |
} | |
struct verify_cookie cookie { | |
.public_key = pgp_cert_from_bytes(&err, (const uint8_t*)publicKeyStringView.data(), (size_t)publicKeyStringView.length()), | |
.get_secret_keys_called = false, | |
.good_checksum = false, | |
.good_but_expired = false, | |
.not_alive = false, | |
.good_but_revoked = false, | |
.missing_keys = false, | |
.bad_checksums = false | |
}; | |
verifier = pgp_detached_verifier_new (NULL, policy, signature, source, | |
verify_get_public_keys_cb, verify_check_cb, | |
&cookie, 0); | |
if (!verifier){ | |
ERROR("Could not create detached verifier"); | |
pgp_policy_free(policy); | |
pgp_reader_free(signature); | |
pgp_reader_free(source); | |
return false; | |
} | |
pgp_reader_free (verifier); | |
pgp_reader_free (source); | |
pgp_reader_free (signature); | |
pgp_policy_free (policy); | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment