Skip to content
Snippets Groups Projects
Commit e9377f2e authored by Adrien Béraud's avatar Adrien Béraud
Browse files

c wrapper: add Blob, PublicKey

parent 083a28f5
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
extern "C" { extern "C" {
#endif #endif
// dht::InfoHash
const char* dht_infohash_print(const dht_infohash* h) const char* dht_infohash_print(const dht_infohash* h)
{ {
return reinterpret_cast<const dht::InfoHash*>(h)->to_c_str(); return reinterpret_cast<const dht::InfoHash*>(h)->to_c_str();
...@@ -15,6 +16,62 @@ void dht_infohash_random(dht_infohash* h) ...@@ -15,6 +16,62 @@ void dht_infohash_random(dht_infohash* h)
*reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash::getRandom(); *reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash::getRandom();
} }
void dht_blob_delete(dht_blob* data)
{
delete reinterpret_cast<dht::Blob*>(data->ptr);
}
// dht::crypto::PublicKey
dht_publickey* dht_publickey_new() {
return reinterpret_cast<dht_publickey*>(new dht::crypto::PublicKey);
}
void dht_publickey_delete(dht_publickey* pk) {
delete reinterpret_cast<dht::crypto::PublicKey*>(pk);
}
int dht_publickey_unpack(dht_publickey* pk, const uint8_t* dat, size_t dat_size) {
try {
reinterpret_cast<dht::crypto::PublicKey*>(pk)->unpack(dat, dat_size);
} catch (const dht::crypto::CryptoException& e) {
return -1;
}
return 0;
}
int dht_publickey_pack(dht_publickey* pk, char* out, size_t* outlen)
{
return gnutls_pubkey_export(reinterpret_cast<dht::crypto::PublicKey*>(pk)->pk, GNUTLS_X509_FMT_DER, out, outlen);
}
dht_infohash dht_publickey_get_id(const dht_publickey* pk) {
dht_infohash h;
*reinterpret_cast<dht::InfoHash*>(&h) = reinterpret_cast<const dht::crypto::PublicKey*>(pk)->getId();
return h;
}
dht_pkid dht_publickey_get_long_id(const dht_publickey* pk) {
dht_pkid h;
*reinterpret_cast<dht::PkId*>(&h) = reinterpret_cast<const dht::crypto::PublicKey*>(pk)->getLongId();
return h;
}
bool dht_publickey_check_signature(const dht_publickey* pk, const char* data, size_t data_size, const char* signature, size_t signature_size)
{
return reinterpret_cast<const dht::crypto::PublicKey*>(pk)->checkSignature((const uint8_t*)data, data_size, (const uint8_t*)signature, signature_size);
}
dht_blob dht_publickey_encrypt(const dht_publickey* pk, const char* data, size_t data_size)
{
dht_blob ret;
ret.ptr = new dht::Blob;
*reinterpret_cast<dht::Blob*>(ret.ptr) = reinterpret_cast<const dht::crypto::PublicKey*>(pk)->encrypt((const uint8_t*)data, data_size);
ret.data = reinterpret_cast<dht::Blob*>(ret.ptr)->data();
ret.data_length = reinterpret_cast<dht::Blob*>(ret.ptr)->size();
return ret;
}
// dht::DhtRunner
dht_runner* dht_runner_new() { dht_runner* dht_runner_new() {
return reinterpret_cast<dht_runner*>(new dht::DhtRunner); return reinterpret_cast<dht_runner*>(new dht::DhtRunner);
} }
......
...@@ -11,17 +11,56 @@ extern "C" { ...@@ -11,17 +11,56 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
// dht::Value
struct OPENDHT_C_PUBLIC dht_value; struct OPENDHT_C_PUBLIC dht_value;
typedef struct dht_value dht_value; typedef struct dht_value dht_value;
// dht::Blob
struct OPENDHT_C_PUBLIC dht_blob {
const uint8_t* data;
size_t data_length;
void* ptr;
};
typedef struct dht_blob dht_blob;
OPENDHT_C_PUBLIC void dht_blob_delete(dht_blob* data);
// dht::InfoHash
struct OPENDHT_C_PUBLIC dht_infohash { uint8_t d[HASH_LEN]; }; struct OPENDHT_C_PUBLIC dht_infohash { uint8_t d[HASH_LEN]; };
typedef struct dht_infohash dht_infohash; typedef struct dht_infohash dht_infohash;
OPENDHT_C_PUBLIC void dht_infohash_random(dht_infohash* h); OPENDHT_C_PUBLIC void dht_infohash_random(dht_infohash* h);
OPENDHT_C_PUBLIC const char* dht_infohash_print(const dht_infohash* h); OPENDHT_C_PUBLIC const char* dht_infohash_print(const dht_infohash* h);
// dht::PkId
struct OPENDHT_C_PUBLIC dht_pkid { uint8_t d[32]; };
typedef struct dht_pkid dht_pkid;
// dht::crypto::PublicKey
struct OPENDHT_C_PUBLIC dht_publickey;
typedef struct dht_publickey dht_publickey;
OPENDHT_C_PUBLIC dht_publickey* dht_publickey_new();
OPENDHT_C_PUBLIC void dht_publickey_delete(dht_publickey* pk);
OPENDHT_C_PUBLIC int dht_publickey_unpack(dht_publickey* pk, const uint8_t* dat, size_t dat_size);
OPENDHT_C_PUBLIC int dht_publickey_pack(dht_publickey* pk, char* out, size_t* outlen);
OPENDHT_C_PUBLIC dht_infohash dht_publickey_get_id(const dht_publickey* pk);
OPENDHT_C_PUBLIC dht_pkid dht_publickey_get_long_id(const dht_publickey* pk);
OPENDHT_C_PUBLIC bool dht_publickey_check_signature(const dht_publickey* pk, const char* data, size_t data_size, const char* signature, size_t signature_size);
OPENDHT_C_PUBLIC dht_blob dht_publickey_encrypt(const dht_publickey* pk, const char* data, size_t data_size);
// dht::crypto::PrivateKey
struct OPENDHT_C_PUBLIC dht_privatekey;
typedef struct dht_privatekey dht_privatekey;
// dht::crypto::Certificate
struct OPENDHT_C_PUBLIC dht_certificate;
typedef struct dht_certificate dht_certificate;
// callbacks
typedef bool (*dht_get_cb)(const dht_value* value, void* user_data); typedef bool (*dht_get_cb)(const dht_value* value, void* user_data);
typedef bool (*dht_value_cb)(const dht_value* value, bool expired, void* user_data);
typedef bool (*dht_done_cb)(bool ok, void* user_data); typedef bool (*dht_done_cb)(bool ok, void* user_data);
typedef bool (*dht_shutdown_cb)(void* user_data);
// dht::DhtRunner
struct OPENDHT_C_PUBLIC dht_runner; struct OPENDHT_C_PUBLIC dht_runner;
typedef struct dht_runner dht_runner; typedef struct dht_runner dht_runner;
OPENDHT_C_PUBLIC dht_runner* dht_runner_new(); OPENDHT_C_PUBLIC dht_runner* dht_runner_new();
......
...@@ -96,8 +96,15 @@ struct OPENDHT_PUBLIC PublicKey ...@@ -96,8 +96,15 @@ struct OPENDHT_PUBLIC PublicKey
*/ */
PkId getLongId() const; PkId getLongId() const;
bool checkSignature(const Blob& data, const Blob& signature) const; bool checkSignature(const uint8_t* data, size_t data_len, const uint8_t* signature, size_t signature_len) const;
Blob encrypt(const Blob&) const; bool checkSignature(const Blob& data, const Blob& signature) const {
return checkSignature(data.data(), data.size(), signature.data(), signature.size());
}
Blob encrypt(const uint8_t* data, size_t data_len) const;
Blob encrypt(const Blob& data) const {
return encrypt(data.data(), data.size());
}
void pack(Blob& b) const; void pack(Blob& b) const;
void unpack(const uint8_t* dat, size_t dat_size); void unpack(const uint8_t* dat, size_t dat_size);
...@@ -681,7 +688,10 @@ OPENDHT_PUBLIC Blob stretchKey(const std::string& password, Blob& salt, size_t k ...@@ -681,7 +688,10 @@ OPENDHT_PUBLIC Blob stretchKey(const std::string& password, Blob& salt, size_t k
/** /**
* AES-GCM encryption. Key must be 128, 192 or 256 bits long (16, 24 or 32 bytes). * AES-GCM encryption. Key must be 128, 192 or 256 bits long (16, 24 or 32 bytes).
*/ */
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const Blob& key); OPENDHT_PUBLIC Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key);
OPENDHT_PUBLIC inline Blob aesEncrypt(const Blob& data, const Blob& key) {
return aesEncrypt(data.data(), data.size(), key);
}
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const std::string& password); OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const std::string& password);
/** /**
......
...@@ -92,12 +92,12 @@ bool aesKeySizeGood(size_t key_size) ...@@ -92,12 +92,12 @@ bool aesKeySizeGood(size_t key_size)
#define GCM_DIGEST_SIZE GCM_BLOCK_SIZE #define GCM_DIGEST_SIZE GCM_BLOCK_SIZE
#endif #endif
Blob aesEncrypt(const Blob& data, const Blob& key) Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key)
{ {
if (not aesKeySizeGood(key.size())) if (not aesKeySizeGood(key.size()))
throw DecryptError("Wrong key size"); throw DecryptError("Wrong key size");
Blob ret(data.size() + GCM_IV_SIZE + GCM_DIGEST_SIZE); Blob ret(data_length + GCM_IV_SIZE + GCM_DIGEST_SIZE);
{ {
crypto::random_device rdev; crypto::random_device rdev;
std::generate_n(ret.begin(), GCM_IV_SIZE, std::bind(rand_byte, std::ref(rdev))); std::generate_n(ret.begin(), GCM_IV_SIZE, std::bind(rand_byte, std::ref(rdev)));
...@@ -105,10 +105,10 @@ Blob aesEncrypt(const Blob& data, const Blob& key) ...@@ -105,10 +105,10 @@ Blob aesEncrypt(const Blob& data, const Blob& key)
struct gcm_aes_ctx aes; struct gcm_aes_ctx aes;
gcm_aes_set_key(&aes, key.size(), key.data()); gcm_aes_set_key(&aes, key.size(), key.data());
gcm_aes_set_iv(&aes, GCM_IV_SIZE, ret.data()); gcm_aes_set_iv(&aes, GCM_IV_SIZE, ret.data());
gcm_aes_update(&aes, data.size(), data.data()); gcm_aes_update(&aes, data_length, data);
gcm_aes_encrypt(&aes, data.size(), ret.data() + GCM_IV_SIZE, data.data()); gcm_aes_encrypt(&aes, data_length, ret.data() + GCM_IV_SIZE, data);
gcm_aes_digest(&aes, GCM_DIGEST_SIZE, ret.data() + GCM_IV_SIZE + data.size()); gcm_aes_digest(&aes, GCM_DIGEST_SIZE, ret.data() + GCM_IV_SIZE + data_length);
return ret; return ret;
} }
...@@ -440,13 +440,12 @@ PublicKey::msgpack_unpack(msgpack::object o) ...@@ -440,13 +440,12 @@ PublicKey::msgpack_unpack(msgpack::object o)
} }
} }
bool bool PublicKey::checkSignature(const uint8_t* data, size_t data_len, const uint8_t* signature, size_t signature_len) const
PublicKey::checkSignature(const Blob& data, const Blob& signature) const
{ {
if (!pk) if (!pk)
return false; return false;
const gnutls_datum_t sig {(uint8_t*)signature.data(), (unsigned)signature.size()}; const gnutls_datum_t sig {(uint8_t*)signature, (unsigned)signature_len};
const gnutls_datum_t dat {(uint8_t*)data.data(), (unsigned)data.size()}; const gnutls_datum_t dat {(uint8_t*)data, (unsigned)data_len};
int rc = gnutls_pubkey_verify_data2(pk, GNUTLS_SIGN_RSA_SHA512, 0, &dat, &sig); int rc = gnutls_pubkey_verify_data2(pk, GNUTLS_SIGN_RSA_SHA512, 0, &dat, &sig);
return rc >= 0; return rc >= 0;
} }
...@@ -466,7 +465,7 @@ PublicKey::encryptBloc(const uint8_t* src, size_t src_size, uint8_t* dst, size_t ...@@ -466,7 +465,7 @@ PublicKey::encryptBloc(const uint8_t* src, size_t src_size, uint8_t* dst, size_t
} }
Blob Blob
PublicKey::encrypt(const Blob& data) const PublicKey::encrypt(const uint8_t* data, size_t data_len) const
{ {
if (!pk) if (!pk)
throw CryptoException("Can't read public key !"); throw CryptoException("Can't read public key !");
...@@ -482,9 +481,9 @@ PublicKey::encrypt(const Blob& data) const ...@@ -482,9 +481,9 @@ PublicKey::encrypt(const Blob& data) const
const unsigned cypher_block_sz = key_len / 8; const unsigned cypher_block_sz = key_len / 8;
/* Use plain RSA if the data is small enough */ /* Use plain RSA if the data is small enough */
if (data.size() <= max_block_sz) { if (data_len <= max_block_sz) {
Blob ret(cypher_block_sz); Blob ret(cypher_block_sz);
encryptBloc(data.data(), data.size(), ret.data(), cypher_block_sz); encryptBloc(data, data_len, ret.data(), cypher_block_sz);
return ret; return ret;
} }
...@@ -499,7 +498,7 @@ PublicKey::encrypt(const Blob& data) const ...@@ -499,7 +498,7 @@ PublicKey::encrypt(const Blob& data) const
crypto::random_device rdev; crypto::random_device rdev;
std::generate_n(key.begin(), key.size(), std::bind(rand_byte, std::ref(rdev))); std::generate_n(key.begin(), key.size(), std::bind(rand_byte, std::ref(rdev)));
} }
auto data_encrypted = aesEncrypt(data, key); auto data_encrypted = aesEncrypt(data, data_len, key);
Blob ret; Blob ret;
ret.reserve(cypher_block_sz + data_encrypted.size()); ret.reserve(cypher_block_sz + data_encrypted.size());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment