1 | // |
2 | // ECDSADigestEngine.cpp |
3 | // |
4 | // |
5 | // Library: Crypto |
6 | // Package: ECDSA |
7 | // Module: ECDSADigestEngine |
8 | // |
9 | // Copyright (c) 2008, Applied Informatics Software Engineering GmbH. |
10 | // and Contributors. |
11 | // |
12 | // SPDX-License-Identifier: BSL-1.0 |
13 | // |
14 | |
15 | |
16 | #include "Poco/Crypto/ECDSADigestEngine.h" |
17 | #include <openssl/ecdsa.h> |
18 | |
19 | |
20 | namespace Poco { |
21 | namespace Crypto { |
22 | |
23 | |
24 | ECDSADigestEngine::ECDSADigestEngine(const ECKey& key, const std::string &name): |
25 | _key(key), |
26 | _engine(name) |
27 | { |
28 | } |
29 | |
30 | |
31 | ECDSADigestEngine::~ECDSADigestEngine() |
32 | { |
33 | } |
34 | |
35 | |
36 | std::size_t ECDSADigestEngine::digestLength() const |
37 | { |
38 | return _engine.digestLength(); |
39 | } |
40 | |
41 | |
42 | void ECDSADigestEngine::reset() |
43 | { |
44 | _engine.reset(); |
45 | _digest.clear(); |
46 | _signature.clear(); |
47 | } |
48 | |
49 | |
50 | const DigestEngine::Digest& ECDSADigestEngine::digest() |
51 | { |
52 | if (_digest.empty()) |
53 | { |
54 | _digest = _engine.digest(); |
55 | } |
56 | return _digest; |
57 | } |
58 | |
59 | |
60 | const DigestEngine::Digest& ECDSADigestEngine::signature() |
61 | { |
62 | if (_signature.empty()) |
63 | { |
64 | digest(); |
65 | _signature.resize(_key.size()); |
66 | unsigned sigLen = static_cast<unsigned>(_signature.size()); |
67 | if (!ECDSA_sign(0, &_digest[0], static_cast<unsigned>(_digest.size()), |
68 | &_signature[0], &sigLen, _key.impl()->getECKey())) |
69 | { |
70 | throw OpenSSLException(); |
71 | } |
72 | if (sigLen < _signature.size()) _signature.resize(sigLen); |
73 | } |
74 | return _signature; |
75 | } |
76 | |
77 | |
78 | bool ECDSADigestEngine::verify(const DigestEngine::Digest& sig) |
79 | { |
80 | digest(); |
81 | EC_KEY* pKey = _key.impl()->getECKey(); |
82 | if (pKey) |
83 | { |
84 | int ret = ECDSA_verify(0, &_digest[0], static_cast<unsigned>(_digest.size()), |
85 | &sig[0], static_cast<unsigned>(sig.size()), |
86 | pKey); |
87 | if (1 == ret) return true; |
88 | else if (0 == ret) return false; |
89 | } |
90 | throw OpenSSLException(); |
91 | } |
92 | |
93 | |
94 | void ECDSADigestEngine::updateImpl(const void* data, std::size_t length) |
95 | { |
96 | _engine.update(data, length); |
97 | } |
98 | |
99 | |
100 | } } // namespace Poco::Crypto |
101 | |