Skip to content

Instantly share code, notes, and snippets.

@anidean
Last active June 10, 2020 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anidean/dc3b4dd75ae6259cfb317c2918950ca0 to your computer and use it in GitHub Desktop.
Save anidean/dc3b4dd75ae6259cfb317c2918950ca0 to your computer and use it in GitHub Desktop.
C++ Wrapper functions for Sequoia PGP
// this file handles the gpg and cryptography functions
// 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__))
#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 ImportAsync(PostBlob* postBlob, const std::string& newKey, void(&callBack)(PostBlob*)) {
//postBlob->err = gpgme_data_new_from_mem(&postBlob->data, newKey.c_str(), newKey.length(), 1);
//if (postBlob->err) return false;
//postBlob->loop->defer([postBlob, &callBack](){
// ImportAsyncHandler(postBlob, callBack);
//});
return true;
}
void ImportAsyncHandler(PostBlob* postBlob, void (&callBack)(PostBlob*)) {
//DEBUG("in asyncwaiter, status == {}", postBlob->err);
/* if (postBlob->err == 0){
DEBUG("deferring ImportAsyncHandler from ImportAsyncHandler");
postBlob->loop->defer([postBlob, &callBack](){
ImportAsyncHandler(postBlob, callBack);
});
return;
}*/
//gpgme_import_result_t importResult = gpgme_op_import_result(postBlob->ctx);
//postBlob->gpgResults[postBlob->outputIndex] = importResult->imports->fpr ? importResult->imports->fpr : ""; // fingerprint
//std::unique_ptr<std::string> fingerprint = std::make_unique<std::string>(importResult->imports->fpr? importResult->imports->fpr:"");
//gpgme_data_release(postBlob->data);
callBack(postBlob);
}
void Fingerprint2Hex1(uint8_t* bin, size_t binsz, unsigned char** fingerprintHex, uint8_t offset){
INFO("doing fingerprint to hex");
unsigned char hex_str[]= "0123456789ABCDEF";
// if (!(*result = (unsigned char *)malloc(binsz * 2 + 1)))
// return (NULL);
//(*result)[binsz * 2] = 0;
//if (!binsz)
// return (NULL);
DEBUG("binsz = {}", binsz);
//for (uint8_t i = offset; i < binsz; ++i){
// fingerprintHex[offset + i * 2 + 0] = hex_str[(bin[i] >> 4) & 0x0F];
// fingerprintHex[offset + i * 2 + 1] = hex_str[(bin[i]) & 0x0F];
//}
//return (*fingerprintHex);
}
void Fingerprint2Hex(uint8_t *bin, int n, char *fingerprintHex, uint8_t offset){
//uint8 buf[] = {0, 1, 10, 11};
//int n = sizeof buf << 1;
//char hexstr[n + 1];
//btox(hexstr, buf, n);
//hexstr[n] = 0; /* Terminate! */
// printf("%s\n", hexstr);
const char xx[]= "0123456789ABCDEF";
while (--n >= 0) fingerprintHex[n+offset] = xx[(bin[n>>1] >> ((1 - (n&1)) << 2)) & 0xF];
}
bool GetFingerprint(char* fingerprintHex, std::string_view publicKeyStringView, bool* isAlive, bool checkLiving, bool inArray, uint8_t offset){
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;
}
pgp_fingerprint_t fingerprint = pgp_cert_fingerprint(cert);
if (!fingerprint){
pgp_cert_free(cert);
pgp_error_free(err);
return false;
}
if (inArray){
//size_t fp_len = 0;
//Fingerprint2Hex(pgp_fingerprint_as_bytes(fingerprint, &fp_len), fp_len, fingerprintHex, offset);
size_t fp_len = 0;
uint8_t *fingerprintBytes = pgp_fingerprint_as_bytes(fingerprint, &fp_len);
//DEBUG("fp_len, {}", fp_len);
Fingerprint2Hex(fingerprintBytes, fp_len << 1, fingerprintHex, offset);
pgp_fingerprint_free(fingerprint);
}
else{
//char* fingerprintHex2 = pgp_fingerprint_to_hex(fingerprint);
//DEBUG("fingerprinthex2: {}", fingerprintHex2);
//free(fingerprintHex2);
size_t fp_len = 0;
uint8_t *fingerprintBytes = pgp_fingerprint_as_bytes(fingerprint, &fp_len);
//DEBUG("fp_len, {}", fp_len);
Fingerprint2Hex(fingerprintBytes, fp_len << 1, fingerprintHex, offset);
//DEBUG("fingerprint hex - {} - ", fingerprintHex, strlen(fingerprintHex));
pgp_fingerprint_free(fingerprint);
}
if (checkLiving){
pgp_policy_t policy = pgp_standard_policy();
pgp_status_t status = pgp_cert_alive(&err, cert, policy, 0);
pgp_policy_free(policy);
*isAlive = !status;
}
pgp_cert_free(cert);
pgp_error_free(err);
return true;
}
bool ValidateKey(std::string_view publicKeyStringView){
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;
}
pgp_cert_free(cert);
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