You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

294 lines
8.7 KiB

  1. #ifdef HAVE_CONFIG_H
  2. #include "config.h"
  3. #endif
  4. #include <decaf.hxx>
  5. #include <decaf/eddsa.hxx>
  6. #include <decaf/spongerng.hxx>
  7. #include "dnssecinfra.hh"
  8. using namespace decaf;
  9. class DecafED25519DNSCryptoKeyEngine : public DNSCryptoKeyEngine
  10. {
  11. public:
  12. explicit DecafED25519DNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo)
  13. {
  14. }
  15. string getName() const override { return "Decaf ED25519"; }
  16. void create(unsigned int bits) override;
  17. storvector_t convertToISCVector() const override;
  18. std::string getPubKeyHash() const override;
  19. std::string sign(const std::string& msg) const override;
  20. bool verify(const std::string& msg, const std::string& signature) const override;
  21. std::string getPublicKeyString() const override;
  22. int getBits() const override;
  23. void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap) override;
  24. void fromPublicKeyString(const std::string& content) override;
  25. void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw) override
  26. {}
  27. static std::shared_ptr<DNSCryptoKeyEngine> maker(unsigned int algorithm)
  28. {
  29. return std::make_shared<DecafED25519DNSCryptoKeyEngine>(algorithm);
  30. }
  31. private:
  32. unsigned char d_pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES];
  33. unsigned char d_seckey[DECAF_EDDSA_25519_PRIVATE_BYTES];
  34. };
  35. void DecafED25519DNSCryptoKeyEngine::create(unsigned int bits)
  36. {
  37. if(bits != (unsigned int)getBits()) {
  38. throw runtime_error("Unsupported key length of "+std::to_string(bits)+" bits requested, DecafED25519 class");
  39. }
  40. SpongeRng rng("/dev/urandom");
  41. typename EdDSA<IsoEd25519>::PrivateKey priv(rng);
  42. typename EdDSA<IsoEd25519>::PublicKey pub(priv);
  43. priv.serialize_into(d_seckey);
  44. pub.serialize_into(d_pubkey);
  45. }
  46. int DecafED25519DNSCryptoKeyEngine::getBits() const
  47. {
  48. return DECAF_EDDSA_25519_PRIVATE_BYTES << 3;
  49. }
  50. DNSCryptoKeyEngine::storvector_t DecafED25519DNSCryptoKeyEngine::convertToISCVector() const
  51. {
  52. /*
  53. Private-key-format: v1.2
  54. Algorithm: 15 (ED25519)
  55. PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI=
  56. */
  57. storvector_t storvector;
  58. storvector.push_back(make_pair("Algorithm", "15 (ED25519)"));
  59. storvector.push_back(make_pair("PrivateKey", string((char*)d_seckey, DECAF_EDDSA_25519_PRIVATE_BYTES)));
  60. return storvector;
  61. }
  62. void DecafED25519DNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
  63. {
  64. /*
  65. Private-key-format: v1.2
  66. Algorithm: 15 (ED25519)
  67. PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI=
  68. */
  69. drc.d_algorithm = pdns_stou(stormap["algorithm"]);
  70. string privateKey = stormap["privatekey"];
  71. if (privateKey.length() != DECAF_EDDSA_25519_PRIVATE_BYTES)
  72. throw runtime_error("Private key size mismatch in ISCMap, DecafED25519 class");
  73. typename EdDSA<IsoEd25519>::PrivateKey priv(Block((const unsigned char*)privateKey.c_str(), DECAF_EDDSA_25519_PRIVATE_BYTES));
  74. typename EdDSA<IsoEd25519>::PublicKey pub(priv);
  75. priv.serialize_into(d_seckey);
  76. pub.serialize_into(d_pubkey);
  77. }
  78. std::string DecafED25519DNSCryptoKeyEngine::getPubKeyHash() const
  79. {
  80. return this->getPublicKeyString();
  81. }
  82. std::string DecafED25519DNSCryptoKeyEngine::getPublicKeyString() const
  83. {
  84. return string((char*)d_pubkey, DECAF_EDDSA_25519_PUBLIC_BYTES);
  85. }
  86. void DecafED25519DNSCryptoKeyEngine::fromPublicKeyString(const std::string& input)
  87. {
  88. if (input.length() != DECAF_EDDSA_25519_PUBLIC_BYTES)
  89. throw runtime_error("Public key size mismatch, DecafED25519 class");
  90. memcpy(d_pubkey, input.c_str(), DECAF_EDDSA_25519_PUBLIC_BYTES);
  91. }
  92. std::string DecafED25519DNSCryptoKeyEngine::sign(const std::string& msg) const
  93. {
  94. typename EdDSA<IsoEd25519>::PrivateKey priv(Block(d_seckey, DECAF_EDDSA_25519_PRIVATE_BYTES));
  95. SecureBuffer message(msg.begin(), msg.end());
  96. SecureBuffer sig = priv.sign(message);
  97. return string(sig.begin(), sig.end());
  98. }
  99. bool DecafED25519DNSCryptoKeyEngine::verify(const std::string& msg, const std::string& signature) const
  100. {
  101. if (signature.length() != DECAF_EDDSA_25519_SIGNATURE_BYTES)
  102. return false;
  103. typename EdDSA<IsoEd25519>::PublicKey pub(Block(d_pubkey, DECAF_EDDSA_25519_PUBLIC_BYTES));
  104. SecureBuffer sig(signature.begin(), signature.end());
  105. SecureBuffer message(msg.begin(), msg.end());
  106. try {
  107. pub.verify(sig, message);
  108. } catch(CryptoException) {
  109. return false;
  110. }
  111. return true;
  112. }
  113. class DecafED448DNSCryptoKeyEngine : public DNSCryptoKeyEngine
  114. {
  115. public:
  116. explicit DecafED448DNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo)
  117. {
  118. }
  119. string getName() const override { return "Decaf ED448"; }
  120. void create(unsigned int bits) override;
  121. storvector_t convertToISCVector() const override;
  122. std::string getPubKeyHash() const override;
  123. std::string sign(const std::string& msg) const override;
  124. bool verify(const std::string& msg, const std::string& signature) const override;
  125. std::string getPublicKeyString() const override;
  126. int getBits() const override;
  127. void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap) override;
  128. void fromPublicKeyString(const std::string& content) override;
  129. void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw) override
  130. {}
  131. static std::shared_ptr<DNSCryptoKeyEngine> maker(unsigned int algorithm)
  132. {
  133. return std::make_shared<DecafED448DNSCryptoKeyEngine>(algorithm);
  134. }
  135. private:
  136. unsigned char d_pubkey[DECAF_EDDSA_448_PUBLIC_BYTES];
  137. unsigned char d_seckey[DECAF_EDDSA_448_PRIVATE_BYTES];
  138. };
  139. void DecafED448DNSCryptoKeyEngine::create(unsigned int bits)
  140. {
  141. if(bits != (unsigned int)getBits()) {
  142. throw runtime_error("Unsupported key length of "+std::to_string(bits)+" bits requested, DecafED448 class");
  143. }
  144. SpongeRng rng("/dev/urandom");
  145. typename EdDSA<Ed448Goldilocks>::PrivateKey priv(rng);
  146. typename EdDSA<Ed448Goldilocks>::PublicKey pub(priv);
  147. priv.serialize_into(d_seckey);
  148. pub.serialize_into(d_pubkey);
  149. }
  150. int DecafED448DNSCryptoKeyEngine::getBits() const
  151. {
  152. return DECAF_EDDSA_448_PRIVATE_BYTES << 3;
  153. }
  154. DNSCryptoKeyEngine::storvector_t DecafED448DNSCryptoKeyEngine::convertToISCVector() const
  155. {
  156. /*
  157. Private-key-format: v1.2
  158. Algorithm: 16 (ED448)
  159. PrivateKey: xZ+5Cgm463xugtkY5B0Jx6erFTXp13rYegst0qRtNsOYnaVpMx0Z/c5EiA9x8wWbDDct/U3FhYWA
  160. */
  161. storvector_t storvector;
  162. storvector.push_back(make_pair("Algorithm", "16 (ED448)"));
  163. storvector.push_back(make_pair("PrivateKey", string((char*)d_seckey, DECAF_EDDSA_448_PRIVATE_BYTES)));
  164. return storvector;
  165. }
  166. void DecafED448DNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
  167. {
  168. /*
  169. Private-key-format: v1.2
  170. Algorithm: 16 (ED448)
  171. PrivateKey: xZ+5Cgm463xugtkY5B0Jx6erFTXp13rYegst0qRtNsOYnaVpMx0Z/c5EiA9x8wWbDDct/U3FhYWA
  172. */
  173. drc.d_algorithm = pdns_stou(stormap["algorithm"]);
  174. string privateKey = stormap["privatekey"];
  175. if (privateKey.length() != DECAF_EDDSA_448_PRIVATE_BYTES)
  176. throw runtime_error("Private key size mismatch in ISCMap, DecafED448 class");
  177. typename EdDSA<Ed448Goldilocks>::PrivateKey priv(Block((const unsigned char*)privateKey.c_str(), DECAF_EDDSA_448_PRIVATE_BYTES));
  178. typename EdDSA<Ed448Goldilocks>::PublicKey pub(priv);
  179. priv.serialize_into(d_seckey);
  180. pub.serialize_into(d_pubkey);
  181. }
  182. std::string DecafED448DNSCryptoKeyEngine::getPubKeyHash() const
  183. {
  184. return this->getPublicKeyString();
  185. }
  186. std::string DecafED448DNSCryptoKeyEngine::getPublicKeyString() const
  187. {
  188. return string((char*)d_pubkey, DECAF_EDDSA_448_PUBLIC_BYTES);
  189. }
  190. void DecafED448DNSCryptoKeyEngine::fromPublicKeyString(const std::string& input)
  191. {
  192. if (input.length() != DECAF_EDDSA_448_PUBLIC_BYTES)
  193. throw runtime_error("Public key size mismatch, DecafED448 class");
  194. memcpy(d_pubkey, input.c_str(), DECAF_EDDSA_448_PUBLIC_BYTES);
  195. }
  196. std::string DecafED448DNSCryptoKeyEngine::sign(const std::string& msg) const
  197. {
  198. typename EdDSA<Ed448Goldilocks>::PrivateKey priv(Block(d_seckey, DECAF_EDDSA_448_PRIVATE_BYTES));
  199. SecureBuffer message(msg.begin(), msg.end());
  200. SecureBuffer sig = priv.sign(message);
  201. return string(sig.begin(), sig.end());
  202. }
  203. bool DecafED448DNSCryptoKeyEngine::verify(const std::string& msg, const std::string& signature) const
  204. {
  205. if (signature.length() != DECAF_EDDSA_448_SIGNATURE_BYTES)
  206. return false;
  207. typename EdDSA<Ed448Goldilocks>::PublicKey pub(Block(d_pubkey, DECAF_EDDSA_448_PUBLIC_BYTES));
  208. SecureBuffer sig(signature.begin(), signature.end());
  209. SecureBuffer message(msg.begin(), msg.end());
  210. try {
  211. pub.verify(sig, message);
  212. } catch(CryptoException) {
  213. return false;
  214. }
  215. return true;
  216. }
  217. namespace {
  218. struct LoaderDecafStruct
  219. {
  220. LoaderDecafStruct()
  221. {
  222. DNSCryptoKeyEngine::report(15, &DecafED25519DNSCryptoKeyEngine::maker, true);
  223. DNSCryptoKeyEngine::report(16, &DecafED448DNSCryptoKeyEngine::maker);
  224. }
  225. } loaderdecaf;
  226. }