common/crypto/signature_utils.cpp (108 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "common/crypto/signature_utils.h"
#include <cryptopp/eccrypto.h>
#include <cryptopp/hex.h>
#include <cryptopp/osrng.h>
#include <cryptopp/pssr.h>
#include <cryptopp/rsa.h>
#include <cryptopp/whrlpool.h>
#include <glog/logging.h>
namespace resdb {
namespace utils {
bool RsaVerifyString(const std::string& message, const std::string& public_key,
const std::string& signature) {
try {
// decode and load public key (using pipeline)
CryptoPP::RSA::PublicKey rsa_public_key;
rsa_public_key.Load(
CryptoPP::StringSource(public_key, true, new CryptoPP::HexDecoder())
.Ref());
// decode signature
std::string decoded_signature;
CryptoPP::StringSource ss(
signature, true,
new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded_signature)));
// verify message
bool result = false;
CryptoPP::RSASS<CryptoPP::PSSR, CryptoPP::Whirlpool>::Verifier verifier(
rsa_public_key);
CryptoPP::StringSource ss2(
decoded_signature + message, true,
new CryptoPP::SignatureVerificationFilter(
verifier,
new CryptoPP::ArraySink((CryptoPP::byte*)&result, sizeof(result))));
return result;
} catch (...) {
LOG(ERROR) << "key not valid";
return false;
}
}
bool ECDSAVerifyString(const std::string& message,
const std::string& public_key,
const std::string& signature) {
std::string decoded;
std::string output;
CryptoPP::StringSource(
signature, true,
new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)) // StringSink
); // StringSource
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey dsa_public_key;
dsa_public_key.Load(
CryptoPP::StringSource(public_key, true, new CryptoPP::HexDecoder())
.Ref());
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Verifier verifier(
dsa_public_key);
bool valid = true;
CryptoPP::StringSource(
decoded + message, true,
new CryptoPP::SignatureVerificationFilter(
verifier,
new CryptoPP::ArraySink((CryptoPP::byte*)&valid, sizeof(valid))));
if (!valid) {
LOG(ERROR) << "signature invalid. signature len:" << signature.size()
<< " message len:" << message.size();
}
return valid;
}
std::string RsaSignString(const std::string& private_key,
const std::string& message) {
// decode and load private key (using pipeline)
CryptoPP::RSA::PrivateKey rsa_private_key;
rsa_private_key.Load(
CryptoPP::StringSource(private_key, true, new CryptoPP::HexDecoder())
.Ref());
// sign message
std::string signature;
CryptoPP::RSASS<CryptoPP::PSSR, CryptoPP::Whirlpool>::Signer signer(
rsa_private_key);
CryptoPP::AutoSeededRandomPool rng;
CryptoPP::StringSource ss(
message, true,
new CryptoPP::SignerFilter(
rng, signer,
new CryptoPP::HexEncoder(new CryptoPP::StringSink(signature))));
return signature;
}
std::string ECDSASignString(const std::string& private_key,
const std::string& message) {
try {
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey privateKey;
privateKey.Load(
CryptoPP::StringSource(private_key, true, new CryptoPP::HexDecoder())
.Ref());
CryptoPP::AutoSeededRandomPool prng;
std::string signature;
CryptoPP::StringSource ss1(
message, true /*pump all*/,
new CryptoPP::SignerFilter(
prng,
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer(
privateKey),
new CryptoPP::StringSink(signature)));
std::string output;
CryptoPP::StringSource(signature, true,
new CryptoPP::HexEncoder(
new CryptoPP::StringSink(output)) // HexEncoder
); // StringSource
return output;
} catch (...) {
LOG(ERROR) << "sign error";
return "";
}
}
} // namespace utils
} // namespace resdb