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