1 /* Copyright (C) 2009, 2010 Simon Josefsson
2  * Copyright (C) 2006, 2007 The Written Word, Inc.  All rights reserved.
3  * Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
4  *
5  * Author: Simon Josefsson
6  *
7  * Redistribution and use in source and binary forms,
8  * with or without modification, are permitted provided
9  * that the following conditions are met:
10  *
11  *   Redistributions of source code must retain the above
12  *   copyright notice, this list of conditions and the
13  *   following disclaimer.
14  *
15  *   Redistributions in binary form must reproduce the above
16  *   copyright notice, this list of conditions and the following
17  *   disclaimer in the documentation and/or other materials
18  *   provided with the distribution.
19  *
20  *   Neither the name of the copyright holder nor the names
21  *   of any other contributors may be used to endorse or
22  *   promote products derived from this software without
23  *   specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
38  * OF SUCH DAMAGE.
39  */
40 
41 #include "libssh2_priv.h"
42 
43 #ifdef LIBSSH2_OPENSSL /* compile only if we build with openssl */
44 
45 #include <string.h>
46 #include "misc.h"
47 
48 #ifndef EVP_MAX_BLOCK_LENGTH
49 #define EVP_MAX_BLOCK_LENGTH 32
50 #endif
51 
52 int
53 read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session,
54                                      const char *key_type,
55                                      const char *filedata,
56                                      size_t filedata_len,
57                                      unsigned const char *passphrase);
58 
59 static unsigned char *
write_bn(unsigned char * buf,const BIGNUM * bn,int bn_bytes)60 write_bn(unsigned char *buf, const BIGNUM *bn, int bn_bytes)
61 {
62     unsigned char *p = buf;
63 
64     /* Left space for bn size which will be written below. */
65     p += 4;
66 
67     *p = 0;
68     BN_bn2bin(bn, p + 1);
69     if(!(*(p + 1) & 0x80)) {
70         memmove(p, p + 1, --bn_bytes);
71     }
72     _libssh2_htonu32(p - 4, bn_bytes);  /* Post write bn size. */
73 
74     return p + bn_bytes;
75 }
76 
77 int
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,const unsigned char * edata,unsigned long elen,const unsigned char * ndata,unsigned long nlen,const unsigned char * ddata,unsigned long dlen,const unsigned char * pdata,unsigned long plen,const unsigned char * qdata,unsigned long qlen,const unsigned char * e1data,unsigned long e1len,const unsigned char * e2data,unsigned long e2len,const unsigned char * coeffdata,unsigned long coefflen)78 _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
79                  const unsigned char *edata,
80                  unsigned long elen,
81                  const unsigned char *ndata,
82                  unsigned long nlen,
83                  const unsigned char *ddata,
84                  unsigned long dlen,
85                  const unsigned char *pdata,
86                  unsigned long plen,
87                  const unsigned char *qdata,
88                  unsigned long qlen,
89                  const unsigned char *e1data,
90                  unsigned long e1len,
91                  const unsigned char *e2data,
92                  unsigned long e2len,
93                  const unsigned char *coeffdata, unsigned long coefflen)
94 {
95     BIGNUM * e;
96     BIGNUM * n;
97     BIGNUM * d = 0;
98     BIGNUM * p = 0;
99     BIGNUM * q = 0;
100     BIGNUM * dmp1 = 0;
101     BIGNUM * dmq1 = 0;
102     BIGNUM * iqmp = 0;
103 
104     e = BN_new();
105     BN_bin2bn(edata, elen, e);
106 
107     n = BN_new();
108     BN_bin2bn(ndata, nlen, n);
109 
110     if(ddata) {
111         d = BN_new();
112         BN_bin2bn(ddata, dlen, d);
113 
114         p = BN_new();
115         BN_bin2bn(pdata, plen, p);
116 
117         q = BN_new();
118         BN_bin2bn(qdata, qlen, q);
119 
120         dmp1 = BN_new();
121         BN_bin2bn(e1data, e1len, dmp1);
122 
123         dmq1 = BN_new();
124         BN_bin2bn(e2data, e2len, dmq1);
125 
126         iqmp = BN_new();
127         BN_bin2bn(coeffdata, coefflen, iqmp);
128     }
129 
130     *rsa = RSA_new();
131 #ifdef HAVE_OPAQUE_STRUCTS
132     RSA_set0_key(*rsa, n, e, d);
133 #else
134     (*rsa)->e = e;
135     (*rsa)->n = n;
136     (*rsa)->d = d;
137 #endif
138 
139 #ifdef HAVE_OPAQUE_STRUCTS
140     RSA_set0_factors(*rsa, p, q);
141 #else
142     (*rsa)->p = p;
143     (*rsa)->q = q;
144 #endif
145 
146 #ifdef HAVE_OPAQUE_STRUCTS
147     RSA_set0_crt_params(*rsa, dmp1, dmq1, iqmp);
148 #else
149     (*rsa)->dmp1 = dmp1;
150     (*rsa)->dmq1 = dmq1;
151     (*rsa)->iqmp = iqmp;
152 #endif
153     return 0;
154 }
155 
156 int
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,const unsigned char * sig,unsigned long sig_len,const unsigned char * m,unsigned long m_len)157 _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
158                          const unsigned char *sig,
159                          unsigned long sig_len,
160                          const unsigned char *m, unsigned long m_len)
161 {
162     unsigned char hash[SHA_DIGEST_LENGTH];
163     int ret;
164 
165     if(_libssh2_sha1(m, m_len, hash))
166         return -1; /* failure */
167     ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
168                      (unsigned char *) sig, sig_len, rsactx);
169     return (ret == 1) ? 0 : -1;
170 }
171 
172 #if LIBSSH2_DSA
173 int
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,const unsigned char * p,unsigned long p_len,const unsigned char * q,unsigned long q_len,const unsigned char * g,unsigned long g_len,const unsigned char * y,unsigned long y_len,const unsigned char * x,unsigned long x_len)174 _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
175                  const unsigned char *p,
176                  unsigned long p_len,
177                  const unsigned char *q,
178                  unsigned long q_len,
179                  const unsigned char *g,
180                  unsigned long g_len,
181                  const unsigned char *y,
182                  unsigned long y_len,
183                  const unsigned char *x, unsigned long x_len)
184 {
185     BIGNUM * p_bn;
186     BIGNUM * q_bn;
187     BIGNUM * g_bn;
188     BIGNUM * pub_key;
189     BIGNUM * priv_key = NULL;
190 
191     p_bn = BN_new();
192     BN_bin2bn(p, p_len, p_bn);
193 
194     q_bn = BN_new();
195     BN_bin2bn(q, q_len, q_bn);
196 
197     g_bn = BN_new();
198     BN_bin2bn(g, g_len, g_bn);
199 
200     pub_key = BN_new();
201     BN_bin2bn(y, y_len, pub_key);
202 
203     if(x_len) {
204         priv_key = BN_new();
205         BN_bin2bn(x, x_len, priv_key);
206     }
207 
208     *dsactx = DSA_new();
209 
210 #ifdef HAVE_OPAQUE_STRUCTS
211     DSA_set0_pqg(*dsactx, p_bn, q_bn, g_bn);
212 #else
213     (*dsactx)->p = p_bn;
214     (*dsactx)->g = g_bn;
215     (*dsactx)->q = q_bn;
216 #endif
217 
218 #ifdef HAVE_OPAQUE_STRUCTS
219     DSA_set0_key(*dsactx, pub_key, priv_key);
220 #else
221     (*dsactx)->pub_key = pub_key;
222     (*dsactx)->priv_key = priv_key;
223 #endif
224     return 0;
225 }
226 
227 int
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,const unsigned char * sig,const unsigned char * m,unsigned long m_len)228 _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
229                          const unsigned char *sig,
230                          const unsigned char *m, unsigned long m_len)
231 {
232     unsigned char hash[SHA_DIGEST_LENGTH];
233     DSA_SIG * dsasig;
234     BIGNUM * r;
235     BIGNUM * s;
236     int ret = -1;
237 
238     r = BN_new();
239     BN_bin2bn(sig, 20, r);
240     s = BN_new();
241     BN_bin2bn(sig + 20, 20, s);
242 
243     dsasig = DSA_SIG_new();
244 #ifdef HAVE_OPAQUE_STRUCTS
245     DSA_SIG_set0(dsasig, r, s);
246 #else
247     dsasig->r = r;
248     dsasig->s = s;
249 #endif
250     if(!_libssh2_sha1(m, m_len, hash))
251         /* _libssh2_sha1() succeeded */
252         ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, dsasig, dsactx);
253 
254     DSA_SIG_free(dsasig);
255 
256     return (ret == 1) ? 0 : -1;
257 }
258 #endif /* LIBSSH_DSA */
259 
260 #if LIBSSH2_ECDSA
261 
262 /* _libssh2_ecdsa_get_curve_type
263  *
264  * returns key curve type that maps to libssh2_curve_type
265  *
266  */
267 
268 libssh2_curve_type
_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx * ec_ctx)269 _libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx)
270 {
271     const EC_GROUP *group = EC_KEY_get0_group(ec_ctx);
272     return EC_GROUP_get_curve_name(group);
273 }
274 
275 /* _libssh2_ecdsa_curve_type_from_name
276  *
277  * returns 0 for success, key curve type that maps to libssh2_curve_type
278  *
279  */
280 
281 int
_libssh2_ecdsa_curve_type_from_name(const char * name,libssh2_curve_type * out_type)282 _libssh2_ecdsa_curve_type_from_name(const char *name,
283                                     libssh2_curve_type *out_type)
284 {
285     int ret = 0;
286     libssh2_curve_type type;
287 
288     if(name == NULL || strlen(name) != 19)
289         return -1;
290 
291     if(strcmp(name, "ecdsa-sha2-nistp256") == 0)
292         type = LIBSSH2_EC_CURVE_NISTP256;
293     else if(strcmp(name, "ecdsa-sha2-nistp384") == 0)
294         type = LIBSSH2_EC_CURVE_NISTP384;
295     else if(strcmp(name, "ecdsa-sha2-nistp521") == 0)
296         type = LIBSSH2_EC_CURVE_NISTP521;
297     else {
298         ret = -1;
299     }
300 
301     if(ret == 0 && out_type) {
302         *out_type = type;
303     }
304 
305     return ret;
306 }
307 
308 /* _libssh2_ecdsa_curve_name_with_octal_new
309  *
310  * Creates a new public key given an octal string, length and type
311  *
312  */
313 
314 int
_libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ec_ctx,const unsigned char * k,size_t k_len,libssh2_curve_type curve)315 _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ec_ctx,
316      const unsigned char *k,
317      size_t k_len, libssh2_curve_type curve)
318 {
319 
320     int ret = 0;
321     const EC_GROUP *ec_group = NULL;
322     EC_KEY *ec_key = EC_KEY_new_by_curve_name(curve);
323     EC_POINT *point = NULL;
324 
325     if(ec_key) {
326         ec_group = EC_KEY_get0_group(ec_key);
327         point = EC_POINT_new(ec_group);
328         ret = EC_POINT_oct2point(ec_group, point, k, k_len, NULL);
329         ret = EC_KEY_set_public_key(ec_key, point);
330 
331         if(point != NULL)
332             EC_POINT_free(point);
333 
334         if(ec_ctx != NULL)
335             *ec_ctx = ec_key;
336     }
337 
338     return (ret == 1) ? 0 : -1;
339 }
340 
341 #define LIBSSH2_ECDSA_VERIFY(digest_type)                           \
342 {                                                                   \
343     unsigned char hash[SHA##digest_type##_DIGEST_LENGTH];           \
344     libssh2_sha##digest_type(m, m_len, hash);                       \
345     ret = ECDSA_do_verify(hash, SHA##digest_type##_DIGEST_LENGTH,   \
346       ecdsa_sig, ec_key);                                           \
347                                                                     \
348 }
349 
350 int
_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,const unsigned char * r,size_t r_len,const unsigned char * s,size_t s_len,const unsigned char * m,size_t m_len)351 _libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
352       const unsigned char *r, size_t r_len,
353       const unsigned char *s, size_t s_len,
354       const unsigned char *m, size_t m_len)
355 {
356     int ret = 0;
357     EC_KEY *ec_key = (EC_KEY*)ctx;
358     libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ec_key);
359 
360 #ifdef HAVE_OPAQUE_STRUCTS
361     ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new();
362     BIGNUM *pr = BN_new();
363     BIGNUM *ps = BN_new();
364 
365     BN_bin2bn(r, r_len, pr);
366     BN_bin2bn(s, s_len, ps);
367     ECDSA_SIG_set0(ecdsa_sig, pr, ps);
368 
369 #else
370     ECDSA_SIG ecdsa_sig_;
371     ECDSA_SIG *ecdsa_sig = &ecdsa_sig_;
372     ecdsa_sig_.r = BN_new();
373     BN_bin2bn(r, r_len, ecdsa_sig_.r);
374     ecdsa_sig_.s = BN_new();
375     BN_bin2bn(s, s_len, ecdsa_sig_.s);
376 #endif
377 
378     if(type == LIBSSH2_EC_CURVE_NISTP256) {
379         LIBSSH2_ECDSA_VERIFY(256);
380     }
381     else if(type == LIBSSH2_EC_CURVE_NISTP384) {
382         LIBSSH2_ECDSA_VERIFY(384);
383     }
384     else if(type == LIBSSH2_EC_CURVE_NISTP521) {
385         LIBSSH2_ECDSA_VERIFY(512);
386     }
387 
388 #ifdef HAVE_OPAQUE_STRUCTS
389     if(ecdsa_sig)
390         ECDSA_SIG_free(ecdsa_sig);
391 #else
392     BN_clear_free(ecdsa_sig_.s);
393     BN_clear_free(ecdsa_sig_.r);
394 #endif
395 
396     return (ret == 1) ? 0 : -1;
397 }
398 
399 #endif /* LIBSSH2_ECDSA */
400 
401 int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,_libssh2_cipher_type (algo),unsigned char * iv,unsigned char * secret,int encrypt)402 _libssh2_cipher_init(_libssh2_cipher_ctx * h,
403                      _libssh2_cipher_type(algo),
404                      unsigned char *iv, unsigned char *secret, int encrypt)
405 {
406 #ifdef HAVE_OPAQUE_STRUCTS
407     *h = EVP_CIPHER_CTX_new();
408     return !EVP_CipherInit(*h, algo(), secret, iv, encrypt);
409 #else
410     EVP_CIPHER_CTX_init(h);
411     return !EVP_CipherInit(h, algo(), secret, iv, encrypt);
412 #endif
413 }
414 
415 int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,_libssh2_cipher_type (algo),int encrypt,unsigned char * block,size_t blocksize)416 _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
417                       _libssh2_cipher_type(algo),
418                       int encrypt, unsigned char *block, size_t blocksize)
419 {
420     unsigned char buf[EVP_MAX_BLOCK_LENGTH];
421     int ret;
422     (void) algo;
423     (void) encrypt;
424 
425 #ifdef HAVE_OPAQUE_STRUCTS
426     ret = EVP_Cipher(*ctx, buf, block, blocksize);
427 #else
428     ret = EVP_Cipher(ctx, buf, block, blocksize);
429 #endif
430 #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
431     if(ret != -1) {
432 #else
433     if(ret == 1) {
434 #endif
435         memcpy(block, buf, blocksize);
436     }
437 
438 #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
439     return ret != -1 ? 0 : 1;
440 #else
441     return ret == 1 ? 0 : 1;
442 #endif
443 }
444 
445 #if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR)
446 
447 #include <openssl/aes.h>
448 #include <openssl/evp.h>
449 
450 typedef struct
451 {
452     AES_KEY       key;
453     EVP_CIPHER_CTX *aes_ctx;
454     unsigned char ctr[AES_BLOCK_SIZE];
455 } aes_ctr_ctx;
456 
457 static EVP_CIPHER * aes_128_ctr_cipher = NULL;
458 static EVP_CIPHER * aes_192_ctr_cipher = NULL;
459 static EVP_CIPHER * aes_256_ctr_cipher = NULL;
460 
461 static int
462 aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
463              const unsigned char *iv, int enc) /* init key */
464 {
465     /*
466      * variable "c" is leaked from this scope, but is later freed
467      * in aes_ctr_cleanup
468      */
469     aes_ctr_ctx *c;
470     const EVP_CIPHER *aes_cipher;
471     (void) enc;
472 
473     switch(EVP_CIPHER_CTX_key_length(ctx)) {
474     case 16:
475         aes_cipher = EVP_aes_128_ecb();
476         break;
477     case 24:
478         aes_cipher = EVP_aes_192_ecb();
479         break;
480     case 32:
481         aes_cipher = EVP_aes_256_ecb();
482         break;
483     default:
484         return 0;
485     }
486 
487     c = malloc(sizeof(*c));
488     if(c == NULL)
489         return 0;
490 
491 #ifdef HAVE_OPAQUE_STRUCTS
492     c->aes_ctx = EVP_CIPHER_CTX_new();
493 #else
494     c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX));
495 #endif
496     if(c->aes_ctx == NULL) {
497         free(c);
498         return 0;
499     }
500 
501     if(EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) {
502 #ifdef HAVE_OPAQUE_STRUCTS
503         EVP_CIPHER_CTX_free(c->aes_ctx);
504 #else
505         free(c->aes_ctx);
506 #endif
507         free(c);
508         return 0;
509     }
510 
511     EVP_CIPHER_CTX_set_padding(c->aes_ctx, 0);
512 
513     memcpy(c->ctr, iv, AES_BLOCK_SIZE);
514 
515     EVP_CIPHER_CTX_set_app_data(ctx, c);
516 
517     return 1;
518 }
519 
520 static int
521 aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
522                   const unsigned char *in,
523                   size_t inl) /* encrypt/decrypt data */
524 {
525     aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx);
526     unsigned char b1[AES_BLOCK_SIZE];
527     int outlen = 0;
528 
529     if(inl != 16) /* libssh2 only ever encrypt one block */
530         return 0;
531 
532     if(c == NULL) {
533         return 0;
534     }
535 
536 /*
537   To encrypt a packet P=P1||P2||...||Pn (where P1, P2, ..., Pn are each
538   blocks of length L), the encryptor first encrypts <X> with <cipher>
539   to obtain a block B1.  The block B1 is then XORed with P1 to generate
540   the ciphertext block C1.  The counter X is then incremented
541 */
542 
543     if(EVP_EncryptUpdate(c->aes_ctx, b1, &outlen,
544                          c->ctr, AES_BLOCK_SIZE) != 1) {
545         return 0;
546     }
547 
548     _libssh2_xor_data(out, in, b1, AES_BLOCK_SIZE);
549     _libssh2_aes_ctr_increment(c->ctr, AES_BLOCK_SIZE);
550 
551     return 1;
552 }
553 
554 static int
555 aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */
556 {
557     aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx);
558 
559     if(c == NULL) {
560         return 1;
561     }
562 
563     if(c->aes_ctx != NULL) {
564 #ifdef HAVE_OPAQUE_STRUCTS
565         EVP_CIPHER_CTX_free(c->aes_ctx);
566 #else
567         _libssh2_cipher_dtor(c->aes_ctx);
568         free(c->aes_ctx);
569 #endif
570     }
571 
572     free(c);
573 
574     return 1;
575 }
576 
577 static const EVP_CIPHER *
578 make_ctr_evp (size_t keylen, EVP_CIPHER **aes_ctr_cipher, int type)
579 {
580 #ifdef HAVE_OPAQUE_STRUCTS
581     *aes_ctr_cipher = EVP_CIPHER_meth_new(type, 16, keylen);
582     if(*aes_ctr_cipher) {
583         EVP_CIPHER_meth_set_iv_length(*aes_ctr_cipher, 16);
584         EVP_CIPHER_meth_set_init(*aes_ctr_cipher, aes_ctr_init);
585         EVP_CIPHER_meth_set_do_cipher(*aes_ctr_cipher, aes_ctr_do_cipher);
586         EVP_CIPHER_meth_set_cleanup(*aes_ctr_cipher, aes_ctr_cleanup);
587     }
588 #else
589     (*aes_ctr_cipher)->nid = type;
590     (*aes_ctr_cipher)->block_size = 16;
591     (*aes_ctr_cipher)->key_len = keylen;
592     (*aes_ctr_cipher)->iv_len = 16;
593     (*aes_ctr_cipher)->init = aes_ctr_init;
594     (*aes_ctr_cipher)->do_cipher = aes_ctr_do_cipher;
595     (*aes_ctr_cipher)->cleanup = aes_ctr_cleanup;
596 #endif
597 
598     return *aes_ctr_cipher;
599 }
600 
601 const EVP_CIPHER *
602 _libssh2_EVP_aes_128_ctr(void)
603 {
604 #ifdef HAVE_OPAQUE_STRUCTS
605     return !aes_128_ctr_cipher ?
606         make_ctr_evp(16, &aes_128_ctr_cipher, NID_aes_128_ctr) :
607         aes_128_ctr_cipher;
608 #else
609     static EVP_CIPHER aes_ctr_cipher;
610     if(!aes_128_ctr_cipher) {
611         aes_128_ctr_cipher = &aes_ctr_cipher;
612         make_ctr_evp(16, &aes_128_ctr_cipher, 0);
613     }
614     return aes_128_ctr_cipher;
615 #endif
616 }
617 
618 const EVP_CIPHER *
619 _libssh2_EVP_aes_192_ctr(void)
620 {
621 #ifdef HAVE_OPAQUE_STRUCTS
622     return !aes_192_ctr_cipher ?
623         make_ctr_evp(24, &aes_192_ctr_cipher, NID_aes_192_ctr) :
624         aes_192_ctr_cipher;
625 #else
626     static EVP_CIPHER aes_ctr_cipher;
627     if(!aes_192_ctr_cipher) {
628         aes_192_ctr_cipher = &aes_ctr_cipher;
629         make_ctr_evp(24, &aes_192_ctr_cipher, 0);
630     }
631     return aes_192_ctr_cipher;
632 #endif
633 }
634 
635 const EVP_CIPHER *
636 _libssh2_EVP_aes_256_ctr(void)
637 {
638 #ifdef HAVE_OPAQUE_STRUCTS
639     return !aes_256_ctr_cipher ?
640         make_ctr_evp(32, &aes_256_ctr_cipher, NID_aes_256_ctr) :
641         aes_256_ctr_cipher;
642 #else
643     static EVP_CIPHER aes_ctr_cipher;
644     if(!aes_256_ctr_cipher) {
645         aes_256_ctr_cipher = &aes_ctr_cipher;
646         make_ctr_evp(32, &aes_256_ctr_cipher, 0);
647     }
648     return aes_256_ctr_cipher;
649 #endif
650 }
651 
652 #endif /* LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) */
653 
654 void _libssh2_openssl_crypto_init(void)
655 {
656 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
657     !defined(LIBRESSL_VERSION_NUMBER)
658 #ifndef OPENSSL_NO_ENGINE
659     ENGINE_load_builtin_engines();
660     ENGINE_register_all_complete();
661 #endif
662 #else
663     OpenSSL_add_all_algorithms();
664     OpenSSL_add_all_ciphers();
665     OpenSSL_add_all_digests();
666 #ifndef OPENSSL_NO_ENGINE
667     ENGINE_load_builtin_engines();
668     ENGINE_register_all_complete();
669 #endif
670 #endif
671 #if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR)
672     aes_128_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_128_ctr();
673     aes_192_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_192_ctr();
674     aes_256_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_256_ctr();
675 #endif
676 }
677 
678 void _libssh2_openssl_crypto_exit(void)
679 {
680 #if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR)
681 #ifdef HAVE_OPAQUE_STRUCTS
682     if(aes_128_ctr_cipher) {
683         EVP_CIPHER_meth_free(aes_128_ctr_cipher);
684     }
685 
686     if(aes_192_ctr_cipher) {
687         EVP_CIPHER_meth_free(aes_192_ctr_cipher);
688     }
689 
690     if(aes_256_ctr_cipher) {
691         EVP_CIPHER_meth_free(aes_256_ctr_cipher);
692     }
693 #endif
694 
695     aes_128_ctr_cipher = NULL;
696     aes_192_ctr_cipher = NULL;
697     aes_256_ctr_cipher = NULL;
698 #endif
699 }
700 
701 /* TODO: Optionally call a passphrase callback specified by the
702  * calling program
703  */
704 static int
705 passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
706 {
707     int passphrase_len = strlen(passphrase);
708     (void) rwflag;
709 
710     if(passphrase_len > (size - 1)) {
711         passphrase_len = size - 1;
712     }
713     memcpy(buf, passphrase, passphrase_len);
714     buf[passphrase_len] = '\0';
715 
716     return passphrase_len;
717 }
718 
719 typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *,
720                                     void *u);
721 
722 static int
723 read_private_key_from_memory(void **key_ctx,
724                              pem_read_bio_func read_private_key,
725                              const char *filedata,
726                              size_t filedata_len,
727                              unsigned const char *passphrase)
728 {
729     BIO * bp;
730 
731     *key_ctx = NULL;
732 
733     bp = BIO_new_mem_buf((char *)filedata, filedata_len);
734     if(!bp) {
735         return -1;
736     }
737     *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb,
738                                 (void *) passphrase);
739 
740     BIO_free(bp);
741     return (*key_ctx) ? 0 : -1;
742 }
743 
744 
745 
746 static int
747 read_private_key_from_file(void **key_ctx,
748                            pem_read_bio_func read_private_key,
749                            const char *filename,
750                            unsigned const char *passphrase)
751 {
752     BIO * bp;
753 
754     *key_ctx = NULL;
755 
756     bp = BIO_new_file(filename, "r");
757     if(!bp) {
758         return -1;
759     }
760 
761     *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb,
762                                 (void *) passphrase);
763 
764     BIO_free(bp);
765     return (*key_ctx) ? 0 : -1;
766 }
767 
768 int
769 _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
770                                     LIBSSH2_SESSION * session,
771                                     const char *filedata, size_t filedata_len,
772                                     unsigned const char *passphrase)
773 {
774     int rc;
775 
776     pem_read_bio_func read_rsa =
777         (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
778 
779     _libssh2_init_if_needed();
780 
781     rc = read_private_key_from_memory((void **) rsa, read_rsa,
782                                       filedata, filedata_len, passphrase);
783 
784     if(rc) {
785         rc = read_openssh_private_key_from_memory((void **)rsa, session,
786                         "ssh-rsa", filedata, filedata_len, passphrase);
787     }
788 
789 return rc;
790 }
791 
792 static unsigned char *
793 gen_publickey_from_rsa(LIBSSH2_SESSION *session, RSA *rsa,
794                        size_t *key_len)
795 {
796     int            e_bytes, n_bytes;
797     unsigned long  len;
798     unsigned char *key;
799     unsigned char *p;
800     const BIGNUM * e;
801     const BIGNUM * n;
802 #ifdef HAVE_OPAQUE_STRUCTS
803     RSA_get0_key(rsa, &n, &e, NULL);
804 #else
805     e = rsa->e;
806     n = rsa->n;
807 #endif
808     e_bytes = BN_num_bytes(e) + 1;
809     n_bytes = BN_num_bytes(n) + 1;
810 
811     /* Key form is "ssh-rsa" + e + n. */
812     len = 4 + 7 + 4 + e_bytes + 4 + n_bytes;
813 
814     key = LIBSSH2_ALLOC(session, len);
815     if(key == NULL) {
816         return NULL;
817     }
818 
819     /* Process key encoding. */
820     p = key;
821 
822     _libssh2_htonu32(p, 7);  /* Key type. */
823     p += 4;
824     memcpy(p, "ssh-rsa", 7);
825     p += 7;
826 
827     p = write_bn(p, e, e_bytes);
828     p = write_bn(p, n, n_bytes);
829 
830     *key_len = (size_t)(p - key);
831     return key;
832 }
833 
834 static int
835 gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
836                            unsigned char **method,
837                            size_t *method_len,
838                            unsigned char **pubkeydata,
839                            size_t *pubkeydata_len,
840                            EVP_PKEY *pk)
841 {
842     RSA*           rsa = NULL;
843     unsigned char *key;
844     unsigned char *method_buf = NULL;
845     size_t  key_len;
846 
847     _libssh2_debug(session,
848                    LIBSSH2_TRACE_AUTH,
849                    "Computing public key from RSA private key envelope");
850 
851     rsa = EVP_PKEY_get1_RSA(pk);
852     if(rsa == NULL) {
853         /* Assume memory allocation error... what else could it be ? */
854         goto __alloc_error;
855     }
856 
857     method_buf = LIBSSH2_ALLOC(session, 7);  /* ssh-rsa. */
858     if(method_buf == NULL) {
859         goto __alloc_error;
860     }
861 
862     key = gen_publickey_from_rsa(session, rsa, &key_len);
863     if(key == NULL) {
864         goto __alloc_error;
865     }
866     RSA_free(rsa);
867 
868     memcpy(method_buf, "ssh-rsa", 7);
869     *method         = method_buf;
870     *method_len     = 7;
871     *pubkeydata     = key;
872     *pubkeydata_len = key_len;
873     return 0;
874 
875   __alloc_error:
876     if(rsa != NULL) {
877         RSA_free(rsa);
878     }
879     if(method_buf != NULL) {
880         LIBSSH2_FREE(session, method_buf);
881     }
882 
883     return _libssh2_error(session,
884                           LIBSSH2_ERROR_ALLOC,
885                           "Unable to allocate memory for private key data");
886 }
887 
888 static int _libssh2_rsa_new_additional_parameters(RSA *rsa)
889 {
890     BN_CTX *ctx = NULL;
891     BIGNUM *aux = NULL;
892     BIGNUM *dmp1 = NULL;
893     BIGNUM *dmq1 = NULL;
894     const BIGNUM *p = NULL;
895     const BIGNUM *q = NULL;
896     const BIGNUM *d = NULL;
897     int rc = 0;
898 
899 #ifdef HAVE_OPAQUE_STRUCTS
900     RSA_get0_key(rsa, NULL, NULL, &d);
901     RSA_get0_factors(rsa, &p, &q);
902 #else
903     d = (*rsa).d;
904     p = (*rsa).p;
905     q = (*rsa).q;
906 #endif
907 
908     ctx = BN_CTX_new();
909     if(ctx == NULL)
910         return -1;
911 
912     aux = BN_new();
913     if(aux == NULL) {
914         rc = -1;
915         goto out;
916     }
917 
918     dmp1 = BN_new();
919     if(dmp1 == NULL) {
920         rc = -1;
921         goto out;
922     }
923 
924     dmq1 = BN_new();
925     if(dmq1 == NULL) {
926         rc = -1;
927         goto out;
928     }
929 
930     if((BN_sub(aux, q, BN_value_one()) == 0) ||
931         (BN_mod(dmq1, d, aux, ctx) == 0) ||
932         (BN_sub(aux, p, BN_value_one()) == 0) ||
933         (BN_mod(dmp1, d, aux, ctx) == 0)) {
934         rc = -1;
935         goto out;
936     }
937 
938 #ifdef HAVE_OPAQUE_STRUCTS
939     RSA_set0_crt_params(rsa, dmp1, dmq1, NULL);
940 #else
941     (*rsa).dmp1 = dmp1;
942     (*rsa).dmq1 = dmq1;
943 #endif
944 
945 out:
946     if(aux)
947         BN_clear_free(aux);
948     BN_CTX_free(ctx);
949 
950     if(rc != 0) {
951         if(dmp1)
952             BN_clear_free(dmp1);
953         if(dmq1)
954             BN_clear_free(dmq1);
955     }
956 
957     return rc;
958 }
959 
960 static int
961 gen_publickey_from_rsa_openssh_priv_data(LIBSSH2_SESSION *session,
962                                          struct string_buf *decrypted,
963                                          unsigned char **method,
964                                          size_t *method_len,
965                                          unsigned char **pubkeydata,
966                                          size_t *pubkeydata_len,
967                                          libssh2_rsa_ctx **rsa_ctx)
968 {
969     int rc = 0;
970     size_t nlen, elen, dlen, plen, qlen, coefflen, commentlen;
971     unsigned char *n, *e, *d, *p, *q, *coeff, *comment;
972     RSA *rsa = NULL;
973 
974     _libssh2_debug(session,
975                    LIBSSH2_TRACE_AUTH,
976                    "Computing RSA keys from private key data");
977 
978     /* public key data */
979     if(_libssh2_get_bignum_bytes(decrypted, &n, &nlen)) {
980         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
981                        "RSA no n");
982         return -1;
983     }
984 
985     if(_libssh2_get_bignum_bytes(decrypted, &e, &elen)) {
986         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
987                        "RSA no e");
988         return -1;
989     }
990 
991     /* private key data */
992     if(_libssh2_get_bignum_bytes(decrypted, &d, &dlen)) {
993         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
994                        "RSA no d");
995         return -1;
996     }
997 
998     if(_libssh2_get_bignum_bytes(decrypted, &coeff, &coefflen)) {
999         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1000                        "RSA no coeff");
1001         return -1;
1002     }
1003 
1004     if(_libssh2_get_bignum_bytes(decrypted, &p, &plen)) {
1005         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1006                        "RSA no p");
1007         return -1;
1008     }
1009 
1010     if(_libssh2_get_bignum_bytes(decrypted, &q, &qlen)) {
1011         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1012                        "RSA no q");
1013         return -1;
1014     }
1015 
1016     if(_libssh2_get_string(decrypted, &comment, &commentlen)) {
1017         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1018                        "RSA no comment");
1019         return -1;
1020     }
1021 
1022     if((rc = _libssh2_rsa_new(&rsa, e, elen, n, nlen, d, dlen, p, plen,
1023                               q, qlen, NULL, 0, NULL, 0,
1024                               coeff, coefflen)) != 0) {
1025         _libssh2_debug(session,
1026                        LIBSSH2_TRACE_AUTH,
1027                        "Could not create RSA private key");
1028         goto fail;
1029     }
1030 
1031     if(rsa != NULL)
1032         rc = _libssh2_rsa_new_additional_parameters(rsa);
1033 
1034     if(rsa != NULL && pubkeydata != NULL && method != NULL) {
1035         EVP_PKEY *pk = EVP_PKEY_new();
1036         EVP_PKEY_set1_RSA(pk, rsa);
1037 
1038         rc = gen_publickey_from_rsa_evp(session, method, method_len,
1039                                         pubkeydata, pubkeydata_len,
1040                                         pk);
1041 
1042         if(pk)
1043             EVP_PKEY_free(pk);
1044     }
1045 
1046     if(rsa_ctx != NULL)
1047         *rsa_ctx = rsa;
1048     else
1049         RSA_free(rsa);
1050 
1051     return rc;
1052 
1053 fail:
1054 
1055     if(rsa != NULL)
1056         RSA_free(rsa);
1057 
1058     return _libssh2_error(session,
1059                           LIBSSH2_ERROR_ALLOC,
1060                           "Unable to allocate memory for private key data");
1061 }
1062 
1063 static int
1064 _libssh2_rsa_new_openssh_private(libssh2_rsa_ctx ** rsa,
1065                                  LIBSSH2_SESSION * session,
1066                                  const char *filename,
1067                                  unsigned const char *passphrase)
1068 {
1069     FILE *fp;
1070     int rc;
1071     unsigned char *buf = NULL;
1072     struct string_buf *decrypted = NULL;
1073 
1074     if(session == NULL) {
1075         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1076                        "Session is required");
1077         return -1;
1078     }
1079 
1080     _libssh2_init_if_needed();
1081 
1082     fp = fopen(filename, "r");
1083     if(!fp) {
1084         _libssh2_error(session, LIBSSH2_ERROR_FILE,
1085                        "Unable to open OpenSSH RSA private key file");
1086         return -1;
1087     }
1088 
1089     rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted);
1090     fclose(fp);
1091     if(rc) {
1092         return rc;
1093     }
1094 
1095     /* We have a new key file, now try and parse it using supported types  */
1096     rc = _libssh2_get_string(decrypted, &buf, NULL);
1097 
1098     if(rc != 0 || buf == NULL) {
1099         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1100                        "Public key type in decrypted key data not found");
1101         return -1;
1102     }
1103 
1104     if(strcmp("ssh-rsa", (const char *)buf) == 0) {
1105         rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted,
1106                                                       NULL, 0,
1107                                                       NULL, 0, rsa);
1108     }
1109     else {
1110         rc = -1;
1111     }
1112 
1113     if(decrypted)
1114         _libssh2_string_buf_free(session, decrypted);
1115 
1116     return rc;
1117 }
1118 
1119 int
1120 _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
1121                          LIBSSH2_SESSION * session,
1122                          const char *filename, unsigned const char *passphrase)
1123 {
1124     int rc;
1125 
1126     pem_read_bio_func read_rsa =
1127         (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
1128 
1129     _libssh2_init_if_needed();
1130 
1131     rc = read_private_key_from_file((void **) rsa, read_rsa,
1132                                     filename, passphrase);
1133 
1134     if(rc) {
1135         rc = _libssh2_rsa_new_openssh_private(rsa, session,
1136                                               filename, passphrase);
1137     }
1138 
1139     return rc;
1140 }
1141 
1142 #if LIBSSH2_DSA
1143 int
1144 _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
1145                                     LIBSSH2_SESSION * session,
1146                                     const char *filedata, size_t filedata_len,
1147                                     unsigned const char *passphrase)
1148 {
1149     int rc;
1150 
1151     pem_read_bio_func read_dsa =
1152         (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
1153 
1154     _libssh2_init_if_needed();
1155 
1156     rc = read_private_key_from_memory((void **)dsa, read_dsa,
1157                                       filedata, filedata_len, passphrase);
1158 
1159     if(rc) {
1160         rc = read_openssh_private_key_from_memory((void **)dsa, session,
1161                             "ssh-dsa", filedata, filedata_len, passphrase);
1162     }
1163 
1164     return rc;
1165 }
1166 
1167 static unsigned char *
1168 gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa,
1169                        size_t *key_len)
1170 {
1171     int            p_bytes, q_bytes, g_bytes, k_bytes;
1172     unsigned long  len;
1173     unsigned char *key;
1174     unsigned char *p;
1175 
1176     const BIGNUM * p_bn;
1177     const BIGNUM * q;
1178     const BIGNUM * g;
1179     const BIGNUM * pub_key;
1180 #ifdef HAVE_OPAQUE_STRUCTS
1181     DSA_get0_pqg(dsa, &p_bn, &q, &g);
1182 #else
1183     p_bn = dsa->p;
1184     q = dsa->q;
1185     g = dsa->g;
1186 #endif
1187 
1188 #ifdef HAVE_OPAQUE_STRUCTS
1189     DSA_get0_key(dsa, &pub_key, NULL);
1190 #else
1191     pub_key = dsa->pub_key;
1192 #endif
1193     p_bytes = BN_num_bytes(p_bn) + 1;
1194     q_bytes = BN_num_bytes(q) + 1;
1195     g_bytes = BN_num_bytes(g) + 1;
1196     k_bytes = BN_num_bytes(pub_key) + 1;
1197 
1198     /* Key form is "ssh-dss" + p + q + g + pub_key. */
1199     len = 4 + 7 + 4 + p_bytes + 4 + q_bytes + 4 + g_bytes + 4 + k_bytes;
1200 
1201     key = LIBSSH2_ALLOC(session, len);
1202     if(key == NULL) {
1203         return NULL;
1204     }
1205 
1206     /* Process key encoding. */
1207     p = key;
1208 
1209     _libssh2_htonu32(p, 7);  /* Key type. */
1210     p += 4;
1211     memcpy(p, "ssh-dss", 7);
1212     p += 7;
1213 
1214     p = write_bn(p, p_bn, p_bytes);
1215     p = write_bn(p, q, q_bytes);
1216     p = write_bn(p, g, g_bytes);
1217     p = write_bn(p, pub_key, k_bytes);
1218 
1219     *key_len = (size_t)(p - key);
1220     return key;
1221 }
1222 
1223 static int
1224 gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
1225                            unsigned char **method,
1226                            size_t *method_len,
1227                            unsigned char **pubkeydata,
1228                            size_t *pubkeydata_len,
1229                            EVP_PKEY *pk)
1230 {
1231     DSA*           dsa = NULL;
1232     unsigned char *key;
1233     unsigned char *method_buf = NULL;
1234     size_t  key_len;
1235 
1236     _libssh2_debug(session,
1237                    LIBSSH2_TRACE_AUTH,
1238                    "Computing public key from DSA private key envelope");
1239 
1240     dsa = EVP_PKEY_get1_DSA(pk);
1241     if(dsa == NULL) {
1242         /* Assume memory allocation error... what else could it be ? */
1243         goto __alloc_error;
1244     }
1245 
1246     method_buf = LIBSSH2_ALLOC(session, 7);  /* ssh-dss. */
1247     if(method_buf == NULL) {
1248         goto __alloc_error;
1249     }
1250 
1251     key = gen_publickey_from_dsa(session, dsa, &key_len);
1252     if(key == NULL) {
1253         goto __alloc_error;
1254     }
1255     DSA_free(dsa);
1256 
1257     memcpy(method_buf, "ssh-dss", 7);
1258     *method         = method_buf;
1259     *method_len     = 7;
1260     *pubkeydata     = key;
1261     *pubkeydata_len = key_len;
1262     return 0;
1263 
1264   __alloc_error:
1265     if(dsa != NULL) {
1266         DSA_free(dsa);
1267     }
1268     if(method_buf != NULL) {
1269         LIBSSH2_FREE(session, method_buf);
1270     }
1271 
1272     return _libssh2_error(session,
1273                           LIBSSH2_ERROR_ALLOC,
1274                           "Unable to allocate memory for private key data");
1275 }
1276 
1277 static int
1278 gen_publickey_from_dsa_openssh_priv_data(LIBSSH2_SESSION *session,
1279                                          struct string_buf *decrypted,
1280                                          unsigned char **method,
1281                                          size_t *method_len,
1282                                          unsigned char **pubkeydata,
1283                                          size_t *pubkeydata_len,
1284                                          libssh2_dsa_ctx **dsa_ctx)
1285 {
1286     int rc = 0;
1287     size_t plen, qlen, glen, pub_len, priv_len;
1288     unsigned char *p, *q, *g, *pub_key, *priv_key;
1289     DSA *dsa = NULL;
1290 
1291     _libssh2_debug(session,
1292                    LIBSSH2_TRACE_AUTH,
1293                    "Computing DSA keys from private key data");
1294 
1295     if(_libssh2_get_bignum_bytes(decrypted, &p, &plen)) {
1296         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1297                        "DSA no p");
1298         return -1;
1299     }
1300 
1301     if(_libssh2_get_bignum_bytes(decrypted, &q, &qlen)) {
1302         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1303                        "DSA no q");
1304         return -1;
1305     }
1306 
1307     if(_libssh2_get_bignum_bytes(decrypted, &g, &glen)) {
1308         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1309                        "DSA no g");
1310         return -1;
1311     }
1312 
1313     if(_libssh2_get_bignum_bytes(decrypted, &pub_key, &pub_len)) {
1314         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1315                        "DSA no public key");
1316         return -1;
1317     }
1318 
1319     if(_libssh2_get_bignum_bytes(decrypted, &priv_key, &priv_len)) {
1320         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1321                        "DSA no private key");
1322         return -1;
1323     }
1324 
1325     rc = _libssh2_dsa_new(&dsa, p, plen, q, qlen, g, glen, pub_key, pub_len,
1326                           priv_key, priv_len);
1327     if(rc != 0) {
1328         _libssh2_debug(session,
1329                        LIBSSH2_ERROR_PROTO,
1330                        "Could not create DSA private key");
1331         goto fail;
1332     }
1333 
1334     if(dsa != NULL && pubkeydata != NULL && method != NULL) {
1335         EVP_PKEY *pk = EVP_PKEY_new();
1336         EVP_PKEY_set1_DSA(pk, dsa);
1337 
1338         rc = gen_publickey_from_dsa_evp(session, method, method_len,
1339                                         pubkeydata, pubkeydata_len,
1340                                         pk);
1341 
1342         if(pk)
1343             EVP_PKEY_free(pk);
1344     }
1345 
1346     if(dsa_ctx != NULL)
1347         *dsa_ctx = dsa;
1348     else
1349         DSA_free(dsa);
1350 
1351     return rc;
1352 
1353 fail:
1354 
1355     if(dsa != NULL)
1356         DSA_free(dsa);
1357 
1358     return _libssh2_error(session,
1359                           LIBSSH2_ERROR_ALLOC,
1360                           "Unable to allocate memory for private key data");
1361 }
1362 
1363 static int
1364 _libssh2_dsa_new_openssh_private(libssh2_dsa_ctx ** dsa,
1365                                  LIBSSH2_SESSION * session,
1366                                  const char *filename,
1367                                  unsigned const char *passphrase)
1368 {
1369     FILE *fp;
1370     int rc;
1371     unsigned char *buf = NULL;
1372     struct string_buf *decrypted = NULL;
1373 
1374     if(session == NULL) {
1375         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1376                        "Session is required");
1377         return -1;
1378     }
1379 
1380     _libssh2_init_if_needed();
1381 
1382     fp = fopen(filename, "r");
1383     if(!fp) {
1384         _libssh2_error(session, LIBSSH2_ERROR_FILE,
1385                        "Unable to open OpenSSH DSA private key file");
1386         return -1;
1387     }
1388 
1389     rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted);
1390     fclose(fp);
1391     if(rc) {
1392         return rc;
1393     }
1394 
1395     /* We have a new key file, now try and parse it using supported types  */
1396     rc = _libssh2_get_string(decrypted, &buf, NULL);
1397 
1398     if(rc != 0 || buf == NULL) {
1399         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1400                        "Public key type in decrypted key data not found");
1401         return -1;
1402     }
1403 
1404     if(strcmp("ssh-dss", (const char *)buf) == 0) {
1405         rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted,
1406                                                       NULL, 0,
1407                                                       NULL, 0, dsa);
1408     }
1409     else {
1410         rc = -1;
1411     }
1412 
1413     if(decrypted)
1414         _libssh2_string_buf_free(session, decrypted);
1415 
1416     return rc;
1417 }
1418 
1419 int
1420 _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
1421                          LIBSSH2_SESSION * session,
1422                          const char *filename, unsigned const char *passphrase)
1423 {
1424     int rc;
1425 
1426     pem_read_bio_func read_dsa =
1427         (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
1428 
1429     _libssh2_init_if_needed();
1430 
1431     rc = read_private_key_from_file((void **) dsa, read_dsa,
1432                                     filename, passphrase);
1433 
1434     if(rc) {
1435         rc = _libssh2_dsa_new_openssh_private(dsa, session,
1436                                               filename, passphrase);
1437     }
1438 
1439     return rc;
1440 }
1441 
1442 #endif /* LIBSSH_DSA */
1443 
1444 #if LIBSSH2_ECDSA
1445 
1446 int
1447 _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
1448                                     LIBSSH2_SESSION * session,
1449                                     const char *filedata, size_t filedata_len,
1450                                     unsigned const char *passphrase)
1451 {
1452     int rc;
1453 
1454     pem_read_bio_func read_ec =
1455         (pem_read_bio_func) &PEM_read_bio_ECPrivateKey;
1456 
1457     _libssh2_init_if_needed();
1458 
1459     rc = read_private_key_from_memory((void **) ec_ctx, read_ec,
1460                                       filedata, filedata_len, passphrase);
1461 
1462     if(rc) {
1463         rc = read_openssh_private_key_from_memory((void **)ec_ctx, session,
1464                                                   "ssh-ecdsa", filedata,
1465                                                   filedata_len, passphrase);
1466     }
1467 
1468     return rc;
1469 }
1470 
1471 #endif /* LIBSSH2_ECDSA */
1472 
1473 
1474 #if LIBSSH2_ED25519
1475 
1476 int
1477 _libssh2_curve25519_new(LIBSSH2_SESSION *session,
1478                         unsigned char **out_public_key,
1479                         unsigned char **out_private_key)
1480 {
1481     EVP_PKEY *key = NULL;
1482     EVP_PKEY_CTX *pctx = NULL;
1483     unsigned char *priv = NULL, *pub = NULL;
1484     size_t privLen, pubLen;
1485     int rc = -1;
1486 
1487     pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
1488     if(pctx == NULL)
1489         return -1;
1490 
1491     if(EVP_PKEY_keygen_init(pctx) != 1 ||
1492        EVP_PKEY_keygen(pctx, &key) != 1) {
1493         goto cleanExit;
1494     }
1495 
1496     if(out_private_key != NULL) {
1497         privLen = LIBSSH2_ED25519_KEY_LEN;
1498         priv = LIBSSH2_ALLOC(session, privLen);
1499         if(priv == NULL)
1500             goto cleanExit;
1501 
1502         if(EVP_PKEY_get_raw_private_key(key, priv, &privLen) != 1 ||
1503            privLen != LIBSSH2_ED25519_KEY_LEN) {
1504             goto cleanExit;
1505         }
1506 
1507         *out_private_key = priv;
1508         priv = NULL;
1509     }
1510 
1511     if(out_public_key != NULL) {
1512         pubLen = LIBSSH2_ED25519_KEY_LEN;
1513         pub = LIBSSH2_ALLOC(session, pubLen);
1514         if(pub == NULL)
1515             goto cleanExit;
1516 
1517         if(EVP_PKEY_get_raw_public_key(key, pub, &pubLen) != 1 ||
1518            pubLen != LIBSSH2_ED25519_KEY_LEN) {
1519             goto cleanExit;
1520         }
1521 
1522         *out_public_key = pub;
1523         pub = NULL;
1524     }
1525 
1526     /* success */
1527     rc = 0;
1528 
1529 cleanExit:
1530 
1531     if(pctx)
1532         EVP_PKEY_CTX_free(pctx);
1533     if(key)
1534         EVP_PKEY_free(key);
1535     if(priv)
1536         LIBSSH2_FREE(session, priv);
1537     if(pub)
1538         LIBSSH2_FREE(session, pub);
1539 
1540     return rc;
1541 }
1542 
1543 
1544 static int
1545 gen_publickey_from_ed_evp(LIBSSH2_SESSION *session,
1546                           unsigned char **method,
1547                           size_t *method_len,
1548                           unsigned char **pubkeydata,
1549                           size_t *pubkeydata_len,
1550                           EVP_PKEY *pk)
1551 {
1552     const char methodName[] = "ssh-ed25519";
1553     unsigned char *methodBuf = NULL;
1554     size_t rawKeyLen = 0;
1555     unsigned char *keyBuf = NULL;
1556     size_t bufLen = 0;
1557     unsigned char *bufPos = NULL;
1558 
1559     _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
1560                    "Computing public key from ED private key envelope");
1561 
1562     methodBuf = LIBSSH2_ALLOC(session, sizeof(methodName) - 1);
1563     if(!methodBuf) {
1564         _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1565                        "Unable to allocate memory for private key data");
1566         goto fail;
1567     }
1568     memcpy(methodBuf, methodName, sizeof(methodName) - 1);
1569 
1570     if(EVP_PKEY_get_raw_public_key(pk, NULL, &rawKeyLen) != 1) {
1571         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1572                        "EVP_PKEY_get_raw_public_key failed");
1573         goto fail;
1574     }
1575 
1576     /* Key form is: type_len(4) + type(11) + pub_key_len(4) + pub_key(32). */
1577     bufLen = 4 + sizeof(methodName) - 1  + 4 + rawKeyLen;
1578     bufPos = keyBuf = LIBSSH2_ALLOC(session, bufLen);
1579     if(!keyBuf) {
1580         _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1581                        "Unable to allocate memory for private key data");
1582         goto fail;
1583     }
1584 
1585     _libssh2_store_str(&bufPos, methodName, sizeof(methodName) - 1);
1586     _libssh2_store_u32(&bufPos, rawKeyLen);
1587 
1588     if(EVP_PKEY_get_raw_public_key(pk, bufPos, &rawKeyLen) != 1) {
1589         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1590                        "EVP_PKEY_get_raw_public_key failed");
1591         goto fail;
1592     }
1593 
1594     *method         = methodBuf;
1595     *method_len     = sizeof(methodName) - 1;
1596     *pubkeydata     = keyBuf;
1597     *pubkeydata_len = bufLen;
1598     return 0;
1599 
1600 fail:
1601     if(methodBuf)
1602         LIBSSH2_FREE(session, methodBuf);
1603     if(keyBuf)
1604         LIBSSH2_FREE(session, keyBuf);
1605     return -1;
1606 }
1607 
1608 
1609 static int
1610 gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session,
1611                                              struct string_buf *decrypted,
1612                                              unsigned char **method,
1613                                              size_t *method_len,
1614                                              unsigned char **pubkeydata,
1615                                              size_t *pubkeydata_len,
1616                                              libssh2_ed25519_ctx **out_ctx)
1617 {
1618     libssh2_ed25519_ctx *ctx = NULL;
1619     unsigned char *method_buf = NULL;
1620     unsigned char *key = NULL;
1621     int i, ret = 0;
1622     unsigned char *pub_key, *priv_key, *buf;
1623     size_t key_len = 0, tmp_len = 0;
1624     unsigned char *p;
1625 
1626     _libssh2_debug(session,
1627                    LIBSSH2_TRACE_AUTH,
1628                    "Computing ED25519 keys from private key data");
1629 
1630     if(_libssh2_get_string(decrypted, &pub_key, &tmp_len) ||
1631        tmp_len != LIBSSH2_ED25519_KEY_LEN) {
1632         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1633                        "Wrong public key length");
1634         return -1;
1635     }
1636 
1637     if(_libssh2_get_string(decrypted, &priv_key, &tmp_len) ||
1638        tmp_len != LIBSSH2_ED25519_PRIVATE_KEY_LEN) {
1639         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1640                        "Wrong private key length");
1641         ret = -1;
1642         goto clean_exit;
1643     }
1644 
1645     /* first 32 bytes of priv_key is the private key, the last 32 bytes are
1646        the public key */
1647     ctx = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL,
1648                                        (const unsigned char *)priv_key,
1649                                        LIBSSH2_ED25519_KEY_LEN);
1650 
1651     /* comment */
1652     if(_libssh2_get_string(decrypted, &buf, &tmp_len)) {
1653         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1654                        "Unable to read comment");
1655         ret = -1;
1656         goto clean_exit;
1657     }
1658 
1659     if(tmp_len > 0) {
1660         unsigned char *comment = LIBSSH2_CALLOC(session, tmp_len + 1);
1661         if(comment != NULL) {
1662             memcpy(comment, buf, tmp_len);
1663             memcpy(comment + tmp_len, "\0", 1);
1664 
1665             _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Key comment: %s",
1666                            comment);
1667 
1668             LIBSSH2_FREE(session, comment);
1669         }
1670     }
1671 
1672     /* Padding */
1673     i = 1;
1674     while(decrypted->dataptr < decrypted->data + decrypted->len) {
1675         if(*decrypted->dataptr != i) {
1676             _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1677                            "Wrong padding");
1678             ret = -1;
1679             goto clean_exit;
1680         }
1681         i++;
1682         decrypted->dataptr++;
1683     }
1684 
1685     if(ret == 0) {
1686         _libssh2_debug(session,
1687                        LIBSSH2_TRACE_AUTH,
1688                        "Computing public key from ED25519 "
1689                        "private key envelope");
1690 
1691         method_buf = LIBSSH2_ALLOC(session, 11);  /* ssh-ed25519. */
1692         if(method_buf == NULL) {
1693             _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1694                            "Unable to allocate memory for ED25519 key");
1695             goto clean_exit;
1696         }
1697 
1698         /* Key form is: type_len(4) + type(11) + pub_key_len(4) +
1699            pub_key(32). */
1700         key_len = LIBSSH2_ED25519_KEY_LEN + 19;
1701         key = LIBSSH2_CALLOC(session, key_len);
1702         if(key == NULL) {
1703             _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1704                            "Unable to allocate memory for ED25519 key");
1705             goto clean_exit;
1706         }
1707 
1708         p = key;
1709 
1710         _libssh2_store_str(&p, "ssh-ed25519", 11);
1711         _libssh2_store_str(&p, (const char *)pub_key, LIBSSH2_ED25519_KEY_LEN);
1712 
1713         memcpy(method_buf, "ssh-ed25519", 11);
1714 
1715         if(method != NULL)
1716             *method = method_buf;
1717         else
1718             LIBSSH2_FREE(session, method_buf);
1719 
1720         if(method_len != NULL)
1721             *method_len = 11;
1722 
1723         if(pubkeydata != NULL)
1724             *pubkeydata = key;
1725         else
1726             LIBSSH2_FREE(session, key);
1727 
1728         if(pubkeydata_len != NULL)
1729             *pubkeydata_len = key_len;
1730 
1731         if(out_ctx != NULL)
1732             *out_ctx = ctx;
1733         else if(ctx != NULL)
1734             _libssh2_ed25519_free(ctx);
1735 
1736         return 0;
1737     }
1738 
1739 clean_exit:
1740 
1741     if(ctx)
1742         _libssh2_ed25519_free(ctx);
1743 
1744     if(method_buf)
1745         LIBSSH2_FREE(session, method_buf);
1746 
1747     if(key)
1748         LIBSSH2_FREE(session, key);
1749 
1750     return -1;
1751 }
1752 
1753 int
1754 _libssh2_ed25519_new_private(libssh2_ed25519_ctx ** ed_ctx,
1755                              LIBSSH2_SESSION * session,
1756                              const char *filename, const uint8_t *passphrase)
1757 {
1758     int rc;
1759     FILE *fp;
1760     unsigned char *buf;
1761     struct string_buf *decrypted = NULL;
1762     libssh2_ed25519_ctx *ctx = NULL;
1763 
1764     if(session == NULL) {
1765         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1766                        "Session is required");
1767         return -1;
1768     }
1769 
1770     _libssh2_init_if_needed();
1771 
1772     fp = fopen(filename, "r");
1773     if(!fp) {
1774         _libssh2_error(session, LIBSSH2_ERROR_FILE,
1775                        "Unable to open ED25519 private key file");
1776         return -1;
1777     }
1778 
1779     rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted);
1780     fclose(fp);
1781     if(rc) {
1782         return rc;
1783     }
1784 
1785     /* We have a new key file, now try and parse it using supported types  */
1786     rc = _libssh2_get_string(decrypted, &buf, NULL);
1787 
1788     if(rc != 0 || buf == NULL) {
1789         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1790                        "Public key type in decrypted key data not found");
1791         return -1;
1792     }
1793 
1794     if(strcmp("ssh-ed25519", (const char *)buf) == 0) {
1795         rc = gen_publickey_from_ed25519_openssh_priv_data(session,
1796                                                           decrypted,
1797                                                           NULL,
1798                                                           NULL,
1799                                                           NULL,
1800                                                           NULL,
1801                                                           &ctx);
1802     }
1803     else {
1804         rc = -1;
1805     }
1806 
1807     if(decrypted)
1808         _libssh2_string_buf_free(session, decrypted);
1809 
1810     if(rc == 0) {
1811         if(ed_ctx != NULL)
1812             *ed_ctx = ctx;
1813         else if(ctx != NULL)
1814             _libssh2_ed25519_free(ctx);
1815     }
1816 
1817     return rc;
1818 }
1819 
1820 int
1821 _libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx ** ed_ctx,
1822                                         LIBSSH2_SESSION * session,
1823                                         const char *filedata,
1824                                         size_t filedata_len,
1825                                         unsigned const char *passphrase)
1826 {
1827     libssh2_ed25519_ctx *ctx = NULL;
1828 
1829     _libssh2_init_if_needed();
1830 
1831     if(read_private_key_from_memory((void **)&ctx,
1832                                     (pem_read_bio_func)
1833                                     &PEM_read_bio_PrivateKey,
1834                                     filedata, filedata_len, passphrase) == 0) {
1835         if(EVP_PKEY_id(ctx) != EVP_PKEY_ED25519) {
1836             _libssh2_ed25519_free(ctx);
1837             return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1838                                   "Private key is not an ED25519 key");
1839         }
1840 
1841         *ed_ctx = ctx;
1842         return 0;
1843     }
1844 
1845     return read_openssh_private_key_from_memory((void **)ed_ctx, session,
1846                                                 "ssh-ed25519",
1847                                                 filedata, filedata_len,
1848                                                 passphrase);
1849 }
1850 
1851 int
1852 _libssh2_ed25519_new_public(libssh2_ed25519_ctx ** ed_ctx,
1853                             LIBSSH2_SESSION * session,
1854                             const unsigned char *raw_pub_key,
1855                             const uint8_t key_len)
1856 {
1857     libssh2_ed25519_ctx *ctx = NULL;
1858 
1859     if(ed_ctx == NULL)
1860         return -1;
1861 
1862     ctx = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL,
1863                                       raw_pub_key, key_len);
1864     if(!ctx)
1865         return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1866                               "could not create ED25519 public key");
1867 
1868     if(ed_ctx != NULL)
1869         *ed_ctx = ctx;
1870     else if(ctx)
1871         _libssh2_ed25519_free(ctx);
1872 
1873     return 0;
1874 }
1875 #endif /* LIBSSH2_ED25519 */
1876 
1877 
1878 int
1879 _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
1880                        libssh2_rsa_ctx * rsactx,
1881                        const unsigned char *hash,
1882                        size_t hash_len,
1883                        unsigned char **signature, size_t *signature_len)
1884 {
1885     int ret;
1886     unsigned char *sig;
1887     unsigned int sig_len;
1888 
1889     sig_len = RSA_size(rsactx);
1890     sig = LIBSSH2_ALLOC(session, sig_len);
1891 
1892     if(!sig) {
1893         return -1;
1894     }
1895 
1896     ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx);
1897 
1898     if(!ret) {
1899         LIBSSH2_FREE(session, sig);
1900         return -1;
1901     }
1902 
1903     *signature = sig;
1904     *signature_len = sig_len;
1905 
1906     return 0;
1907 }
1908 
1909 #if LIBSSH2_DSA
1910 int
1911 _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
1912                        const unsigned char *hash,
1913                        unsigned long hash_len, unsigned char *signature)
1914 {
1915     DSA_SIG *sig;
1916     const BIGNUM * r;
1917     const BIGNUM * s;
1918     int r_len, s_len;
1919     (void) hash_len;
1920 
1921     sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
1922     if(!sig) {
1923         return -1;
1924     }
1925 
1926 #ifdef HAVE_OPAQUE_STRUCTS
1927     DSA_SIG_get0(sig, &r, &s);
1928 #else
1929     r = sig->r;
1930     s = sig->s;
1931 #endif
1932     r_len = BN_num_bytes(r);
1933     if(r_len < 1 || r_len > 20) {
1934         DSA_SIG_free(sig);
1935         return -1;
1936     }
1937     s_len = BN_num_bytes(s);
1938     if(s_len < 1 || s_len > 20) {
1939         DSA_SIG_free(sig);
1940         return -1;
1941     }
1942 
1943     memset(signature, 0, 40);
1944 
1945     BN_bn2bin(r, signature + (20 - r_len));
1946     BN_bn2bin(s, signature + 20 + (20 - s_len));
1947 
1948     DSA_SIG_free(sig);
1949 
1950     return 0;
1951 }
1952 #endif /* LIBSSH_DSA */
1953 
1954 #if LIBSSH2_ECDSA
1955 
1956 int
1957 _libssh2_ecdsa_sign(LIBSSH2_SESSION * session, libssh2_ecdsa_ctx * ec_ctx,
1958     const unsigned char *hash, unsigned long hash_len,
1959     unsigned char **signature, size_t *signature_len)
1960 {
1961     int r_len, s_len;
1962     int rc = 0;
1963     size_t out_buffer_len = 0;
1964     unsigned char *sp;
1965     const BIGNUM *pr = NULL, *ps = NULL;
1966     unsigned char *temp_buffer = NULL;
1967     unsigned char *out_buffer = NULL;
1968 
1969     ECDSA_SIG *sig = ECDSA_do_sign(hash, hash_len, ec_ctx);
1970     if(sig == NULL)
1971         return -1;
1972 #ifdef HAVE_OPAQUE_STRUCTS
1973     ECDSA_SIG_get0(sig, &pr, &ps);
1974 #else
1975     pr = sig->r;
1976     ps = sig->s;
1977 #endif
1978 
1979     r_len = BN_num_bytes(pr) + 1;
1980     s_len = BN_num_bytes(ps) + 1;
1981 
1982     temp_buffer = malloc(r_len + s_len + 8);
1983     if(temp_buffer == NULL) {
1984         rc = -1;
1985         goto clean_exit;
1986     }
1987 
1988     sp = temp_buffer;
1989     sp = write_bn(sp, pr, r_len);
1990     sp = write_bn(sp, ps, s_len);
1991 
1992     out_buffer_len = (size_t)(sp - temp_buffer);
1993 
1994     out_buffer = LIBSSH2_CALLOC(session, out_buffer_len);
1995     if(out_buffer == NULL) {
1996         rc = -1;
1997         goto clean_exit;
1998     }
1999 
2000     memcpy(out_buffer, temp_buffer, out_buffer_len);
2001 
2002     *signature = out_buffer;
2003     *signature_len = out_buffer_len;
2004 
2005 clean_exit:
2006 
2007     if(temp_buffer != NULL)
2008         free(temp_buffer);
2009 
2010     if(sig)
2011         ECDSA_SIG_free(sig);
2012 
2013     return rc;
2014 }
2015 #endif /* LIBSSH2_ECDSA */
2016 
2017 int
2018 _libssh2_sha1_init(libssh2_sha1_ctx *ctx)
2019 {
2020 #ifdef HAVE_OPAQUE_STRUCTS
2021     *ctx = EVP_MD_CTX_new();
2022 
2023     if(*ctx == NULL)
2024         return 0;
2025 
2026     if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha1")))
2027         return 1;
2028 
2029     EVP_MD_CTX_free(*ctx);
2030     *ctx = NULL;
2031 
2032     return 0;
2033 #else
2034     EVP_MD_CTX_init(ctx);
2035     return EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"));
2036 #endif
2037 }
2038 
2039 int
2040 _libssh2_sha1(const unsigned char *message, unsigned long len,
2041               unsigned char *out)
2042 {
2043 #ifdef HAVE_OPAQUE_STRUCTS
2044     EVP_MD_CTX * ctx = EVP_MD_CTX_new();
2045 
2046     if(ctx == NULL)
2047         return 1; /* error */
2048 
2049     if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"))) {
2050         EVP_DigestUpdate(ctx, message, len);
2051         EVP_DigestFinal(ctx, out, NULL);
2052         EVP_MD_CTX_free(ctx);
2053         return 0; /* success */
2054     }
2055     EVP_MD_CTX_free(ctx);
2056 #else
2057     EVP_MD_CTX ctx;
2058 
2059     EVP_MD_CTX_init(&ctx);
2060     if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"))) {
2061         EVP_DigestUpdate(&ctx, message, len);
2062         EVP_DigestFinal(&ctx, out, NULL);
2063         return 0; /* success */
2064     }
2065 #endif
2066     return 1; /* error */
2067 }
2068 
2069 int
2070 _libssh2_sha256_init(libssh2_sha256_ctx *ctx)
2071 {
2072 #ifdef HAVE_OPAQUE_STRUCTS
2073     *ctx = EVP_MD_CTX_new();
2074 
2075     if(*ctx == NULL)
2076         return 0;
2077 
2078     if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha256")))
2079         return 1;
2080 
2081     EVP_MD_CTX_free(*ctx);
2082     *ctx = NULL;
2083 
2084     return 0;
2085 #else
2086     EVP_MD_CTX_init(ctx);
2087     return EVP_DigestInit(ctx, EVP_get_digestbyname("sha256"));
2088 #endif
2089 }
2090 
2091 int
2092 _libssh2_sha256(const unsigned char *message, unsigned long len,
2093                 unsigned char *out)
2094 {
2095 #ifdef HAVE_OPAQUE_STRUCTS
2096     EVP_MD_CTX * ctx = EVP_MD_CTX_new();
2097 
2098     if(ctx == NULL)
2099         return 1; /* error */
2100 
2101     if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha256"))) {
2102         EVP_DigestUpdate(ctx, message, len);
2103         EVP_DigestFinal(ctx, out, NULL);
2104         EVP_MD_CTX_free(ctx);
2105         return 0; /* success */
2106     }
2107     EVP_MD_CTX_free(ctx);
2108 #else
2109     EVP_MD_CTX ctx;
2110 
2111     EVP_MD_CTX_init(&ctx);
2112     if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha256"))) {
2113         EVP_DigestUpdate(&ctx, message, len);
2114         EVP_DigestFinal(&ctx, out, NULL);
2115         return 0; /* success */
2116     }
2117 #endif
2118     return 1; /* error */
2119 }
2120 
2121 int
2122 _libssh2_sha384_init(libssh2_sha384_ctx *ctx)
2123 {
2124 #ifdef HAVE_OPAQUE_STRUCTS
2125     *ctx = EVP_MD_CTX_new();
2126 
2127     if(*ctx == NULL)
2128         return 0;
2129 
2130     if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha384")))
2131         return 1;
2132 
2133     EVP_MD_CTX_free(*ctx);
2134     *ctx = NULL;
2135 
2136     return 0;
2137 #else
2138     EVP_MD_CTX_init(ctx);
2139     return EVP_DigestInit(ctx, EVP_get_digestbyname("sha384"));
2140 #endif
2141 }
2142 
2143 int
2144 _libssh2_sha384(const unsigned char *message, unsigned long len,
2145     unsigned char *out)
2146 {
2147 #ifdef HAVE_OPAQUE_STRUCTS
2148     EVP_MD_CTX * ctx = EVP_MD_CTX_new();
2149 
2150     if(ctx == NULL)
2151         return 1; /* error */
2152 
2153     if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha384"))) {
2154         EVP_DigestUpdate(ctx, message, len);
2155         EVP_DigestFinal(ctx, out, NULL);
2156         EVP_MD_CTX_free(ctx);
2157         return 0; /* success */
2158     }
2159     EVP_MD_CTX_free(ctx);
2160 #else
2161     EVP_MD_CTX ctx;
2162 
2163     EVP_MD_CTX_init(&ctx);
2164     if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha384"))) {
2165         EVP_DigestUpdate(&ctx, message, len);
2166         EVP_DigestFinal(&ctx, out, NULL);
2167         return 0; /* success */
2168     }
2169 #endif
2170     return 1; /* error */
2171 }
2172 
2173 int
2174 _libssh2_sha512_init(libssh2_sha512_ctx *ctx)
2175 {
2176 #ifdef HAVE_OPAQUE_STRUCTS
2177     *ctx = EVP_MD_CTX_new();
2178 
2179     if(*ctx == NULL)
2180         return 0;
2181 
2182     if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha512")))
2183         return 1;
2184 
2185     EVP_MD_CTX_free(*ctx);
2186     *ctx = NULL;
2187 
2188     return 0;
2189 #else
2190     EVP_MD_CTX_init(ctx);
2191     return EVP_DigestInit(ctx, EVP_get_digestbyname("sha512"));
2192 #endif
2193 }
2194 
2195 int
2196 _libssh2_sha512(const unsigned char *message, unsigned long len,
2197     unsigned char *out)
2198 {
2199 #ifdef HAVE_OPAQUE_STRUCTS
2200     EVP_MD_CTX * ctx = EVP_MD_CTX_new();
2201 
2202     if(ctx == NULL)
2203         return 1; /* error */
2204 
2205     if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha512"))) {
2206         EVP_DigestUpdate(ctx, message, len);
2207         EVP_DigestFinal(ctx, out, NULL);
2208         EVP_MD_CTX_free(ctx);
2209         return 0; /* success */
2210     }
2211     EVP_MD_CTX_free(ctx);
2212 #else
2213     EVP_MD_CTX ctx;
2214 
2215     EVP_MD_CTX_init(&ctx);
2216     if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha512"))) {
2217         EVP_DigestUpdate(&ctx, message, len);
2218         EVP_DigestFinal(&ctx, out, NULL);
2219         return 0; /* success */
2220     }
2221 #endif
2222     return 1; /* error */
2223 }
2224 
2225 int
2226 _libssh2_md5_init(libssh2_md5_ctx *ctx)
2227 {
2228     /* MD5 digest is not supported in OpenSSL FIPS mode
2229      * Trying to init it will result in a latent OpenSSL error:
2230      * "digital envelope routines:FIPS_DIGESTINIT:disabled for fips"
2231      * So, just return 0 in FIPS mode
2232      */
2233 #if OPENSSL_VERSION_NUMBER >= 0x000907000L && \
2234     defined(OPENSSL_VERSION_MAJOR) && \
2235     OPENSSL_VERSION_MAJOR < 3 && \
2236     !defined(LIBRESSL_VERSION_NUMBER)
2237      if(FIPS_mode() != 0)
2238          return 0;
2239 #endif
2240 
2241 #ifdef HAVE_OPAQUE_STRUCTS
2242     *ctx = EVP_MD_CTX_new();
2243 
2244     if(*ctx == NULL)
2245         return 0;
2246 
2247     if(EVP_DigestInit(*ctx, EVP_get_digestbyname("md5")))
2248         return 1;
2249 
2250     EVP_MD_CTX_free(*ctx);
2251     *ctx = NULL;
2252 
2253     return 0;
2254 #else
2255     EVP_MD_CTX_init(ctx);
2256     return EVP_DigestInit(ctx, EVP_get_digestbyname("md5"));
2257 #endif
2258 }
2259 
2260 #if LIBSSH2_ECDSA
2261 
2262 static int
2263 gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
2264                           unsigned char **method,
2265                           size_t *method_len,
2266                           unsigned char **pubkeydata,
2267                           size_t *pubkeydata_len,
2268                           EVP_PKEY *pk)
2269 {
2270     int rc = 0;
2271     EC_KEY *ec = NULL;
2272     unsigned char *p;
2273     unsigned char *method_buf = NULL;
2274     unsigned char *key;
2275     size_t  key_len = 0;
2276     unsigned char *octal_value = NULL;
2277     size_t octal_len;
2278     const EC_POINT *public_key;
2279     const EC_GROUP *group;
2280     BN_CTX *bn_ctx;
2281     libssh2_curve_type type;
2282 
2283     _libssh2_debug(session,
2284        LIBSSH2_TRACE_AUTH,
2285        "Computing public key from EC private key envelope");
2286 
2287     bn_ctx = BN_CTX_new();
2288     if(bn_ctx == NULL)
2289         return -1;
2290 
2291     ec = EVP_PKEY_get1_EC_KEY(pk);
2292     if(ec == NULL) {
2293         rc = -1;
2294         goto clean_exit;
2295     }
2296 
2297     public_key = EC_KEY_get0_public_key(ec);
2298     group = EC_KEY_get0_group(ec);
2299     type = _libssh2_ecdsa_get_curve_type(ec);
2300 
2301     method_buf = LIBSSH2_ALLOC(session, 19);
2302     if(method_buf == NULL) {
2303         return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
2304             "out of memory");
2305     }
2306 
2307     if(type == LIBSSH2_EC_CURVE_NISTP256)
2308         memcpy(method_buf, "ecdsa-sha2-nistp256", 19);
2309     else if(type == LIBSSH2_EC_CURVE_NISTP384)
2310         memcpy(method_buf, "ecdsa-sha2-nistp384", 19);
2311     else if(type == LIBSSH2_EC_CURVE_NISTP521)
2312         memcpy(method_buf, "ecdsa-sha2-nistp521", 19);
2313     else {
2314         _libssh2_debug(session,
2315             LIBSSH2_TRACE_ERROR,
2316             "Unsupported EC private key type");
2317         rc = -1;
2318         goto clean_exit;
2319     }
2320 
2321     /* get length */
2322     octal_len = EC_POINT_point2oct(group, public_key,
2323                                    POINT_CONVERSION_UNCOMPRESSED,
2324                                    NULL, 0, bn_ctx);
2325     if(octal_len > EC_MAX_POINT_LEN) {
2326         rc = -1;
2327         goto clean_exit;
2328     }
2329 
2330     octal_value = malloc(octal_len);
2331     if(octal_value == NULL) {
2332         rc = -1;
2333         goto clean_exit;
2334     }
2335 
2336     /* convert to octal */
2337     if(EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED,
2338        octal_value, octal_len, bn_ctx) != octal_len) {
2339            rc = -1;
2340            goto clean_exit;
2341     }
2342 
2343     /* Key form is: type_len(4) + type(19) + domain_len(4) + domain(8) +
2344        pub_key_len(4) + pub_key(~65). */
2345     key_len = 4 + 19 + 4 + 8 + 4 + octal_len;
2346     key = LIBSSH2_ALLOC(session, key_len);
2347     if(key == NULL) {
2348         rc = -1;
2349         goto  clean_exit;
2350     }
2351 
2352     /* Process key encoding. */
2353     p = key;
2354 
2355     /* Key type */
2356     _libssh2_store_str(&p, (const char *)method_buf, 19);
2357 
2358     /* Name domain */
2359     _libssh2_store_str(&p, (const char *)method_buf + 11, 8);
2360 
2361     /* Public key */
2362     _libssh2_store_str(&p, (const char *)octal_value, octal_len);
2363 
2364     *method         = method_buf;
2365     *method_len     = 19;
2366     *pubkeydata     = key;
2367     *pubkeydata_len = key_len;
2368 
2369 clean_exit:
2370 
2371     if(ec != NULL)
2372         EC_KEY_free(ec);
2373 
2374     if(bn_ctx != NULL) {
2375         BN_CTX_free(bn_ctx);
2376     }
2377 
2378     if(octal_value != NULL)
2379         free(octal_value);
2380 
2381     if(rc == 0)
2382         return 0;
2383 
2384     if(method_buf != NULL)
2385         LIBSSH2_FREE(session, method_buf);
2386 
2387     return -1;
2388 }
2389 
2390 static int
2391 gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
2392                                            libssh2_curve_type curve_type,
2393                                            struct string_buf *decrypted,
2394                                            unsigned char **method,
2395                                            size_t *method_len,
2396                                            unsigned char **pubkeydata,
2397                                            size_t *pubkeydata_len,
2398                                            libssh2_ecdsa_ctx **ec_ctx)
2399 {
2400     int rc = 0;
2401     size_t curvelen, exponentlen, pointlen;
2402     unsigned char *curve, *exponent, *point_buf;
2403     EC_KEY *ec_key = NULL;
2404     BIGNUM *bn_exponent;
2405 
2406     _libssh2_debug(session,
2407                    LIBSSH2_TRACE_AUTH,
2408                    "Computing ECDSA keys from private key data");
2409 
2410     if(_libssh2_get_string(decrypted, &curve, &curvelen) ||
2411         curvelen == 0) {
2412         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2413                        "ECDSA no curve");
2414         return -1;
2415     }
2416 
2417     if(_libssh2_get_string(decrypted, &point_buf, &pointlen)) {
2418         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2419                        "ECDSA no point");
2420         return -1;
2421     }
2422 
2423     if(_libssh2_get_bignum_bytes(decrypted, &exponent, &exponentlen)) {
2424         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2425                        "ECDSA no exponent");
2426         return -1;
2427     }
2428 
2429     if((rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key, point_buf,
2430         pointlen, curve_type)) != 0) {
2431         rc = -1;
2432         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2433                        "ECDSA could not create key");
2434         goto fail;
2435     }
2436 
2437     bn_exponent = BN_new();
2438     if(bn_exponent == NULL) {
2439         rc = -1;
2440         _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
2441                        "Unable to allocate memory for private key data");
2442         goto fail;
2443     }
2444 
2445     BN_bin2bn(exponent, exponentlen, bn_exponent);
2446     rc = (EC_KEY_set_private_key(ec_key, bn_exponent) != 1);
2447 
2448     if(rc == 0 && ec_key != NULL && pubkeydata != NULL && method != NULL) {
2449         EVP_PKEY *pk = EVP_PKEY_new();
2450         EVP_PKEY_set1_EC_KEY(pk, ec_key);
2451 
2452         rc = gen_publickey_from_ec_evp(session, method, method_len,
2453                                        pubkeydata, pubkeydata_len,
2454                                        pk);
2455 
2456         if(pk)
2457             EVP_PKEY_free(pk);
2458     }
2459 
2460     if(ec_ctx != NULL)
2461         *ec_ctx = ec_key;
2462     else
2463         EC_KEY_free(ec_key);
2464 
2465     return rc;
2466 
2467 fail:
2468     if(ec_key != NULL)
2469         EC_KEY_free(ec_key);
2470 
2471     return rc;
2472 }
2473 
2474 static int
2475 _libssh2_ecdsa_new_openssh_private(libssh2_ecdsa_ctx ** ec_ctx,
2476                                    LIBSSH2_SESSION * session,
2477                                    const char *filename,
2478                                    unsigned const char *passphrase)
2479 {
2480     FILE *fp;
2481     int rc;
2482     unsigned char *buf = NULL;
2483     libssh2_curve_type type;
2484     struct string_buf *decrypted = NULL;
2485 
2486     if(session == NULL) {
2487         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2488                            "Session is required");
2489         return -1;
2490     }
2491 
2492     _libssh2_init_if_needed();
2493 
2494     fp = fopen(filename, "r");
2495     if(!fp) {
2496         _libssh2_error(session, LIBSSH2_ERROR_FILE,
2497                        "Unable to open OpenSSH ECDSA private key file");
2498         return -1;
2499     }
2500 
2501     rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted);
2502     fclose(fp);
2503     if(rc) {
2504         return rc;
2505     }
2506 
2507     /* We have a new key file, now try and parse it using supported types  */
2508     rc = _libssh2_get_string(decrypted, &buf, NULL);
2509 
2510     if(rc != 0 || buf == NULL) {
2511         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2512                        "Public key type in decrypted key data not found");
2513         return -1;
2514     }
2515 
2516     rc = _libssh2_ecdsa_curve_type_from_name((const char *)buf, &type);
2517 
2518     if(rc == 0) {
2519         rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type,
2520                                                         decrypted, NULL, 0,
2521                                                         NULL, 0, ec_ctx);
2522     }
2523     else {
2524         rc = -1;
2525     }
2526 
2527     if(decrypted)
2528         _libssh2_string_buf_free(session, decrypted);
2529 
2530     return rc;
2531 }
2532 
2533 int
2534 _libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx,
2535        LIBSSH2_SESSION * session,
2536        const char *filename, unsigned const char *passphrase)
2537 {
2538     int rc;
2539 
2540     pem_read_bio_func read_ec = (pem_read_bio_func) &PEM_read_bio_ECPrivateKey;
2541 
2542     _libssh2_init_if_needed();
2543 
2544     rc = read_private_key_from_file((void **) ec_ctx, read_ec,
2545       filename, passphrase);
2546 
2547     if(rc) {
2548         return _libssh2_ecdsa_new_openssh_private(ec_ctx, session,
2549                                                   filename, passphrase);
2550     }
2551 
2552     return rc;
2553 }
2554 
2555 /*
2556  * _libssh2_ecdsa_create_key
2557  *
2558  * Creates a local private key based on input curve
2559  * and returns octal value and octal length
2560  *
2561  */
2562 
2563 int
2564 _libssh2_ecdsa_create_key(LIBSSH2_SESSION *session,
2565                           _libssh2_ec_key **out_private_key,
2566                           unsigned char **out_public_key_octal,
2567                           size_t *out_public_key_octal_len,
2568                           libssh2_curve_type curve_type)
2569 {
2570     int ret = 1;
2571     size_t octal_len = 0;
2572     unsigned char octal_value[EC_MAX_POINT_LEN];
2573     const EC_POINT *public_key = NULL;
2574     EC_KEY *private_key = NULL;
2575     const EC_GROUP *group = NULL;
2576 
2577     /* create key */
2578     BN_CTX *bn_ctx = BN_CTX_new();
2579     if(!bn_ctx)
2580         return -1;
2581 
2582     private_key = EC_KEY_new_by_curve_name(curve_type);
2583     group = EC_KEY_get0_group(private_key);
2584 
2585     EC_KEY_generate_key(private_key);
2586     public_key = EC_KEY_get0_public_key(private_key);
2587 
2588     /* get length */
2589     octal_len = EC_POINT_point2oct(group, public_key,
2590                                    POINT_CONVERSION_UNCOMPRESSED,
2591                                    NULL, 0, bn_ctx);
2592     if(octal_len > EC_MAX_POINT_LEN) {
2593         ret = -1;
2594         goto clean_exit;
2595     }
2596 
2597     /* convert to octal */
2598     if(EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED,
2599        octal_value, octal_len, bn_ctx) != octal_len) {
2600            ret = -1;
2601            goto clean_exit;
2602     }
2603 
2604     if(out_private_key != NULL)
2605         *out_private_key = private_key;
2606 
2607     if(out_public_key_octal) {
2608         *out_public_key_octal = LIBSSH2_ALLOC(session, octal_len);
2609         if(*out_public_key_octal == NULL) {
2610             ret = -1;
2611             goto clean_exit;
2612         }
2613 
2614         memcpy(*out_public_key_octal, octal_value, octal_len);
2615     }
2616 
2617     if(out_public_key_octal_len != NULL)
2618         *out_public_key_octal_len = octal_len;
2619 
2620 clean_exit:
2621 
2622     if(bn_ctx)
2623         BN_CTX_free(bn_ctx);
2624 
2625     return (ret == 1) ? 0 : -1;
2626 }
2627 
2628 /* _libssh2_ecdh_gen_k
2629  *
2630  * Computes the shared secret K given a local private key,
2631  * remote public key and length
2632  */
2633 
2634 int
2635 _libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key,
2636     const unsigned char *server_public_key, size_t server_public_key_len)
2637 {
2638     int ret = 0;
2639     int rc;
2640     size_t secret_len;
2641     unsigned char *secret = NULL;
2642     const EC_GROUP *private_key_group;
2643     EC_POINT *server_public_key_point;
2644 
2645     BN_CTX *bn_ctx = BN_CTX_new();
2646 
2647     if(!bn_ctx)
2648         return -1;
2649 
2650     if(k == NULL)
2651         return -1;
2652 
2653     private_key_group = EC_KEY_get0_group(private_key);
2654 
2655     server_public_key_point = EC_POINT_new(private_key_group);
2656     if(server_public_key_point == NULL)
2657         return -1;
2658 
2659     rc = EC_POINT_oct2point(private_key_group, server_public_key_point,
2660                             server_public_key, server_public_key_len, bn_ctx);
2661     if(rc != 1) {
2662         ret = -1;
2663         goto clean_exit;
2664     }
2665 
2666     secret_len = (EC_GROUP_get_degree(private_key_group) + 7) / 8;
2667     secret = malloc(secret_len);
2668     if(!secret) {
2669         ret = -1;
2670         goto clean_exit;
2671     }
2672 
2673     secret_len = ECDH_compute_key(secret, secret_len, server_public_key_point,
2674                                   private_key, NULL);
2675 
2676     if(secret_len <= 0 || secret_len > EC_MAX_POINT_LEN) {
2677         ret = -1;
2678         goto clean_exit;
2679     }
2680 
2681     BN_bin2bn(secret, secret_len, *k);
2682 
2683 clean_exit:
2684 
2685     if(server_public_key_point != NULL)
2686         EC_POINT_free(server_public_key_point);
2687 
2688     if(bn_ctx != NULL)
2689         BN_CTX_free(bn_ctx);
2690 
2691     if(secret != NULL)
2692         free(secret);
2693 
2694     return ret;
2695 }
2696 
2697 
2698 #endif /* LIBSSH2_ECDSA */
2699 
2700 #if LIBSSH2_ED25519
2701 
2702 int
2703 _libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session,
2704                       uint8_t **out_sig, size_t *out_sig_len,
2705                       const uint8_t *message, size_t message_len)
2706 {
2707     int rc = -1;
2708     EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
2709     size_t sig_len = 0;
2710     unsigned char *sig = NULL;
2711 
2712     if(md_ctx != NULL) {
2713         if(EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, ctx) != 1)
2714             goto clean_exit;
2715         if(EVP_DigestSign(md_ctx, NULL, &sig_len, message, message_len) != 1)
2716             goto clean_exit;
2717 
2718         if(sig_len != LIBSSH2_ED25519_SIG_LEN)
2719             goto clean_exit;
2720 
2721         sig = LIBSSH2_CALLOC(session, sig_len);
2722         if(sig == NULL)
2723             goto clean_exit;
2724 
2725         rc = EVP_DigestSign(md_ctx, sig, &sig_len, message, message_len);
2726     }
2727 
2728     if(rc == 1) {
2729         *out_sig = sig;
2730         *out_sig_len = sig_len;
2731     }
2732     else {
2733         *out_sig_len = 0;
2734         *out_sig = NULL;
2735         LIBSSH2_FREE(session, sig);
2736     }
2737 
2738 clean_exit:
2739 
2740     if(md_ctx)
2741         EVP_MD_CTX_free(md_ctx);
2742 
2743     return (rc == 1 ? 0 : -1);
2744 }
2745 
2746 int
2747 _libssh2_curve25519_gen_k(_libssh2_bn **k,
2748                           uint8_t private_key[LIBSSH2_ED25519_KEY_LEN],
2749                           uint8_t server_public_key[LIBSSH2_ED25519_KEY_LEN])
2750 {
2751     int rc = -1;
2752     unsigned char out_shared_key[LIBSSH2_ED25519_KEY_LEN];
2753     EVP_PKEY *peer_key = NULL, *server_key = NULL;
2754     EVP_PKEY_CTX *server_key_ctx = NULL;
2755     BN_CTX *bn_ctx = NULL;
2756     size_t out_len = 0;
2757 
2758     if(k == NULL || *k == NULL)
2759         return -1;
2760 
2761     bn_ctx = BN_CTX_new();
2762     if(bn_ctx == NULL)
2763         return -1;
2764 
2765     peer_key = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL,
2766                                            server_public_key,
2767                                            LIBSSH2_ED25519_KEY_LEN);
2768 
2769     server_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL,
2770                                               private_key,
2771                                               LIBSSH2_ED25519_KEY_LEN);
2772 
2773     if(peer_key == NULL || server_key == NULL) {
2774         goto cleanExit;
2775     }
2776 
2777     server_key_ctx = EVP_PKEY_CTX_new(server_key, NULL);
2778     if(server_key_ctx == NULL) {
2779         goto cleanExit;
2780     }
2781 
2782     rc = EVP_PKEY_derive_init(server_key_ctx);
2783     if(rc <= 0) goto cleanExit;
2784 
2785     rc = EVP_PKEY_derive_set_peer(server_key_ctx, peer_key);
2786     if(rc <= 0) goto cleanExit;
2787 
2788     rc = EVP_PKEY_derive(server_key_ctx, NULL, &out_len);
2789     if(rc <= 0) goto cleanExit;
2790 
2791     if(out_len != LIBSSH2_ED25519_KEY_LEN) {
2792         rc = -1;
2793         goto cleanExit;
2794     }
2795 
2796     rc = EVP_PKEY_derive(server_key_ctx, out_shared_key, &out_len);
2797 
2798     if(rc == 1 && out_len == LIBSSH2_ED25519_KEY_LEN) {
2799         BN_bin2bn(out_shared_key, LIBSSH2_ED25519_KEY_LEN, *k);
2800     }
2801     else {
2802         rc = -1;
2803     }
2804 
2805 cleanExit:
2806 
2807     if(server_key_ctx)
2808         EVP_PKEY_CTX_free(server_key_ctx);
2809     if(peer_key)
2810         EVP_PKEY_free(peer_key);
2811     if(server_key)
2812         EVP_PKEY_free(server_key);
2813     if(bn_ctx != NULL)
2814         BN_CTX_free(bn_ctx);
2815 
2816     return (rc == 1) ? 0 : -1;
2817 }
2818 
2819 
2820 int
2821 _libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s,
2822                         size_t s_len, const uint8_t *m, size_t m_len)
2823 {
2824     int ret = -1;
2825 
2826     EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
2827     if(NULL == md_ctx)
2828         return -1;
2829 
2830     ret = EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, ctx);
2831     if(ret != 1)
2832         goto clean_exit;
2833 
2834     ret = EVP_DigestVerify(md_ctx, s, s_len, m, m_len);
2835 
2836     clean_exit:
2837 
2838     EVP_MD_CTX_free(md_ctx);
2839 
2840     return (ret == 1) ? 0 : -1;
2841 }
2842 
2843 #endif /* LIBSSH2_ED25519 */
2844 
2845 static int
2846 _libssh2_pub_priv_openssh_keyfile(LIBSSH2_SESSION *session,
2847                                   unsigned char **method,
2848                                   size_t *method_len,
2849                                   unsigned char **pubkeydata,
2850                                   size_t *pubkeydata_len,
2851                                   const char *privatekey,
2852                                   const char *passphrase)
2853 {
2854     FILE *fp;
2855     unsigned char *buf = NULL;
2856     struct string_buf *decrypted = NULL;
2857     int rc = 0;
2858 
2859     if(session == NULL) {
2860         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2861                        "Session is required");
2862         return -1;
2863     }
2864 
2865     _libssh2_init_if_needed();
2866 
2867     fp = fopen(privatekey, "r");
2868     if(!fp) {
2869         _libssh2_error(session, LIBSSH2_ERROR_FILE,
2870                        "Unable to open private key file");
2871         return -1;
2872     }
2873 
2874     rc = _libssh2_openssh_pem_parse(session, (const unsigned char *)passphrase,
2875                                     fp, &decrypted);
2876     fclose(fp);
2877     if(rc) {
2878         _libssh2_error(session, LIBSSH2_ERROR_FILE,
2879                        "Not an OpenSSH key file");
2880         return rc;
2881     }
2882 
2883     /* We have a new key file, now try and parse it using supported types  */
2884     rc = _libssh2_get_string(decrypted, &buf, NULL);
2885 
2886     if(rc != 0 || buf == NULL) {
2887         _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2888                        "Public key type in decrypted key data not found");
2889         return -1;
2890     }
2891 
2892     rc = -1;
2893 
2894 #if LIBSSH2_ED25519
2895     if(strcmp("ssh-ed25519", (const char *)buf) == 0) {
2896         rc = gen_publickey_from_ed25519_openssh_priv_data(session, decrypted,
2897                                                           method, method_len,
2898                                                           pubkeydata,
2899                                                           pubkeydata_len,
2900                                                           NULL);
2901     }
2902 #endif
2903 #if LIBSSH2_RSA
2904     if(strcmp("ssh-rsa", (const char *)buf) == 0) {
2905         rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted,
2906                                                       method, method_len,
2907                                                       pubkeydata,
2908                                                       pubkeydata_len,
2909                                                       NULL);
2910     }
2911 #endif
2912 #if LIBSSH2_DSA
2913     if(strcmp("ssh-dss", (const char *)buf) == 0) {
2914         rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted,
2915                                                       method, method_len,
2916                                                       pubkeydata,
2917                                                       pubkeydata_len,
2918                                                       NULL);
2919     }
2920 #endif
2921 #if LIBSSH2_ECDSA
2922     {
2923         libssh2_curve_type type;
2924 
2925         if(_libssh2_ecdsa_curve_type_from_name((const char *)buf,
2926                                                &type) == 0) {
2927             rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type,
2928                                                             decrypted,
2929                                                             method, method_len,
2930                                                             pubkeydata,
2931                                                             pubkeydata_len,
2932                                                             NULL);
2933         }
2934     }
2935 #endif
2936 
2937     if(decrypted)
2938         _libssh2_string_buf_free(session, decrypted);
2939 
2940     if(rc != 0) {
2941         _libssh2_error(session, LIBSSH2_ERROR_FILE,
2942                        "Unsupported OpenSSH key type");
2943     }
2944 
2945     return rc;
2946 }
2947 
2948 int
2949 _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
2950                           unsigned char **method,
2951                           size_t *method_len,
2952                           unsigned char **pubkeydata,
2953                           size_t *pubkeydata_len,
2954                           const char *privatekey,
2955                           const char *passphrase)
2956 {
2957     int       st;
2958     BIO*      bp;
2959     EVP_PKEY* pk;
2960     int       pktype;
2961     int       rc;
2962 
2963     _libssh2_debug(session,
2964                    LIBSSH2_TRACE_AUTH,
2965                    "Computing public key from private key file: %s",
2966                    privatekey);
2967 
2968     bp = BIO_new_file(privatekey, "r");
2969     if(bp == NULL) {
2970         return _libssh2_error(session,
2971                               LIBSSH2_ERROR_FILE,
2972                               "Unable to extract public key from private key "
2973                               "file: Unable to open private key file");
2974     }
2975 
2976     BIO_reset(bp);
2977     pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase);
2978     BIO_free(bp);
2979 
2980     if(pk == NULL) {
2981 
2982         /* Try OpenSSH format */
2983         rc = _libssh2_pub_priv_openssh_keyfile(session,
2984                                                method,
2985                                                method_len,
2986                                                pubkeydata, pubkeydata_len,
2987                                                privatekey, passphrase);
2988         if(rc != 0) {
2989             return _libssh2_error(session,
2990                                   LIBSSH2_ERROR_FILE,
2991                                   "Unable to extract public key "
2992                                   "from private key file: "
2993                                   "Wrong passphrase or invalid/unrecognized "
2994                                   "private key file format");
2995         }
2996 
2997         return 0;
2998     }
2999 
3000 #ifdef HAVE_OPAQUE_STRUCTS
3001     pktype = EVP_PKEY_id(pk);
3002 #else
3003     pktype = pk->type;
3004 #endif
3005 
3006     switch(pktype) {
3007 #if LIBSSH2_ED25519
3008     case EVP_PKEY_ED25519 :
3009         st = gen_publickey_from_ed_evp(
3010             session, method, method_len, pubkeydata, pubkeydata_len, pk);
3011         break;
3012 #endif /* LIBSSH2_ED25519 */
3013     case EVP_PKEY_RSA :
3014         st = gen_publickey_from_rsa_evp(
3015             session, method, method_len, pubkeydata, pubkeydata_len, pk);
3016         break;
3017 
3018 #if LIBSSH2_DSA
3019     case EVP_PKEY_DSA :
3020         st = gen_publickey_from_dsa_evp(
3021             session, method, method_len, pubkeydata, pubkeydata_len, pk);
3022         break;
3023 #endif /* LIBSSH_DSA */
3024 
3025 #if LIBSSH2_ECDSA
3026     case EVP_PKEY_EC :
3027         st = gen_publickey_from_ec_evp(
3028             session, method, method_len, pubkeydata, pubkeydata_len, pk);
3029     break;
3030 #endif
3031 
3032     default :
3033         st = _libssh2_error(session,
3034                             LIBSSH2_ERROR_FILE,
3035                             "Unable to extract public key "
3036                             "from private key file: "
3037                             "Unsupported private key file format");
3038         break;
3039     }
3040 
3041     EVP_PKEY_free(pk);
3042     return st;
3043 }
3044 
3045 static int
3046 _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
3047                                         void **key_ctx,
3048                                         const char *key_type,
3049                                         unsigned char **method,
3050                                         size_t *method_len,
3051                                         unsigned char **pubkeydata,
3052                                         size_t *pubkeydata_len,
3053                                         const char *privatekeydata,
3054                                         size_t privatekeydata_len,
3055                                         unsigned const char *passphrase)
3056 {
3057     int rc;
3058     unsigned char *buf = NULL;
3059     struct string_buf *decrypted = NULL;
3060 
3061     if(key_ctx != NULL)
3062         *key_ctx = NULL;
3063 
3064     if(session == NULL)
3065         return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
3066                               "Session is required");
3067 
3068     if(key_type != NULL && (strlen(key_type) > 11 || strlen(key_type) < 7))
3069         return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
3070                               "type is invalid");
3071 
3072     _libssh2_init_if_needed();
3073 
3074     rc = _libssh2_openssh_pem_parse_memory(session, passphrase,
3075                                            privatekeydata,
3076                                            privatekeydata_len, &decrypted);
3077 
3078     if(rc)
3079         return rc;
3080 
3081    /* We have a new key file, now try and parse it using supported types  */
3082    rc = _libssh2_get_string(decrypted, &buf, NULL);
3083 
3084    if(rc != 0 || buf == NULL)
3085        return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
3086                              "Public key type in decrypted "
3087                              "key data not found");
3088 
3089    rc = LIBSSH2_ERROR_FILE;
3090 
3091 #if LIBSSH2_ED25519
3092     if(strcmp("ssh-ed25519", (const char *)buf) == 0) {
3093         if(key_type == NULL || strcmp("ssh-ed25519", key_type) == 0) {
3094             rc = gen_publickey_from_ed25519_openssh_priv_data(session,
3095                                                               decrypted,
3096                                                               method,
3097                                                               method_len,
3098                                                               pubkeydata,
3099                                                               pubkeydata_len,
3100                                               (libssh2_ed25519_ctx**)key_ctx);
3101         }
3102    }
3103 #endif
3104 #if LIBSSH2_RSA
3105     if(strcmp("ssh-rsa", (const char *)buf) == 0) {
3106         if(key_type == NULL || strcmp("ssh-rsa", key_type) == 0) {
3107             rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted,
3108                                                           method, method_len,
3109                                                           pubkeydata,
3110                                                           pubkeydata_len,
3111                                                 (libssh2_rsa_ctx**)key_ctx);
3112         }
3113    }
3114 #endif
3115 #if LIBSSH2_DSA
3116     if(strcmp("ssh-dss", (const char *)buf) == 0) {
3117         if(key_type == NULL || strcmp("ssh-dss", key_type) == 0) {
3118             rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted,
3119                                                          method, method_len,
3120                                                           pubkeydata,
3121                                                           pubkeydata_len,
3122                                                  (libssh2_dsa_ctx**)key_ctx);
3123         }
3124    }
3125 #endif
3126 #if LIBSSH2_ECDSA
3127 {
3128    libssh2_curve_type type;
3129 
3130    if(_libssh2_ecdsa_curve_type_from_name((const char *)buf, &type) == 0) {
3131        if(key_type == NULL || strcmp("ssh-ecdsa", key_type) == 0) {
3132            rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type,
3133                                                            decrypted,
3134                                                            method, method_len,
3135                                                            pubkeydata,
3136                                                            pubkeydata_len,
3137                                                (libssh2_ecdsa_ctx**)key_ctx);
3138         }
3139     }
3140 }
3141 #endif
3142 
3143     if(rc == LIBSSH2_ERROR_FILE)
3144         rc = _libssh2_error(session, LIBSSH2_ERROR_FILE,
3145                          "Unable to extract public key from private key file: "
3146                          "invalid/unrecognized private key file format");
3147 
3148     if(decrypted)
3149         _libssh2_string_buf_free(session, decrypted);
3150 
3151     return rc;
3152 }
3153 
3154 int
3155 read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session,
3156                                      const char *key_type,
3157                                      const char *filedata,
3158                                      size_t filedata_len,
3159                                      unsigned const char *passphrase)
3160 {
3161     return _libssh2_pub_priv_openssh_keyfilememory(session, key_ctx, key_type,
3162                                                    NULL, NULL, NULL, NULL,
3163                                                    filedata, filedata_len,
3164                                                    passphrase);
3165 }
3166 
3167 int
3168 _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
3169                                 unsigned char **method,
3170                                 size_t *method_len,
3171                                 unsigned char **pubkeydata,
3172                                 size_t *pubkeydata_len,
3173                                 const char *privatekeydata,
3174                                 size_t privatekeydata_len,
3175                                 const char *passphrase)
3176 {
3177     int       st;
3178     BIO*      bp;
3179     EVP_PKEY* pk;
3180     int       pktype;
3181 
3182     _libssh2_debug(session,
3183                    LIBSSH2_TRACE_AUTH,
3184                    "Computing public key from private key.");
3185 
3186     bp = BIO_new_mem_buf((char *)privatekeydata, privatekeydata_len);
3187     if(!bp)
3188         return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
3189                               "Unable to allocate memory when"
3190                               "computing public key");
3191     BIO_reset(bp);
3192     pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase);
3193     BIO_free(bp);
3194 
3195     if(pk == NULL) {
3196         /* Try OpenSSH format */
3197         st = _libssh2_pub_priv_openssh_keyfilememory(session, NULL, NULL,
3198                                                      method,
3199                                                      method_len,
3200                                                      pubkeydata,
3201                                                      pubkeydata_len,
3202                                                      privatekeydata,
3203                                                      privatekeydata_len,
3204                                            (unsigned const char *)passphrase);
3205         if(st != 0)
3206             return st;
3207         return 0;
3208     }
3209 
3210 #ifdef HAVE_OPAQUE_STRUCTS
3211     pktype = EVP_PKEY_id(pk);
3212 #else
3213     pktype = pk->type;
3214 #endif
3215 
3216     switch(pktype) {
3217 #if LIBSSH2_ED25519
3218     case EVP_PKEY_ED25519 :
3219         st = gen_publickey_from_ed_evp(
3220             session, method, method_len, pubkeydata, pubkeydata_len, pk);
3221         break;
3222 #endif /* LIBSSH2_ED25519 */
3223     case EVP_PKEY_RSA :
3224         st = gen_publickey_from_rsa_evp(session, method, method_len,
3225                                         pubkeydata, pubkeydata_len, pk);
3226         break;
3227 #if LIBSSH2_DSA
3228     case EVP_PKEY_DSA :
3229         st = gen_publickey_from_dsa_evp(session, method, method_len,
3230                                         pubkeydata, pubkeydata_len, pk);
3231         break;
3232 #endif /* LIBSSH_DSA */
3233 #if LIBSSH2_ECDSA
3234     case EVP_PKEY_EC :
3235         st = gen_publickey_from_ec_evp(session, method, method_len,
3236                                        pubkeydata, pubkeydata_len, pk);
3237         break;
3238 #endif /* LIBSSH2_ECDSA */
3239     default :
3240         st = _libssh2_error(session,
3241                             LIBSSH2_ERROR_FILE,
3242                             "Unable to extract public key "
3243                             "from private key file: "
3244                             "Unsupported private key file format");
3245         break;
3246     }
3247 
3248     EVP_PKEY_free(pk);
3249     return st;
3250 }
3251 
3252 void
3253 _libssh2_dh_init(_libssh2_dh_ctx *dhctx)
3254 {
3255     *dhctx = BN_new();                          /* Random from client */
3256 }
3257 
3258 int
3259 _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
3260                      _libssh2_bn *g, _libssh2_bn *p, int group_order,
3261                      _libssh2_bn_ctx *bnctx)
3262 {
3263     /* Generate x and e */
3264     BN_rand(*dhctx, group_order * 8 - 1, 0, -1);
3265     BN_mod_exp(public, g, *dhctx, p, bnctx);
3266     return 0;
3267 }
3268 
3269 int
3270 _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
3271                    _libssh2_bn *f, _libssh2_bn *p,
3272                    _libssh2_bn_ctx *bnctx)
3273 {
3274     /* Compute the shared secret */
3275     BN_mod_exp(secret, f, *dhctx, p, bnctx);
3276     return 0;
3277 }
3278 
3279 void
3280 _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
3281 {
3282     BN_clear_free(*dhctx);
3283     *dhctx = NULL;
3284 }
3285 
3286 #endif /* LIBSSH2_OPENSSL */
3287