Family.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include <string.h>
  2. #include <openssl/evp.h>
  3. #include <openssl/ssl.h>
  4. #include "Crypto.h"
  5. #include "FS.h"
  6. #include "Log.h"
  7. #include "Family.h"
  8. namespace i2p
  9. {
  10. namespace data
  11. {
  12. Families::Families ()
  13. {
  14. }
  15. Families::~Families ()
  16. {
  17. }
  18. void Families::LoadCertificate (const std::string& filename)
  19. {
  20. SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
  21. int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
  22. if (ret)
  23. {
  24. SSL * ssl = SSL_new (ctx);
  25. X509 * cert = SSL_get_certificate (ssl);
  26. if (cert)
  27. {
  28. std::shared_ptr<i2p::crypto::Verifier> verifier;
  29. // extract issuer name
  30. char name[100];
  31. X509_NAME_oneline (X509_get_issuer_name(cert), name, 100);
  32. char * cn = strstr (name, "CN=");
  33. if (cn)
  34. {
  35. cn += 3;
  36. char * family = strstr (cn, ".family");
  37. if (family) family[0] = 0;
  38. }
  39. auto pkey = X509_get_pubkey (cert);
  40. int keyType = EVP_PKEY_base_id (pkey);
  41. switch (keyType)
  42. {
  43. case EVP_PKEY_DSA:
  44. // TODO:
  45. break;
  46. case EVP_PKEY_EC:
  47. {
  48. EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey);
  49. if (ecKey)
  50. {
  51. auto group = EC_KEY_get0_group (ecKey);
  52. if (group)
  53. {
  54. int curve = EC_GROUP_get_curve_name (group);
  55. if (curve == NID_X9_62_prime256v1)
  56. {
  57. uint8_t signingKey[64];
  58. BIGNUM * x = BN_new(), * y = BN_new();
  59. EC_POINT_get_affine_coordinates_GFp (group,
  60. EC_KEY_get0_public_key (ecKey), x, y, NULL);
  61. i2p::crypto::bn2buf (x, signingKey, 32);
  62. i2p::crypto::bn2buf (y, signingKey + 32, 32);
  63. BN_free (x); BN_free (y);
  64. verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>();
  65. verifier->SetPublicKey (signingKey);
  66. }
  67. else
  68. LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
  69. }
  70. EC_KEY_free (ecKey);
  71. }
  72. break;
  73. }
  74. default:
  75. LogPrint (eLogWarning, "Family: Certificate key type ", keyType, " is not supported");
  76. }
  77. EVP_PKEY_free (pkey);
  78. if (verifier && cn)
  79. m_SigningKeys[cn] = verifier;
  80. }
  81. SSL_free (ssl);
  82. }
  83. else
  84. LogPrint (eLogError, "Family: Can't open certificate file ", filename);
  85. SSL_CTX_free (ctx);
  86. }
  87. void Families::LoadCertificates ()
  88. {
  89. std::string certDir = i2p::fs::DataDirPath("certificates", "family");
  90. std::vector<std::string> files;
  91. int numCertificates = 0;
  92. if (!i2p::fs::ReadDir(certDir, files)) {
  93. LogPrint(eLogWarning, "Family: Can't load family certificates from ", certDir);
  94. return;
  95. }
  96. for (const std::string & file : files) {
  97. if (file.compare(file.size() - 4, 4, ".crt") != 0) {
  98. LogPrint(eLogWarning, "Family: ignoring file ", file);
  99. continue;
  100. }
  101. LoadCertificate (file);
  102. numCertificates++;
  103. }
  104. LogPrint (eLogInfo, "Family: ", numCertificates, " certificates loaded");
  105. }
  106. bool Families::VerifyFamily (const std::string& family, const IdentHash& ident,
  107. const char * signature, const char * key)
  108. {
  109. uint8_t buf[50], signatureBuf[64];
  110. size_t len = family.length (), signatureLen = strlen (signature);
  111. if (len + 32 > 50)
  112. {
  113. LogPrint (eLogError, "Family: ", family, " is too long");
  114. return false;
  115. }
  116. memcpy (buf, family.c_str (), len);
  117. memcpy (buf + len, (const uint8_t *)ident, 32);
  118. len += 32;
  119. Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
  120. auto it = m_SigningKeys.find (family);
  121. if (it != m_SigningKeys.end ())
  122. return it->second->Verify (buf, len, signatureBuf);
  123. // TODO: process key
  124. return true;
  125. }
  126. std::string CreateFamilySignature (const std::string& family, const IdentHash& ident)
  127. {
  128. auto filename = i2p::fs::DataDirPath("family", (family + ".key"));
  129. std::string sig;
  130. SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
  131. int ret = SSL_CTX_use_PrivateKey_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
  132. if (ret)
  133. {
  134. SSL * ssl = SSL_new (ctx);
  135. EVP_PKEY * pkey = SSL_get_privatekey (ssl);
  136. EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey);
  137. if (ecKey)
  138. {
  139. auto group = EC_KEY_get0_group (ecKey);
  140. if (group)
  141. {
  142. int curve = EC_GROUP_get_curve_name (group);
  143. if (curve == NID_X9_62_prime256v1)
  144. {
  145. uint8_t signingPrivateKey[32], buf[50], signature[64];
  146. i2p::crypto::bn2buf (EC_KEY_get0_private_key (ecKey), signingPrivateKey, 32);
  147. i2p::crypto::ECDSAP256Signer signer (signingPrivateKey);
  148. size_t len = family.length ();
  149. memcpy (buf, family.c_str (), len);
  150. memcpy (buf + len, (const uint8_t *)ident, 32);
  151. len += 32;
  152. signer.Sign (buf, len, signature);
  153. len = Base64EncodingBufferSize (64);
  154. char * b64 = new char[len+1];
  155. len = ByteStreamToBase64 (signature, 64, b64, len);
  156. b64[len] = 0;
  157. sig = b64;
  158. delete[] b64;
  159. }
  160. else
  161. LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
  162. }
  163. }
  164. SSL_free (ssl);
  165. }
  166. else
  167. LogPrint (eLogError, "Family: Can't open keys file: ", filename);
  168. SSL_CTX_free (ctx);
  169. return sig;
  170. }
  171. }
  172. }