diff --git a/c/opendht.cpp b/c/opendht.cpp index 16c79a5d9acb25dcf9c942cd998a9abd35f18120..ed5412370e5d5424c4ee5ff9af57c9d484105455 100644 --- a/c/opendht.cpp +++ b/c/opendht.cpp @@ -122,7 +122,7 @@ void dht_publickey_delete(dht_publickey* pk) { delete reinterpret_cast<PubkeySp*>(pk); } -int dht_publickey_pack(dht_publickey* pk, char* out, size_t* outlen) { +int dht_publickey_export(const dht_publickey* pk, char* out, size_t* outlen) { const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk); return gnutls_pubkey_export(pkey->pk, GNUTLS_X509_FMT_DER, out, outlen); } @@ -164,6 +164,13 @@ dht_privatekey* dht_privatekey_import(const uint8_t* dat, size_t dat_size, const } } +int dht_privatekey_export(const dht_privatekey* k, char* out, size_t* out_size, const char* password) { + if (!out or !out_size or !*out_size) + return -1; + const auto& key = *reinterpret_cast<const PrivkeySp*>(k); + return key->serialize((uint8_t*)out, out_size, password); +} + dht_publickey* dht_privatekey_get_publickey(const dht_privatekey* k) { const auto& key = *reinterpret_cast<const PrivkeySp*>(k); return reinterpret_cast<dht_publickey*>(new PubkeySp(std::make_shared<dht::crypto::PublicKey>(key->getPublicKey()))); diff --git a/c/opendht_c.h b/c/opendht_c.h index fd102f279b2230a0e9e3021b6d07cdddebd6b1ea..be856cbb42f262268199a66643be667dbfc0193a 100644 --- a/c/opendht_c.h +++ b/c/opendht_c.h @@ -45,7 +45,7 @@ struct OPENDHT_C_PUBLIC dht_publickey; typedef struct dht_publickey dht_publickey; OPENDHT_C_PUBLIC dht_publickey* dht_publickey_import(const uint8_t* dat, size_t dat_size); OPENDHT_C_PUBLIC void dht_publickey_delete(dht_publickey* pk); -OPENDHT_C_PUBLIC int dht_publickey_pack(dht_publickey* pk, char* out, size_t* out_size); +OPENDHT_C_PUBLIC int dht_publickey_export(const dht_publickey* pk, char* out, size_t* out_size); 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); @@ -56,6 +56,7 @@ struct OPENDHT_C_PUBLIC dht_privatekey; typedef struct dht_privatekey dht_privatekey; OPENDHT_C_PUBLIC dht_privatekey* dht_privatekey_generate(unsigned key_length_bits); OPENDHT_C_PUBLIC dht_privatekey* dht_privatekey_import(const uint8_t* dat, size_t dat_size, const char* password); +OPENDHT_C_PUBLIC int dht_privatekey_export(const dht_privatekey*, char* out, size_t* out_size, const char* password); OPENDHT_C_PUBLIC dht_publickey* dht_privatekey_get_publickey(const dht_privatekey*); OPENDHT_C_PUBLIC void dht_privatekey_delete(dht_privatekey*); diff --git a/include/opendht/crypto.h b/include/opendht/crypto.h index 17ef2b2d3614a746f78fe9fe0af713db1b4455a1..284c6486b82635b517969fd28bbf0a240e2a7b68 100644 --- a/include/opendht/crypto.h +++ b/include/opendht/crypto.h @@ -160,6 +160,7 @@ struct OPENDHT_PUBLIC PrivateKey explicit operator bool() const { return key; } PublicKey getPublicKey() const; + int serialize(uint8_t* out, size_t* out_len, const std::string& password = {}) const; Blob serialize(const std::string& password = {}) const; /** diff --git a/src/crypto.cpp b/src/crypto.cpp index 0e3ed7ab59104a86a19486005a873ac46f735c86..216253a5961f78c58783c7c193092bf59f9f5046 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -348,9 +348,7 @@ PrivateKey::serialize(const std::string& password) const size_t buf_sz = 8192; Blob buffer; buffer.resize(buf_sz); - int err = password.empty() - ? gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN, buffer.data(), &buf_sz) - : gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, password.c_str(), GNUTLS_PKCS_PBES2_AES_256, buffer.data(), &buf_sz); + auto err = serialize(buffer.data(), &buf_sz, password); if (err != GNUTLS_E_SUCCESS) { std::cerr << "Could not export private key - " << gnutls_strerror(err) << std::endl; return {}; @@ -359,6 +357,16 @@ PrivateKey::serialize(const std::string& password) const return buffer; } +int +PrivateKey::serialize(uint8_t* out, size_t* out_len, const std::string& password) const +{ + if (!x509_key) + return -1; + return password.empty() + ? gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN, out, out_len) + : gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, password.c_str(), GNUTLS_PKCS_PBES2_AES_256, out, out_len); +} + PublicKey PrivateKey::getPublicKey() const {