Loading...
Searching...
No Matches
signature_utils.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019-2022 ExpoLab, UC Davis
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 */
25
27
28#include <cryptopp/eccrypto.h>
29#include <cryptopp/hex.h>
30#include <cryptopp/osrng.h>
31#include <cryptopp/pssr.h>
32#include <cryptopp/rsa.h>
33#include <cryptopp/whrlpool.h>
34#include <glog/logging.h>
35
36namespace resdb {
37namespace utils {
38
39bool RsaVerifyString(const std::string& message, const std::string& public_key,
40 const std::string& signature) {
41 try {
42 // decode and load public key (using pipeline)
43 CryptoPP::RSA::PublicKey rsa_public_key;
44 rsa_public_key.Load(
45 CryptoPP::StringSource(public_key, true, new CryptoPP::HexDecoder())
46 .Ref());
47
48 // decode signature
49 std::string decoded_signature;
50 CryptoPP::StringSource ss(
51 signature, true,
52 new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded_signature)));
53
54 // verify message
55 bool result = false;
56 CryptoPP::RSASS<CryptoPP::PSSR, CryptoPP::Whirlpool>::Verifier verifier(
57 rsa_public_key);
58 CryptoPP::StringSource ss2(
59 decoded_signature + message, true,
60 new CryptoPP::SignatureVerificationFilter(
61 verifier,
62 new CryptoPP::ArraySink((CryptoPP::byte*)&result, sizeof(result))));
63
64 return result;
65 } catch (...) {
66 LOG(ERROR) << "key not valid";
67 return false;
68 }
69}
70
71bool ECDSAVerifyString(const std::string& message,
72 const std::string& public_key,
73 const std::string& signature) {
74 std::string decoded;
75 std::string output;
76 CryptoPP::StringSource(
77 signature, true,
78 new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded)) // StringSink
79 ); // StringSource
80
81 CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey dsa_public_key;
82 dsa_public_key.Load(
83 CryptoPP::StringSource(public_key, true, new CryptoPP::HexDecoder())
84 .Ref());
85 CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Verifier verifier(
86 dsa_public_key);
87
88 bool valid = true;
89 CryptoPP::StringSource(
90 decoded + message, true,
91 new CryptoPP::SignatureVerificationFilter(
92 verifier,
93 new CryptoPP::ArraySink((CryptoPP::byte*)&valid, sizeof(valid))));
94 if (!valid) {
95 LOG(ERROR) << "signature invalid. signature len:" << signature.size()
96 << " message len:" << message.size();
97 }
98 return valid;
99}
100
101std::string RsaSignString(const std::string& private_key,
102 const std::string& message) {
103 // decode and load private key (using pipeline)
104 CryptoPP::RSA::PrivateKey rsa_private_key;
105 rsa_private_key.Load(
106 CryptoPP::StringSource(private_key, true, new CryptoPP::HexDecoder())
107 .Ref());
108
109 // sign message
110 std::string signature;
111 CryptoPP::RSASS<CryptoPP::PSSR, CryptoPP::Whirlpool>::Signer signer(
112 rsa_private_key);
113 CryptoPP::AutoSeededRandomPool rng;
114 CryptoPP::StringSource ss(
115 message, true,
116 new CryptoPP::SignerFilter(
117 rng, signer,
118 new CryptoPP::HexEncoder(new CryptoPP::StringSink(signature))));
119 return signature;
120}
121
122std::string ECDSASignString(const std::string& private_key,
123 const std::string& message) {
124 try {
125 CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey privateKey;
126 privateKey.Load(
127 CryptoPP::StringSource(private_key, true, new CryptoPP::HexDecoder())
128 .Ref());
129 CryptoPP::AutoSeededRandomPool prng;
130 std::string signature;
131
132 CryptoPP::StringSource ss1(
133 message, true /*pump all*/,
134 new CryptoPP::SignerFilter(
135 prng,
136 CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer(
137 privateKey),
138 new CryptoPP::StringSink(signature)));
139
140 std::string output;
141 CryptoPP::StringSource(signature, true,
142 new CryptoPP::HexEncoder(
143 new CryptoPP::StringSink(output)) // HexEncoder
144 ); // StringSource
145 return output;
146 } catch (...) {
147 LOG(ERROR) << "sign error";
148 return "";
149 }
150}
151
152} // namespace utils
153} // namespace resdb
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)