| 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 | |