28#include <cryptopp/aes.h>
29#include <cryptopp/cmac.h>
30#include <cryptopp/dsa.h>
31#include <cryptopp/eccrypto.h>
32#include <cryptopp/filters.h>
33#include <cryptopp/hex.h>
34#include <cryptopp/osrng.h>
35#include <cryptopp/pssr.h>
36#include <cryptopp/rsa.h>
37#include <cryptopp/sha.h>
38#include <cryptopp/whrlpool.h>
39#include <glog/logging.h>
48bool ED25519verifyString(
const std::string& message,
49 const std::string& public_key,
50 const std::string& signature) {
51 CryptoPP::byte byteKey[CryptoPP::ed25519PrivateKey::PUBLIC_KEYLENGTH];
52 if (public_key.size() != CryptoPP::ed25519PrivateKey::PUBLIC_KEYLENGTH) {
53 LOG(ERROR) <<
"public key len invalid:" << public_key.size();
56 memcpy(byteKey, public_key.c_str(), public_key.size());
57 auto verifier = CryptoPP::ed25519::Verifier(byteKey);
60 CryptoPP::StringSource(
61 signature + message,
true,
62 new CryptoPP::SignatureVerificationFilter(
64 new CryptoPP::ArraySink((CryptoPP::byte*)&valid,
sizeof(valid))));
66 LOG(ERROR) <<
"signature invalid. signature len:" << signature.size()
67 <<
" message len:" << message.size();
72bool CmacVerifyString(
const std::string& message,
const std::string& public_key,
73 const std::string& signature) {
77 CryptoPP::SecByteBlock privKey((
const unsigned char*)(public_key.data()),
79 CryptoPP::CMAC<CryptoPP::AES> cmac(privKey.data(), privKey.size());
80 const int flags = CryptoPP::HashVerificationFilter::HASH_AT_END |
81 CryptoPP::HashVerificationFilter::PUT_RESULT;
84 CryptoPP::StringSource ss3(
85 message + signature,
true,
86 new CryptoPP::HashVerificationFilter(
87 cmac,
new CryptoPP::ArraySink((CryptoPP::byte*)&res,
sizeof(res)),
94std::string ED25519signString(
const std::string& message,
95 CryptoPP::ed25519::Signer* signer) {
96 CryptoPP::AutoSeededRandomPool prng;
97 std::string signature;
98 CryptoPP::StringSource(
100 new CryptoPP::SignerFilter(CryptoPP::NullRNG(), *signer,
101 new CryptoPP::StringSink(signature)));
107std::string CmacSignString(
const std::string& private_key,
108 const std::string& message) {
109 std::string mac =
"";
114 CryptoPP::SecByteBlock mac_private_key(
115 (
const unsigned char*)(private_key.data()), private_key.size());
117 CryptoPP::CMAC<CryptoPP::AES> cmac(mac_private_key.data(),
118 mac_private_key.size());
120 CryptoPP::StringSource ss1(
122 new CryptoPP::HashFilter(cmac,
new CryptoPP::StringSink(mac)));
129 const CertificateInfo& certificate_info) {
130 private_key_ = private_key;
131 if (private_key_.key().empty()) {
132 LOG(ERROR) <<
"private invalid";
135 node_id_ = certificate_info.node_id();
136 admin_public_key_ = certificate_info.admin_public_key();
138 if (private_key_.hash_type() == SignatureInfo::ED25519) {
139 CryptoPP::byte byteKey[CryptoPP::ed25519PrivateKey::SECRET_KEYLENGTH];
140 if (private_key_.key().size() !=
141 CryptoPP::ed25519PrivateKey::SECRET_KEYLENGTH) {
144 memcpy(byteKey, private_key_.key().c_str(), private_key_.key().size());
145 signer_ = std::make_unique<CryptoPP::ed25519::Signer>(byteKey);
151 std::unique_lock<std::shared_mutex> lk(mutex_);
153 !
VerifyKey(public_key.public_key_info(), public_key.certificate())) {
158 keys_[public_key.public_key_info().node_id()] = public_key;
163 std::shared_lock<std::shared_mutex> lk(mutex_);
164 auto it = keys_.find(node_id);
165 if (it == keys_.end()) {
166 return absl::InvalidArgumentError(
"Public key not exist.");
168 return it->second.public_key_info().key();
172 std::shared_lock<std::shared_mutex> lk(mutex_);
173 std::vector<CertificateKey>
keys;
174 for (
auto key : keys_) {
175 keys.push_back(key.second);
181 std::shared_lock<std::shared_mutex> lk(mutex_);
187 CryptoPP::byte
const* pData = (CryptoPP::byte*)str.data();
188 unsigned int nDataLen = str.size();
189 CryptoPP::byte aDigest[CryptoPP::SHA256::DIGESTSIZE];
191 CryptoPP::SHA256().CalculateDigest(aDigest, pData, nDataLen);
192 return std::string((
char*)aDigest, CryptoPP::SHA256::DIGESTSIZE);
196 const std::string& message) {
198 info.set_node_id(node_id_);
199 switch (private_key_.hash_type()) {
200 case SignatureInfo::RSA:
203 case SignatureInfo::ED25519:
204 info.set_signature(ED25519signString(message, signer_.get()));
206 case SignatureInfo::CMAC_AES:
207 info.set_signature(CmacSignString(private_key_.key(), message));
209 case SignatureInfo::ECDSA:
219 const SignatureInfo& sign) {
221 if (!message.SerializeToString(&str)) {
228 const SignatureInfo& info) {
229 if (info.signature().empty()) {
230 LOG(ERROR) <<
" signature is empty";
234 if (!public_key.ok()) {
235 LOG(ERROR) <<
"key not found:" << info.node_id();
238 return VerifyMessage(message, *public_key, info.signature());
242 const CertificateKeyInfo& info) {
244 if (!info.SerializeToString(&str)) {
245 return absl::InvalidArgumentError(
"Serialize fail");
251 const SignatureInfo& sign) {
253 if (!info.SerializeToString(&str)) {
256 return VerifyMessage(str, admin_public_key_, sign.signature());
260 const KeyInfo& public_key,
261 const std::string& signature) {
262 if (public_key.key().empty() || signature.empty()) {
263 LOG(ERROR) <<
"public is empty, size(" << public_key.key().size()
264 <<
") or signature is empty, size(" << signature.size() <<
")";
271 switch (public_key.hash_type()) {
272 case SignatureInfo::RSA:
274 case SignatureInfo::ED25519:
275 return ED25519verifyString(message, public_key.key(), signature);
276 case SignatureInfo::CMAC_AES:
277 return CmacVerifyString(message, public_key.key(), signature);
278 case SignatureInfo::ECDSA:
bool VerifyKey(const CertificateKeyInfo &info, const SignatureInfo &sign)
size_t GetPublicKeysSize() const
absl::StatusOr< SignatureInfo > SignCertificateKeyInfo(const CertificateKeyInfo &info)
absl::StatusOr< KeyInfo > GetPublicKey(int64_t node_id) const
SignatureVerifier(const KeyInfo &private_key, const CertificateInfo &certificate_info)
std::vector< CertificateKey > GetAllPublicKeys() const
static std::string CalculateHash(const std::string &str)
bool AddPublicKey(const CertificateKey &pub_key, bool need_verify=true)
virtual absl::StatusOr< SignatureInfo > SignMessage(const std::string &message)
virtual bool VerifyMessage(const std::string &message, const SignatureInfo &sign)
bool RsaVerifyString(const std::string &message, const std::string &public_key, const std::string &signature)
std::string ECDSASignString(const std::string &private_key, const std::string &message)
bool ECDSAVerifyString(const std::string &message, const std::string &public_key, const std::string &signature)
std::string RsaSignString(const std::string &private_key, const std::string &message)