26 #include <gnutls/gnutls.h> 27 #include <gnutls/abstract.h> 28 #include <gnutls/x509.h> 62 using Identity = std::pair<std::shared_ptr<PrivateKey>, std::shared_ptr<Certificate>>;
79 explicit operator bool()
const {
return pk; }
80 bool operator ==(
const PublicKey& o)
const {
81 return pk == o.pk || getId() == o.getId();
83 bool operator !=(
const PublicKey& o)
const {
87 PublicKey& operator=(PublicKey&& o) noexcept;
92 InfoHash getId()
const;
97 PkId getLongId()
const;
99 bool checkSignature(
const Blob& data,
const Blob& signature)
const;
102 void pack(
Blob& b)
const;
103 void unpack(
const uint8_t* dat,
size_t dat_size);
105 std::string toString()
const;
107 template <
typename Packer>
108 void msgpack_pack(Packer& p)
const 112 p.pack_bin(b.size());
113 p.pack_bin_body((
const char*)b.data(), b.size());
116 void msgpack_unpack(msgpack::object o);
118 gnutls_pubkey_t pk {};
120 PublicKey(
const PublicKey&) =
delete;
121 PublicKey& operator=(
const PublicKey&) =
delete;
122 void encryptBloc(
const uint8_t* src,
size_t src_size, uint8_t* dst,
size_t dst_size)
const;
143 explicit operator bool()
const {
return key; }
146 Blob serialize(
const std::string& password = {})
const;
159 Blob decrypt(
const Blob& cypher)
const;
167 static PrivateKey generate(
unsigned key_length = 4096);
170 gnutls_privkey_t key {};
171 gnutls_x509_privkey_t x509_key {};
175 Blob decryptBloc(
const uint8_t* src,
size_t src_size)
const;
183 using clock = std::chrono::system_clock;
184 using time_point = clock::time_point;
185 using duration = clock::duration;
194 void pack(
Blob& b)
const;
195 void unpack(
const uint8_t* dat,
size_t dat_size);
196 Blob getPacked()
const {
202 template <
typename Packer>
203 void msgpack_pack(Packer& p)
const 205 Blob b = getPacked();
206 p.pack_bin(b.size());
207 p.pack_bin_body((
const char*)b.data(), b.size());
210 void msgpack_unpack(msgpack::object o);
212 void revoke(
const Certificate& crt, time_point t = time_point::min());
221 void sign(
const Identity&
id) { sign(*
id.first, *
id.second); }
225 std::string toString()
const;
230 Blob getNumber()
const;
233 std::string getIssuerName()
const;
236 std::string getIssuerUID()
const;
238 time_point getUpdateTime()
const;
239 time_point getNextUpdateTime()
const;
241 gnutls_x509_crl_t
get() {
return crl; }
242 gnutls_x509_crl_t getCopy()
const {
246 gnutls_x509_crl_t ret = copy.crl;
252 gnutls_x509_crl_t crl {};
272 Certificate(
const Blob& crt);
273 Certificate(
const std::string& pem) : cert(nullptr) {
274 unpack((
const uint8_t*)pem.data(), pem.size());
276 Certificate(
const uint8_t* dat,
size_t dat_size) : cert(nullptr) {
277 unpack(dat, dat_size);
284 template<
typename Iterator>
293 template<
typename Iterator>
294 Certificate(
const std::vector<std::pair<Iterator, Iterator>>& certs) {
301 void pack(
Blob& b)
const;
302 void unpack(
const uint8_t* dat,
size_t dat_size);
303 Blob getPacked()
const {
317 template<
typename Iterator>
318 void unpack(
const Iterator& begin,
const Iterator& end)
320 std::shared_ptr<Certificate> tmp_subject {};
321 std::shared_ptr<Certificate> first {};
322 for (Iterator icrt = begin; icrt < end; ++icrt) {
323 auto tmp_crt = std::make_shared<Certificate>(*icrt);
325 tmp_subject->issuer = tmp_crt;
326 tmp_subject = std::move(tmp_crt);
344 template<
typename Iterator>
345 void unpack(
const std::vector<std::pair<Iterator, Iterator>>& certs)
347 std::shared_ptr<Certificate> tmp_issuer;
349 for (
auto li = certs.rbegin(); li != certs.rend(); ++li) {
351 gnutls_x509_crt_init(&tmp_crt.cert);
352 const gnutls_datum_t crt_dt {(uint8_t*)&(*li->first), (unsigned)(li->second-li->first)};
353 int err = gnutls_x509_crt_import(tmp_crt.cert, &crt_dt, GNUTLS_X509_FMT_PEM);
354 if (err != GNUTLS_E_SUCCESS)
355 err = gnutls_x509_crt_import(tmp_crt.cert, &crt_dt, GNUTLS_X509_FMT_DER);
356 if (err != GNUTLS_E_SUCCESS)
357 throw CryptoException(std::string(
"Could not read certificate - ") + gnutls_strerror(err));
358 tmp_crt.issuer = tmp_issuer;
359 tmp_issuer = std::make_shared<Certificate>(std::move(tmp_crt));
361 *
this = tmp_issuer ? std::move(*tmp_issuer) :
Certificate();
364 template <
typename Packer>
365 void msgpack_pack(Packer& p)
const 369 p.pack_bin(b.size());
370 p.pack_bin_body((
const char*)b.data(), b.size());
373 void msgpack_unpack(msgpack::object o);
375 explicit operator bool()
const {
return cert; }
376 PublicKey getPublicKey()
const;
379 InfoHash getId()
const;
381 PkId getLongId()
const;
384 std::string getName()
const;
387 std::string getUID()
const;
390 std::string getIssuerName()
const;
393 std::string getIssuerUID()
const;
395 enum class NameType { UNKNOWN = 0, RFC822, DNS, URI, IP };
398 std::vector<std::pair<NameType, std::string>> getAltNames()
const;
400 std::chrono::system_clock::time_point getActivation()
const;
401 std::chrono::system_clock::time_point getExpiration()
const;
413 std::string toString(
bool chain =
true)
const;
415 std::string print()
const;
421 void revoke(
const PrivateKey&,
const Certificate&);
426 std::vector<std::shared_ptr<RevocationList>> getRevocationLists()
const;
431 void addRevocationList(RevocationList&&);
432 void addRevocationList(std::shared_ptr<RevocationList>);
434 static Certificate generate(
const PrivateKey& key,
const std::string& name =
"dhtnode", Identity ca = {},
bool is_ca =
false);
436 gnutls_x509_crt_t getCopy()
const {
439 auto copy = Certificate(getPacked());
440 gnutls_x509_crt_t ret = copy.cert;
445 std::vector<gnutls_x509_crt_t>
446 getChain(
bool copy =
false)
const 450 std::vector<gnutls_x509_crt_t> crts;
451 for (
auto c =
this; c; c = c->issuer.get())
452 crts.emplace_back(copy ? c->getCopy() : c->cert);
457 std::vector<gnutls_x509_crt_t>,
458 std::vector<gnutls_x509_crl_t>
460 getChainWithRevocations(
bool copy =
false)
const 464 std::vector<gnutls_x509_crt_t> crts;
465 std::vector<gnutls_x509_crl_t> crls;
466 for (
auto c =
this; c; c = c->issuer.get()) {
467 crts.emplace_back(copy ? c->getCopy() : c->cert);
468 crls.reserve(crls.size() + c->revocation_lists.size());
469 for (
const auto& crl : c->revocation_lists)
470 crls.emplace_back(copy ? crl->getCopy() : crl->get());
475 gnutls_x509_crt_t cert {};
476 std::shared_ptr<Certificate> issuer {};
478 Certificate(
const Certificate&) =
delete;
479 Certificate& operator=(
const Certificate&) =
delete;
481 struct crlNumberCmp {
482 bool operator() (
const std::shared_ptr<RevocationList>& lhs,
const std::shared_ptr<RevocationList>& rhs)
const {
483 return lhs->getNumber() < rhs->getNumber();
487 std::set<std::shared_ptr<RevocationList>, crlNumberCmp> revocation_lists;
495 bool hasError()
const {
return ret < 0; }
496 bool isValid()
const {
return !hasError() and !(result & GNUTLS_CERT_INVALID); }
497 explicit operator bool()
const {
return isValid(); }
498 std::string toString()
const;
499 OPENDHT_PUBLIC
friend std::ostream& operator<< (std::ostream& s,
const VerifyResult& h);
510 void remove(
const Certificate& crt,
bool parents =
true);
516 gnutls_x509_trust_list_t trust;
527 explicit secure_vector(
unsigned size, T _item): data_(size, _item) {}
534 crypto::random_device rdev;
536 std::uniform_int_distribution<int> rand_byte{ 0, std::numeric_limits<uint8_t>::max() };
538 std::uniform_int_distribution<uint8_t> rand_byte;
540 std::generate_n((uint8_t*)ret.data_.data(), ret.size()*
sizeof(T), std::bind(rand_byte, std::ref(rdev)));
554 data_ = std::move(c.data_);
559 data_ = std::move(c);
562 std::vector<T>& writable() { clean();
return data_; }
563 const std::vector<T>& makeInsecure()
const {
return data_; }
564 const uint8_t* data()
const {
return data_.data(); }
567 clean(data_.begin(), data_.end());
570 void clear() { clean(); data_.clear(); }
572 size_t size()
const {
return data_.size(); }
573 bool empty()
const {
return data_.empty(); }
576 void resize(
size_t s) {
577 if (s == data_.size())
return;
578 if (s < data_.size()) {
580 clean(data_.begin()+s, data_.end());
584 auto data = std::move(data_);
587 std::copy(data.begin(), data.end(), data_.begin());
588 clean(data.begin(), data.end());
596 static void clean(
const typename std::vector<T>::iterator& i,
const typename std::vector<T>::iterator& j) {
597 volatile uint8_t* b =
reinterpret_cast<uint8_t*
>(&*i);
598 volatile uint8_t* e =
reinterpret_cast<uint8_t*
>(&*j);
602 std::vector<T> data_;
614 OPENDHT_PUBLIC Identity
generateIdentity(
const std::string& name, Identity ca,
unsigned key_length,
bool is_ca);
615 OPENDHT_PUBLIC Identity
generateIdentity(
const std::string& name =
"dhtnode", Identity ca = {},
unsigned key_length = 4096);
617 OPENDHT_PUBLIC Identity generateEcIdentity(
const std::string& name, Identity ca,
bool is_ca);
618 OPENDHT_PUBLIC Identity generateEcIdentity(
const std::string& name =
"dhtnode", Identity ca = {});
629 OPENDHT_PUBLIC
Blob hash(
const Blob& data,
size_t hash_length = 512/8);
631 OPENDHT_PUBLIC
void hash(
const uint8_t* data,
size_t data_length, uint8_t*
hash,
size_t hash_length);
640 OPENDHT_PUBLIC
Blob stretchKey(
const std::string& password,
Blob& salt,
size_t key_length = 512/8);
Certificate(const Iterator &begin, const Iterator &end)
OPENDHT_PUBLIC Blob hash(const Blob &data, size_t hash_length=512/8)
OPENDHT_PUBLIC Blob stretchKey(const std::string &password, Blob &salt, size_t key_length=512/8)
Certificate(gnutls_x509_crt_t crt)
void unpack(const std::vector< std::pair< Iterator, Iterator >> &certs)
PublicKey(gnutls_pubkey_t k)
OPENDHT_PUBLIC Blob aesDecrypt(const Blob &data, const Blob &key)
std::vector< uint8_t > Blob
OPENDHT_PUBLIC Blob aesEncrypt(const Blob &data, const Blob &key)
OPENDHT_PUBLIC Identity generateIdentity(const std::string &name, Identity ca, unsigned key_length, bool is_ca)
Certificate(const std::vector< std::pair< Iterator, Iterator >> &certs)
void unpack(const Iterator &begin, const Iterator &end)