1 //
2 // ECKeyImpl.h
3 //
4 //
5 // Library: Crypto
6 // Package: EC
7 // Module:  ECKeyImpl
8 //
9 // Definition of the ECKeyImpl 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_ECKeyImplImpl_INCLUDED
19 #define Crypto_ECKeyImplImpl_INCLUDED
20 
21 
22 #include "Poco/Crypto/Crypto.h"
23 #include "Poco/Crypto/EVPPKey.h"
24 #include "Poco/Crypto/KeyPairImpl.h"
25 #include "Poco/Crypto/OpenSSLInitializer.h"
26 #include "Poco/RefCountedObject.h"
27 #include "Poco/AutoPtr.h"
28 #include <istream>
29 #include <ostream>
30 #include <vector>
31 #include <openssl/objects.h>
32 #include <openssl/ec.h>
33 
34 
35 namespace Poco {
36 namespace Crypto {
37 
38 
39 class X509Certificate;
40 class PKCS12Container;
41 
42 
43 class ECKeyImpl: public KeyPairImpl
44 	/// Elliptic Curve key clas implementation.
45 {
46 public:
47 	using Ptr = Poco::AutoPtr<ECKeyImpl>;
48 	using ByteVec = std::vector<unsigned char>;
49 
50 	ECKeyImpl(const EVPPKey& key);
51 		/// Constructs ECKeyImpl by extracting the EC key.
52 
53 	ECKeyImpl(const X509Certificate& cert);
54 		/// Constructs ECKeyImpl by extracting the EC public key from the given certificate.
55 
56 	ECKeyImpl(const PKCS12Container& cert);
57 		/// Constructs ECKeyImpl by extracting the EC private key from the given certificate.
58 
59 	ECKeyImpl(int eccGroup);
60 		/// Creates the ECKey of the specified group. Creates a new public/private keypair using the given parameters.
61 		/// Can be used to sign data and verify signatures.
62 
63 	ECKeyImpl(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase);
64 		/// Creates the ECKey, by reading public and private key from the given files and
65 		/// using the given passphrase for the private key. Can only by used for signing if
66 		/// a private key is available.
67 
68 	ECKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase);
69 		/// Creates the ECKey. Can only by used for signing if pPrivKey
70 		/// is not null. If a private key file is specified, you don't need to
71 		/// specify a public key file. OpenSSL will auto-create it from the private key.
72 
73 	~ECKeyImpl();
74 		/// Destroys the ECKeyImpl.
75 
76 	EC_KEY* getECKey();
77 		/// Returns the OpenSSL EC key.
78 
79 	const EC_KEY* getECKey() const;
80 		/// Returns the OpenSSL EC key.
81 
82 	int size() const;
83 		/// Returns the EC key length in bits.
84 
85 	int groupId() const;
86 		/// Returns the EC key group integer Id.
87 
88 	std::string groupName() const;
89 		/// Returns the EC key group name.
90 
91 	void save(const std::string& publicKeyFile,
92 		const std::string& privateKeyFile = "",
93 		const std::string& privateKeyPassphrase = "") const;
94 		/// Exports the public and private keys to the given files.
95 		///
96 		/// If an empty filename is specified, the corresponding key
97 		/// is not exported.
98 
99 	void save(std::ostream* pPublicKeyStream,
100 		std::ostream* pPrivateKeyStream = 0,
101 		const std::string& privateKeyPassphrase = "") const;
102 		/// Exports the public and private key to the given streams.
103 		///
104 		/// If a null pointer is passed for a stream, the corresponding
105 		/// key is not exported.
106 
107 	static std::string getCurveName(int nid = -1);
108 		/// Returns elliptical curve name corresponding to
109 		/// the given nid; if nid is not found, returns
110 		/// empty string.
111 		///
112 		/// If nid is -1, returns first curve name.
113 		///
114 		/// If no curves are found, returns empty string;
115 
116 	static int getCurveNID(std::string& name);
117 		/// Returns the NID of the specified curve.
118 		///
119 		/// If name is empty, returns the first curve NID
120 		/// and updates the name accordingly.
121 
122 	static bool hasCurve(const std::string& name);
123 		/// Returns true if the named curve is found,
124 		/// false otherwise.
125 
126 private:
127 	void checkEC(const std::string& method, const std::string& func) const;
128 	void freeEC();
129 
130 	EC_KEY* _pEC;
131 };
132 
133 
134 //
135 // inlines
136 //
getECKey()137 inline EC_KEY* ECKeyImpl::getECKey()
138 {
139 	return _pEC;
140 }
141 
142 
getECKey()143 inline const EC_KEY* ECKeyImpl::getECKey() const
144 {
145 	return _pEC;
146 }
147 
148 
groupName()149 inline std::string ECKeyImpl::groupName() const
150 {
151 	return OBJ_nid2sn(groupId());
152 }
153 
154 
save(const std::string & publicKeyFile,const std::string & privateKeyFile,const std::string & privateKeyPassphrase)155 inline void ECKeyImpl::save(const std::string& publicKeyFile,
156 	const std::string& privateKeyFile,
157 	const std::string& privateKeyPassphrase) const
158 {
159 	EVPPKey(_pEC).save(publicKeyFile, privateKeyFile, privateKeyPassphrase);
160 }
161 
162 
save(std::ostream * pPublicKeyStream,std::ostream * pPrivateKeyStream,const std::string & privateKeyPassphrase)163 inline void ECKeyImpl::save(std::ostream* pPublicKeyStream,
164 	std::ostream* pPrivateKeyStream,
165 	const std::string& privateKeyPassphrase) const
166 {
167 	EVPPKey(_pEC).save(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase);
168 }
169 
170 
171 } } // namespace Poco::Crypto
172 
173 
174 #endif // Crypto_ECKeyImplImpl_INCLUDED
175