1 | // |
2 | // ECTest.cpp |
3 | // |
4 | // |
5 | // Copyright (c) 2008, Applied Informatics Software Engineering GmbH. |
6 | // and Contributors. |
7 | // |
8 | // SPDX-License-Identifier: BSL-1.0 |
9 | // |
10 | |
11 | |
12 | #include "ECTest.h" |
13 | #include "Poco/CppUnit/TestCaller.h" |
14 | #include "Poco/CppUnit/TestSuite.h" |
15 | #include "Poco/Crypto/ECKey.h" |
16 | #include "Poco/Crypto/ECDSADigestEngine.h" |
17 | #include <openssl/pem.h> |
18 | #include <iostream> |
19 | #include <sstream> |
20 | #include <cstring> |
21 | |
22 | |
23 | using namespace Poco::Crypto; |
24 | |
25 | |
26 | ECTest::ECTest(const std::string& name): CppUnit::TestCase(name) |
27 | { |
28 | } |
29 | |
30 | |
31 | ECTest::~ECTest() |
32 | { |
33 | } |
34 | |
35 | |
36 | void ECTest::testCurveNIDName() |
37 | { |
38 | std::string curveName = ECKey::getCurveName(); |
39 | assertTrue (!curveName.empty()); |
40 | assertTrue (ECKey::getCurveNID(curveName) != -1); |
41 | assertTrue (ECKey::hasCurve(curveName)); |
42 | } |
43 | |
44 | |
45 | void ECTest::testECNewKeys() |
46 | { |
47 | try |
48 | { |
49 | std::string curveName = ECKey::getCurveName(); |
50 | if (!curveName.empty()) |
51 | { |
52 | ECKey key(curveName); |
53 | std::ostringstream strPub; |
54 | std::ostringstream strPriv; |
55 | key.save(&strPub, &strPriv, "testpwd" ); |
56 | std::string pubKey = strPub.str(); |
57 | std::string privKey = strPriv.str(); |
58 | |
59 | // now do the round trip |
60 | std::istringstream iPub(pubKey); |
61 | std::istringstream iPriv(privKey); |
62 | ECKey key2(&iPub, &iPriv, "testpwd" ); |
63 | |
64 | std::istringstream iPriv2(privKey); |
65 | ECKey key3(0, &iPriv2, "testpwd" ); |
66 | std::ostringstream strPub3; |
67 | key3.save(&strPub3); |
68 | std::string pubFromPrivate = strPub3.str(); |
69 | assertTrue (pubFromPrivate == pubKey); |
70 | } |
71 | else |
72 | std::cerr << "No elliptic curves found!" << std::endl; |
73 | } |
74 | catch (Poco::Exception& ex) |
75 | { |
76 | std::cerr << ex.displayText() << std::endl; |
77 | throw; |
78 | } |
79 | } |
80 | |
81 | |
82 | void ECTest::testECNewKeysNoPassphrase() |
83 | { |
84 | try |
85 | { |
86 | std::string curveName = ECKey::getCurveName(); |
87 | if (!curveName.empty()) |
88 | { |
89 | ECKey key(curveName); |
90 | std::ostringstream strPub; |
91 | std::ostringstream strPriv; |
92 | key.save(&strPub, &strPriv); |
93 | std::string pubKey = strPub.str(); |
94 | std::string privKey = strPriv.str(); |
95 | |
96 | // now do the round trip |
97 | std::istringstream iPub(pubKey); |
98 | std::istringstream iPriv(privKey); |
99 | ECKey key2(&iPub, &iPriv); |
100 | |
101 | std::istringstream iPriv2(privKey); |
102 | ECKey key3(0, &iPriv2); |
103 | std::ostringstream strPub3; |
104 | key3.save(&strPub3); |
105 | std::string pubFromPrivate = strPub3.str(); |
106 | assertTrue (pubFromPrivate == pubKey); |
107 | } |
108 | else |
109 | std::cerr << "No elliptic curves found!" << std::endl; |
110 | } |
111 | catch (Poco::Exception& ex) |
112 | { |
113 | std::cerr << ex.displayText() << std::endl; |
114 | throw; |
115 | } |
116 | } |
117 | |
118 | |
119 | void ECTest::testECDSASignSha256() |
120 | { |
121 | try |
122 | { |
123 | std::string curveName = ECKey::getCurveName(); |
124 | if (!curveName.empty()) |
125 | { |
126 | std::string msg("Test this sign message" ); |
127 | ECKey key(curveName); |
128 | ECDSADigestEngine eng(key, "SHA256" ); |
129 | eng.update(msg.c_str(), static_cast<unsigned>(msg.length())); |
130 | const Poco::DigestEngine::Digest& sig = eng.signature(); |
131 | |
132 | // verify |
133 | std::ostringstream strPub; |
134 | key.save(&strPub); |
135 | std::string pubKey = strPub.str(); |
136 | std::istringstream iPub(pubKey); |
137 | ECKey keyPub(&iPub); |
138 | ECDSADigestEngine eng2(keyPub, "SHA256" ); |
139 | eng2.update(msg.c_str(), static_cast<unsigned>(msg.length())); |
140 | assertTrue (eng2.verify(sig)); |
141 | } |
142 | else |
143 | std::cerr << "No elliptic curves found!" << std::endl; |
144 | } |
145 | catch (Poco::Exception& ex) |
146 | { |
147 | std::cerr << ex.displayText() << std::endl; |
148 | throw; |
149 | } |
150 | } |
151 | |
152 | |
153 | void ECTest::testECDSASignManipulated() |
154 | { |
155 | try |
156 | { |
157 | std::string curveName = ECKey::getCurveName(); |
158 | if (!curveName.empty()) |
159 | { |
160 | std::string msg("Test this sign message" ); |
161 | std::string msgManip("Test that sign message" ); |
162 | ECKey key(curveName); |
163 | ECDSADigestEngine eng(key, "SHA256" ); |
164 | eng.update(msg.c_str(), static_cast<unsigned>(msg.length())); |
165 | const Poco::DigestEngine::Digest& sig = eng.signature(); |
166 | std::string hexDig = Poco::DigestEngine::digestToHex(sig); |
167 | |
168 | // verify |
169 | std::ostringstream strPub; |
170 | key.save(&strPub); |
171 | std::string pubKey = strPub.str(); |
172 | std::istringstream iPub(pubKey); |
173 | ECKey keyPub(&iPub); |
174 | ECDSADigestEngine eng2(keyPub, "SHA256" ); |
175 | eng2.update(msgManip.c_str(), static_cast<unsigned>(msgManip.length())); |
176 | assertTrue (!eng2.verify(sig)); |
177 | } |
178 | else |
179 | std::cerr << "No elliptic curves found!" << std::endl; |
180 | } |
181 | catch (Poco::Exception& ex) |
182 | { |
183 | std::cerr << ex.displayText() << std::endl; |
184 | throw; |
185 | } |
186 | } |
187 | |
188 | |
189 | void ECTest::setUp() |
190 | { |
191 | } |
192 | |
193 | |
194 | void ECTest::tearDown() |
195 | { |
196 | } |
197 | |
198 | |
199 | CppUnit::Test* ECTest::suite() |
200 | { |
201 | CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ECTest" ); |
202 | |
203 | CppUnit_addTest(pSuite, ECTest, testCurveNIDName); |
204 | CppUnit_addTest(pSuite, ECTest, testECNewKeys); |
205 | CppUnit_addTest(pSuite, ECTest, testECNewKeysNoPassphrase); |
206 | CppUnit_addTest(pSuite, ECTest, testECDSASignSha256); |
207 | CppUnit_addTest(pSuite, ECTest, testECDSASignManipulated); |
208 | |
209 | return pSuite; |
210 | } |
211 | |