@@ -72,28 +72,36 @@ HybridEdKeyPair::generateKeyPairSync(
72
72
73
73
std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>>
74
74
HybridEdKeyPair::sign (
75
- const std::shared_ptr<ArrayBuffer>& message
75
+ const std::shared_ptr<ArrayBuffer>& message,
76
+ const std::optional<std::shared_ptr<ArrayBuffer>>& key
76
77
) {
77
78
// get owned NativeArrayBuffer before passing to sync function
78
79
auto nativeMessage = ToNativeArrayBuffer (message);
80
+ std::optional<std::shared_ptr<ArrayBuffer>> nativeKey = std::nullopt;
81
+ if (key.has_value ()) {
82
+ nativeKey = ToNativeArrayBuffer (key.value ());
83
+ }
79
84
80
- return Promise<std::shared_ptr<ArrayBuffer>>::async ([this , nativeMessage]() {
81
- return this ->signSync (nativeMessage);
85
+ return Promise<std::shared_ptr<ArrayBuffer>>::async ([this , nativeMessage, nativeKey ]() {
86
+ return this ->signSync (nativeMessage, nativeKey );
82
87
}
83
88
);
84
89
}
85
90
86
91
std::shared_ptr<ArrayBuffer>
87
92
HybridEdKeyPair::signSync (
88
- const std::shared_ptr<ArrayBuffer>& message
93
+ const std::shared_ptr<ArrayBuffer>& message,
94
+ const std::optional<std::shared_ptr<ArrayBuffer>>& key
89
95
) {
90
- this ->checkKeyPair ();
91
96
92
97
size_t sig_len = 0 ;
93
98
uint8_t * sig = NULL ;
94
99
EVP_MD_CTX* md_ctx = nullptr ;
95
100
EVP_PKEY_CTX* pkey_ctx = nullptr ;
96
101
102
+ // get key to use for signing
103
+ EVP_PKEY* pkey = this ->importPrivateKey (key);
104
+
97
105
// key context
98
106
md_ctx = EVP_MD_CTX_new ();
99
107
if (md_ctx == nullptr ) {
@@ -107,7 +115,7 @@ HybridEdKeyPair::signSync(
107
115
throw std::runtime_error (" Error creating signing context: " + this ->curve );
108
116
}
109
117
110
- if (EVP_DigestSignInit (md_ctx, &pkey_ctx, NULL , NULL , this -> pkey ) <= 0 ) {
118
+ if (EVP_DigestSignInit (md_ctx, &pkey_ctx, NULL , NULL , pkey) <= 0 ) {
111
119
EVP_MD_CTX_free (md_ctx);
112
120
char * err = ERR_error_string (ERR_get_error (), NULL );
113
121
throw std::runtime_error (" Failed to initialize signing: " + std::string (err));
@@ -142,24 +150,31 @@ HybridEdKeyPair::signSync(
142
150
std::shared_ptr<Promise<bool >>
143
151
HybridEdKeyPair::verify (
144
152
const std::shared_ptr<ArrayBuffer>& signature,
145
- const std::shared_ptr<ArrayBuffer>& message
153
+ const std::shared_ptr<ArrayBuffer>& message,
154
+ const std::optional<std::shared_ptr<ArrayBuffer>>& key
146
155
) {
147
156
// get owned NativeArrayBuffers before passing to sync function
148
157
auto nativeSignature = ToNativeArrayBuffer (signature);
149
158
auto nativeMessage = ToNativeArrayBuffer (message);
159
+ std::optional<std::shared_ptr<ArrayBuffer>> nativeKey = std::nullopt;
160
+ if (key.has_value ()) {
161
+ nativeKey = ToNativeArrayBuffer (key.value ());
162
+ }
150
163
151
- return Promise<bool >::async ([this , nativeSignature, nativeMessage]() {
152
- return this ->verifySync (nativeSignature, nativeMessage);
164
+ return Promise<bool >::async ([this , nativeSignature, nativeMessage, nativeKey ]() {
165
+ return this ->verifySync (nativeSignature, nativeMessage, nativeKey );
153
166
}
154
167
);
155
168
}
156
169
157
170
bool
158
171
HybridEdKeyPair::verifySync (
159
172
const std::shared_ptr<ArrayBuffer>& signature,
160
- const std::shared_ptr<ArrayBuffer>& message
173
+ const std::shared_ptr<ArrayBuffer>& message,
174
+ const std::optional<std::shared_ptr<ArrayBuffer>>& key
161
175
) {
162
- this ->checkKeyPair ();
176
+ // get key to use for verifying
177
+ EVP_PKEY* pkey = this ->importPrivateKey (key);
163
178
164
179
EVP_MD_CTX* md_ctx = nullptr ;
165
180
EVP_PKEY_CTX* pkey_ctx = nullptr ;
@@ -177,7 +192,7 @@ HybridEdKeyPair::verifySync(
177
192
throw std::runtime_error (" Error creating verify context: " + this ->curve );
178
193
}
179
194
180
- if (EVP_DigestVerifyInit (md_ctx, &pkey_ctx, NULL , NULL , this -> pkey ) <= 0 ) {
195
+ if (EVP_DigestVerifyInit (md_ctx, &pkey_ctx, NULL , NULL , pkey) <= 0 ) {
181
196
EVP_MD_CTX_free (md_ctx);
182
197
char * err = ERR_error_string (ERR_get_error (), NULL );
183
198
throw std::runtime_error (" Failed to initialize verify: " + std::string (err));
@@ -230,4 +245,24 @@ HybridEdKeyPair::setCurve(const std::string& curve) {
230
245
this ->curve = curve;
231
246
}
232
247
248
+ EVP_PKEY*
249
+ HybridEdKeyPair::importPrivateKey (const std::optional<std::shared_ptr<ArrayBuffer>>& key) {
250
+ EVP_PKEY* pkey = nullptr ;
251
+ if (key.has_value ()) {
252
+ pkey = EVP_PKEY_new_raw_private_key (
253
+ EVP_PKEY_ED25519, // TODO: use this->curve somehow
254
+ NULL ,
255
+ key.value ()->data (),
256
+ 32
257
+ );
258
+ if (pkey == nullptr ) {
259
+ throw std::runtime_error (" Failed to read private key" );
260
+ }
261
+ } else {
262
+ this ->checkKeyPair ();
263
+ pkey = this ->pkey ;
264
+ }
265
+ return pkey;
266
+ }
267
+
233
268
} // namespace margelo::nitro::crypto
0 commit comments