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