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