1 // 2 // ECDSADigestEngine.h 3 // 4 // 5 // Library: Crypto 6 // Package: ECDSA 7 // Module: ECDSADigestEngine 8 // 9 // Definition of the ECDSADigestEngine class. 10 // 11 // Copyright (c) 2008, Applied Informatics Software Engineering GmbH. 12 // and Contributors. 13 // 14 // SPDX-License-Identifier: BSL-1.0 15 // 16 17 18 #ifndef Crypto_ECDSADigestEngine_INCLUDED 19 #define Crypto_ECDSADigestEngine_INCLUDED 20 21 22 #include "Poco/Crypto/Crypto.h" 23 #include "Poco/Crypto/ECKey.h" 24 #include "Poco/DigestEngine.h" 25 #include "Poco/Crypto/DigestEngine.h" 26 #include <istream> 27 #include <ostream> 28 29 30 namespace Poco { 31 namespace Crypto { 32 33 34 class Crypto_API ECDSADigestEngine: public Poco::DigestEngine 35 /// This class implements a Poco::DigestEngine that can be 36 /// used to compute a secure digital signature. 37 /// 38 /// First another Poco::Crypto::DigestEngine is created and 39 /// used to compute a cryptographic hash of the data to be 40 /// signed. Then, the hash value is encrypted, using 41 /// the ECDSA private key. 42 /// 43 /// To verify a signature, pass it to the verify() 44 /// member function. It will decrypt the signature 45 /// using the ECDSA public key and compare the resulting 46 /// hash with the actual hash of the data. 47 { 48 public: 49 50 ECDSADigestEngine(const ECKey& key, const std::string &name); 51 /// Creates the ECDSADigestEngine with the given ECDSA key, 52 /// using the hash algorithm with the given name 53 /// (e.g., "SHA1", "SHA256", "SHA512", etc.). 54 /// See the OpenSSL documentation for a list of supported digest algorithms. 55 /// 56 /// Throws a Poco::NotFoundException if no algorithm with the given name exists. 57 58 ~ECDSADigestEngine(); 59 /// Destroys the ECDSADigestEngine. 60 61 std::size_t digestLength() const; 62 /// Returns the length of the digest in bytes. 63 64 void reset(); 65 /// Resets the engine so that a new 66 /// digest can be computed. 67 68 const DigestEngine::Digest& digest(); 69 /// Finishes the computation of the digest 70 /// (the first time it's called) and 71 /// returns the message digest. 72 /// 73 /// Can be called multiple times. 74 75 const DigestEngine::Digest& signature(); 76 /// Signs the digest using the ECDSADSA algorithm 77 /// and the private key (the first time it's 78 /// called) and returns the result. 79 /// 80 /// Can be called multiple times. 81 82 bool verify(const DigestEngine::Digest& signature); 83 /// Verifies the data against the signature. 84 /// 85 /// Returns true if the signature can be verified, false otherwise. 86 87 protected: 88 void updateImpl(const void* data, std::size_t length); 89 90 private: 91 ECKey _key; 92 Poco::Crypto::DigestEngine _engine; 93 Poco::DigestEngine::Digest _digest; 94 Poco::DigestEngine::Digest _signature; 95 }; 96 97 98 class Crypto_API ECDSASignature 99 /// A helper class for dealing with ECDSA signatures. 100 { 101 public: 102 using ByteVec = std::vector<unsigned char>; 103 104 explicit ECDSASignature(const ByteVec& derSignature); 105 /// Creates the ECDSASignature from a DER-encoded signature. 106 107 ECDSASignature(const ByteVec& rawR, const ByteVec& rawS); 108 /// Creates the ECDSASignature from raw r and s values. 109 110 ~ECDSASignature(); 111 /// Destroys the ECDSASignature. 112 113 ByteVec toDER() const; 114 /// Returns a buffer containing the DER-encoded signature. 115 116 ByteVec rawR() const; 117 /// Returns a raw P value. 118 119 ByteVec rawS() const; 120 /// Returns a raw Q value. 121 122 private: 123 ECDSA_SIG* _pSig; 124 }; 125 126 127 } } // namespace Poco::Crypto 128 129 130 #endif // Crypto_ECDSADigestEngine_INCLUDED 131