1 /*
2  * ProFTPD - mod_sftp key mgmt (keys)
3  * Copyright (c) 2008-2021 TJ Saunders
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  *
19  * As a special exemption, TJ Saunders and other respective copyright holders
20  * give permission to link this program with OpenSSL, and distribute the
21  * resulting executable, without including the source code for OpenSSL in the
22  * source distribution.
23  */
24 
25 #include "mod_sftp.h"
26 
27 #include "msg.h"
28 #include "packet.h"
29 #include "crypto.h"
30 #include "keys.h"
31 #include "agent.h"
32 #include "interop.h"
33 #include "bcrypt.h"
34 #if defined(PR_USE_SODIUM)
35 # include <sodium.h>
36 #endif /* PR_USE_SODIUM */
37 
38 extern xaset_t *server_list;
39 extern module sftp_module;
40 
41 /* Note: Should this size be made bigger, in light of larger hostkeys? */
42 #define SFTP_DEFAULT_HOSTKEY_SZ		4096
43 #define SFTP_MAX_SIG_SZ			4096
44 
45 struct sftp_hostkey {
46   enum sftp_key_type_e key_type;
47   EVP_PKEY *pkey;
48 
49   /* Non-OpenSSL keys */
50   unsigned char *ed25519_public_key;
51   unsigned long long ed25519_public_keylen;
52   unsigned char *ed25519_secret_key;
53   unsigned long long ed25519_secret_keylen;
54 
55   const unsigned char *key_data;
56   uint32_t key_datalen;
57 
58   /* This will usually not be null; if the key was obtained from a local
59    * file, this will point to that file.
60    */
61   const char *file_path;
62 
63   /* This will usually be null; if the key was obtained from an agent,
64    * this point will point to the Unix domain socket to use for talking
65    * to that agent, e.g. for data signing requests.
66    */
67   const char *agent_path;
68 };
69 
70 static struct sftp_hostkey *sftp_dsa_hostkey = NULL;
71 static struct sftp_hostkey *sftp_ed25519_hostkey = NULL;
72 static struct sftp_hostkey *sftp_rsa_hostkey = NULL;
73 
74 #ifdef PR_USE_OPENSSL_ECC
75 static struct sftp_hostkey *sftp_ecdsa256_hostkey = NULL;
76 static struct sftp_hostkey *sftp_ecdsa384_hostkey = NULL;
77 static struct sftp_hostkey *sftp_ecdsa521_hostkey = NULL;
78 #endif /* PR_USE_OPENSSL_ECC */
79 
80 static const char *passphrase_provider = NULL;
81 
82 struct sftp_pkey {
83   struct sftp_pkey *next;
84   size_t pkeysz;
85 
86   char *host_pkey;
87   void *host_pkey_ptr;
88   server_rec *server;
89 };
90 
91 #define SFTP_PASSPHRASE_TIMEOUT		10
92 
93 static struct sftp_pkey *sftp_pkey_list = NULL;
94 static unsigned int sftp_npkeys = 0;
95 static struct sftp_pkey *server_pkey = NULL;
96 
97 struct sftp_pkey_data {
98   server_rec *s;
99   const char *path;
100   char *buf;
101   size_t buflen, bufsz;
102   const char *prompt;
103 };
104 
105 /* Default minimum key sizes, in BITS.  The RSA minimum of 768 bits comes from
106  * the OpenSSH-7.2 implementation.  And the others follow from that, based on
107  * the assumptions described here:
108  *   https://en.wikipedia.org/wiki/Key_size#Asymmetric_algorithm_key_lengths
109  *   http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/key-size.htm
110  *
111  * Note that the RSA size refers to the size of the modulus.  The DSA size
112  * refers to the size of the modulus.  The EC size refers to the minimum
113  * order of the base point on the elliptic curve.
114  */
115 static int keys_rsa_min_nbits = 768;
116 static int keys_dsa_min_nbits = 384;
117 static int keys_ec_min_nbits = 160;
118 
119 /* Public key files start with "BEGIN ... PUBLIC KEY" and "END ... PUBLIC KEY"
120  * lines.  Note that the "..." can be multiple different values ("RSA", "SSH2",
121  * etc).
122  */
123 #define SFTP_PUBLICKEY_BEGIN		"BEGIN PUBLIC KEY"
124 #define SFTP_PUBLICKEY_BEGIN_LEN	(sizeof(SFTP_PUBLICKEY_BEGIN) - 1)
125 #define SFTP_PUBLICKEY_END		"END PUBLIC KEY"
126 #define SFTP_PUBLICKEY_END_LEN		(sizeof(SFTP_PUBLICKEY_BEGIN) - 1)
127 
128 /* OpenSSH's homegrown private key file format.
129  *
130  * See the PROTOCOL.key file in the OpenSSH source distribution for details
131  * on their homegrown private key format.  See also the implementations in
132  * sskey.c#sshkey_private_to_blob2 (for writing private keys) and
133  * sshkey.c#sshkey_parse_private2 (for reading private keys).  The values
134  * for different encryption ciphers are in the `ciphers[]` table in cipher.c.
135  */
136 
137 #define SFTP_OPENSSH_BEGIN		"-----BEGIN OPENSSH PRIVATE KEY-----\n"
138 #define SFTP_OPENSSH_END		"-----END OPENSSH PRIVATE KEY-----\n"
139 #define SFTP_OPENSSH_BEGIN_LEN		(sizeof(SFTP_OPENSSH_BEGIN) - 1)
140 #define SFTP_OPENSSH_END_LEN		(sizeof(SFTP_OPENSSH_END) - 1)
141 #define SFTP_OPENSSH_KDFNAME		"bcrypt"
142 #define SFTP_OPENSSH_MAGIC		"openssh-key-v1"
143 
144 /* Encryption cipher info. */
145 struct openssh_cipher {
146   const char *algo;
147   uint32_t blocksz;
148   uint32_t key_len;
149   uint32_t iv_len;
150   uint32_t auth_len;
151 
152   const EVP_CIPHER *(*get_cipher)(void);
153 };
154 
155 static struct openssh_cipher ciphers[] = {
156   { "none",        8,  0, 0, 0, EVP_enc_null },
157   { "aes256-cbc", 16, 32, 16, 0, EVP_aes_256_cbc },
158 #if defined(HAVE_EVP_AES_256_CTR_OPENSSL)
159   { "aes256-ctr", 16, 32, 16, 0, EVP_aes_256_ctr },
160 #else
161   { "aes256-ctr", 16, 32, 16, 0, NULL },
162 #endif /* HAVE_EVP_AES_256_CTR_OPENSSL */
163 
164   { NULL,          0,  0, 0, 0, NULL }
165 };
166 
167 static int read_openssh_private_key(pool *p, const char *path, int fd,
168     const char *passphrase, enum sftp_key_type_e *key_type, EVP_PKEY **pkey,
169     unsigned char **key, uint32_t *keylen);
170 
171 static const char *trace_channel = "ssh2";
172 
prepare_provider_fds(int stdout_fd,int stderr_fd)173 static void prepare_provider_fds(int stdout_fd, int stderr_fd) {
174   long nfiles = 0;
175   register unsigned int i = 0;
176   struct rlimit rlim;
177 
178   if (stdout_fd != STDOUT_FILENO) {
179     if (dup2(stdout_fd, STDOUT_FILENO) < 0) {
180       pr_log_debug(DEBUG0, MOD_SFTP_VERSION
181         ": error duping fd %d to stdout: %s", stdout_fd, strerror(errno));
182     }
183 
184     (void) close(stdout_fd);
185   }
186 
187   if (stderr_fd != STDERR_FILENO) {
188     if (dup2(stderr_fd, STDERR_FILENO) < 0) {
189       pr_log_debug(DEBUG0, MOD_SFTP_VERSION
190         ": error duping fd %d to stderr: %s", stderr_fd, strerror(errno));
191     }
192 
193     (void) close(stderr_fd);
194   }
195 
196   /* Make sure not to pass on open file descriptors. For stdout and stderr,
197    * we dup some pipes, so that we can capture what the command may write
198    * to stdout or stderr.  The stderr output will be logged to the SFTPLog.
199    *
200    * First, use getrlimit() to obtain the maximum number of open files
201    * for this process -- then close that number.
202    */
203 #if defined(RLIMIT_NOFILE) || defined(RLIMIT_OFILE)
204 # if defined(RLIMIT_NOFILE)
205   if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
206 # elif defined(RLIMIT_OFILE)
207   if (getrlimit(RLIMIT_OFILE, &rlim) < 0) {
208 # endif
209     /* Ignore ENOSYS (and EPERM, since some libc's use this as ENOSYS). */
210     if (errno != ENOSYS &&
211         errno != EPERM) {
212       pr_log_debug(DEBUG0, MOD_SFTP_VERSION ": getrlimit error: %s",
213         strerror(errno));
214     }
215 
216     /* Pick some arbitrary high number. */
217     nfiles = 255;
218 
219   } else {
220     nfiles = (unsigned long) rlim.rlim_max;
221   }
222 
223 #else /* no RLIMIT_NOFILE or RLIMIT_OFILE */
224    nfiles = 255;
225 #endif
226 
227   /* Appears that on some platforms (e.g. Solaris, Mac OSX), having too
228    * high of an fd value can lead to undesirable behavior for some reason.
229    * Need to track down why; the behavior I saw was the inability of
230    * select() to work properly on the stdout/stderr fds attached to the
231    * exec'd script.
232    */
233   if (nfiles > 255) {
234     nfiles = 255;
235   }
236 
237   if (nfiles < 0) {
238     /* Yes, using a long for the nfiles variable is not quite kosher; it should
239      * be an unsigned type, otherwise a large limit (say, RLIMIT_INFINITY)
240      * might overflow the data type.  In that case, though, we want to know
241      * about it -- and using a signed type, we will know if the overflowed
242      * value is a negative number.  Chances are we do NOT want to be closing
243      * fds whose value is as high as they can possibly get; that's too many
244      * fds to iterate over.  Long story short, using a long int is just fine.
245      */
246     nfiles = 255;
247   }
248 
249   /* Close the "non-standard" file descriptors. */
250   for (i = 3; i < nfiles; i++) {
251     pr_signals_handle();
252     (void) close(i);
253   }
254 
255   return;
256 }
257 
258 static void prepare_provider_pipes(int *stdout_pipe, int *stderr_pipe) {
259   if (pipe(stdout_pipe) < 0) {
260     pr_log_debug(DEBUG0, MOD_SFTP_VERSION ": error opening stdout pipe: %s",
261       strerror(errno));
262     stdout_pipe[0] = -1;
263     stdout_pipe[1] = STDOUT_FILENO;
264 
265   } else {
266     if (fcntl(stdout_pipe[0], F_SETFD, FD_CLOEXEC) < 0) {
267       pr_log_debug(DEBUG0, MOD_SFTP_VERSION
268         ": error setting close-on-exec flag on stdout pipe read fd: %s",
269         strerror(errno));
270     }
271 
272     if (fcntl(stdout_pipe[1], F_SETFD, 0) < 0) {
273       pr_log_debug(DEBUG0, MOD_SFTP_VERSION
274         ": error setting close-on-exec flag on stdout pipe write fd: %s",
275         strerror(errno));
276     }
277   }
278 
279   if (pipe(stderr_pipe) < 0) {
280     pr_log_debug(DEBUG0, MOD_SFTP_VERSION ": error opening stderr pipe: %s",
281       strerror(errno));
282     stderr_pipe[0] = -1;
283     stderr_pipe[1] = STDERR_FILENO;
284 
285   } else {
286     if (fcntl(stderr_pipe[0], F_SETFD, FD_CLOEXEC) < 0) {
287       pr_log_debug(DEBUG0, MOD_SFTP_VERSION
288         ": error setting close-on-exec flag on stderr pipe read fd: %s",
289         strerror(errno));
290     }
291 
292     if (fcntl(stderr_pipe[1], F_SETFD, 0) < 0) {
293       pr_log_debug(DEBUG0, MOD_SFTP_VERSION
294         ": error setting close-on-exec flag on stderr pipe write fd: %s",
295         strerror(errno));
296     }
297   }
298 }
299 
300 static int exec_passphrase_provider(server_rec *s, char *buf, int buflen,
301     const char *path) {
302   pid_t pid;
303   int status;
304   int stdout_pipe[2], stderr_pipe[2];
305 
306   struct sigaction sa_ignore, sa_intr, sa_quit;
307   sigset_t set_chldmask, set_save;
308 
309   /* Prepare signal dispositions. */
310   sa_ignore.sa_handler = SIG_IGN;
311   sigemptyset(&sa_ignore.sa_mask);
312   sa_ignore.sa_flags = 0;
313 
314   if (sigaction(SIGINT, &sa_ignore, &sa_intr) < 0) {
315     return -1;
316   }
317 
318   if (sigaction(SIGQUIT, &sa_ignore, &sa_quit) < 0) {
319     return -1;
320   }
321 
322   sigemptyset(&set_chldmask);
323   sigaddset(&set_chldmask, SIGCHLD);
324 
325   if (sigprocmask(SIG_BLOCK, &set_chldmask, &set_save) < 0) {
326     return -1;
327   }
328 
329   prepare_provider_pipes(stdout_pipe, stderr_pipe);
330 
331   pid = fork();
332   if (pid < 0) {
333     int xerrno = errno;
334 
335     pr_log_pri(PR_LOG_ALERT,
336       MOD_SFTP_VERSION ": error: unable to fork: %s", strerror(xerrno));
337 
338     errno = xerrno;
339     status = -1;
340 
341   } else if (pid == 0) {
342     char nbuf[32];
343     pool *tmp_pool;
344     char *stdin_argv[4];
345 
346     /* Child process */
347     session.pid = getpid();
348 
349     /* Note: there is no need to clean up this temporary pool, as we've
350      * forked.  If the exec call succeeds, this child process will exit
351      * normally, and its process space recovered by the OS.  If the exec
352      * call fails, we still exit, and the process space is recovered by
353      * the OS.  Either way, the memory will be cleaned up without need for
354      * us to do it explicitly (unless one wanted to be pedantic about it,
355      * of course).
356      */
357     tmp_pool = make_sub_pool(s->pool);
358 
359     /* Restore previous signal actions. */
360     sigaction(SIGINT, &sa_intr, NULL);
361     sigaction(SIGQUIT, &sa_quit, NULL);
362     sigprocmask(SIG_SETMASK, &set_save, NULL);
363 
364     stdin_argv[0] = pstrdup(tmp_pool, passphrase_provider);
365 
366     memset(nbuf, '\0', sizeof(nbuf));
367     pr_snprintf(nbuf, sizeof(nbuf)-1, "%u", (unsigned int) s->ServerPort);
368     nbuf[sizeof(nbuf)-1] = '\0';
369     stdin_argv[1] = pstrcat(tmp_pool, s->ServerName, ":", nbuf, NULL);
370     stdin_argv[2] = pstrdup(tmp_pool, path);
371     stdin_argv[3] = NULL;
372 
373     PRIVS_ROOT
374 
375     pr_log_debug(DEBUG6, MOD_SFTP_VERSION
376       ": executing '%s' with uid %lu (euid %lu), gid %lu (egid %lu)",
377       passphrase_provider,
378       (unsigned long) getuid(), (unsigned long) geteuid(),
379       (unsigned long) getgid(), (unsigned long) getegid());
380 
381     /* Prepare the file descriptors that the process will inherit. */
382     prepare_provider_fds(stdout_pipe[1], stderr_pipe[1]);
383 
384     errno = 0;
385     execv(passphrase_provider, stdin_argv);
386 
387     /* Since all previous file descriptors (including those for log files)
388      * have been closed, and root privs have been revoked, there's little
389      * chance of directing a message of execv() failure to proftpd's log
390      * files.  execv() only returns if there's an error; the only way we
391      * can signal this to the waiting parent process is to exit with a
392      * non-zero value (the value of errno will do nicely).
393      */
394 
395     exit(errno);
396 
397   } else {
398     int res;
399     int maxfd = -1, fds, send_sigterm = 1;
400     fd_set readfds;
401     time_t start_time = time(NULL);
402     struct timeval tv;
403 
404     /* Parent process */
405 
406     close(stdout_pipe[1]);
407     stdout_pipe[1] = -1;
408 
409     close(stderr_pipe[1]);
410     stderr_pipe[1] = -1;
411 
412     if (stdout_pipe[0] > maxfd) {
413       maxfd = stdout_pipe[0];
414     }
415 
416     if (stderr_pipe[0] > maxfd) {
417       maxfd = stderr_pipe[0];
418     }
419 
420     res = waitpid(pid, &status, WNOHANG);
421     while (res <= 0) {
422       if (res < 0) {
423         if (errno != EINTR) {
424           pr_log_debug(DEBUG2, MOD_SFTP_VERSION
425             ": passphrase provider error: unable to wait for pid %u: %s",
426             (unsigned int) pid, strerror(errno));
427           status = -1;
428           break;
429 
430         } else {
431           pr_signals_handle();
432           continue;
433         }
434       }
435 
436       /* Check the time elapsed since we started. */
437       if ((time(NULL) - start_time) > SFTP_PASSPHRASE_TIMEOUT) {
438 
439         /* Send TERM, the first time, to be polite. */
440         if (send_sigterm) {
441           send_sigterm = 0;
442           pr_log_debug(DEBUG6, MOD_SFTP_VERSION
443             ": '%s' has exceeded the timeout (%lu seconds), sending "
444             "SIGTERM (signal %d)", passphrase_provider,
445             (unsigned long) SFTP_PASSPHRASE_TIMEOUT, SIGTERM);
446           kill(pid, SIGTERM);
447 
448         } else {
449           /* The child is still around?  Terminate with extreme prejudice. */
450           pr_log_debug(DEBUG6, MOD_SFTP_VERSION
451             ": '%s' has exceeded the timeout (%lu seconds), sending "
452             "SIGKILL (signal %d)", passphrase_provider,
453             (unsigned long) SFTP_PASSPHRASE_TIMEOUT, SIGKILL);
454           kill(pid, SIGKILL);
455         }
456       }
457 
458       /* Select on the pipe read fds, to see if the child has anything
459        * to tell us.
460        */
461       FD_ZERO(&readfds);
462 
463       FD_SET(stdout_pipe[0], &readfds);
464       FD_SET(stderr_pipe[0], &readfds);
465 
466       /* Note: this delay should be configurable somehow. */
467       tv.tv_sec = 2L;
468       tv.tv_usec = 0L;
469 
470       fds = select(maxfd + 1, &readfds, NULL, NULL, &tv);
471 
472       if (fds == -1 &&
473           errno == EINTR) {
474         pr_signals_handle();
475       }
476 
477       if (fds > 0) {
478         /* The child sent us something.  How thoughtful. */
479 
480         if (FD_ISSET(stdout_pipe[0], &readfds)) {
481           res = read(stdout_pipe[0], buf, buflen);
482           if (res > 0) {
483             buf[buflen-1] = '\0';
484 
485             while (res &&
486                    (buf[res-1] == '\r' ||
487                     buf[res-1] == '\n')) {
488               pr_signals_handle();
489               res--;
490             }
491             buf[res] = '\0';
492 
493           } else if (res < 0) {
494             pr_log_debug(DEBUG2, MOD_SFTP_VERSION
495               ": error reading stdout from '%s': %s",
496               passphrase_provider, strerror(errno));
497           }
498         }
499 
500         if (FD_ISSET(stderr_pipe[0], &readfds)) {
501           long stderrlen, stderrsz;
502           char *stderrbuf;
503           pool *tmp_pool = make_sub_pool(s->pool);
504 
505           stderrbuf = pr_fsio_getpipebuf(tmp_pool, stderr_pipe[0], &stderrsz);
506           memset(stderrbuf, '\0', stderrsz);
507 
508           stderrlen = read(stderr_pipe[0], stderrbuf, stderrsz-1);
509           if (stderrlen > 0) {
510             while (stderrlen &&
511                    (stderrbuf[stderrlen-1] == '\r' ||
512                     stderrbuf[stderrlen-1] == '\n')) {
513               stderrlen--;
514             }
515             stderrbuf[stderrlen] = '\0';
516 
517             pr_log_debug(DEBUG5, MOD_SFTP_VERSION
518               ": stderr from '%s': %s", passphrase_provider, stderrbuf);
519 
520           } else if (res < 0) {
521             pr_log_debug(DEBUG2, MOD_SFTP_VERSION
522               ": error reading stderr from '%s': %s",
523               passphrase_provider, strerror(errno));
524           }
525 
526           destroy_pool(tmp_pool);
527           tmp_pool = NULL;
528         }
529       }
530 
531       res = waitpid(pid, &status, WNOHANG);
532     }
533   }
534 
535   /* Restore the previous signal actions. */
536   if (sigaction(SIGINT, &sa_intr, NULL) < 0) {
537     return -1;
538   }
539 
540   if (sigaction(SIGQUIT, &sa_quit, NULL) < 0) {
541     return -1;
542   }
543 
544   if (sigprocmask(SIG_SETMASK, &set_save, NULL) < 0) {
545     return -1;
546   }
547 
548   if (WIFSIGNALED(status)) {
549     pr_log_debug(DEBUG2, MOD_SFTP_VERSION ": '%s' died from signal %d",
550       passphrase_provider, WTERMSIG(status));
551     errno = EPERM;
552     return -1;
553   }
554 
555   return 0;
556 }
557 
558 /* Return the size of a page on this architecture. */
559 static size_t get_pagesz(void) {
560   long pagesz;
561 
562 #if defined(_SC_PAGESIZE)
563   pagesz = sysconf(_SC_PAGESIZE);
564 #elif defined(_SC_PAGE_SIZE)
565   pagesz = sysconf(_SC_PAGE_SIZE);
566 #else
567   /* Default to using OpenSSL's defined buffer size for PEM files. */
568   pagesz = PEM_BUFSIZE;
569 #endif /* !_SC_PAGESIZE and !_SC_PAGE_SIZE */
570 
571   return pagesz;
572 }
573 
574 /* Return a page-aligned pointer to memory of at least the given size. */
575 static char *get_page(size_t sz, void **ptr) {
576   void *d;
577   long pagesz = get_pagesz(), p;
578 
579   d = calloc(1, sz + (pagesz-1));
580   if (d == NULL) {
581     pr_log_pri(PR_LOG_ALERT, MOD_SFTP_VERSION ": Out of memory!");
582     exit(1);
583   }
584 
585   *ptr = d;
586 
587   p = ((long) d + (pagesz-1)) &~ (pagesz-1);
588 
589   return ((char *) p);
590 }
591 
592 static unsigned char *decode_base64(pool *p, unsigned char *text,
593     size_t text_len, size_t *data_len) {
594   unsigned char *data = NULL;
595   int have_padding = FALSE, res;
596 
597   /* Due to Base64's padding, we need to detect if the last block was padded
598    * with zeros; we do this by looking for '=' characters at the end of the
599    * text being decoded.  If we see these characters, then we will "trim" off
600    * any trailing zero values in the decoded data, on the ASSUMPTION that they
601    * are the auto-added padding bytes.
602    */
603   if (text[text_len-1] == '=') {
604     have_padding = TRUE;
605   }
606 
607   data = pcalloc(p, text_len);
608   res = EVP_DecodeBlock((unsigned char *) data, (unsigned char *) text,
609     (int) text_len);
610   if (res <= 0) {
611     /* Base64-decoding error. */
612     errno = EINVAL;
613     return NULL;
614   }
615 
616   if (have_padding == TRUE) {
617     /* Assume that only one or two zero bytes of padding were added. */
618     if (data[res-1] == '\0') {
619       res -= 1;
620 
621       if (data[res-1] == '\0') {
622         res -= 1;
623       }
624     }
625   }
626 
627   *data_len = (size_t) res;
628   return data;
629 }
630 
631 static int is_public_key(int fd) {
632   struct stat st;
633   char begin_buf[SFTP_PUBLICKEY_BEGIN_LEN+20];
634   ssize_t len;
635   off_t minsz;
636 
637   if (fstat(fd, &st) < 0) {
638     return -1;
639   }
640 
641   minsz = SFTP_PUBLICKEY_BEGIN_LEN + SFTP_PUBLICKEY_END_LEN;
642   if (st.st_size < minsz) {
643     return FALSE;
644   }
645 
646   len = pread(fd, begin_buf, sizeof(begin_buf), 0);
647   if (len != sizeof(begin_buf)) {
648     return FALSE;
649   }
650 
651   begin_buf[len-1] = '\0';
652 
653   if (strstr(begin_buf, "PUBLIC KEY") == NULL) {
654     return FALSE;
655   }
656 
657   if (strstr(begin_buf, "BEGIN") == NULL) {
658     return FALSE;
659   }
660 
661   return TRUE;
662 }
663 
664 static int is_openssh_private_key(int fd) {
665   struct stat st;
666   char begin_buf[SFTP_OPENSSH_BEGIN_LEN], end_buf[SFTP_OPENSSH_END_LEN];
667   ssize_t len;
668   off_t minsz;
669 
670   if (fstat(fd, &st) < 0) {
671     return -1;
672   }
673 
674   minsz = SFTP_OPENSSH_BEGIN_LEN + SFTP_OPENSSH_END_LEN;
675   if (st.st_size < minsz) {
676     return FALSE;
677   }
678 
679   len = pread(fd, begin_buf, sizeof(begin_buf), 0);
680   if (len != sizeof(begin_buf)) {
681     return FALSE;
682   }
683 
684   if (memcmp(begin_buf, SFTP_OPENSSH_BEGIN, SFTP_OPENSSH_BEGIN_LEN) != 0) {
685     return FALSE;
686   }
687 
688   len = pread(fd, end_buf, sizeof(end_buf), st.st_size - SFTP_OPENSSH_END_LEN);
689   if (len != sizeof(end_buf)) {
690     return FALSE;
691   }
692 
693   if (memcmp(end_buf, SFTP_OPENSSH_END, SFTP_OPENSSH_END_LEN) != 0) {
694     return FALSE;
695   }
696 
697   return TRUE;
698 }
699 
700 static int get_passphrase_cb(char *buf, int buflen, int rwflag, void *d) {
701   static int need_banner = TRUE;
702   struct sftp_pkey_data *pdata = d;
703 
704   if (passphrase_provider == NULL) {
705     register unsigned int attempt;
706     size_t pwlen = 0;
707 
708     pr_log_debug(DEBUG0, MOD_SFTP_VERSION ": requesting passphrase from admin");
709 
710     if (need_banner) {
711       fprintf(stderr, "\nPlease provide passphrase for the encrypted host key:\n");
712       need_banner = FALSE;
713     }
714 
715     /* You get three attempts at entering the passphrase correctly. */
716     for (attempt = 0; attempt < 3; attempt++) {
717       int res;
718 
719       /* Always handle signals in a loop. */
720       pr_signals_handle();
721 
722       res = EVP_read_pw_string(buf, buflen, pdata->prompt, TRUE);
723 
724       /* A return value of zero from EVP_read_pw_string() means success; -1
725        * means a system error occurred, and 1 means user interaction problems.
726        */
727       if (res != 0) {
728          fprintf(stderr, "\nPassphrases do not match.  Please try again.\n");
729          continue;
730       }
731 
732       /* Ensure that the buffer is NUL-terminated. */
733       buf[buflen-1] = '\0';
734       pwlen = strlen(buf);
735       if (pwlen < 1) {
736         fprintf(stderr, "Error: passphrase must be at least one character\n");
737 
738       } else {
739         sstrncpy(pdata->buf, buf, pdata->bufsz);
740         pdata->buflen = pwlen;
741 
742         return pwlen;
743       }
744     }
745 
746   } else {
747     pr_log_debug(DEBUG0, MOD_SFTP_VERSION ": requesting passphrase from '%s'",
748       passphrase_provider);
749 
750     if (exec_passphrase_provider(pdata->s, buf, buflen, pdata->path) < 0) {
751       pr_log_debug(DEBUG0, MOD_SFTP_VERSION
752         ": error obtaining passphrase from '%s': %s",
753         passphrase_provider, strerror(errno));
754 
755     } else {
756       size_t pwlen;
757       /* Ensure that the buffer is NUL-terminated. */
758       buf[buflen-1] = '\0';
759 
760       pwlen = strlen(buf);
761 
762       sstrncpy(pdata->buf, buf, pdata->bufsz);
763       pdata->buflen = pwlen;
764 
765       return pwlen;
766     }
767   }
768 
769 #if OPENSSL_VERSION_NUMBER < 0x00908001
770   PEMerr(PEM_F_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD);
771 #else
772   PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD);
773 #endif
774 
775   pr_memscrub(buf, buflen);
776   return -1;
777 }
778 
779 static int get_passphrase(struct sftp_pkey *k, const char *path) {
780   pool *tmp_pool;
781   char prompt[256];
782   FILE *fp = NULL;
783   EVP_PKEY *pkey = NULL;
784   unsigned char *key_data = NULL;
785   uint32_t key_datalen = 0;
786   int fd, prompt_fd = -1, res, xerrno, openssh_format = FALSE,
787     public_key_format = FALSE;
788   struct sftp_pkey_data pdata;
789   register unsigned int attempt;
790 
791   memset(prompt, '\0', sizeof(prompt));
792   res = pr_snprintf(prompt, sizeof(prompt)-1,
793     "Host key for the %s#%d (%s) server: ",
794     pr_netaddr_get_ipstr(k->server->addr), k->server->ServerPort,
795     k->server->ServerName);
796   prompt[res] = '\0';
797   prompt[sizeof(prompt)-1] = '\0';
798 
799   PRIVS_ROOT
800   fd = open(path, O_RDONLY);
801   xerrno = errno;
802   PRIVS_RELINQUISH
803 
804   if (fd < 0) {
805     SYSerr(SYS_F_FOPEN, xerrno);
806     errno = xerrno;
807     return -1;
808   }
809 
810   /* Make sure the fd isn't one of the big three. */
811   if (fd <= STDERR_FILENO) {
812     res = pr_fs_get_usable_fd(fd);
813     if (res >= 0) {
814       (void) close(fd);
815       fd = res;
816     }
817   }
818 
819   public_key_format = is_public_key(fd);
820   if (public_key_format == TRUE) {
821     pr_trace_msg(trace_channel, 3, "hostkey file '%s' uses a public key format",
822       path);
823     (void) pr_log_pri(PR_LOG_WARNING, MOD_SFTP_VERSION
824       ": unable to use public key '%s' for SFTPHostKey", path);
825     (void) close(fd);
826     errno = EINVAL;
827     return -1;
828   }
829 
830   openssh_format = is_openssh_private_key(fd);
831   if (openssh_format != TRUE) {
832     fp = fdopen(fd, "r");
833     if (fp == NULL) {
834       xerrno = errno;
835 
836       (void) close(fd);
837       SYSerr(SYS_F_FOPEN, xerrno);
838 
839       errno = xerrno;
840       return -1;
841     }
842 
843     /* As the file contains sensitive data, we do not want it lingering
844      * around in stdio buffers.
845      */
846     (void) setvbuf(fp, NULL, _IONBF, 0);
847 
848   } else {
849     pr_trace_msg(trace_channel, 9,
850       "handling host key '%s' as an OpenSSH-formatted private key", path);
851   }
852 
853   k->host_pkey = get_page(PEM_BUFSIZE, &k->host_pkey_ptr);
854   if (k->host_pkey == NULL) {
855     pr_log_pri(PR_LOG_ALERT, MOD_SFTP_VERSION ": Out of memory!");
856     exit(1);
857   }
858 
859   pdata.s = k->server;
860   pdata.buf = k->host_pkey;
861   pdata.buflen = 0;
862   pdata.bufsz = k->pkeysz;
863   pdata.path = path;
864   pdata.prompt = prompt;
865 
866   /* Reconnect stderr to the term because proftpd connects stderr, earlier,
867    * to the general stderr logfile.
868    */
869   prompt_fd = open("/dev/null", O_WRONLY);
870   if (prompt_fd == -1) {
871     /* This is an arbitrary, meaningless placeholder number. */
872     prompt_fd = 76;
873   }
874 
875   dup2(STDERR_FILENO, prompt_fd);
876   dup2(STDOUT_FILENO, STDERR_FILENO);
877 
878   tmp_pool = make_sub_pool(sftp_pool);
879   pr_pool_tag(tmp_pool, "SFTP Passphrase pool");
880 
881   /* The user gets three tries to enter the correct passphrase. */
882   for (attempt = 0; attempt < 3; attempt++) {
883 
884     /* Always handle signals in a loop. */
885     pr_signals_handle();
886 
887     if (openssh_format == FALSE) {
888       pkey = PEM_read_PrivateKey(fp, NULL, get_passphrase_cb, &pdata);
889       if (pkey != NULL) {
890         break;
891       }
892 
893       if (fseek(fp, 0, SEEK_SET) < 0) {
894         pr_trace_msg(trace_channel, 3,
895           "error rewinding file handle for '%s': %s", path, strerror(errno));
896       }
897 
898     } else {
899       char buf[PEM_BUFSIZE];
900       const char *passphrase;
901       enum sftp_key_type_e key_type = SFTP_KEY_UNKNOWN;
902 
903       /* First we try with no passphrase.  Failing that, we have to invoke the
904        * get_passphase_cb() callback ourselves for OpenSSH keys.
905        */
906       if (attempt == 0) {
907         passphrase = pstrdup(tmp_pool, "");
908         res = read_openssh_private_key(tmp_pool, path, fd, passphrase,
909           &key_type, &pkey, &key_data, &key_datalen);
910 
911         if (lseek(fd, 0, SEEK_SET) < 0) {
912           pr_trace_msg(trace_channel, 3, "error rewinding fd %d for '%s': %s",
913             fd, path, strerror(errno));
914         }
915         if (res == 0) {
916           break;
917         }
918       }
919 
920       res = get_passphrase_cb(buf, PEM_BUFSIZE, 0, &pdata);
921       if (res > 0) {
922         passphrase = pdata.buf;
923 
924         res = read_openssh_private_key(tmp_pool, path, fd, passphrase,
925           &key_type, &pkey, &key_data, &key_datalen);
926         if (res == 0) {
927           break;
928         }
929 
930         if (lseek(fd, 0, SEEK_SET) < 0) {
931           pr_trace_msg(trace_channel, 3, "error rewinding fd %d for '%s': %s",
932             fd, path, strerror(errno));
933         }
934 
935       } else {
936         pr_trace_msg(trace_channel, 2,
937           "error reading passphrase for OpenSSH key: %s",
938           sftp_crypto_get_errors());
939       }
940     }
941 
942     ERR_clear_error();
943     fprintf(stderr, "\nWrong passphrase for this key.  Please try again.\n");
944   }
945 
946   if (fp != NULL) {
947     fclose(fp);
948   }
949 
950   /* Restore the normal stderr logging. */
951   (void) dup2(prompt_fd, STDERR_FILENO);
952   (void) close(prompt_fd);
953 
954   if (pkey == NULL &&
955       key_data == NULL) {
956     return -1;
957   }
958 
959   if (pkey != NULL) {
960     EVP_PKEY_free(pkey);
961   }
962 
963   if (key_data != NULL) {
964     pr_memscrub(key_data, key_datalen);
965   }
966 
967   destroy_pool(tmp_pool);
968 
969   if (pdata.buflen > 0) {
970 #if OPENSSL_VERSION_NUMBER >= 0x000905000L
971     /* Use the obtained passphrase as additional entropy, ostensibly
972      * unknown to attackers who may be watching the network, for
973      * OpenSSL's PRNG.
974      *
975      * Human language gives about 2-3 bits of entropy per byte (RFC1750).
976      */
977     RAND_add(pdata.buf, pdata.buflen, pdata.buflen * 0.25);
978 #endif
979 
980 #ifdef HAVE_MLOCK
981     PRIVS_ROOT
982     if (mlock(k->host_pkey, k->pkeysz) < 0) {
983       pr_log_debug(DEBUG1, MOD_SFTP_VERSION
984         ": error locking passphrase into memory: %s", strerror(errno));
985 
986     } else {
987       pr_log_debug(DEBUG1, MOD_SFTP_VERSION ": passphrase locked into memory");
988     }
989     PRIVS_RELINQUISH
990 #endif
991   }
992 
993   return 0;
994 }
995 
996 static struct sftp_pkey *lookup_pkey(void) {
997   struct sftp_pkey *k, *pkey = NULL;
998 
999   for (k = sftp_pkey_list; k; k = k->next) {
1000 
1001     /* If this pkey matches the current server_rec, mark it and move on. */
1002     if (k->server == main_server) {
1003 
1004 #ifdef HAVE_MLOCK
1005       /* mlock() the passphrase memory areas again; page locks are not
1006        * inherited across forks.
1007        */
1008       PRIVS_ROOT
1009       if (k->host_pkey) {
1010         if (mlock(k->host_pkey, k->pkeysz) < 0) {
1011           (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1012             "error locking passphrase into memory: %s", strerror(errno));
1013         }
1014       }
1015       PRIVS_RELINQUISH
1016 #endif /* HAVE_MLOCK */
1017 
1018       pkey = k;
1019       continue;
1020     }
1021 
1022     /* Otherwise, scrub the passphrase's memory areas. */
1023     if (k->host_pkey) {
1024       pr_memscrub(k->host_pkey, k->pkeysz);
1025       free(k->host_pkey_ptr);
1026       k->host_pkey = k->host_pkey_ptr = NULL;
1027     }
1028   }
1029 
1030   return pkey;
1031 }
1032 
1033 static void scrub_pkeys(void) {
1034   struct sftp_pkey *k;
1035 
1036   if (sftp_pkey_list == NULL) {
1037     return;
1038   }
1039 
1040   /* Scrub and free all passphrases in memory. */
1041   pr_log_debug(DEBUG5, MOD_SFTP_VERSION
1042     ": scrubbing %u %s from memory",
1043     sftp_npkeys, sftp_npkeys != 1 ? "passphrases" : "passphrase");
1044 
1045   for (k = sftp_pkey_list; k; k = k->next) {
1046     if (k->host_pkey) {
1047       pr_memscrub(k->host_pkey, k->pkeysz);
1048       free(k->host_pkey_ptr);
1049       k->host_pkey = k->host_pkey_ptr = NULL;
1050     }
1051   }
1052 
1053   sftp_pkey_list = NULL;
1054   sftp_npkeys = 0;
1055 }
1056 
1057 static int pkey_cb(char *buf, int buflen, int rwflag, void *d) {
1058   struct sftp_pkey *k;
1059 
1060   if (d == NULL)
1061     return 0;
1062 
1063   k = (struct sftp_pkey *) d;
1064 
1065   if (k->host_pkey) {
1066     sstrncpy(buf, k->host_pkey, buflen);
1067     buf[buflen - 1] = '\0';
1068     return strlen(buf);
1069   }
1070 
1071   return 0;
1072 }
1073 
1074 static int has_req_perms(int fd, const char *path) {
1075   struct stat st;
1076 
1077   if (fstat(fd, &st) < 0) {
1078     return -1;
1079   }
1080 
1081   if (st.st_mode & (S_IRWXG|S_IRWXO)) {
1082     if (!(sftp_opts & SFTP_OPT_INSECURE_HOSTKEY_PERMS)) {
1083       errno = EACCES;
1084       return -1;
1085     }
1086 
1087     pr_log_pri(PR_LOG_INFO, MOD_SFTP_VERSION
1088       "notice: the permissions on SFTPHostKey '%s' (%04o) allow "
1089       "group-readable and/or world-readable access, increasing chances of "
1090       "system users reading the private key", path, st.st_mode);
1091   }
1092 
1093   return 0;
1094 }
1095 
1096 static uint32_t read_pkey_from_data(pool *p, unsigned char *pkey_data,
1097     uint32_t pkey_datalen, EVP_PKEY **pkey, enum sftp_key_type_e *key_type,
1098     int openssh_format) {
1099   char *pkey_type = NULL;
1100   uint32_t res, len = 0;
1101 
1102   res = sftp_msg_read_string2(p, &pkey_data, &pkey_datalen, &pkey_type);
1103   if (res == 0) {
1104     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1105       "error reading key: invalid/unsupported key format");
1106     return 0;
1107   }
1108   len += res;
1109 
1110   if (strncmp(pkey_type, "ssh-rsa", 8) == 0) {
1111     RSA *rsa;
1112     BIGNUM *rsa_e = NULL, *rsa_n = NULL, *rsa_d = NULL;
1113 
1114     *pkey = EVP_PKEY_new();
1115     if (*pkey == NULL) {
1116       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1117         "error allocating EVP_PKEY: %s", sftp_crypto_get_errors());
1118       return 0;
1119     }
1120 
1121     rsa = RSA_new();
1122     if (rsa == NULL) {
1123       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1124         "error allocating RSA: %s", sftp_crypto_get_errors());
1125       EVP_PKEY_free(*pkey);
1126       *pkey = NULL;
1127       return 0;
1128     }
1129 
1130     res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &rsa_e);
1131     if (res == 0) {
1132       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1133         "error reading key: invalid/unsupported key format");
1134       RSA_free(rsa);
1135       EVP_PKEY_free(*pkey);
1136       *pkey = NULL;
1137       return 0;
1138     }
1139     len += res;
1140 
1141     res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &rsa_n);
1142     if (res == 0) {
1143       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1144         "error reading key: invalid/unsupported key format");
1145       RSA_free(rsa);
1146       EVP_PKEY_free(*pkey);
1147       *pkey = NULL;
1148       return 0;
1149     }
1150     len += res;
1151 
1152     if (openssh_format) {
1153       BIGNUM *rsa_p, *rsa_q, *rsa_iqmp;
1154 
1155       /* The OpenSSH private key format encodes more factors. */
1156 
1157       res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &rsa_d);
1158       if (res == 0) {
1159         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1160           "error reading key: invalid/unsupported key format");
1161         RSA_free(rsa);
1162         EVP_PKEY_free(*pkey);
1163         *pkey = NULL;
1164         return 0;
1165       }
1166       len += res;
1167 
1168       /* RSA_get0_crt_params */
1169       res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &rsa_iqmp);
1170       if (res == 0) {
1171         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1172           "error reading key: invalid/unsupported key format");
1173         RSA_free(rsa);
1174         EVP_PKEY_free(*pkey);
1175         *pkey = NULL;
1176         return 0;
1177       }
1178       len += res;
1179 
1180       /* RSA_get0_factors */
1181       res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &rsa_p);
1182       if (res == 0) {
1183         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1184           "error reading key: invalid/unsupported key format");
1185         RSA_free(rsa);
1186         EVP_PKEY_free(*pkey);
1187         *pkey = NULL;
1188         return 0;
1189       }
1190       len += res;
1191 
1192       res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &rsa_q);
1193       if (res == 0) {
1194         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1195           "error reading key: invalid/unsupported key format");
1196         RSA_free(rsa);
1197         EVP_PKEY_free(*pkey);
1198         *pkey = NULL;
1199         return 0;
1200       }
1201       len += res;
1202 
1203 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
1204     !defined(HAVE_LIBRESSL)
1205       RSA_set0_crt_params(rsa, NULL, NULL, rsa_iqmp);
1206       RSA_set0_factors(rsa, rsa_p, rsa_q);
1207 #else
1208       rsa->iqmp = rsa_iqmp;
1209       rsa->p = rsa_p;
1210       rsa->q = rsa_q;
1211 #endif /* prior to OpenSSL-1.1.0 */
1212 
1213       /* Turns out that for OpenSSH formatted RSA keys, the 'e' and 'n' values
1214        * are in the opposite order than the normal PEM format.  Typical.
1215        */
1216 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
1217     !defined(HAVE_LIBRESSL)
1218       RSA_set0_key(rsa, rsa_e, rsa_n, rsa_d);
1219 #else
1220       rsa->e = rsa_n;
1221       rsa->n = rsa_e;
1222       rsa->d = rsa_d;
1223 #endif /* prior to OpenSSL-1.1.0 */
1224     } else {
1225 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
1226     !defined(HAVE_LIBRESSL)
1227       RSA_set0_key(rsa, rsa_n, rsa_e, rsa_d);
1228 #else
1229       rsa->e = rsa_e;
1230       rsa->n = rsa_n;
1231       rsa->d = rsa_d;
1232 #endif /* prior to OpenSSL-1.1.0 */
1233     }
1234 
1235     if (EVP_PKEY_assign_RSA(*pkey, rsa) != 1) {
1236       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1237         "error assigning RSA to EVP_PKEY: %s", sftp_crypto_get_errors());
1238       RSA_free(rsa);
1239       EVP_PKEY_free(*pkey);
1240       *pkey = NULL;
1241       return 0;
1242     }
1243 
1244     if (key_type != NULL) {
1245       *key_type = SFTP_KEY_RSA;
1246     }
1247 
1248   } else if (strncmp(pkey_type, "ssh-dss", 8) == 0) {
1249 #if !defined(OPENSSL_NO_DSA)
1250     DSA *dsa;
1251     BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key = NULL;
1252 
1253     *pkey = EVP_PKEY_new();
1254     if (*pkey == NULL) {
1255       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1256         "error allocating EVP_PKEY: %s", sftp_crypto_get_errors());
1257       return 0;
1258     }
1259 
1260     dsa = DSA_new();
1261     if (dsa == NULL) {
1262       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1263         "error allocating DSA: %s", sftp_crypto_get_errors());
1264       EVP_PKEY_free(*pkey);
1265       *pkey = NULL;
1266       return 0;
1267     }
1268 
1269     res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &dsa_p);
1270     if (res == 0) {
1271       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1272         "error reading key: invalid/unsupported key format");
1273       DSA_free(dsa);
1274       EVP_PKEY_free(*pkey);
1275       *pkey = NULL;
1276       return 0;
1277     }
1278     len += res;
1279 
1280     res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &dsa_q);
1281     if (res == 0) {
1282       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1283         "error reading key: invalid/unsupported key format");
1284       DSA_free(dsa);
1285       EVP_PKEY_free(*pkey);
1286       *pkey = NULL;
1287       return 0;
1288     }
1289     len += res;
1290 
1291     res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &dsa_g);
1292     if (res == 0) {
1293       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1294         "error reading key: invalid/unsupported key format");
1295       DSA_free(dsa);
1296       EVP_PKEY_free(*pkey);
1297       *pkey = NULL;
1298       return 0;
1299     }
1300     len += res;
1301 
1302     res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &dsa_pub_key);
1303     if (res == 0) {
1304       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1305         "error reading key: invalid/unsupported key format");
1306       DSA_free(dsa);
1307       EVP_PKEY_free(*pkey);
1308       *pkey = NULL;
1309       return 0;
1310     }
1311     len += res;
1312 
1313     if (openssh_format) {
1314       res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &dsa_priv_key);
1315       if (res == 0) {
1316         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1317           "error reading key: invalid/unsupported key format");
1318         DSA_free(dsa);
1319         EVP_PKEY_free(*pkey);
1320         *pkey = NULL;
1321         return 0;
1322       }
1323       len += res;
1324     }
1325 
1326 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
1327     !defined(HAVE_LIBRESSL)
1328     DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g);
1329     DSA_set0_key(dsa, dsa_pub_key, dsa_priv_key);
1330 #else
1331     dsa->p = dsa_p;
1332     dsa->q = dsa_q;
1333     dsa->g = dsa_g;
1334     dsa->pub_key = dsa_pub_key;
1335     dsa->priv_key = dsa_priv_key;
1336 #endif /* prior to OpenSSL-1.1.0 */
1337 
1338     if (EVP_PKEY_assign_DSA(*pkey, dsa) != 1) {
1339       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1340         "error assigning RSA to EVP_PKEY: %s", sftp_crypto_get_errors());
1341       DSA_free(dsa);
1342       EVP_PKEY_free(*pkey);
1343       *pkey = NULL;
1344       return 0;
1345     }
1346 
1347     if (key_type != NULL) {
1348       *key_type = SFTP_KEY_DSA;
1349     }
1350 #else
1351     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1352       "unsupported public key algorithm '%s'", pkey_type);
1353     errno = EINVAL;
1354     return 0;
1355 #endif /* !OPENSSL_NO_DSA */
1356 
1357 #ifdef PR_USE_OPENSSL_ECC
1358   } else if (strncmp(pkey_type, "ecdsa-sha2-nistp256", 20) == 0 ||
1359              strncmp(pkey_type, "ecdsa-sha2-nistp384", 20) == 0 ||
1360              strncmp(pkey_type, "ecdsa-sha2-nistp521", 20) == 0) {
1361     EC_KEY *ec;
1362     const char *curve_name;
1363     const EC_GROUP *curve;
1364     EC_POINT *point;
1365     int ec_nid;
1366     char *ptr = NULL;
1367 
1368     res = sftp_msg_read_string2(p, &pkey_data, &pkey_datalen, &ptr);
1369     if (res == 0) {
1370       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1371         "error reading key: invalid/unsupported key format");
1372       return 0;
1373     }
1374     len += res;
1375 
1376     curve_name = (const char *) ptr;
1377 
1378     /* If the curve name does not match the last 8 characters of the
1379      * public key type (which, in the case of ECDSA keys, contains the
1380      * curve name), then it's definitely a mismatch.
1381      */
1382     if (strncmp(pkey_type + 11, curve_name, 9) != 0) {
1383       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1384         "EC public key curve name '%s' does not match public key "
1385         "algorithm '%s'", curve_name, pkey_type);
1386       return 0;
1387     }
1388 
1389     if (strncmp(curve_name, "nistp256", 9) == 0) {
1390       ec_nid = NID_X9_62_prime256v1;
1391 
1392       if (key_type != NULL) {
1393         *key_type = SFTP_KEY_ECDSA_256;
1394       }
1395 
1396     } else if (strncmp(curve_name, "nistp384", 9) == 0) {
1397       ec_nid = NID_secp384r1;
1398 
1399       if (key_type != NULL) {
1400         *key_type = SFTP_KEY_ECDSA_384;
1401       }
1402 
1403     } else if (strncmp(curve_name, "nistp521", 9) == 0) {
1404       ec_nid = NID_secp521r1;
1405 
1406       if (key_type != NULL) {
1407         *key_type = SFTP_KEY_ECDSA_521;
1408       }
1409 
1410     } else {
1411       ec_nid = -1;
1412     }
1413 
1414     ec = EC_KEY_new_by_curve_name(ec_nid);
1415     if (ec == NULL) {
1416       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1417         "error allocating EC_KEY for %s: %s", pkey_type,
1418         sftp_crypto_get_errors());
1419       return 0;
1420     }
1421 
1422     curve = EC_KEY_get0_group(ec);
1423 
1424     point = EC_POINT_new(curve);
1425     if (point == NULL) {
1426       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1427         "error allocating EC_POINT for %s: %s", pkey_type,
1428         sftp_crypto_get_errors());
1429       EC_KEY_free(ec);
1430       return 0;
1431     }
1432 
1433     res = sftp_msg_read_ecpoint2(p, &pkey_data, &pkey_datalen, curve, &point);
1434     if (res == 0) {
1435       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1436         "error reading key: invalid/unsupported key format");
1437       EC_KEY_free(ec);
1438       return 0;
1439     }
1440     len += res;
1441 
1442     if (point == NULL) {
1443       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1444         "error reading EC_POINT from public key data: %s", strerror(errno));
1445       EC_POINT_free(point);
1446       EC_KEY_free(ec);
1447       return 0;
1448     }
1449 
1450     if (sftp_keys_validate_ecdsa_params(curve, point) < 0) {
1451       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1452         "error validating EC public key: %s", strerror(errno));
1453       EC_POINT_free(point);
1454       EC_KEY_free(ec);
1455       return 0;
1456     }
1457 
1458     if (EC_KEY_set_public_key(ec, point) != 1) {
1459       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1460         "error setting public key on EC_KEY: %s", sftp_crypto_get_errors());
1461       EC_POINT_free(point);
1462       EC_KEY_free(ec);
1463       return 0;
1464     }
1465 
1466     if (openssh_format) {
1467       BIGNUM *ec_priv_key = NULL;
1468 
1469       res = sftp_msg_read_mpint2(p, &pkey_data, &pkey_datalen, &ec_priv_key);
1470       if (res == 0) {
1471         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1472           "error reading key: invalid/unsupported key format");
1473         EC_POINT_free(point);
1474         EC_KEY_free(ec);
1475         *pkey = NULL;
1476         return 0;
1477       }
1478       len += res;
1479 
1480       if (EC_KEY_set_private_key(ec, ec_priv_key) != 1) {
1481         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1482           "error setting private key on EC_KEY: %s", sftp_crypto_get_errors());
1483         EC_POINT_free(point);
1484         EC_KEY_free(ec);
1485         return 0;
1486       }
1487     }
1488 
1489     *pkey = EVP_PKEY_new();
1490     if (*pkey == NULL) {
1491       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1492         "error allocating EVP_PKEY: %s", sftp_crypto_get_errors());
1493       EC_POINT_free(point);
1494       EC_KEY_free(ec);
1495       return 0;
1496     }
1497 
1498     if (EVP_PKEY_assign_EC_KEY(*pkey, ec) != 1) {
1499       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1500         "error assigning ECDSA-256 to EVP_PKEY: %s", sftp_crypto_get_errors());
1501       EC_POINT_free(point);
1502       EC_KEY_free(ec);
1503       EVP_PKEY_free(*pkey);
1504       *pkey = NULL;
1505       return 0;
1506     }
1507 #endif /* PR_USE_OPENSSL_ECC */
1508 
1509 #if defined(PR_USE_SODIUM)
1510   } else if (strncmp(pkey_type, "ssh-ed25519", 12) == 0) {
1511     /* XXX Should we return error, if openssh_format != TRUE?  Not sure how
1512      * else we would see such keys.
1513      */
1514 
1515     if (key_type != NULL) {
1516       *key_type = SFTP_KEY_ED25519;
1517     }
1518 #endif /* PR_USE_SODIUM */
1519 
1520   } else {
1521     pr_trace_msg(trace_channel, 3, "unsupported public key algorithm '%s'",
1522       pkey_type);
1523     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1524       "unsupported public key algorithm '%s'", pkey_type);
1525     errno = EINVAL;
1526     return 0;
1527   }
1528 
1529   return len;
1530 }
1531 
1532 static const char *get_pkey_type_desc(int pkey_type) {
1533   const char *key_desc = NULL;
1534 
1535   switch (pkey_type) {
1536 #ifdef EVP_PKEY_NONE
1537     case EVP_PKEY_NONE:
1538       key_desc = "undefined";
1539       break;
1540 #endif
1541 
1542 #ifdef EVP_PKEY_RSA
1543     case EVP_PKEY_RSA:
1544       key_desc = "RSA";
1545       break;
1546 #endif
1547 
1548 #ifdef EVP_PKEY_DSA
1549     case EVP_PKEY_DSA:
1550       key_desc = "DSA";
1551       break;
1552 #endif
1553 
1554 #ifdef EVP_PKEY_DH
1555     case EVP_PKEY_DH:
1556       key_desc = "DH";
1557       break;
1558 #endif
1559 
1560 #ifdef EVP_PKEY_EC
1561     case EVP_PKEY_EC:
1562       key_desc = "ECC";
1563       break;
1564 #endif
1565 
1566     default:
1567       key_desc = "unknown";
1568   }
1569 
1570   return key_desc;
1571 }
1572 
1573 static const char *get_key_type_desc(enum sftp_key_type_e key_type) {
1574   const char *key_desc = NULL;
1575 
1576   switch (key_type) {
1577     case SFTP_KEY_UNKNOWN:
1578       key_desc = "unknown";
1579       break;
1580 
1581     case SFTP_KEY_DSA:
1582       key_desc = "DSA";
1583       break;
1584 
1585     case SFTP_KEY_RSA:
1586       key_desc = "RSA";
1587       break;
1588 
1589     case SFTP_KEY_ECDSA_256:
1590       key_desc = "ECDSA256";
1591       break;
1592 
1593     case SFTP_KEY_ECDSA_384:
1594       key_desc = "ECDSA384";
1595       break;
1596 
1597     case SFTP_KEY_ECDSA_521:
1598       key_desc = "ECDSA521";
1599       break;
1600 
1601     case SFTP_KEY_ED25519:
1602       key_desc = "ED25519";
1603       break;
1604 
1605     default:
1606       key_desc = "undefined";
1607       break;
1608   }
1609 
1610   return key_desc;
1611 }
1612 
1613 #ifdef PR_USE_OPENSSL_ECC
1614 /* Make sure the given ECDSA private key is suitable for use. */
1615 static int validate_ecdsa_private_key(const EC_KEY *ec) {
1616   BN_CTX *bn_ctx;
1617   BIGNUM *ec_order, *bn_tmp;
1618   int ec_order_nbits, priv_key_nbits;
1619 
1620   /* A BN_CTX is like our pools; we allocate one, use it to get any
1621    * number of BIGNUM variables, and only have free up the BN_CTX when
1622    * we're done, rather than all of the individual BIGNUMs.
1623    */
1624 
1625   bn_ctx = BN_CTX_new();
1626   if (bn_ctx == NULL) {
1627     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1628       "error allocating BN_CTX: %s", sftp_crypto_get_errors());
1629     return -1;
1630   }
1631 
1632   BN_CTX_start(bn_ctx);
1633 
1634   ec_order = BN_CTX_get(bn_ctx);
1635   if (ec_order == NULL) {
1636     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1637       "error getting new BIGNUM from BN_CTX: %s", sftp_crypto_get_errors());
1638     BN_CTX_free(bn_ctx);
1639     errno = EPERM;
1640     return -1;
1641   }
1642 
1643   bn_tmp = BN_CTX_get(bn_ctx);
1644   if (bn_tmp == NULL) {
1645     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1646       "error getting new BIGNUM from BN_CTX: %s", sftp_crypto_get_errors());
1647     BN_CTX_free(bn_ctx);
1648     errno = EPERM;
1649     return -1;
1650   }
1651 
1652   /* Make sure that log2(private key) is greater than log2(EC order)/2. */
1653 
1654   if (EC_GROUP_get_order(EC_KEY_get0_group(ec), ec_order, bn_ctx) != 1) {
1655     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1656       "error getting the EC group order: %s", sftp_crypto_get_errors());
1657     BN_CTX_free(bn_ctx);
1658     errno = EPERM;
1659     return -1;
1660   }
1661 
1662   priv_key_nbits = BN_num_bits(EC_KEY_get0_private_key(ec));
1663   ec_order_nbits = BN_num_bits(ec_order);
1664 
1665   if (priv_key_nbits <= (ec_order_nbits / 2)) {
1666     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1667       "ECDSA private key (%d bits) is too small, must be at "
1668       "least %d bits", priv_key_nbits, ec_order_nbits);
1669     BN_CTX_free(bn_ctx);
1670     errno = EACCES;
1671     return -1;
1672   }
1673 
1674   /* Ensure that the private key < (EC order - 1). */
1675 
1676   if (BN_sub(bn_tmp, ec_order, BN_value_one()) == 0) {
1677     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1678       "error subtracting one from EC group order: %s",
1679       sftp_crypto_get_errors());
1680     BN_CTX_free(bn_ctx);
1681     errno = EPERM;
1682     return -1;
1683   }
1684 
1685   if (BN_cmp(EC_KEY_get0_private_key(ec), bn_tmp) >= 0) {
1686     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1687       "ECDSA private key is greater than or equal to EC group order, "
1688       "rejecting");
1689     BN_CTX_free(bn_ctx);
1690     errno = EACCES;
1691     return -1;
1692   }
1693 
1694   BN_CTX_free(bn_ctx);
1695   return 0;
1696 }
1697 
1698 /* This is used to validate the ECDSA parameters we might receive e.g. from
1699  * a client.  These checks come from Section 3.2.2.1 of 'Standards for
1700  * Efficient Cryptography Group, "Elliptic Curve Cryptography", SEC 1,
1701  * May 2009:
1702  *
1703  *  http://www.secg.org/download/aid-780/sec1-v2.pdf
1704  *
1705  * as per RFC 5656 recommendation.
1706  */
1707 int sftp_keys_validate_ecdsa_params(const EC_GROUP *group,
1708     const EC_POINT *point) {
1709   BN_CTX *bn_ctx;
1710   BIGNUM *ec_order, *x_coord, *y_coord, *bn_tmp;
1711   int coord_nbits, ec_order_nbits;
1712   EC_POINT *subgroup_order = NULL;
1713 
1714   if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != NID_X9_62_prime_field) {
1715     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1716       "ECDSA group is not a prime field, rejecting");
1717     errno = EACCES;
1718     return -1;
1719   }
1720 
1721   /* A Q of infinity is unacceptable. */
1722   if (EC_POINT_is_at_infinity(group, point) != 0) {
1723     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1724       "ECDSA EC point has infinite value, rejecting");
1725     errno = EACCES;
1726     return -1;
1727   }
1728 
1729   /* A BN_CTX is like our pools; we allocate one, use it to get any
1730    * number of BIGNUM variables, and only have free up the BN_CTX when
1731    * we're done, rather than all of the individual BIGNUMs.
1732    */
1733 
1734   bn_ctx = BN_CTX_new();
1735   if (bn_ctx == NULL) {
1736     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1737       "error allocating BN_CTX: %s", sftp_crypto_get_errors());
1738     return -1;
1739   }
1740 
1741   BN_CTX_start(bn_ctx);
1742 
1743   ec_order = BN_CTX_get(bn_ctx);
1744   if (ec_order == NULL) {
1745     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1746       "error getting new BIGNUM from BN_CTX: %s", sftp_crypto_get_errors());
1747     BN_CTX_free(bn_ctx);
1748     errno = EPERM;
1749     return -1;
1750   }
1751 
1752   if (EC_GROUP_get_order(group, ec_order, bn_ctx) != 1) {
1753     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1754       "error getting EC group order: %s", sftp_crypto_get_errors());
1755     BN_CTX_free(bn_ctx);
1756     errno = EPERM;
1757     return -1;
1758   }
1759 
1760   x_coord = BN_CTX_get(bn_ctx);
1761   if (x_coord == NULL) {
1762     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1763       "error getting new BIGNUM from BN_CTX: %s", sftp_crypto_get_errors());
1764     BN_CTX_free(bn_ctx);
1765     errno = EPERM;
1766     return -1;
1767   }
1768 
1769   y_coord = BN_CTX_get(bn_ctx);
1770   if (y_coord == NULL) {
1771     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1772       "error getting new BIGNUM from BN_CTX: %s", sftp_crypto_get_errors());
1773     BN_CTX_free(bn_ctx);
1774     errno = EPERM;
1775     return -1;
1776   }
1777 
1778   if (EC_POINT_get_affine_coordinates_GFp(group, point, x_coord, y_coord,
1779       bn_ctx) != 1) {
1780     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1781       "error getting EC point affine coordinates: %s",
1782       sftp_crypto_get_errors());
1783     BN_CTX_free(bn_ctx);
1784     errno = EPERM;
1785     return -1;
1786   }
1787 
1788   /* Ensure that the following are both true:
1789    *
1790    *  log2(X coord) > log2(EC order)/2
1791    *  log2(Y coord) > log2(EC order)/2
1792    */
1793 
1794   coord_nbits = BN_num_bits(x_coord);
1795   ec_order_nbits = BN_num_bits(ec_order);
1796   if (coord_nbits <= (ec_order_nbits / 2)) {
1797     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1798       "EC public key X coordinate (%d bits) too small (<= %d bits), rejecting",
1799       coord_nbits, (ec_order_nbits / 2));
1800     BN_CTX_free(bn_ctx);
1801     errno = EACCES;
1802     return -1;
1803   }
1804 
1805   coord_nbits = BN_num_bits(y_coord);
1806   if (coord_nbits <= (ec_order_nbits / 2)) {
1807     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1808       "EC public key Y coordinate (%d bits) too small (<= %d bits), rejecting",
1809       coord_nbits, (ec_order_nbits / 2));
1810     BN_CTX_free(bn_ctx);
1811     errno = EACCES;
1812     return -1;
1813   }
1814 
1815   /* Ensure that the following is true:
1816    *
1817    *  subgroup order == infinity
1818    */
1819 
1820   subgroup_order = EC_POINT_new(group);
1821   if (subgroup_order == NULL) {
1822     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1823       "error allocating new EC_POINT: %s", sftp_crypto_get_errors());
1824     BN_CTX_free(bn_ctx);
1825     errno = EPERM;
1826     return -1;
1827   }
1828 
1829   if (EC_POINT_mul(group, subgroup_order, NULL, point, ec_order, bn_ctx) != 1) {
1830     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1831       "error doing EC point multiplication: %s", sftp_crypto_get_errors());
1832     EC_POINT_free(subgroup_order);
1833     BN_CTX_free(bn_ctx);
1834     errno = EPERM;
1835     return -1;
1836   }
1837 
1838   if (EC_POINT_is_at_infinity(group, subgroup_order) != 1) {
1839     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1840       "EC public key has finite subgroup order, rejecting");
1841     EC_POINT_free(subgroup_order);
1842     BN_CTX_free(bn_ctx);
1843     errno = EACCES;
1844     return -1;
1845   }
1846 
1847   EC_POINT_free(subgroup_order);
1848 
1849   /*  Ensure that the following are both true:
1850    *
1851    *  X < order - 1
1852    *  Y < order - 1
1853    */
1854 
1855   bn_tmp = BN_CTX_get(bn_ctx);
1856   if (bn_tmp == NULL) {
1857     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1858       "error getting new BIGNUM from BN_CTX: %s", sftp_crypto_get_errors());
1859     BN_CTX_free(bn_ctx);
1860     errno = EPERM;
1861     return -1;
1862   }
1863 
1864   if (BN_sub(bn_tmp, ec_order, BN_value_one()) == 0) {
1865     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1866       "error subtracting one from EC group order: %s",
1867       sftp_crypto_get_errors());
1868     BN_CTX_free(bn_ctx);
1869     errno = EPERM;
1870     return -1;
1871   }
1872 
1873   if (BN_cmp(x_coord, bn_tmp) >= 0) {
1874     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1875       "EC public key X coordinate too large (>= EC group order - 1), "
1876       "rejecting");
1877     BN_CTX_free(bn_ctx);
1878     errno = EACCES;
1879     return -1;
1880   }
1881 
1882   if (BN_cmp(y_coord, bn_tmp) >= 0) {
1883     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1884       "EC public key Y coordinate too large (>= EC group order - 1), "
1885       "rejecting");
1886     BN_CTX_free(bn_ctx);
1887     errno = EACCES;
1888     return -1;
1889   }
1890 
1891   BN_CTX_free(bn_ctx);
1892   return 0;
1893 }
1894 #endif /* PR_USE_OPENSSL_ECC */
1895 
1896 #ifdef SFTP_DEBUG_KEYS
1897 static void debug_rsa_key(pool *p, const char *label, RSA *rsa) {
1898   BIO *bio = NULL;
1899   char *data;
1900   long datalen;
1901 
1902   bio = BIO_new(BIO_s_mem());
1903   RSA_print(bio, rsa, 0);
1904   BIO_flush(bio);
1905   datalen = BIO_get_mem_data(bio, &data);
1906   if (data != NULL &&
1907       datalen > 0) {
1908     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "%s",label);
1909     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "%.*s",
1910       (int) datalen, data);
1911   }
1912 
1913   BIO_free(bio);
1914 }
1915 #endif
1916 
1917 static int get_pkey_type(EVP_PKEY *pkey) {
1918   int pkey_type;
1919 
1920 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
1921     !defined(HAVE_LIBRESS)
1922   pkey_type = EVP_PKEY_base_id(pkey);
1923 #else
1924   pkey_type = EVP_PKEY_type(pkey->type);
1925 #endif /* OpenSSL 1.1.x and later */
1926 
1927   return pkey_type;
1928 }
1929 
1930 static int rsa_compare_keys(pool *p, EVP_PKEY *remote_pkey,
1931     EVP_PKEY *local_pkey) {
1932   RSA *remote_rsa = NULL, *local_rsa = NULL;
1933   BIGNUM *remote_rsa_e = NULL, *local_rsa_e = NULL;
1934   BIGNUM *remote_rsa_n = NULL, *local_rsa_n = NULL;
1935   int res = 0;
1936 
1937   local_rsa = EVP_PKEY_get1_RSA(local_pkey);
1938   if (keys_rsa_min_nbits > 0) {
1939     int rsa_nbits;
1940 
1941     rsa_nbits = RSA_size(local_rsa) * 8;
1942     if (rsa_nbits < keys_rsa_min_nbits) {
1943       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1944         "local RSA key size (%d bits) less than required minimum (%d bits)",
1945         rsa_nbits, keys_rsa_min_nbits);
1946       RSA_free(local_rsa);
1947       errno = EPERM;
1948       return -1;
1949     }
1950 
1951     pr_trace_msg(trace_channel, 19,
1952       "comparing RSA keys using local RSA key (%d bits, min %d)", rsa_nbits,
1953       keys_rsa_min_nbits);
1954   }
1955 
1956   remote_rsa = EVP_PKEY_get1_RSA(remote_pkey);
1957 
1958 #ifdef SFTP_DEBUG_KEYS
1959   debug_rsa_key(p, "remote RSA key:", remote_rsa);
1960   debug_rsa_key(p, "local RSA key:", local_rsa);
1961 #endif
1962 
1963 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
1964     !defined(HAVE_LIBRESSL)
1965   RSA_get0_key(remote_rsa, &remote_rsa_n, &remote_rsa_e, NULL);
1966   RSA_get0_key(local_rsa, &local_rsa_n, &local_rsa_e, NULL);
1967 #else
1968   remote_rsa_e = remote_rsa->e;
1969   local_rsa_e = local_rsa->e;
1970   remote_rsa_n = remote_rsa->n;
1971   local_rsa_n = local_rsa->n;
1972 #endif /* prior to OpenSSL-1.1.0 */
1973 
1974   if (BN_cmp(remote_rsa_e, local_rsa_e) != 0) {
1975     pr_trace_msg(trace_channel, 17, "%s",
1976       "RSA key mismatch: client-sent RSA key component 'e' does not match "
1977       "local RSA key component 'e'");
1978     res = -1;
1979   }
1980 
1981   if (res == 0) {
1982     if (BN_cmp(remote_rsa_n, local_rsa_n) != 0) {
1983       pr_trace_msg(trace_channel, 17, "%s",
1984         "RSA key mismatch: client-sent RSA key component 'n' does not match "
1985         "local RSA key component 'n'");
1986       res = -1;
1987     }
1988   }
1989 
1990   RSA_free(remote_rsa);
1991   RSA_free(local_rsa);
1992   return res;
1993 }
1994 
1995 #if !defined(OPENSSL_NO_DSA)
1996 static int dsa_compare_keys(pool *p, EVP_PKEY *remote_pkey,
1997     EVP_PKEY *local_pkey) {
1998   DSA *remote_dsa = NULL, *local_dsa = NULL;
1999   BIGNUM *remote_dsa_p, *remote_dsa_q, *remote_dsa_g;
2000   BIGNUM *local_dsa_p, *local_dsa_q, *local_dsa_g;
2001   BIGNUM *remote_dsa_pub_key, *local_dsa_pub_key;
2002   int res = 0;
2003 
2004   local_dsa = EVP_PKEY_get1_DSA(local_pkey);
2005   if (keys_dsa_min_nbits > 0) {
2006     int dsa_nbits;
2007 
2008     dsa_nbits = DSA_size(local_dsa) * 8;
2009     if (dsa_nbits < keys_dsa_min_nbits) {
2010       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2011         "local DSA key size (%d bits) less than required minimum (%d bits)",
2012         dsa_nbits, keys_dsa_min_nbits);
2013       DSA_free(local_dsa);
2014       errno = EPERM;
2015       return -1;
2016     }
2017 
2018     pr_trace_msg(trace_channel, 19,
2019       "comparing DSA keys using local DSA key (%d bits)", dsa_nbits);
2020   }
2021 
2022   remote_dsa = EVP_PKEY_get1_DSA(remote_pkey);
2023 
2024 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
2025     !defined(HAVE_LIBRESSL)
2026   DSA_get0_pqg(remote_dsa, &remote_dsa_p, &remote_dsa_q, &remote_dsa_g);
2027   DSA_get0_pqg(local_dsa, &local_dsa_p, &local_dsa_q, &local_dsa_g);
2028   DSA_get0_key(remote_dsa, &remote_dsa_pub_key, NULL);
2029   DSA_get0_key(local_dsa, &local_dsa_pub_key, NULL);
2030 #else
2031   remote_dsa_p = remote_dsa->p;
2032   remote_dsa_q = remote_dsa->q;
2033   remote_dsa_g = remote_dsa->g;
2034   remote_dsa_pub_key = remote_dsa->pub_key;
2035   local_dsa_p = local_dsa->p;
2036   local_dsa_q = local_dsa->q;
2037   local_dsa_g = local_dsa->g;
2038   local_dsa_pub_key = local_dsa->pub_key;
2039 #endif /* prior to OpenSSL-1.1.0 */
2040 
2041   if (BN_cmp(remote_dsa_p, local_dsa_p) != 0) {
2042     pr_trace_msg(trace_channel, 17, "%s",
2043       "DSA key mismatch: client-sent DSA key parameter 'p' does not match "
2044       "local DSA key parameter 'p'");
2045     res = -1;
2046   }
2047 
2048   if (res == 0) {
2049     if (BN_cmp(remote_dsa_q, local_dsa_q) != 0) {
2050       pr_trace_msg(trace_channel, 17, "%s",
2051         "DSA key mismatch: client-sent DSA key parameter 'q' does not match "
2052         "local DSA key parameter 'q'");
2053       res = -1;
2054     }
2055   }
2056 
2057   if (res == 0) {
2058     if (BN_cmp(remote_dsa_g, local_dsa_g) != 0) {
2059       pr_trace_msg(trace_channel, 17, "%s",
2060         "DSA key mismatch: client-sent DSA key parameter 'g' does not match "
2061         "local DSA key parameter 'g'");
2062       res = -1;
2063     }
2064   }
2065 
2066   if (res == 0) {
2067     if (BN_cmp(remote_dsa_pub_key, local_dsa_pub_key) != 0) {
2068       pr_trace_msg(trace_channel, 17, "%s",
2069         "DSA key mismatch: client-sent DSA key parameter 'pub_key' does not "
2070         "match local DSA key parameter 'pub_key'");
2071       res = -1;
2072     }
2073   }
2074 
2075   DSA_free(remote_dsa);
2076   DSA_free(local_dsa);
2077   return res;
2078 }
2079 #endif /* OPENSSL_NO_DSA */
2080 
2081 #if defined(PR_USE_OPENSSL_ECC)
2082 static int ecdsa_compare_keys(pool *p, EVP_PKEY *remote_pkey,
2083     EVP_PKEY *local_pkey) {
2084   EC_KEY *remote_ec, *local_ec;
2085   int res = 0;
2086 
2087   local_ec = EVP_PKEY_get1_EC_KEY(local_pkey);
2088   if (keys_ec_min_nbits > 0) {
2089     int ec_nbits;
2090 
2091     ec_nbits = EVP_PKEY_bits(local_pkey) * 8;
2092     if (ec_nbits < keys_ec_min_nbits) {
2093       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2094         "local EC key size (%d bits) less than required minimum (%d bits)",
2095         ec_nbits, keys_ec_min_nbits);
2096       EC_KEY_free(local_ec);
2097       errno = EPERM;
2098       return -1;
2099     }
2100 
2101     pr_trace_msg(trace_channel, 19,
2102       "comparing EC keys using local EC key (%d bits)", ec_nbits);
2103   }
2104 
2105   remote_ec = EVP_PKEY_get1_EC_KEY(remote_pkey);
2106 
2107   if (EC_GROUP_cmp(EC_KEY_get0_group(local_ec),
2108       EC_KEY_get0_group(remote_ec), NULL) != 0) {
2109     pr_trace_msg(trace_channel, 17, "%s",
2110       "ECC key mismatch: client-sent curve does not match local ECC curve");
2111     res = -1;
2112   }
2113 
2114   if (res == 0) {
2115     if (EC_POINT_cmp(EC_KEY_get0_group(local_ec),
2116         EC_KEY_get0_public_key(local_ec),
2117         EC_KEY_get0_public_key(remote_ec), NULL) != 0) {
2118       pr_trace_msg(trace_channel, 17, "%s",
2119         "ECC key mismatch: client-sent public key 'Q' does not match "
2120         "local ECC public key 'Q'");
2121       res = -1;
2122     }
2123   }
2124 
2125   EC_KEY_free(remote_ec);
2126   EC_KEY_free(local_ec);
2127   return res;
2128 }
2129 #endif /* PR_USE_OPENSSL_ECC */
2130 
2131 #if defined(PR_USE_SODIUM)
2132 static int ed25519_compare_keys(pool *p,
2133     unsigned char *remote_pubkey_data, uint32_t remote_pubkey_datalen,
2134     unsigned char *local_pubkey_data, uint32_t local_pubkey_datalen) {
2135   int res = 0;
2136 
2137   if (remote_pubkey_datalen != local_pubkey_datalen) {
2138     return -1;
2139   }
2140 
2141   if (memcmp(remote_pubkey_data, local_pubkey_data, remote_pubkey_datalen) != 0) {
2142     res = -1;
2143   }
2144 
2145   return res;
2146 }
2147 #endif /* PR_USE_SODIUM */
2148 
2149 /* Compare a "blob" of pubkey data sent by the client for authentication
2150  * with a local file pubkey (from an RFC4716 formatted file).  Returns -1 if
2151  * there was an error, TRUE if the keys are equals, and FALSE if not.
2152  */
2153 int sftp_keys_compare_keys(pool *p,
2154     unsigned char *remote_pubkey_data, uint32_t remote_pubkey_datalen,
2155     unsigned char *local_pubkey_data, uint32_t local_pubkey_datalen) {
2156   enum sftp_key_type_e remote_key_type, local_key_type;
2157   EVP_PKEY *remote_pkey = NULL, *local_pkey = NULL;
2158   int res = -1;
2159   uint32_t len = 0;
2160 
2161   if (remote_pubkey_data == NULL ||
2162       local_pubkey_data == NULL) {
2163     errno = EINVAL;
2164     return -1;
2165   }
2166 
2167   remote_key_type = local_key_type = SFTP_KEY_UNKNOWN;
2168 
2169   len = read_pkey_from_data(p, remote_pubkey_data, remote_pubkey_datalen,
2170     &remote_pkey, &remote_key_type, FALSE);
2171   if (len == 0) {
2172     return -1;
2173   }
2174 
2175   len = read_pkey_from_data(p, local_pubkey_data, local_pubkey_datalen,
2176     &local_pkey, &local_key_type, FALSE);
2177   if (len == 0) {
2178     int xerrno = errno;
2179 
2180     if (remote_pkey != NULL) {
2181       EVP_PKEY_free(remote_pkey);
2182     }
2183 
2184     errno = xerrno;
2185     return -1;
2186   }
2187 
2188   if (remote_pkey != NULL &&
2189       local_pkey != NULL &&
2190       remote_key_type == local_key_type) {
2191     switch (get_pkey_type(remote_pkey)) {
2192       case EVP_PKEY_RSA: {
2193         if (rsa_compare_keys(p, remote_pkey, local_pkey) == 0) {
2194           res = TRUE;
2195 
2196         } else {
2197           res = FALSE;
2198         }
2199 
2200         break;
2201       }
2202 
2203 #if !defined(OPENSSL_NO_DSA)
2204       case EVP_PKEY_DSA: {
2205         if (dsa_compare_keys(p, remote_pkey, local_pkey) == 0) {
2206           res = TRUE;
2207 
2208         } else {
2209           res = FALSE;
2210         }
2211 
2212         break;
2213       }
2214 #endif /* !OPENSSL_NO_DSA */
2215 
2216 #ifdef PR_USE_OPENSSL_ECC
2217       case EVP_PKEY_EC: {
2218         if (ecdsa_compare_keys(p, remote_pkey, local_pkey) == 0) {
2219           res = TRUE;
2220 
2221         } else {
2222           res = FALSE;
2223         }
2224 
2225         break;
2226       }
2227 #endif /* PR_USE_OPENSSL_ECC */
2228 
2229       default:
2230         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2231           "unable to compare %s keys: unsupported key type",
2232           get_pkey_type_desc(get_pkey_type(remote_pkey)));
2233         errno = ENOSYS;
2234         break;
2235     }
2236 
2237   } else if (remote_key_type == SFTP_KEY_ED25519 &&
2238              remote_key_type == local_key_type) {
2239 #if defined(PR_USE_SODIUM)
2240     if (ed25519_compare_keys(p, remote_pubkey_data, remote_pubkey_datalen,
2241         local_pubkey_data, local_pubkey_datalen) == 0) {
2242       res = TRUE;
2243 
2244     } else {
2245       res = FALSE;
2246     }
2247 #endif /* PR_USE_SODIUM */
2248 
2249   } else {
2250     if (pr_trace_get_level(trace_channel) >= 17) {
2251       const char *remote_key_desc, *local_key_desc;
2252 
2253       remote_key_desc = get_key_type_desc(remote_key_type);
2254       local_key_desc = get_key_type_desc(local_key_type);
2255 
2256       pr_trace_msg(trace_channel, 17, "key mismatch: cannot compare %s key "
2257         "(client-sent) with %s key (local)", remote_key_desc, local_key_desc);
2258     }
2259 
2260     res = FALSE;
2261   }
2262 
2263   if (remote_pkey != NULL) {
2264     EVP_PKEY_free(remote_pkey);
2265   }
2266 
2267   if (local_pkey != NULL) {
2268     EVP_PKEY_free(local_pkey);
2269   }
2270 
2271   return res;
2272 }
2273 
2274 const char *sftp_keys_get_fingerprint(pool *p, unsigned char *key_data,
2275     uint32_t key_datalen, int digest_algo) {
2276 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
2277     defined(HAVE_LIBRESSL)
2278   EVP_MD_CTX ctx;
2279 #endif /* prior to OpenSSL-1.1.0 */
2280   EVP_MD_CTX *pctx;
2281   const EVP_MD *digest;
2282   char *digest_name = "none", *fp;
2283   unsigned char *fp_data;
2284   unsigned int fp_datalen = 0;
2285   register unsigned int i;
2286 
2287   switch (digest_algo) {
2288     case SFTP_KEYS_FP_DIGEST_MD5:
2289       digest = EVP_md5();
2290       digest_name = "md5";
2291       break;
2292 
2293     case SFTP_KEYS_FP_DIGEST_SHA1:
2294       digest = EVP_sha1();
2295       digest_name = "sha1";
2296       break;
2297 
2298 #if defined(HAVE_SHA256_OPENSSL)
2299     case SFTP_KEYS_FP_DIGEST_SHA256:
2300       digest = EVP_sha256();
2301       digest_name = "sha256";
2302       break;
2303 #endif /* HAVE_SHA256_OPENSSL */
2304 
2305     default:
2306       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2307         "unsupported key fingerprint digest algorithm (%d)", digest_algo);
2308       errno = EACCES;
2309       return NULL;
2310   }
2311 
2312 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
2313     !defined(HAVE_LIBRESSL)
2314   pctx = EVP_MD_CTX_new();
2315 #else
2316   pctx = &ctx;
2317 #endif /* prior to OpenSSL-1.1.0 */
2318 
2319   /* In OpenSSL 0.9.6, many of the EVP_Digest* functions returned void, not
2320    * int.  Without these ugly OpenSSL version preprocessor checks, the
2321    * compiler will error out with "void value not ignored as it ought to be".
2322    */
2323 
2324 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
2325   if (EVP_DigestInit(pctx, digest) != 1) {
2326     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2327       "error initializing %s digest: %s", digest_name,
2328       sftp_crypto_get_errors());
2329 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
2330      !defined(HAVE_LIBRESSL)
2331     EVP_MD_CTX_free(pctx);
2332 # endif /* OpenSSL-1.1.0 and later */
2333     errno = EPERM;
2334     return NULL;
2335   }
2336 #else
2337   EVP_DigestInit(pctx, digest);
2338 #endif
2339 
2340 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
2341   if (EVP_DigestUpdate(pctx, key_data, key_datalen) != 1) {
2342     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2343       "error updating %s digest: %s", digest_name, sftp_crypto_get_errors());
2344 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
2345      !defined(HAVE_LIBRESSL)
2346     EVP_MD_CTX_free(pctx);
2347 # endif /* OpenSSL-1.1.0 and later */
2348     errno = EPERM;
2349     return NULL;
2350   }
2351 #else
2352   EVP_DigestUpdate(pctx, key_data, key_datalen);
2353 #endif
2354 
2355   fp_data = palloc(p, EVP_MAX_MD_SIZE);
2356 
2357 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
2358   if (EVP_DigestFinal(pctx, fp_data, &fp_datalen) != 1) {
2359     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2360       "error finishing %s digest: %s", digest_name, sftp_crypto_get_errors());
2361 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
2362      !defined(HAVE_LIBRESSL)
2363     EVP_MD_CTX_free(pctx);
2364 # endif /* OpenSSL-1.1.0 and later */
2365     errno = EPERM;
2366     return NULL;
2367   }
2368 #else
2369   EVP_DigestFinal(pctx, fp_data, &fp_datalen);
2370 #endif
2371 
2372 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
2373     !defined(HAVE_LIBRESSL)
2374   EVP_MD_CTX_free(pctx);
2375 #endif /* OpenSSL-1.1.0 and later */
2376 
2377   /* Now encode that digest in fp_data as hex characters. */
2378   fp = "";
2379 
2380   for (i = 0; i < fp_datalen; i++) {
2381     char c[4];
2382 
2383     memset(c, '\0', sizeof(c));
2384     pr_snprintf(c, sizeof(c), "%02x:", fp_data[i]);
2385     fp = pstrcat(p, fp, &c, NULL);
2386   }
2387   fp[strlen(fp)-1] = '\0';
2388 
2389   return fp;
2390 }
2391 
2392 #ifdef PR_USE_OPENSSL_ECC
2393 /* Returns the NID for the configured EVP_PKEY_EC key. */
2394 static int get_ecdsa_nid(EC_KEY *ec) {
2395   register unsigned int i;
2396   const EC_GROUP *key_group;
2397   EC_GROUP *new_group = NULL;
2398   BN_CTX *bn_ctx = NULL;
2399   int supported_ecdsa_nids[] = {
2400     NID_X9_62_prime256v1,
2401     NID_secp384r1,
2402     NID_secp521r1,
2403     -1
2404   };
2405   int nid;
2406 
2407   if (ec == NULL) {
2408     errno = EINVAL;
2409     return -1;
2410   }
2411 
2412   /* Since the EC group might be encoded in different ways, we need to try
2413    * different lookups to find the NID.
2414    *
2415    * First, we see if the EC group is encoded as a "named group" in the
2416    * private key.
2417    */
2418   key_group = EC_KEY_get0_group(ec);
2419   nid = EC_GROUP_get_curve_name(key_group);
2420   if (nid > 0) {
2421     return nid;
2422   }
2423 
2424   /* Otherwise, we check to see if the group is encoded via explicit group
2425    * parameters in the private key.
2426    */
2427 
2428   bn_ctx = BN_CTX_new();
2429   if (bn_ctx == NULL) {
2430     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2431       "error allocated BN_CTX: %s", sftp_crypto_get_errors());
2432     return -1;
2433   }
2434 
2435   for (i = 0; supported_ecdsa_nids[i] != -1; i++) {
2436     new_group = EC_GROUP_new_by_curve_name(supported_ecdsa_nids[i]);
2437     if (new_group == NULL) {
2438       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2439         "error creating new EC_GROUP by curve name %d: %s",
2440         supported_ecdsa_nids[i], sftp_crypto_get_errors());
2441       BN_CTX_free(bn_ctx);
2442       return -1;
2443     }
2444 
2445     if (EC_GROUP_cmp(key_group, new_group, bn_ctx) == 0) {
2446       /* We have a match. */
2447       break;
2448     }
2449 
2450     EC_GROUP_free(new_group);
2451     new_group = NULL;
2452   }
2453 
2454   BN_CTX_free(bn_ctx);
2455 
2456   if (supported_ecdsa_nids[i] != -1) {
2457     EC_GROUP_set_asn1_flag(new_group, OPENSSL_EC_NAMED_CURVE);
2458     if (EC_KEY_set_group(ec, new_group) != 1) {
2459       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2460         "error setting EC group on key: %s", sftp_crypto_get_errors());
2461       EC_GROUP_free(new_group);
2462       return -1;
2463     }
2464 
2465     EC_GROUP_free(new_group);
2466   }
2467 
2468   return supported_ecdsa_nids[i];
2469 }
2470 #endif /* PR_USE_OPENSSL_ECC */
2471 
2472 static int handle_hostkey(pool *p, EVP_PKEY *pkey,
2473     const unsigned char *key_data, uint32_t key_datalen,
2474     const char *file_path, const char *agent_path) {
2475 
2476   switch (get_pkey_type(pkey)) {
2477     case EVP_PKEY_RSA: {
2478 #if OPENSSL_VERSION_NUMBER < 0x0090702fL
2479       /* In OpenSSL-0.9.7a and later, RSA blinding is turned on by default.
2480        * Thus if our OpenSSL is older than that, manually enable RSA
2481        * blinding.
2482        */
2483       RSA *rsa;
2484 
2485       rsa = EVP_PKEY_get1_RSA(pkey);
2486       if (rsa) {
2487         if (RSA_blinding_on(rsa, NULL) != 1) {
2488           (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2489             "error enabling RSA blinding for key '%s': %s",
2490             file_path ? file_path : agent_path,
2491             sftp_crypto_get_errors());
2492 
2493         } else {
2494           (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2495             "RSA blinding enabled for key '%s'",
2496             file_path ? file_path : agent_path);
2497         }
2498 
2499         RSA_free(rsa);
2500       }
2501 #endif
2502 
2503       if (sftp_rsa_hostkey != NULL) {
2504         /* If we have an existing RSA hostkey, free it up. */
2505         EVP_PKEY_free(sftp_rsa_hostkey->pkey);
2506         sftp_rsa_hostkey->pkey = NULL;
2507         sftp_rsa_hostkey->key_data = NULL;
2508         sftp_rsa_hostkey->key_datalen = 0;
2509         sftp_rsa_hostkey->file_path = NULL;
2510         sftp_rsa_hostkey->agent_path = NULL;
2511 
2512       } else {
2513         sftp_rsa_hostkey = pcalloc(p, sizeof(struct sftp_hostkey));
2514       }
2515 
2516       sftp_rsa_hostkey->key_type = SFTP_KEY_RSA;
2517       sftp_rsa_hostkey->pkey = pkey;
2518       sftp_rsa_hostkey->key_data = key_data;
2519       sftp_rsa_hostkey->key_datalen = key_datalen;
2520       sftp_rsa_hostkey->file_path = file_path;
2521       sftp_rsa_hostkey->agent_path = agent_path;
2522 
2523       if (file_path != NULL) {
2524         pr_trace_msg(trace_channel, 4, "using '%s' as RSA hostkey", file_path);
2525 
2526       } else if (agent_path != NULL) {
2527         pr_trace_msg(trace_channel, 4,
2528           "using RSA hostkey from SSH agent at '%s'", agent_path);
2529       }
2530 
2531       break;
2532     }
2533 
2534     case EVP_PKEY_DSA: {
2535       if (sftp_dsa_hostkey != NULL) {
2536         /* If we have an existing DSA hostkey, free it up. */
2537         EVP_PKEY_free(sftp_dsa_hostkey->pkey);
2538         sftp_dsa_hostkey->pkey = NULL;
2539         sftp_dsa_hostkey->key_data = NULL;
2540         sftp_dsa_hostkey->key_datalen = 0;
2541         sftp_dsa_hostkey->file_path = NULL;
2542         sftp_dsa_hostkey->agent_path = NULL;
2543 
2544       } else {
2545         sftp_dsa_hostkey = pcalloc(p, sizeof(struct sftp_hostkey));
2546       }
2547 
2548       sftp_dsa_hostkey->key_type = SFTP_KEY_DSA;
2549       sftp_dsa_hostkey->pkey = pkey;
2550       sftp_dsa_hostkey->key_data = key_data;
2551       sftp_dsa_hostkey->key_datalen = key_datalen;
2552       sftp_dsa_hostkey->file_path = file_path;
2553       sftp_dsa_hostkey->agent_path = agent_path;
2554 
2555       if (file_path != NULL) {
2556         pr_trace_msg(trace_channel, 4, "using '%s' as DSA hostkey", file_path);
2557 
2558       } else if (agent_path != NULL) {
2559         pr_trace_msg(trace_channel, 4,
2560           "using DSA hostkey from SSH agent at '%s'", agent_path);
2561       }
2562 
2563       break;
2564     }
2565 
2566 #ifdef PR_USE_OPENSSL_ECC
2567     case EVP_PKEY_EC: {
2568       EC_KEY *ec;
2569       int ec_nid;
2570 
2571       ec = EVP_PKEY_get1_EC_KEY(pkey);
2572       ec_nid = get_ecdsa_nid(ec);
2573       if (ec_nid < 0) {
2574         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2575           "unsupported NID in EC key, ignoring");
2576         EC_KEY_free(ec);
2577         EVP_PKEY_free(pkey);
2578         return -1;
2579       }
2580 
2581       if (sftp_keys_validate_ecdsa_params(EC_KEY_get0_group(ec),
2582           EC_KEY_get0_public_key(ec)) < 0) {
2583         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2584           "error validating EC public key: %s", strerror(errno));
2585         EC_KEY_free(ec);
2586         EVP_PKEY_free(pkey);
2587         return -1;
2588       }
2589 
2590       if (validate_ecdsa_private_key(ec)) {
2591         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2592           "error validating EC private key: %s", strerror(errno));
2593         EC_KEY_free(ec);
2594         EVP_PKEY_free(pkey);
2595         return -1;
2596       }
2597 
2598       EC_KEY_free(ec);
2599 
2600       switch (ec_nid) {
2601         case NID_X9_62_prime256v1:
2602           if (sftp_ecdsa256_hostkey != NULL) {
2603             /* If we have an existing 256-bit ECDSA hostkey, free it up. */
2604             EVP_PKEY_free(sftp_ecdsa256_hostkey->pkey);
2605             sftp_ecdsa256_hostkey->pkey = NULL;
2606             sftp_ecdsa256_hostkey->key_data = NULL;
2607             sftp_ecdsa256_hostkey->key_datalen = 0;
2608             sftp_ecdsa256_hostkey->file_path = NULL;
2609             sftp_ecdsa256_hostkey->agent_path = NULL;
2610 
2611           } else {
2612             sftp_ecdsa256_hostkey = pcalloc(p, sizeof(struct sftp_hostkey));
2613           }
2614 
2615           sftp_ecdsa256_hostkey->key_type = SFTP_KEY_ECDSA_256;
2616           sftp_ecdsa256_hostkey->pkey = pkey;
2617           sftp_ecdsa256_hostkey->key_data = key_data;
2618           sftp_ecdsa256_hostkey->key_datalen = key_datalen;
2619           sftp_ecdsa256_hostkey->file_path = file_path;
2620           sftp_ecdsa256_hostkey->agent_path = agent_path;
2621 
2622           if (file_path != NULL) {
2623             (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2624               "using '%s' as 256-bit ECDSA hostkey", file_path);
2625 
2626           } else if (agent_path != NULL) {
2627             (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2628               "using 256-bit ECDSA hostkey from SSH agent at '%s'", agent_path);
2629           }
2630 
2631           break;
2632 
2633         case NID_secp384r1:
2634           if (sftp_ecdsa384_hostkey != NULL) {
2635             /* If we have an existing 384-bit ECDSA hostkey, free it up. */
2636             EVP_PKEY_free(sftp_ecdsa384_hostkey->pkey);
2637             sftp_ecdsa384_hostkey->pkey = NULL;
2638             sftp_ecdsa384_hostkey->key_data = NULL;
2639             sftp_ecdsa384_hostkey->key_datalen = 0;
2640             sftp_ecdsa384_hostkey->file_path = NULL;
2641             sftp_ecdsa384_hostkey->agent_path = NULL;
2642 
2643           } else {
2644             sftp_ecdsa384_hostkey = pcalloc(p, sizeof(struct sftp_hostkey));
2645           }
2646 
2647           sftp_ecdsa384_hostkey->key_type = SFTP_KEY_ECDSA_384;
2648           sftp_ecdsa384_hostkey->pkey = pkey;
2649           sftp_ecdsa384_hostkey->key_data = key_data;
2650           sftp_ecdsa384_hostkey->key_datalen = key_datalen;
2651           sftp_ecdsa384_hostkey->file_path = file_path;
2652           sftp_ecdsa384_hostkey->agent_path = agent_path;
2653 
2654           if (file_path != NULL) {
2655             (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2656               "using '%s' as 384-bit ECDSA hostkey", file_path);
2657 
2658           } else if (agent_path != NULL) {
2659             (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2660               "using 384-bit ECDSA hostkey from SSH agent at '%s'", agent_path);
2661           }
2662 
2663           break;
2664 
2665         case NID_secp521r1:
2666           if (sftp_ecdsa521_hostkey != NULL) {
2667             /* If we have an existing 521-bit ECDSA hostkey, free it up. */
2668             EVP_PKEY_free(sftp_ecdsa521_hostkey->pkey);
2669             sftp_ecdsa521_hostkey->pkey = NULL;
2670             sftp_ecdsa521_hostkey->key_data = NULL;
2671             sftp_ecdsa521_hostkey->key_datalen = 0;
2672             sftp_ecdsa521_hostkey->file_path = NULL;
2673             sftp_ecdsa521_hostkey->agent_path = NULL;
2674 
2675           } else {
2676             sftp_ecdsa521_hostkey = pcalloc(p, sizeof(struct sftp_hostkey));
2677           }
2678 
2679           sftp_ecdsa521_hostkey->key_type = SFTP_KEY_ECDSA_521;
2680           sftp_ecdsa521_hostkey->pkey = pkey;
2681           sftp_ecdsa521_hostkey->key_data = key_data;
2682           sftp_ecdsa521_hostkey->key_datalen = key_datalen;
2683           sftp_ecdsa521_hostkey->file_path = file_path;
2684           sftp_ecdsa521_hostkey->agent_path = agent_path;
2685 
2686           if (file_path != NULL) {
2687             (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2688               "using '%s' as 521-bit ECDSA hostkey", file_path);
2689 
2690           } else if (agent_path != NULL) {
2691             (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2692               "using 521-bit hostkey from SSH agent at '%s'", agent_path);
2693           }
2694 
2695           break;
2696       }
2697 
2698       break;
2699     }
2700 #endif /* PR_USE_OPENSSL_ECC */
2701 
2702     default:
2703       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2704         "unknown private key type (%d), ignoring", get_pkey_type(pkey));
2705       EVP_PKEY_free(pkey);
2706       return -1;
2707   }
2708 
2709   return 0;
2710 }
2711 
2712 static int load_agent_hostkeys(pool *p, const char *path) {
2713   register unsigned int i;
2714   int accepted_nkeys = 0, res;
2715   array_header *key_list;
2716 
2717   key_list = make_array(p, 0, sizeof(struct agent_key *));
2718 
2719   res = sftp_agent_get_keys(p, path, key_list);
2720   if (res < 0) {
2721     int xerrno = errno;
2722 
2723     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2724       "error loading hostkeys from SSH agent at '%s': %s", path,
2725       strerror(xerrno));
2726 
2727     errno = xerrno;
2728     return -1;
2729   }
2730 
2731   if (key_list->nelts == 0) {
2732     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2733       "SSH agent at '%s' returned no keys", path);
2734     errno = ENOENT;
2735     return -1;
2736   }
2737 
2738   pr_trace_msg(trace_channel, 9, "processing %d keys from SSH agent at '%s'",
2739     key_list->nelts, path);
2740 
2741   for (i = 0; i < key_list->nelts; i++) {
2742     EVP_PKEY *pkey;
2743     uint32_t len;
2744     struct agent_key *agent_key;
2745 
2746     agent_key = ((struct agent_key **) key_list->elts)[i];
2747 
2748     len = read_pkey_from_data(p, agent_key->key_data, agent_key->key_datalen,
2749       &pkey, NULL, FALSE);
2750     if (len == 0) {
2751       continue;
2752     }
2753 
2754     if (handle_hostkey(p, pkey, agent_key->key_data, agent_key->key_datalen,
2755         NULL, path) == 0) {
2756       accepted_nkeys++;
2757     }
2758   }
2759 
2760   if (accepted_nkeys == 0) {
2761     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2762       "none of the keys provided by the SSH agent at '%s' were acceptable",
2763       path);
2764     errno = EINVAL;
2765     return -1;
2766   }
2767 
2768   pr_trace_msg(trace_channel, 9, "loaded %d keys from SSH agent at '%s'",
2769     accepted_nkeys, path);
2770 
2771   /* Return the number of keys we successfully accept from the agent. */
2772   return accepted_nkeys;
2773 }
2774 
2775 static struct openssh_cipher *get_openssh_cipher(const char *name) {
2776   register unsigned int i;
2777   struct openssh_cipher *cipher = NULL;
2778 
2779   for (i = 0; ciphers[i].algo != NULL; i++) {
2780     if (strcmp(ciphers[i].algo, name) == 0) {
2781       cipher = &ciphers[i];
2782       break;
2783     }
2784   }
2785 
2786   /* The CTR algorithms require our own implementation, not the OpenSSL
2787    * implementation.
2788    */
2789   if (cipher->get_cipher == NULL) {
2790     cipher->get_cipher = sftp_crypto_get_cipher(name, NULL, NULL);
2791     if (cipher->get_cipher == NULL) {
2792       errno = ENOSYS;
2793       return NULL;
2794     }
2795   }
2796 
2797   errno = ENOENT;
2798   return cipher;
2799 }
2800 
2801 static int decrypt_openssh_data(pool *p, const char *path,
2802     unsigned char *encrypted_data, uint32_t encrypted_len,
2803     const char *passphrase, struct openssh_cipher *cipher,
2804     const char *kdf_name, unsigned char *kdf_data, uint32_t kdf_len,
2805     unsigned char **decrypted_data, uint32_t *decrypted_len) {
2806   EVP_CIPHER *openssl_cipher;
2807   EVP_CIPHER_CTX *cipher_ctx = NULL;
2808   unsigned char *buf, *key, *iv, *salt_data;
2809   uint32_t buflen, key_len, rounds, salt_len;
2810   size_t passphrase_len;
2811 
2812   if (strcmp(kdf_name, "none") == 0) {
2813     *decrypted_data = encrypted_data;
2814     *decrypted_len = encrypted_len;
2815 
2816     return 0;
2817   }
2818 
2819   if (strcmp(kdf_name, "bcrypt") != 0) {
2820     pr_trace_msg(trace_channel, 3,
2821       "'%s' key uses unsupported %s KDF", path, kdf_name);
2822     errno = ENOSYS;
2823     return -1;
2824   }
2825 
2826   salt_len = sftp_msg_read_int(p, &kdf_data, &kdf_len);
2827   salt_data = sftp_msg_read_data(p, &kdf_data, &kdf_len, salt_len);
2828   rounds = sftp_msg_read_int(p, &kdf_data, &kdf_len);
2829 
2830   pr_trace_msg(trace_channel, 9,
2831     "'%s' key %s KDF using %lu bytes of salt, %lu rounds", path,
2832     kdf_name, (unsigned long) salt_len, (unsigned long) rounds);
2833 
2834   /* Compute the decryption key using the KDF and the passphrase.  Note that
2835    * we derive the key AND the IV using this approach at the same time.
2836    */
2837   passphrase_len = strlen(passphrase);
2838   key_len = cipher->key_len + cipher->iv_len;
2839 
2840   pr_trace_msg(trace_channel, 13,
2841     "generating %s decryption key using %s KDF (key len = %lu, IV len = %lu)",
2842     cipher->algo, kdf_name, (unsigned long) cipher->key_len,
2843     (unsigned long) cipher->iv_len);
2844   key = pcalloc(p, key_len);
2845   if (sftp_bcrypt_pbkdf2(p, passphrase, passphrase_len, salt_data, salt_len,
2846       rounds, key, key_len) < 0) {
2847     pr_trace_msg(trace_channel, 3,
2848       "error computing key using %s KDF: %s", kdf_name, strerror(errno));
2849     errno = EPERM;
2850     return -1;
2851   }
2852 
2853   if (cipher->iv_len > 0) {
2854     iv = key + cipher->key_len;
2855 
2856   } else {
2857     iv = NULL;
2858   }
2859 
2860   cipher_ctx = EVP_CIPHER_CTX_new();
2861   if (cipher_ctx == NULL) {
2862     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2863       "error allocating cipher context: %s", sftp_crypto_get_errors());
2864     errno = EPERM;
2865     return -1;
2866   }
2867   EVP_CIPHER_CTX_init(cipher_ctx);
2868 
2869   openssl_cipher = (cipher->get_cipher)();
2870 
2871 #if defined(PR_USE_OPENSSL_EVP_CIPHERINIT_EX)
2872   if (EVP_CipherInit_ex(cipher_ctx, openssl_cipher, NULL, key, iv, 0) != 1) {
2873 #else
2874   if (EVP_CipherInit(cipher_ctx, openssl_cipher, key, iv, 0) != 1) {
2875 #endif /* PR_USE_OPENSSL_EVP_CIPHERINIT_EX */
2876     pr_trace_msg(trace_channel, 3,
2877       "error initializing %s cipher for decryption: %s", cipher->algo,
2878       sftp_crypto_get_errors());
2879     EVP_CIPHER_CTX_free(cipher_ctx);
2880     pr_memscrub(key, key_len);
2881     errno = EPERM;
2882     return -1;
2883   }
2884 
2885   if (cipher->key_len > 0) {
2886     if (EVP_CIPHER_CTX_set_key_length(cipher_ctx, cipher->key_len) != 1) {
2887       pr_trace_msg(trace_channel, 3,
2888         "error setting key length (%lu bytes) for %s cipher for decryption: %s",
2889         (unsigned long) cipher->key_len, cipher->algo,
2890         sftp_crypto_get_errors());
2891       EVP_CIPHER_CTX_cleanup(cipher_ctx);
2892       EVP_CIPHER_CTX_free(cipher_ctx);
2893       pr_memscrub(key, key_len);
2894       errno = EPERM;
2895       return -1;
2896     }
2897   }
2898 
2899   buflen = encrypted_len;
2900   buf = pcalloc(p, buflen);
2901 
2902   /* TODO: this currently works because our data does NOT contain any extra
2903    * trailing AEAD bytes.  Need to fix that in the future.
2904    */
2905 
2906   if (EVP_Cipher(cipher_ctx, buf, encrypted_data, encrypted_len) != 1) {
2907     /* This might happen due to a wrong/bad passphrase. */
2908     pr_trace_msg(trace_channel, 3,
2909       "error decrypting %s data for key: %s", cipher->algo,
2910       sftp_crypto_get_errors());
2911     EVP_CIPHER_CTX_cleanup(cipher_ctx);
2912     EVP_CIPHER_CTX_free(cipher_ctx);
2913     pr_memscrub(key, key_len);
2914     pr_memscrub(buf, buflen);
2915     errno = EPERM;
2916     return -1;
2917   }
2918 
2919   EVP_CIPHER_CTX_cleanup(cipher_ctx);
2920   EVP_CIPHER_CTX_free(cipher_ctx);
2921   pr_memscrub(key, key_len);
2922 
2923   *decrypted_data = buf;
2924   *decrypted_len = buflen;
2925   return 0;
2926 }
2927 
2928 /* See openssh-7.9p1/sshkey.c#sshkey_from_blob_internal(). */
2929 static int deserialize_openssh_private_key(pool *p, const char *path,
2930     unsigned char **data, uint32_t *data_len, enum sftp_key_type_e *key_type,
2931     EVP_PKEY **pkey, unsigned char **key, uint32_t *keylen) {
2932   uint32_t len = 0;
2933 
2934   len = read_pkey_from_data(p, *data, *data_len, pkey, key_type, TRUE);
2935   if (len == 0) {
2936     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
2937       "unsupported key type %d found in '%s'", *key_type, path);
2938     errno = EPERM;
2939     return -1;
2940   }
2941 
2942   /* Advance our pointers for all of the data read from them. */
2943   (*data) += len;
2944   (*data_len) -= len;
2945 
2946   if (*key_type == SFTP_KEY_ED25519) {
2947     const char *pkey_type = "ssh-ed25519";
2948     uint32_t public_keylen = 0, secret_keylen = 0, res = 0;
2949     unsigned char *public_key = NULL, *secret_key = NULL;
2950 
2951     public_keylen = sftp_msg_read_int(p, data, data_len);
2952     public_key = sftp_msg_read_data(p, data, data_len, public_keylen);
2953     if (public_key == NULL) {
2954       pr_trace_msg(trace_channel, 2,
2955         "error reading %s key: invalid/supported key format", pkey_type);
2956       errno = EINVAL;
2957       return -1;
2958     }
2959 
2960     secret_keylen = sftp_msg_read_int(p, data, data_len);
2961     secret_key = sftp_msg_read_data(p, data, data_len, secret_keylen);
2962     if (secret_key == NULL) {
2963       pr_trace_msg(trace_channel, 2,
2964         "error reading %s key: invalid/supported key format", pkey_type);
2965       errno = EINVAL;
2966       return -1;
2967     }
2968 
2969     /* The Ed25519 secret key is what we need to extract. */
2970     *key = secret_key;
2971     *keylen = secret_keylen;
2972 
2973   } else {
2974     *key = NULL;
2975     *keylen = 0;
2976   }
2977 
2978   return 0;
2979 }
2980 
2981 static int decrypt_openssh_private_key(pool *p, const char *path,
2982     unsigned char *encrypted_data, uint32_t encrypted_len,
2983     const char *passphrase, struct openssh_cipher *cipher,
2984     const char *kdf_name, unsigned char *kdf_data, uint32_t kdf_len,
2985     enum sftp_key_type_e *key_type, EVP_PKEY **pkey, unsigned char **key,
2986     uint32_t *keylen) {
2987   unsigned char *decrypted_data = NULL, *decrypted_ptr = NULL;
2988   uint32_t check_bytes[2], decrypted_len = 0, decrypted_sz = 0;
2989   char *comment = NULL;
2990   int res;
2991   unsigned int i = 0;
2992 
2993   res = decrypt_openssh_data(p, path, encrypted_data, encrypted_len, passphrase,
2994     cipher, kdf_name, kdf_data, kdf_len, &decrypted_data, &decrypted_len);
2995   if (res < 0) {
2996     pr_trace_msg(trace_channel, 6,
2997       "failed to decrypt '%s' using %s cipher: %s", path, cipher->algo,
2998       strerror(errno));
2999     errno = EINVAL;
3000     return -1;
3001   }
3002 
3003   pr_trace_msg(trace_channel, 14,
3004     "decrypted %lu bytes into %lu bytes", (unsigned long) encrypted_len,
3005     (unsigned long) decrypted_len);
3006 
3007   decrypted_ptr = decrypted_data;
3008   decrypted_sz = decrypted_len;
3009 
3010   check_bytes[0] = sftp_msg_read_int(p, &decrypted_data, &decrypted_len);
3011   check_bytes[1] = sftp_msg_read_int(p, &decrypted_data, &decrypted_len);
3012 
3013   if (check_bytes[0] != check_bytes[1]) {
3014     pr_trace_msg(trace_channel, 6,
3015       "'%s' has mismatched check bytes (%lu != %lu); wrong passphrase", path,
3016       (unsigned long) check_bytes[0], (unsigned long) check_bytes[1]);
3017     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3018       "unable to read hostkey '%s': wrong passphrase", path);
3019 
3020     pr_memscrub(decrypted_ptr, decrypted_sz);
3021     errno = EINVAL;
3022     return -1;
3023   }
3024 
3025   res = deserialize_openssh_private_key(p, path, &decrypted_data,
3026     &decrypted_len, key_type, pkey, key, keylen);
3027   if (res < 0) {
3028     int xerrno = errno;
3029 
3030     pr_memscrub(decrypted_ptr, decrypted_sz);
3031     errno = xerrno;
3032     return -1;
3033   }
3034 
3035   comment = sftp_msg_read_string(p, &decrypted_data, &decrypted_len);
3036   if (comment != NULL) {
3037     pr_trace_msg(trace_channel, 9,
3038       "'%s' comment: '%s'", path, comment);
3039   }
3040 
3041   /* Verify the expected remaining padding. */
3042   for (i = 1; decrypted_len > 0; i++) {
3043     char padding;
3044 
3045     pr_signals_handle();
3046 
3047     padding = sftp_msg_read_byte(p, &decrypted_data, &decrypted_len);
3048     if (padding != (i & 0xFF)) {
3049       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3050         "'%s' key has invalid padding", path);
3051       pr_memscrub(decrypted_ptr, decrypted_sz);
3052       errno = EINVAL;
3053       return -1;
3054     }
3055   }
3056 
3057   pr_memscrub(decrypted_ptr, decrypted_sz);
3058   return 0;
3059 }
3060 
3061 static int unwrap_openssh_private_key(pool *p, const char *path,
3062     unsigned char *text, size_t text_len, const char *passphrase,
3063     enum sftp_key_type_e *key_type, EVP_PKEY **pkey, unsigned char **key,
3064     uint32_t *keylen) {
3065   char *cipher_name, *kdf_name;
3066   unsigned char *buf, *data = NULL, *kdf_data, *encrypted_data;
3067   size_t data_len = 0, magicsz;
3068   uint32_t bufsz, buflen, kdf_len = 0, key_count = 0, encrypted_len = 0;
3069   struct openssh_cipher *cipher = NULL;
3070   int xerrno = 0;
3071 
3072   data = decode_base64(p, text, text_len, &data_len);
3073   xerrno = errno;
3074 
3075   if (data == NULL) {
3076     pr_trace_msg(trace_channel, 6,
3077       "error base64-decoding key '%s': %s", path, strerror(xerrno));
3078     errno = xerrno;
3079     return -1;
3080   }
3081 
3082   magicsz = sizeof(SFTP_OPENSSH_MAGIC);
3083   if (data_len < magicsz) {
3084     pr_trace_msg(trace_channel, 6,
3085       "'%s' key base64-decoded data too short (%lu bytes < %lu minimum "
3086       "required)", path, (unsigned long) data_len, (unsigned long) magicsz);
3087     errno = EINVAL;
3088     return -1;
3089   }
3090 
3091   if (memcmp(data, SFTP_OPENSSH_MAGIC, magicsz) != 0) {
3092     pr_trace_msg(trace_channel, 6,
3093       "'%s' key base64-decoded contains invalid magic value", path);
3094     errno = EINVAL;
3095     return -1;
3096   }
3097 
3098   data += magicsz;
3099   data_len -= magicsz;
3100 
3101   buf = data;
3102   bufsz = buflen = data_len;
3103 
3104   cipher_name = sftp_msg_read_string(p, &buf, &buflen);
3105   kdf_name = sftp_msg_read_string(p, &buf, &buflen);
3106 
3107   kdf_len = sftp_msg_read_int(p, &buf, &buflen);
3108   kdf_data = sftp_msg_read_data(p, &buf, &buflen, kdf_len);
3109   key_count = sftp_msg_read_int(p, &buf, &buflen);
3110 
3111   /* Ignore the public key */
3112   (void) sftp_msg_read_string(p, &buf, &buflen);
3113 
3114   encrypted_len = sftp_msg_read_int(p, &buf, &buflen);
3115 
3116   pr_trace_msg(trace_channel, 9,
3117     "'%s' key cipher = '%s', KDF = '%s' (%lu bytes KDF data), "
3118      "key count = %lu, (%lu bytes encrypted data)", path, cipher_name, kdf_name,
3119      (unsigned long) kdf_len, (unsigned long) key_count,
3120      (unsigned long) encrypted_len);
3121 
3122   cipher = get_openssh_cipher(cipher_name);
3123   if (cipher == NULL) {
3124     pr_trace_msg(trace_channel, 6,
3125       "'%s' key uses unexpected/unsupported cipher (%s)", path, cipher_name);
3126     errno = EPERM;
3127     return -1;
3128   }
3129 
3130   if ((passphrase == NULL ||
3131        strlen(passphrase) == 0) &&
3132       strcmp(cipher_name, "none") != 0) {
3133     pr_trace_msg(trace_channel, 6,
3134       "'%s' key requires passphrase for cipher (%s)", path, cipher_name);
3135     errno = EPERM;
3136     return -1;
3137   }
3138 
3139   /* We only support the "none" and "bcrypt" KDFs at present. */
3140   if (strcmp(kdf_name, "bcrypt") != 0 &&
3141       strcmp(kdf_name, "none") != 0) {
3142     pr_trace_msg(trace_channel, 6,
3143       "'%s' key encrypted using unsupported KDF '%s'", path, kdf_name);
3144     errno = EPERM;
3145     return -1;
3146   }
3147 
3148   /* If our KDF is "none" and our cipher is NOT "none", we have a problem. */
3149   if (strcmp(kdf_name, "none") == 0 &&
3150       strcmp(cipher_name, "none") != 0) {
3151     pr_trace_msg(trace_channel, 6,
3152       "'%s' key encrypted using mismatched KDF and cipher algorithms: "
3153       "KDF '%s', cipher '%s'", path, kdf_name, cipher_name);
3154     errno = EPERM;
3155     return -1;
3156   }
3157 
3158   /* OpenSSH only supports one key at present.  Huh. */
3159   if (key_count != 1) {
3160     pr_trace_msg(trace_channel, 6,
3161       "'%s' key includes unexpected/unsupported key count (%lu)",
3162       path, (unsigned long) key_count);
3163     errno = EPERM;
3164     return -1;
3165   }
3166 
3167   /* XXX Should we enforce that the KDF data be empty for the "none" KDF? */
3168   if (strcmp(kdf_name, "none") == 0 &&
3169       kdf_len > 0) {
3170     pr_trace_msg(trace_channel, 6,
3171       "'%s' key uses KDF 'none', but contains unexpected %lu bytes "
3172       "of KDF options", path, (unsigned long) kdf_len);
3173   }
3174 
3175   if (buflen < encrypted_len) {
3176     pr_trace_msg(trace_channel, 6,
3177       "'%s' key declares %lu bytes of encrypted data, but has "
3178       "only %lu bytes remaining", path, (unsigned long) encrypted_len,
3179       (unsigned long) buflen);
3180     errno = EPERM;
3181     return -1;
3182   }
3183 
3184   if (encrypted_len < cipher->blocksz ||
3185       (encrypted_len % cipher->blocksz) != 0) {
3186     pr_trace_msg(trace_channel, 6,
3187       "'%s' key declares %lu bytes of encrypted data, which is invalid for "
3188       "the %s cipher block size (%lu bytes)", path,
3189       (unsigned long) encrypted_len, cipher_name,
3190       (unsigned long) cipher->blocksz);
3191     errno = EPERM;
3192     return -1;
3193   }
3194 
3195   if (buflen < (encrypted_len + cipher->auth_len)) {
3196     pr_trace_msg(trace_channel, 6,
3197       "'%s' key declares %lu bytes of encrypted data and %lu bytes of auth "
3198       "data, but has only %lu bytes remaining", path,
3199       (unsigned long) encrypted_len, (unsigned long) cipher->auth_len,
3200       (unsigned long) buflen);
3201     errno = EPERM;
3202     return -1;
3203   }
3204 
3205   encrypted_data = sftp_msg_read_data(p, &buf, &buflen, encrypted_len);
3206 
3207 #if 0
3208   if (cipher->auth_len > 0) {
3209     /* Read (and ignore) any auth data (for AEAD ciphers). */
3210     (void) sftp_msg_read_data(p, &encrypted_data, &encrypted_len,
3211       cipher->auth_len);
3212   }
3213 
3214   /* We should have used all of the encrypted data, with none left over. */
3215   if (encrypted_len != 0) {
3216     pr_trace_msg(trace_channel, 3,
3217       "'%s' key provided too much data (%lu bytes remaining unexpectedly)",
3218       path, (unsigned long) encrypted_len);
3219     pr_memscrub(buf, buflen);
3220     errno = EINVAL;
3221     return -1;
3222   }
3223 #endif
3224 
3225   return decrypt_openssh_private_key(p, path, encrypted_data, encrypted_len,
3226     passphrase, cipher, kdf_name, kdf_data, kdf_len, key_type, pkey, key,
3227     keylen);
3228 }
3229 
3230 static int read_openssh_private_key(pool *p, const char *path, int fd,
3231     const char *passphrase, enum sftp_key_type_e *key_type, EVP_PKEY **pkey,
3232     unsigned char **key, uint32_t *keylen) {
3233   struct stat st;
3234   pool *tmp_pool;
3235   unsigned char *decoded_buf, *decoded_ptr, *input_buf, *input_ptr;
3236   unsigned char *tmp_key = NULL;
3237   int res, xerrno = 0;
3238   size_t decoded_len, input_len;
3239   off_t input_sz;
3240 
3241   if (p == NULL ||
3242       path == NULL ||
3243       fd < 0 ||
3244       key == NULL ||
3245       keylen == NULL) {
3246     errno = EINVAL;
3247     return -1;
3248   }
3249 
3250   if (fstat(fd, &st) < 0) {
3251     return -1;
3252   }
3253 
3254   tmp_pool = make_sub_pool(p);
3255 
3256   /* Read the entire file into memory. */
3257   /* TODO: Impose maximum size limit for this treatment? */
3258   input_sz = st.st_size;
3259   input_ptr = input_buf = palloc(tmp_pool, input_sz);
3260   input_len = 0;
3261 
3262   res = read(fd, input_buf, input_sz);
3263   xerrno = errno;
3264 
3265   while (res != 0) {
3266     pr_signals_handle();
3267 
3268     if (res < 0) {
3269       pr_log_debug(DEBUG0, MOD_SFTP_VERSION ": error reading '%s': %s",
3270         path, strerror(xerrno));
3271       destroy_pool(tmp_pool);
3272       errno = xerrno;
3273       return -1;
3274     }
3275 
3276     input_buf += res;
3277     input_len += res;
3278     input_sz -= res;
3279 
3280     res = read(fd, input_buf, input_sz);
3281     xerrno = errno;
3282   }
3283 
3284   input_buf = input_ptr;
3285 
3286   /* Now we read from the input buffer into a buffer for decoding, for use
3287    * in the unwrapping process.
3288    */
3289   decoded_ptr = decoded_buf = palloc(tmp_pool, input_len);
3290   decoded_len = 0;
3291 
3292   /* We know (due to the OpenSSH private key check) that the first bytes
3293    * match the expected start, and that the last bytes match the expected end.
3294    * So skip past them.
3295    */
3296   input_buf += SFTP_OPENSSH_BEGIN_LEN;
3297   input_len -= (SFTP_OPENSSH_BEGIN_LEN + SFTP_OPENSSH_END_LEN);
3298 
3299   while (input_len > 0) {
3300     char ch;
3301 
3302     pr_signals_handle();
3303 
3304     ch = *input_buf;
3305 
3306     /* Skip whitespace */
3307     if (ch != '\r' &&
3308         ch != '\n') {
3309       *decoded_buf++ = ch;
3310       decoded_len++;
3311     }
3312 
3313     input_buf++;
3314     input_len--;
3315   }
3316 
3317   res = unwrap_openssh_private_key(tmp_pool, path, decoded_ptr, decoded_len,
3318     passphrase, key_type, pkey, &tmp_key, keylen);
3319   xerrno = errno;
3320 
3321   if (res < 0) {
3322     destroy_pool(tmp_pool);
3323     errno = xerrno;
3324     return -1;
3325   }
3326 
3327   /* At this point, our unwrapped key is allocated out of the temporary pool.
3328    * We need to copy it to memory out of the longer-lived pool given to us.
3329    */
3330   if (*keylen > 0) {
3331     *key = palloc(p, *keylen);
3332     memcpy(*key, tmp_key, *keylen);
3333 
3334     pr_memscrub(tmp_key, *keylen);
3335   }
3336 
3337   destroy_pool(tmp_pool);
3338   return 0;
3339 }
3340 
3341 #ifdef PR_USE_SODIUM
3342 static int handle_ed25519_hostkey(pool *p, const unsigned char *key_data,
3343     uint32_t key_datalen, const char *file_path) {
3344   unsigned char *public_key;
3345 
3346   if (sftp_ed25519_hostkey != NULL) {
3347     /* If we have an existing ED25519 hostkey, free it up. */
3348     pr_memscrub(sftp_ed25519_hostkey->ed25519_secret_key,
3349       sftp_ed25519_hostkey->ed25519_secret_keylen);
3350     sftp_ed25519_hostkey->ed25519_secret_key = NULL;
3351     sftp_ed25519_hostkey->ed25519_secret_keylen = 0;
3352 
3353     pr_memscrub(sftp_ed25519_hostkey->ed25519_public_key,
3354       sftp_ed25519_hostkey->ed25519_public_keylen);
3355     sftp_ed25519_hostkey->ed25519_public_key = NULL;
3356     sftp_ed25519_hostkey->ed25519_public_keylen = 0;
3357 
3358     sftp_ed25519_hostkey->file_path = NULL;
3359     sftp_ed25519_hostkey->agent_path = NULL;
3360 
3361   } else {
3362     sftp_ed25519_hostkey = pcalloc(p, sizeof(struct sftp_hostkey));
3363   }
3364 
3365   sftp_ed25519_hostkey->key_type = SFTP_KEY_ED25519;
3366   sftp_ed25519_hostkey->ed25519_secret_key = (unsigned char *) key_data;
3367   sftp_ed25519_hostkey->ed25519_secret_keylen = key_datalen;
3368 
3369   /* Use the secret key to get the public key. */
3370   public_key = palloc(p, crypto_sign_ed25519_PUBLICKEYBYTES);
3371   if (crypto_sign_ed25519_sk_to_pk(public_key, key_data) != 0) {
3372     return -1;
3373   }
3374 
3375   sftp_ed25519_hostkey->ed25519_public_key = public_key;
3376   sftp_ed25519_hostkey->ed25519_public_keylen = crypto_sign_ed25519_PUBLICKEYBYTES;
3377 
3378   sftp_ed25519_hostkey->file_path = file_path;
3379   pr_trace_msg(trace_channel, 4, "using '%s' as Ed25519 hostkey", file_path);
3380 
3381   return 0;
3382 }
3383 #endif /* PR_USE_SODIUM */
3384 
3385 static int load_openssh_hostkey(pool *p, const char *path, int fd) {
3386   const char *passphrase = NULL;
3387   enum sftp_key_type_e key_type = SFTP_KEY_UNKNOWN;
3388   EVP_PKEY *pkey = NULL;
3389   unsigned char *key = NULL;
3390   uint32_t keylen = 0;
3391   int res;
3392 
3393   if (server_pkey != NULL) {
3394     passphrase = server_pkey->host_pkey;
3395   }
3396 
3397   res = read_openssh_private_key(p, path, fd, passphrase, &key_type, &pkey,
3398     &key, &keylen);
3399   if (res < 0) {
3400     return -1;
3401   }
3402 
3403   switch (key_type) {
3404 #ifdef PR_USE_SODIUM
3405     case SFTP_KEY_ED25519:
3406       res = handle_ed25519_hostkey(p, key, keylen, path);
3407       break;
3408 #endif /* PR_USE_SODIUM */
3409 
3410     default:
3411       res = handle_hostkey(p, pkey, NULL, 0, path, NULL);
3412       break;
3413   }
3414 
3415   return res;
3416 }
3417 
3418 static int load_file_hostkey(pool *p, const char *path) {
3419   int fd, xerrno = 0, openssh_format = FALSE, public_key_format = FALSE;
3420   FILE *fp;
3421   EVP_PKEY *pkey;
3422 
3423   pr_signals_block();
3424   PRIVS_ROOT
3425 
3426   /* XXX Would we ever want to allow host keys to be read from FIFOs?  If
3427    * so, we would need to include the O_NONBLOCK flag here.
3428    */
3429   fd = open(path, O_RDONLY, 0);
3430   xerrno = errno;
3431   PRIVS_RELINQUISH
3432   pr_signals_unblock();
3433 
3434   if (fd < 0) {
3435     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3436       "error reading '%s': %s", path, strerror(xerrno));
3437     errno = xerrno;
3438     return -1;
3439   }
3440 
3441   if (has_req_perms(fd, path) < 0) {
3442     xerrno = errno;
3443 
3444     if (xerrno == EACCES) {
3445       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3446         "'%s' is accessible by group or world, which is not allowed", path);
3447 
3448     } else {
3449       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3450         "error checking '%s' perms: %s", path, strerror(xerrno));
3451     }
3452 
3453     (void) close(fd);
3454     errno = xerrno;
3455     return -1;
3456   }
3457 
3458   if (server_pkey == NULL) {
3459     server_pkey = lookup_pkey();
3460   }
3461 
3462   /* Make sure this is not a public key inadvertently configured as a hostkey.
3463    */
3464   public_key_format = is_public_key(fd);
3465   if (public_key_format == TRUE) {
3466     pr_trace_msg(trace_channel, 3, "hostkey file '%s' uses a public key format",
3467       path);
3468     (void) pr_log_pri(PR_LOG_WARNING, MOD_SFTP_VERSION
3469       ": unable to use public key '%s' for SFTPHostKey", path);
3470     (void) close(fd);
3471     errno = EINVAL;
3472     return -1;
3473   }
3474 
3475   /* If this happens to be in the OpenSSH private key format, handle it
3476    * separately.
3477    */
3478   openssh_format = is_openssh_private_key(fd);
3479   if (openssh_format == TRUE) {
3480     int res;
3481 
3482     pr_trace_msg(trace_channel, 9, "hostkey file '%s' uses OpenSSH key format",
3483       path);
3484 
3485     res = load_openssh_hostkey(p, path, fd);
3486     xerrno = errno;
3487 
3488     (void) close(fd);
3489     errno = xerrno;
3490     return res;
3491   }
3492 
3493   /* OpenSSL's APIs prefer stdio file handles. */
3494   fp = fdopen(fd, "r");
3495   if (fp == NULL) {
3496     xerrno = errno;
3497 
3498     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3499       "error opening stdio handle on fd %d: %s", fd, strerror(xerrno));
3500     (void) close(fd);
3501 
3502     errno = xerrno;
3503     return -1;
3504   }
3505 
3506   /* As the file contains sensitive data, we do not want it lingering
3507    * around in stdio buffers.
3508    */
3509   (void) setvbuf(fp, NULL, _IONBF, 0);
3510 
3511   if (server_pkey != NULL) {
3512     pkey = PEM_read_PrivateKey(fp, NULL, pkey_cb, (void *) server_pkey);
3513 
3514   } else {
3515     /* Assume that the key is not passphrase-protected. */
3516     pkey = PEM_read_PrivateKey(fp, NULL, NULL, "");
3517   }
3518 
3519   fclose(fp);
3520 
3521   if (pkey == NULL) {
3522     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3523       "error reading private key from '%s': %s", path,
3524       sftp_crypto_get_errors());
3525     return -1;
3526   }
3527 
3528   return handle_hostkey(p, pkey, NULL, 0, path, NULL);
3529 }
3530 
3531 int sftp_keys_get_hostkey(pool *p, const char *path) {
3532   int res;
3533 
3534   /* Check whether we are to load keys from a file on disk, or from an
3535    * SSH agent.
3536    */
3537   if (strncmp(path, "agent:", 6) != 0) {
3538     pr_trace_msg(trace_channel, 9,  "loading host key from file '%s'", path);
3539     res = load_file_hostkey(p, path);
3540 
3541   } else {
3542     const char *agent_path;
3543 
3544     /* Skip past the "agent:" prefix. */
3545     agent_path = (path + 6);
3546 
3547     pr_trace_msg(trace_channel, 9,  "loading host keys from SSH agent at '%s'",
3548       agent_path);
3549     res = load_agent_hostkeys(p, agent_path);
3550   }
3551 
3552   return res;
3553 }
3554 
3555 static int get_rsa_hostkey_data(pool *p, unsigned char **buf,
3556     unsigned char **ptr, uint32_t *buflen) {
3557   RSA *rsa;
3558   BIGNUM *rsa_n = NULL, *rsa_e = NULL;
3559 
3560   rsa = EVP_PKEY_get1_RSA(sftp_rsa_hostkey->pkey);
3561   if (rsa == NULL) {
3562     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3563       "error using RSA hostkey: %s", sftp_crypto_get_errors());
3564     return -1;
3565   }
3566 
3567   /* XXX Is this buffer large enough?  Too large? */
3568   *ptr = *buf = palloc(p, *buflen);
3569   sftp_msg_write_string(buf, buflen, "ssh-rsa");
3570 
3571 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
3572     !defined(HAVE_LIBRESSL)
3573   RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
3574 #else
3575   rsa_e = rsa->e;
3576   rsa_n = rsa->n;
3577 #endif /* prior to OpenSSL-1.1.0 */
3578   sftp_msg_write_mpint(buf, buflen, rsa_e);
3579   sftp_msg_write_mpint(buf, buflen, rsa_n);
3580 
3581   RSA_free(rsa);
3582   return 0;
3583 }
3584 
3585 #if !defined(OPENSSL_NO_DSA)
3586 static int get_dsa_hostkey_data(pool *p, unsigned char **buf,
3587     unsigned char **ptr, uint32_t *buflen) {
3588   DSA *dsa;
3589   BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL;
3590 
3591   dsa = EVP_PKEY_get1_DSA(sftp_dsa_hostkey->pkey);
3592   if (dsa == NULL) {
3593     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3594       "error using DSA hostkey: %s", sftp_crypto_get_errors());
3595     return -1;
3596   }
3597 
3598   /* XXX Is this buffer large enough?  Too large? */
3599   *ptr = *buf = palloc(p, *buflen);
3600   sftp_msg_write_string(buf, buflen, "ssh-dss");
3601 
3602 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
3603     !defined(HAVE_LIBRESSL)
3604   DSA_get0_pqg(dsa, &dsa_p, &dsa_q, &dsa_g);
3605   DSA_get0_key(dsa, &dsa_pub_key, NULL);
3606 #else
3607   dsa_p = dsa->p;
3608   dsa_q = dsa->q;
3609   dsa_g = dsa->g;
3610   dsa_pub_key = dsa->pub_key;;
3611 #endif /* prior to OpenSSL-1.1.0 */
3612   sftp_msg_write_mpint(buf, buflen, dsa_p);
3613   sftp_msg_write_mpint(buf, buflen, dsa_q);
3614   sftp_msg_write_mpint(buf, buflen, dsa_g);
3615   sftp_msg_write_mpint(buf, buflen, dsa_pub_key);
3616 
3617   DSA_free(dsa);
3618   return 0;
3619 }
3620 #endif /* !OPENSSL_NO_DSA */
3621 
3622 #ifdef PR_USE_OPENSSL_ECC
3623 static int get_ecdsa_hostkey_data(pool *p, struct sftp_hostkey *hostkey,
3624     const char *algo, const char *curve, unsigned char **buf,
3625     unsigned char **ptr, uint32_t *buflen) {
3626   EC_KEY *ec;
3627 
3628   ec = EVP_PKEY_get1_EC_KEY(hostkey->pkey);
3629   if (ec == NULL) {
3630     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3631       "error using %s hostkey: %s", algo, sftp_crypto_get_errors());
3632     return -1;
3633   }
3634 
3635   /* XXX Is this buffer large enough?  Too large? */
3636   *ptr = *buf = palloc(p, *buflen);
3637   sftp_msg_write_string(buf, buflen, algo);
3638   sftp_msg_write_string(buf, buflen, curve);
3639   sftp_msg_write_ecpoint(buf, buflen, EC_KEY_get0_group(ec),
3640     EC_KEY_get0_public_key(ec));
3641 
3642   EC_KEY_free(ec);
3643   return 0;
3644 }
3645 #endif /* PR_USE_OPENSSL_ECC */
3646 
3647 #ifdef PR_USE_SODIUM
3648 static int get_ed25519_hostkey_data(pool *p, unsigned char **buf,
3649     unsigned char **ptr, uint32_t *buflen) {
3650 
3651   /* XXX Is this buffer large enough?  Too large? */
3652   *ptr = *buf = palloc(p, *buflen);
3653   sftp_msg_write_string(buf, buflen, "ssh-ed25519");
3654   sftp_msg_write_data(buf, buflen, sftp_ed25519_hostkey->ed25519_public_key,
3655     sftp_ed25519_hostkey->ed25519_public_keylen, TRUE);
3656 
3657   return 0;
3658 }
3659 #endif /* PR_USE_SODIUM */
3660 
3661 const unsigned char *sftp_keys_get_hostkey_data(pool *p,
3662     enum sftp_key_type_e key_type, uint32_t *datalen) {
3663   unsigned char *buf = NULL, *ptr = NULL;
3664   uint32_t buflen = SFTP_DEFAULT_HOSTKEY_SZ;
3665   int res;
3666 
3667   switch (key_type) {
3668     case SFTP_KEY_RSA:
3669     case SFTP_KEY_RSA_SHA256:
3670     case SFTP_KEY_RSA_SHA512: {
3671       res = get_rsa_hostkey_data(p, &buf, &ptr, &buflen);
3672       if (res < 0) {
3673         return NULL;
3674       }
3675 
3676       break;
3677     }
3678 
3679 #if !defined(OPENSSL_NO_DSA)
3680     case SFTP_KEY_DSA: {
3681       res = get_dsa_hostkey_data(p, &buf, &ptr, &buflen);
3682       if (res < 0) {
3683         return NULL;
3684       }
3685 
3686       break;
3687     }
3688 #endif /* !OPENSSL_NO_DSA */
3689 
3690 #ifdef PR_USE_OPENSSL_ECC
3691     case SFTP_KEY_ECDSA_256: {
3692       res = get_ecdsa_hostkey_data(p, sftp_ecdsa256_hostkey,
3693         "ecdsa-sha2-nistp256", "nistp256", &buf, &ptr, &buflen);
3694       if (res < 0) {
3695         return NULL;
3696       }
3697 
3698       break;
3699     }
3700 
3701     case SFTP_KEY_ECDSA_384: {
3702       res = get_ecdsa_hostkey_data(p, sftp_ecdsa384_hostkey,
3703         "ecdsa-sha2-nistp384", "nistp384", &buf, &ptr, &buflen);
3704       if (res < 0) {
3705         return NULL;
3706       }
3707 
3708       break;
3709     }
3710 
3711     case SFTP_KEY_ECDSA_521: {
3712       res = get_ecdsa_hostkey_data(p, sftp_ecdsa521_hostkey,
3713         "ecdsa-sha2-nistp521", "nistp521", &buf, &ptr, &buflen);
3714       if (res < 0) {
3715         return NULL;
3716       }
3717 
3718       break;
3719     }
3720 #endif /* PR_USE_OPENSSL_ECC */
3721 
3722 #ifdef PR_USE_SODIUM
3723     case SFTP_KEY_ED25519: {
3724       res = get_ed25519_hostkey_data(p, &buf, &ptr, &buflen);
3725       if (res < 0) {
3726         return NULL;
3727       }
3728 
3729       break;
3730     }
3731 #endif /* PR_USE_SODIUM */
3732 
3733     default:
3734       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3735         "unknown/unsupported key type (%d) requested, ignoring", key_type);
3736       return NULL;
3737   }
3738 
3739   *datalen = SFTP_DEFAULT_HOSTKEY_SZ - buflen;
3740 
3741   /* If the caller provided a pool, make a copy of the data from the
3742    * given pool, and return the copy.  Make sure to scrub the original
3743    * after making the copy.
3744    *
3745    * Note that we do this copy, even though we use the given pool, since
3746    * we only know the actual size of the data after the fact.  And we need
3747    * to provide the size of the data to the caller, NOT the optimistic size
3748    * we allocate out of the pool for writing the data in the first place.
3749    * Hence the copy.
3750    */
3751   buf = palloc(p, *datalen);
3752   memcpy(buf, ptr, *datalen);
3753 
3754   pr_memscrub(ptr, *datalen);
3755   return buf;
3756 }
3757 
3758 int sftp_keys_clear_dsa_hostkey(void) {
3759   if (sftp_dsa_hostkey == NULL) {
3760     errno = ENOENT;
3761     return -1;
3762   }
3763 
3764   if (sftp_dsa_hostkey->pkey != NULL) {
3765     EVP_PKEY_free(sftp_dsa_hostkey->pkey);
3766   }
3767 
3768   sftp_dsa_hostkey = NULL;
3769   return 0;
3770 }
3771 
3772 int sftp_keys_clear_ecdsa_hostkey(void) {
3773 #ifdef PR_USE_OPENSSL_ECC
3774   int count = 0;
3775 
3776   if (sftp_ecdsa256_hostkey != NULL) {
3777     if (sftp_ecdsa256_hostkey->pkey != NULL) {
3778       EVP_PKEY_free(sftp_ecdsa256_hostkey->pkey);
3779     }
3780 
3781     sftp_ecdsa256_hostkey = NULL;
3782     count++;
3783   }
3784 
3785   if (sftp_ecdsa384_hostkey != NULL) {
3786     if (sftp_ecdsa384_hostkey->pkey != NULL) {
3787       EVP_PKEY_free(sftp_ecdsa384_hostkey->pkey);
3788     }
3789 
3790     sftp_ecdsa384_hostkey = NULL;
3791     count++;
3792   }
3793 
3794   if (sftp_ecdsa521_hostkey != NULL) {
3795     if (sftp_ecdsa521_hostkey->pkey != NULL) {
3796       EVP_PKEY_free(sftp_ecdsa521_hostkey->pkey);
3797     }
3798 
3799     sftp_ecdsa521_hostkey = NULL;
3800     count++;
3801   }
3802 
3803   if (count > 0) {
3804     return 0;
3805   }
3806 
3807 #endif /* PR_USE_OPENSSL_ECC */
3808   errno = ENOENT;
3809   return -1;
3810 }
3811 
3812 int sftp_keys_clear_ed25519_hostkey(void) {
3813   if (sftp_ed25519_hostkey == NULL) {
3814     errno = ENOENT;
3815     return -1;
3816   }
3817 
3818   if (sftp_ed25519_hostkey->ed25519_secret_key != NULL) {
3819     pr_memscrub(sftp_ed25519_hostkey->ed25519_secret_key,
3820       sftp_ed25519_hostkey->ed25519_secret_keylen);
3821     sftp_ed25519_hostkey->ed25519_secret_key = NULL;
3822     sftp_ed25519_hostkey->ed25519_secret_keylen = 0;
3823   }
3824 
3825   if (sftp_ed25519_hostkey->ed25519_public_key != NULL) {
3826     pr_memscrub(sftp_ed25519_hostkey->ed25519_public_key,
3827       sftp_ed25519_hostkey->ed25519_public_keylen);
3828     sftp_ed25519_hostkey->ed25519_public_key = NULL;
3829     sftp_ed25519_hostkey->ed25519_public_keylen = 0;
3830   }
3831 
3832   return 0;
3833 }
3834 
3835 int sftp_keys_clear_rsa_hostkey(void) {
3836   if (sftp_rsa_hostkey == NULL) {
3837     errno = ENOENT;
3838     return -1;
3839   }
3840 
3841   if (sftp_rsa_hostkey->pkey != NULL) {
3842     EVP_PKEY_free(sftp_rsa_hostkey->pkey);
3843   }
3844 
3845   sftp_rsa_hostkey = NULL;
3846   return 0;
3847 }
3848 
3849 int sftp_keys_have_dsa_hostkey(void) {
3850   if (sftp_dsa_hostkey == NULL) {
3851     errno = ENOENT;
3852     return -1;
3853   }
3854 
3855   return 0;
3856 }
3857 
3858 /* Returns the count of returned NIDs for the configured ECDSA hostkeys,
3859  * if any.
3860  */
3861 int sftp_keys_have_ecdsa_hostkey(pool *p, int **nids) {
3862 #ifdef PR_USE_OPENSSL_ECC
3863   int count = 0;
3864 
3865   if (nids != NULL) {
3866     *nids = palloc(p, sizeof(int) * 3);
3867   }
3868 
3869   if (sftp_ecdsa256_hostkey != NULL) {
3870     EC_KEY *ec;
3871 
3872     ec = EVP_PKEY_get1_EC_KEY(sftp_ecdsa256_hostkey->pkey);
3873     if (nids != NULL) {
3874       (*nids)[count] = get_ecdsa_nid(ec);
3875     }
3876     count++;
3877     EC_KEY_free(ec);
3878 
3879   } else if (sftp_ecdsa384_hostkey != NULL) {
3880     EC_KEY *ec;
3881 
3882     ec = EVP_PKEY_get1_EC_KEY(sftp_ecdsa384_hostkey->pkey);
3883     if (nids != NULL) {
3884       (*nids)[count] = get_ecdsa_nid(ec);
3885     }
3886     count++;
3887     EC_KEY_free(ec);
3888 
3889   } else if (sftp_ecdsa521_hostkey != NULL) {
3890     EC_KEY *ec;
3891 
3892     ec = EVP_PKEY_get1_EC_KEY(sftp_ecdsa521_hostkey->pkey);
3893     if (nids != NULL) {
3894       (*nids)[count] = get_ecdsa_nid(ec);
3895     }
3896     count++;
3897     EC_KEY_free(ec);
3898   }
3899 
3900   if (count > 0) {
3901     return count;
3902   }
3903 #endif /* PR_USE_OPENSSL_ECC */
3904 
3905   errno = ENOENT;
3906   return -1;
3907 }
3908 
3909 int sftp_keys_have_ed25519_hostkey(void) {
3910   if (sftp_ed25519_hostkey == NULL) {
3911     errno = ENOENT;
3912     return -1;
3913   }
3914 
3915   return 0;
3916 }
3917 
3918 int sftp_keys_have_rsa_hostkey(void) {
3919   if (sftp_rsa_hostkey == NULL) {
3920     errno = ENOENT;
3921     return -1;
3922   }
3923 
3924   return 0;
3925 }
3926 
3927 static const unsigned char *agent_sign_data(pool *p, const char *agent_path,
3928     const unsigned char *key_data, uint32_t key_datalen,
3929     const unsigned char *data, size_t datalen, size_t *siglen, int flags) {
3930   unsigned char *sig_data;
3931   uint32_t sig_datalen = 0;
3932 
3933   pr_trace_msg(trace_channel, 15,
3934     "asking SSH agent at '%s' to sign data", agent_path);
3935 
3936   /* Ask the agent to sign the data for this hostkey for us. */
3937   sig_data = (unsigned char *) sftp_agent_sign_data(p, agent_path,
3938     key_data, key_datalen, data, datalen, &sig_datalen, flags);
3939 
3940   if (sig_data == NULL) {
3941     int xerrno = errno;
3942 
3943     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3944       "SSH agent at '%s' could not sign data: %s", agent_path,
3945       strerror(xerrno));
3946 
3947     errno = xerrno;
3948     return NULL;
3949   }
3950 
3951   /* The SSH agent already provides the signed data in the correct
3952    * SSH2-style.
3953    */
3954 
3955   *siglen = sig_datalen;
3956   return sig_data;
3957 }
3958 
3959 static const unsigned char *get_rsa_signed_data(pool *p,
3960     const unsigned char *data, size_t datalen, size_t *siglen,
3961     const char *sig_name, const EVP_MD *md) {
3962   RSA *rsa;
3963 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
3964     defined(HAVE_LIBRESSL)
3965   EVP_MD_CTX ctx;
3966 #endif /* prior to OpenSSL-1.1.0 */
3967   EVP_MD_CTX *pctx;
3968   unsigned char dgst[EVP_MAX_MD_SIZE], *sig_data;
3969   unsigned char *buf, *ptr;
3970   size_t bufsz;
3971   uint32_t buflen, dgstlen = 0, sig_datalen = 0, sig_rsalen = 0;
3972   int res;
3973 
3974   rsa = EVP_PKEY_get1_RSA(sftp_rsa_hostkey->pkey);
3975   if (rsa == NULL) {
3976     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3977       "error using RSA hostkey: %s", sftp_crypto_get_errors());
3978     return NULL;
3979   }
3980 
3981   if (keys_rsa_min_nbits > 0) {
3982     int rsa_nbits;
3983 
3984     rsa_nbits = RSA_size(rsa) * 8;
3985     if (rsa_nbits < keys_rsa_min_nbits) {
3986       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
3987         "RSA hostkey size (%d bits) less than required minimum (%d bits)",
3988         rsa_nbits, keys_rsa_min_nbits);
3989       RSA_free(rsa);
3990 
3991       errno = EINVAL;
3992       return NULL;
3993     }
3994   }
3995 
3996 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
3997     !defined(HAVE_LIBRESSL)
3998   pctx = EVP_MD_CTX_new();
3999 #else
4000   pctx = &ctx;
4001 #endif /* prior to OpenSSL-1.1.0 */
4002 
4003   EVP_DigestInit(pctx, md);
4004   EVP_DigestUpdate(pctx, data, datalen);
4005   EVP_DigestFinal(pctx, dgst, &dgstlen);
4006 
4007 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4008     !defined(HAVE_LIBRESSL)
4009   EVP_MD_CTX_free(pctx);
4010 #endif /* OpenSSL-1.1.0 and later */
4011 
4012   sig_rsalen = RSA_size(rsa);
4013   sig_data = pcalloc(p, sig_rsalen);
4014   res = RSA_sign(EVP_MD_type(md), dgst, dgstlen, sig_data, &sig_datalen, rsa);
4015 
4016   /* Regardless of whether the RSA signing succeeds or fails, we are done
4017    * with the digest buffer.
4018    */
4019   pr_memscrub(dgst, dgstlen);
4020 
4021   if (res != 1) {
4022     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4023       "error signing data using RSA: %s", sftp_crypto_get_errors());
4024     RSA_free(rsa);
4025     return NULL;
4026   }
4027 
4028   /* XXX Is this buffer large enough?  Too large? */
4029   buflen = bufsz = SFTP_MAX_SIG_SZ;
4030   ptr = buf = sftp_msg_getbuf(p, bufsz);
4031 
4032   /* Now build up the signature, SSH2-style */
4033   sftp_msg_write_string(&buf, &buflen, sig_name);
4034   sftp_msg_write_data(&buf, &buflen, sig_data, sig_datalen, TRUE);
4035 
4036   pr_memscrub(sig_data, sig_datalen);
4037   RSA_free(rsa);
4038 
4039   /* At this point, buflen is the amount remaining in the allocated buffer.
4040    * So the total length of the signed data is the buffer size, minus those
4041    * remaining unused bytes.
4042    */
4043   *siglen = (bufsz - buflen);
4044   return ptr;
4045 }
4046 
4047 static const unsigned char *rsa_sign_data(pool *p, const unsigned char *data,
4048     size_t datalen, size_t *siglen) {
4049   if (sftp_rsa_hostkey->agent_path != NULL) {
4050     return agent_sign_data(p, sftp_rsa_hostkey->agent_path,
4051       sftp_rsa_hostkey->key_data, sftp_rsa_hostkey->key_datalen, data, datalen,
4052       siglen, 0);
4053   }
4054 
4055   return get_rsa_signed_data(p, data, datalen, siglen, "ssh-rsa", EVP_sha1());
4056 }
4057 
4058 #if defined(HAVE_SHA256_OPENSSL)
4059 static const unsigned char *rsa_sha256_sign_data(pool *p,
4060     const unsigned char *data, size_t datalen, size_t *siglen) {
4061   if (sftp_rsa_hostkey->agent_path != NULL) {
4062     return agent_sign_data(p, sftp_rsa_hostkey->agent_path,
4063       sftp_rsa_hostkey->key_data, sftp_rsa_hostkey->key_datalen, data, datalen,
4064       siglen, SFTP_AGENT_SIGN_FL_USE_RSA_SHA256);
4065   }
4066 
4067   return get_rsa_signed_data(p, data, datalen, siglen, "rsa-sha2-256",
4068     EVP_sha256());
4069 }
4070 #endif /* HAVE_SHA256_OPENSSL */
4071 
4072 #if defined(HAVE_SHA512_OPENSSL)
4073 static const unsigned char *rsa_sha512_sign_data(pool *p,
4074     const unsigned char *data, size_t datalen, size_t *siglen) {
4075   if (sftp_rsa_hostkey->agent_path != NULL) {
4076     return agent_sign_data(p, sftp_rsa_hostkey->agent_path,
4077       sftp_rsa_hostkey->key_data, sftp_rsa_hostkey->key_datalen, data, datalen,
4078       siglen, SFTP_AGENT_SIGN_FL_USE_RSA_SHA512);
4079   }
4080 
4081   return get_rsa_signed_data(p, data, datalen, siglen, "rsa-sha2-512",
4082     EVP_sha512());
4083 }
4084 #endif /* HAVE_SHA256_OPENSSL */
4085 
4086 /* RFC 4253, Section 6.6, is quite specific about the length of a DSA
4087  * ("ssh-dss") signature blob.  It is comprised of two integers R and S,
4088  * each 160 bits (20 bytes), so that the total signature blob is 40 bytes
4089  * long.
4090  */
4091 #define SFTP_DSA_INTEGER_LEN			20
4092 #define SFTP_DSA_SIGNATURE_LEN			(SFTP_DSA_INTEGER_LEN * 2)
4093 
4094 #if !defined(OPENSSL_NO_DSA)
4095 static const unsigned char *dsa_sign_data(pool *p, const unsigned char *data,
4096     size_t datalen, size_t *siglen) {
4097   DSA *dsa;
4098   DSA_SIG *sig;
4099   BIGNUM *sig_r = NULL, *sig_s = NULL;
4100 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
4101     defined(HAVE_LIBRESSL)
4102   EVP_MD_CTX ctx;
4103 #endif /* prior to OpenSSL-1.1.0 */
4104   EVP_MD_CTX *pctx;
4105   const EVP_MD *sha1 = EVP_sha1();
4106   unsigned char dgst[EVP_MAX_MD_SIZE], *sig_data;
4107   unsigned char *buf, *ptr;
4108   size_t bufsz;
4109   uint32_t buflen, dgstlen = 0;
4110   unsigned int rlen = 0, slen = 0;
4111 
4112   if (sftp_dsa_hostkey->agent_path != NULL) {
4113     return agent_sign_data(p, sftp_dsa_hostkey->agent_path,
4114       sftp_dsa_hostkey->key_data, sftp_dsa_hostkey->key_datalen, data, datalen,
4115       siglen, 0);
4116   }
4117 
4118   dsa = EVP_PKEY_get1_DSA(sftp_dsa_hostkey->pkey);
4119   if (dsa == NULL) {
4120     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4121       "error using DSA hostkey: %s", sftp_crypto_get_errors());
4122     return NULL;
4123   }
4124 
4125   if (keys_dsa_min_nbits > 0) {
4126     int dsa_nbits;
4127 
4128     dsa_nbits = DSA_size(dsa) * 8;
4129     if (dsa_nbits < keys_dsa_min_nbits) {
4130       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4131         "DSA hostkey size (%d bits) less than required minimum (%d bits)",
4132         dsa_nbits, keys_dsa_min_nbits);
4133       DSA_free(dsa);
4134 
4135       errno = EINVAL;
4136       return NULL;
4137     }
4138   }
4139 
4140 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4141     !defined(HAVE_LIBRESSL)
4142   pctx = EVP_MD_CTX_new();
4143 #else
4144   pctx = &ctx;
4145 #endif /* prior to OpenSSL-1.1.0 */
4146 
4147   EVP_DigestInit(pctx, sha1);
4148   EVP_DigestUpdate(pctx, data, datalen);
4149   EVP_DigestFinal(pctx, dgst, &dgstlen);
4150 
4151 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4152     !defined(HAVE_LIBRESSL)
4153   EVP_MD_CTX_free(pctx);
4154 #endif /* OpenSSL-1.1.0 and later */
4155 
4156   sig = DSA_do_sign(dgst, dgstlen, dsa);
4157   if (sig == NULL) {
4158     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4159       "error obtaining DSA signature: %s", sftp_crypto_get_errors());
4160     pr_memscrub(dgst, dgstlen);
4161     DSA_free(dsa);
4162     return NULL;
4163   }
4164 
4165   /* Got the signature, no need for the digest memory. */
4166   pr_memscrub(dgst, dgstlen);
4167 
4168 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4169     !defined(HAVE_LIBRESSL)
4170   DSA_SIG_get0(sig, &sig_r, &sig_s);
4171 #else
4172   sig_r = sig->r;
4173   sig_s = sig->s;
4174 #endif /* prior to OpenSSL-1.1.0 */
4175 
4176   rlen = BN_num_bytes(sig_r);
4177   slen = BN_num_bytes(sig_s);
4178 
4179   /* Make sure the values of R and S are big enough. */
4180   if (rlen > SFTP_DSA_INTEGER_LEN ||
4181       slen > SFTP_DSA_INTEGER_LEN) {
4182     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4183       "bad DSA signature size (%u, %u)", rlen, slen);
4184     DSA_SIG_free(sig);
4185     DSA_free(dsa);
4186     return NULL;
4187   }
4188 
4189   sig_data = pcalloc(p, SFTP_MAX_SIG_SZ);
4190 
4191   /* These may look strange, but the pointer arithmetic is necessary to
4192    * ensure the correct placement of the R and S values in the signature,
4193    * per RFC 4253 Section 6.6 requirements.
4194    */
4195   BN_bn2bin(sig_r,
4196     sig_data + SFTP_DSA_SIGNATURE_LEN - SFTP_DSA_INTEGER_LEN - rlen);
4197   BN_bn2bin(sig_s, sig_data + SFTP_DSA_SIGNATURE_LEN - slen);
4198 
4199   /* Done with the signature. */
4200   DSA_SIG_free(sig);
4201   DSA_free(dsa);
4202 
4203   /* XXX Is this buffer large enough?  Too large? */
4204   buflen = bufsz = SFTP_MAX_SIG_SZ;
4205   ptr = buf = sftp_msg_getbuf(p, bufsz);
4206 
4207   /* Now build up the signature, SSH2-style */
4208   sftp_msg_write_string(&buf, &buflen, "ssh-dss");
4209   sftp_msg_write_data(&buf, &buflen, sig_data, SFTP_DSA_SIGNATURE_LEN, TRUE);
4210 
4211   /* At this point, buflen is the amount remaining in the allocated buffer.
4212    * So the total length of the signed data is the buffer size, minus those
4213    * remaining unused bytes.
4214    */
4215   *siglen = (bufsz - buflen);
4216   return ptr;
4217 }
4218 #endif /* !OPENSSL_NO_DSA */
4219 
4220 #ifdef PR_USE_OPENSSL_ECC
4221 static const unsigned char *ecdsa_sign_data(pool *p, const unsigned char *data,
4222     size_t datalen, size_t *siglen, int nid) {
4223   EVP_PKEY *pkey = NULL;
4224   EC_KEY *ec = NULL;
4225   ECDSA_SIG *sig;
4226   BIGNUM *sig_r = NULL, *sig_s = NULL;
4227 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
4228     defined(HAVE_LIBRESSL)
4229   EVP_MD_CTX ctx;
4230 #endif /* prior to OpenSSL-1.1.0 */
4231   EVP_MD_CTX *pctx;
4232   const EVP_MD *md;
4233   unsigned char dgst[EVP_MAX_MD_SIZE];
4234   unsigned char *buf, *ptr, *sig_buf, *sig_ptr;
4235   uint32_t bufsz, buflen, dgstlen = 0, sig_buflen, sig_bufsz;
4236 
4237   switch (nid) {
4238     case NID_X9_62_prime256v1:
4239       if (sftp_ecdsa256_hostkey->agent_path != NULL) {
4240         return agent_sign_data(p, sftp_ecdsa256_hostkey->agent_path,
4241           sftp_ecdsa256_hostkey->key_data, sftp_ecdsa256_hostkey->key_datalen,
4242           data, datalen, siglen, 0);
4243       }
4244 
4245       ec = EVP_PKEY_get1_EC_KEY(sftp_ecdsa256_hostkey->pkey);
4246       if (ec == NULL) {
4247         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4248           "error using ECDSA-256 hostkey: %s", sftp_crypto_get_errors());
4249         return NULL;
4250       }
4251 
4252       pkey = sftp_ecdsa256_hostkey->pkey;
4253       md = EVP_sha256();
4254       break;
4255 
4256     case NID_secp384r1:
4257       if (sftp_ecdsa384_hostkey->agent_path != NULL) {
4258         return agent_sign_data(p, sftp_ecdsa384_hostkey->agent_path,
4259           sftp_ecdsa384_hostkey->key_data, sftp_ecdsa384_hostkey->key_datalen,
4260           data, datalen, siglen, 0);
4261       }
4262 
4263       ec = EVP_PKEY_get1_EC_KEY(sftp_ecdsa384_hostkey->pkey);
4264       if (ec == NULL) {
4265         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4266           "error using ECDSA-384 hostkey: %s", sftp_crypto_get_errors());
4267         return NULL;
4268       }
4269 
4270       pkey = sftp_ecdsa384_hostkey->pkey;
4271       md = EVP_sha384();
4272       break;
4273 
4274     case NID_secp521r1:
4275       if (sftp_ecdsa521_hostkey->agent_path != NULL) {
4276         return agent_sign_data(p, sftp_ecdsa521_hostkey->agent_path,
4277           sftp_ecdsa521_hostkey->key_data, sftp_ecdsa521_hostkey->key_datalen,
4278           data, datalen, siglen, 0);
4279       }
4280 
4281       ec = EVP_PKEY_get1_EC_KEY(sftp_ecdsa521_hostkey->pkey);
4282       if (ec == NULL) {
4283         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4284           "error using ECDSA-521 hostkey: %s", sftp_crypto_get_errors());
4285         return NULL;
4286       }
4287 
4288       pkey = sftp_ecdsa521_hostkey->pkey;
4289       md = EVP_sha512();
4290       break;
4291 
4292     default:
4293       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4294         "unknown/unsupported ECDSA NID (%d) requested", nid);
4295       return NULL;
4296   }
4297 
4298   if (keys_ec_min_nbits > 0) {
4299     int ec_nbits;
4300 
4301     ec_nbits = EVP_PKEY_bits(pkey) * 8;
4302     if (ec_nbits < keys_ec_min_nbits) {
4303       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4304         "EC hostkey size (%d bits) less than required minimum (%d bits)",
4305         ec_nbits, keys_ec_min_nbits);
4306       EC_KEY_free(ec);
4307 
4308       errno = EINVAL;
4309       return NULL;
4310     }
4311   }
4312 
4313   buflen = bufsz = SFTP_MAX_SIG_SZ;
4314   ptr = buf = sftp_msg_getbuf(p, bufsz);
4315 
4316 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4317     !defined(HAVE_LIBRESSL)
4318   pctx = EVP_MD_CTX_new();
4319 #else
4320   pctx = &ctx;
4321 #endif /* prior to OpenSSL-1.1.0 */
4322 
4323   EVP_DigestInit(pctx, md);
4324   EVP_DigestUpdate(pctx, data, datalen);
4325   EVP_DigestFinal(pctx, dgst, &dgstlen);
4326 
4327 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4328     !defined(HAVE_LIBRESSL)
4329   EVP_MD_CTX_free(pctx);
4330 #endif /* OpenSSL-1.1.0 and later */
4331 
4332   sig = ECDSA_do_sign(dgst, dgstlen, ec);
4333   if (sig == NULL) {
4334     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4335       "error obtaining ECDSA signature: %s", sftp_crypto_get_errors());
4336     pr_memscrub(dgst, dgstlen);
4337     EC_KEY_free(ec);
4338     return NULL;
4339   }
4340 
4341   /* Got the signature, no need for the digest memory. */
4342   pr_memscrub(dgst, dgstlen);
4343 
4344   /* Unlike DSA, the R and S lengths for ECDSA are dependent on the curve
4345    * selected, so we do no sanity checking of their lengths.
4346    */
4347 
4348 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4349     !defined(HAVE_LIBRESSL)
4350   ECDSA_SIG_get0(sig, &sig_r, &sig_s);
4351 #else
4352   sig_r = sig->r;
4353   sig_s = sig->s;
4354 #endif /* prior to OpenSSL-1.1.0 */
4355 
4356   /* XXX Is this buffer large enough?  Too large? */
4357   sig_buflen = sig_bufsz = 256;
4358   sig_ptr = sig_buf = palloc(p, sig_bufsz);
4359 
4360   sftp_msg_write_mpint(&sig_buf, &sig_buflen, sig_r);
4361   sftp_msg_write_mpint(&sig_buf, &sig_buflen, sig_s);
4362 
4363   /* Done with the signature. */
4364   ECDSA_SIG_free(sig);
4365   EC_KEY_free(ec);
4366 
4367   /* XXX Is this buffer large enough?  Too large? */
4368   buflen = bufsz = SFTP_MAX_SIG_SZ;
4369   ptr = buf = sftp_msg_getbuf(p, bufsz);
4370 
4371   /* Now build up the signature, SSH2-style */
4372   switch (nid) {
4373     case NID_X9_62_prime256v1:
4374       sftp_msg_write_string(&buf, &buflen, "ecdsa-sha2-nistp256");
4375       break;
4376 
4377     case NID_secp384r1:
4378       sftp_msg_write_string(&buf, &buflen, "ecdsa-sha2-nistp384");
4379       break;
4380 
4381     case NID_secp521r1:
4382       sftp_msg_write_string(&buf, &buflen, "ecdsa-sha2-nistp521");
4383       break;
4384   }
4385 
4386   sftp_msg_write_data(&buf, &buflen, sig_ptr, (sig_bufsz - sig_buflen), TRUE);
4387   pr_memscrub(sig_ptr, sig_bufsz);
4388 
4389   /* At this point, buflen is the amount remaining in the allocated buffer.
4390    * So the total length of the signed data is the buffer size, minus those
4391    * remaining unused bytes.
4392    */
4393   *siglen = (bufsz - buflen);
4394   return ptr;
4395 }
4396 #endif /* PR_USE_OPENSSL_ECC */
4397 
4398 #ifdef PR_USE_SODIUM
4399 static const unsigned char *ed25519_sign_data(pool *p,
4400     const unsigned char *data, size_t datalen, size_t *siglen) {
4401 
4402   unsigned char *buf, *ptr, *sig_buf, *sig_ptr;
4403   uint32_t bufsz, buflen, sig_buflen, sig_bufsz;
4404   unsigned long long slen;
4405   int res;
4406 
4407 /* XXX TODO ED25519: Test this! */
4408   if (sftp_ed25519_hostkey->agent_path != NULL) {
4409     return agent_sign_data(p, sftp_ed25519_hostkey->agent_path,
4410       sftp_ed25519_hostkey->ed25519_public_key,
4411       sftp_ed25519_hostkey->ed25519_public_keylen,
4412       data, datalen, siglen, 0);
4413   }
4414 
4415   sig_buflen = sig_bufsz = slen = datalen + crypto_sign_ed25519_BYTES;
4416   sig_ptr = sig_buf = palloc(p, sig_bufsz);
4417 
4418   res = crypto_sign_ed25519(sig_buf, &slen, data, datalen,
4419     sftp_ed25519_hostkey->ed25519_secret_key);
4420   if (res != 0) {
4421     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4422       "failed to sign data using Ed25519 (%d)", res);
4423     pr_memscrub(sig_ptr, sig_bufsz);
4424     return NULL;
4425   }
4426 
4427   sig_buflen = slen;
4428   if (sig_buflen <= datalen) {
4429     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4430       "invalid Ed25519 signature (%lu bytes) generated, expected more than "
4431       "%lu bytes", (unsigned long) sig_buflen, (unsigned long) datalen);
4432     pr_memscrub(sig_ptr, sig_bufsz);
4433     return NULL;
4434   }
4435 
4436   /* XXX Is this buffer large enough?  Too large? */
4437   buflen = bufsz = SFTP_MAX_SIG_SZ;
4438   ptr = buf = sftp_msg_getbuf(p, bufsz);
4439 
4440   /* Now build up the signature, SSH2-style */
4441   sftp_msg_write_string(&buf, &buflen, "ssh-ed25519");
4442   sftp_msg_write_data(&buf, &buflen, sig_ptr, sig_buflen - datalen, TRUE);
4443   pr_memscrub(sig_ptr, sig_bufsz);
4444 
4445   /* At this point, buflen is the amount remaining in the allocated buffer.
4446    * So the total length of the signed data is the buffer size, minus those
4447    * remaining unused bytes.
4448    */
4449   *siglen = (bufsz - buflen);
4450   return ptr;
4451 }
4452 #endif /* PR_USE_SODIUM */
4453 
4454 const unsigned char *sftp_keys_sign_data(pool *p,
4455     enum sftp_key_type_e key_type, const unsigned char *data,
4456     size_t datalen, size_t *siglen) {
4457   const unsigned char *res;
4458 
4459   switch (key_type) {
4460     case SFTP_KEY_RSA:
4461       res = rsa_sign_data(p, data, datalen, siglen);
4462       break;
4463 
4464 #if defined(HAVE_SHA256_OPENSSL)
4465     case SFTP_KEY_RSA_SHA256:
4466       res = rsa_sha256_sign_data(p, data, datalen, siglen);
4467       break;
4468 #endif /* HAVE_SHA256_OPENSSL */
4469 
4470 #if defined(HAVE_SHA512_OPENSSL)
4471     case SFTP_KEY_RSA_SHA512:
4472       res = rsa_sha512_sign_data(p, data, datalen, siglen);
4473       break;
4474 #endif /* HAVE_SHA512_OPENSSL */
4475 
4476 #if !defined(OPENSSL_NO_DSA)
4477     case SFTP_KEY_DSA:
4478       res = dsa_sign_data(p, data, datalen, siglen);
4479       break;
4480 #endif /* !OPENSSL_NO_DSA */
4481 
4482 #ifdef PR_USE_OPENSSL_ECC
4483     case SFTP_KEY_ECDSA_256:
4484       res = ecdsa_sign_data(p, data, datalen, siglen, NID_X9_62_prime256v1);
4485       break;
4486 
4487     case SFTP_KEY_ECDSA_384:
4488       res = ecdsa_sign_data(p, data, datalen, siglen, NID_secp384r1);
4489       break;
4490 
4491     case SFTP_KEY_ECDSA_521:
4492       res = ecdsa_sign_data(p, data, datalen, siglen, NID_secp521r1);
4493       break;
4494 #endif /* PR_USE_OPENSSL_ECC */
4495 
4496 #if defined(PR_USE_SODIUM)
4497     case SFTP_KEY_ED25519:
4498       res = ed25519_sign_data(p, data, datalen, siglen);
4499       break;
4500 #endif /* PR_USE_SODIUM */
4501 
4502     default:
4503       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4504         "unknown key type (%d) requested for signing, ignoring", key_type);
4505       return NULL;
4506   }
4507 
4508   if (res != NULL &&
4509       p != NULL) {
4510     unsigned char *buf;
4511 
4512     buf = palloc(p, *siglen);
4513     memcpy(buf, res, *siglen);
4514 
4515     pr_memscrub((char *) res, *siglen);
4516     return buf;
4517   }
4518 
4519   return res;
4520 }
4521 
4522 int sftp_keys_verify_pubkey_type(pool *p, unsigned char *pubkey_data,
4523     uint32_t pubkey_len, enum sftp_key_type_e pubkey_type) {
4524   EVP_PKEY *pkey = NULL;
4525   int res = FALSE;
4526   uint32_t len;
4527 
4528   if (pubkey_data == NULL ||
4529       pubkey_len == 0) {
4530     errno = EINVAL;
4531     return -1;
4532   }
4533 
4534   len = read_pkey_from_data(p, pubkey_data, pubkey_len, &pkey, NULL, FALSE);
4535   if (len == 0) {
4536     return -1;
4537   }
4538 
4539   switch (pubkey_type) {
4540     case SFTP_KEY_RSA:
4541     case SFTP_KEY_RSA_SHA256:
4542     case SFTP_KEY_RSA_SHA512:
4543       res = (get_pkey_type(pkey) == EVP_PKEY_RSA);
4544       break;
4545 
4546     case SFTP_KEY_DSA:
4547       res = (get_pkey_type(pkey) == EVP_PKEY_DSA);
4548       break;
4549 
4550 #ifdef PR_USE_OPENSSL_ECC
4551     case SFTP_KEY_ECDSA_256:
4552     case SFTP_KEY_ECDSA_384:
4553     case SFTP_KEY_ECDSA_521:
4554       if (get_pkey_type(pkey) == EVP_PKEY_EC) {
4555         EC_KEY *ec;
4556         int ec_nid;
4557 
4558         ec = EVP_PKEY_get1_EC_KEY(pkey);
4559         ec_nid = get_ecdsa_nid(ec);
4560         EC_KEY_free(ec);
4561 
4562         switch (ec_nid) {
4563           case NID_X9_62_prime256v1:
4564             res = (pubkey_type == SFTP_KEY_ECDSA_256);
4565             break;
4566 
4567           case NID_secp384r1:
4568             res = (pubkey_type == SFTP_KEY_ECDSA_384);
4569             break;
4570 
4571           case NID_secp521r1:
4572             res = (pubkey_type == SFTP_KEY_ECDSA_521);
4573             break;
4574         }
4575       }
4576       break;
4577 #endif /* PR_USE_OPENSSL_ECC */
4578 
4579 #if defined(PR_USE_SODIUM)
4580     case SFTP_KEY_ED25519: {
4581       char *pkey_type;
4582 
4583       pkey_type = sftp_msg_read_string(p, &pubkey_data, &pubkey_len);
4584       if (strcmp(pkey_type, "ssh-ed25519") != 0) {
4585         pr_trace_msg(trace_channel, 8,
4586          "invalid public key type '%s' for Ed25519 key", pkey_type);
4587         res = FALSE;
4588 
4589       } else {
4590         uint32_t pklen;
4591 
4592         pklen = sftp_msg_read_int(p, &pubkey_data, &pubkey_len);
4593 
4594         res = (pklen == (uint32_t) crypto_sign_ed25519_PUBLICKEYBYTES);
4595         if (res == FALSE) {
4596           pr_trace_msg(trace_channel, 8,
4597            "Ed25519 public key length (%lu bytes) does not match expected "
4598            "length (%lu bytes)", (unsigned long) pklen,
4599            (unsigned long) crypto_sign_ed25519_PUBLICKEYBYTES);
4600         }
4601       }
4602       break;
4603     }
4604 #endif /* PR_USE_SODIUM */
4605 
4606     default:
4607       /* No matching public key type/algorithm. */
4608       errno = ENOENT;
4609       res = FALSE;
4610       break;
4611   }
4612 
4613   if (pkey != NULL) {
4614     EVP_PKEY_free(pkey);
4615   }
4616 
4617   return res;
4618 }
4619 
4620 static int verify_rsa_signed_data(pool *p, EVP_PKEY *pkey,
4621     unsigned char *signature, uint32_t signature_len,
4622     unsigned char *sig_data, size_t sig_datalen, const EVP_MD *md) {
4623 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
4624     defined(HAVE_LIBRESSL)
4625   EVP_MD_CTX ctx;
4626 #endif /* prior to OpenSSL-1.1.0 */
4627   EVP_MD_CTX *pctx;
4628   RSA *rsa;
4629   uint32_t len, sig_len;
4630   unsigned char digest[EVP_MAX_MD_SIZE], *sig;
4631   unsigned int digest_len = 0, modulus_len = 0;
4632   int ok = FALSE, res = 0;
4633 
4634   len = sftp_msg_read_int2(p, &signature, &signature_len, &sig_len);
4635   if (len == 0) {
4636     errno = EINVAL;
4637     return -1;
4638   }
4639 
4640   len = sftp_msg_read_data2(p, &signature, &signature_len, sig_len, &sig);
4641   if (len == 0) {
4642     errno = EINVAL;
4643     return -1;
4644   }
4645 
4646   if (sig == NULL) {
4647     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4648       "error verifying RSA signature: missing signature data");
4649     errno = EINVAL;
4650     return -1;
4651   }
4652 
4653   rsa = EVP_PKEY_get1_RSA(pkey);
4654 
4655   if (keys_rsa_min_nbits > 0) {
4656     int rsa_nbits;
4657 
4658     rsa_nbits = RSA_size(rsa) * 8;
4659     if (rsa_nbits < keys_rsa_min_nbits) {
4660       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4661         "RSA key size (%d bits) less than required minimum (%d bits)",
4662         rsa_nbits, keys_rsa_min_nbits);
4663       RSA_free(rsa);
4664 
4665       errno = EINVAL;
4666       return -1;
4667     }
4668   }
4669 
4670   modulus_len = RSA_size(rsa);
4671 
4672   /* If the signature provided by the client is more than the expected
4673    * key length, the verification will fail.
4674    */
4675   if (sig_len > modulus_len) {
4676     RSA_free(rsa);
4677 
4678     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4679       "error verifying RSA signature: signature len (%lu) > RSA modulus "
4680       "len (%u)", (unsigned long) sig_len, modulus_len);
4681     errno = EINVAL;
4682     return -1;
4683   }
4684 
4685   /* If the signature provided by the client is less than the expected
4686    * key length, the verification will fail.  In such cases, we need to
4687    * pad the provided signature with leading zeros (Bug#3992).
4688    */
4689   if (sig_len < modulus_len) {
4690     unsigned int padding_len;
4691     unsigned char *padded_sig;
4692 
4693     padding_len = modulus_len - sig_len;
4694     padded_sig = pcalloc(p, modulus_len);
4695 
4696     pr_trace_msg(trace_channel, 12, "padding client-sent RSA signature "
4697       "(%lu) bytes with %u bytes of zeroed data", (unsigned long) sig_len,
4698       padding_len);
4699     memmove(padded_sig + padding_len, sig, sig_len);
4700 
4701     sig = padded_sig;
4702     sig_len = (uint32_t) modulus_len;
4703   }
4704 
4705 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4706     !defined(HAVE_LIBRESSL)
4707   pctx = EVP_MD_CTX_new();
4708 #else
4709   pctx = &ctx;
4710 #endif /* prior to OpenSSL-1.1.0 */
4711 
4712   EVP_DigestInit(pctx, md);
4713   EVP_DigestUpdate(pctx, sig_data, sig_datalen);
4714   EVP_DigestFinal(pctx, digest, &digest_len);
4715 
4716 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4717     !defined(HAVE_LIBRESSL)
4718   EVP_MD_CTX_free(pctx);
4719 #endif /* OpenSSL-1.1.0 and later */
4720 
4721   ok = RSA_verify(EVP_MD_type(md), digest, digest_len, sig, sig_len, rsa);
4722   if (ok == 1) {
4723     res = 0;
4724 
4725   } else {
4726     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4727       "error verifying RSA signature: %s", sftp_crypto_get_errors());
4728     res = -1;
4729   }
4730 
4731   pr_memscrub(digest, digest_len);
4732   RSA_free(rsa);
4733   return res;
4734 }
4735 
4736 static int rsa_verify_signed_data(pool *p, EVP_PKEY *pkey,
4737     unsigned char *signature, uint32_t signature_len,
4738     unsigned char *sig_data, size_t sig_datalen) {
4739   return verify_rsa_signed_data(p, pkey, signature, signature_len,
4740     sig_data, sig_datalen, EVP_sha1());
4741 }
4742 
4743 #if defined(HAVE_SHA256_OPENSSL)
4744 static int rsa_sha256_verify_signed_data(pool *p, EVP_PKEY *pkey,
4745     unsigned char *signature, uint32_t signature_len,
4746     unsigned char *sig_data, size_t sig_datalen) {
4747   return verify_rsa_signed_data(p, pkey, signature, signature_len,
4748     sig_data, sig_datalen, EVP_sha256());
4749 }
4750 #endif /* HAVE_SHA256_OPENSSL */
4751 
4752 #if defined(HAVE_SHA512_OPENSSL)
4753 static int rsa_sha512_verify_signed_data(pool *p, EVP_PKEY *pkey,
4754     unsigned char *signature, uint32_t signature_len,
4755     unsigned char *sig_data, size_t sig_datalen) {
4756   return verify_rsa_signed_data(p, pkey, signature, signature_len,
4757     sig_data, sig_datalen, EVP_sha512());
4758 }
4759 #endif /* HAVE_SHA512_OPENSSL */
4760 
4761 #if !defined(OPENSSL_NO_DSA)
4762 static int dsa_verify_signed_data(pool *p, EVP_PKEY *pkey,
4763     unsigned char *signature, uint32_t signature_len,
4764     unsigned char *sig_data, size_t sig_datalen) {
4765 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
4766     defined(HAVE_LIBRESSL)
4767   EVP_MD_CTX ctx;
4768 #endif /* prior to OpenSSL-1.1.0 */
4769   EVP_MD_CTX *pctx;
4770   DSA *dsa;
4771   DSA_SIG *dsa_sig;
4772   BIGNUM *sig_r, *sig_s;
4773   uint32_t len, sig_len;
4774   unsigned char digest[EVP_MAX_MD_SIZE], *sig;
4775   unsigned int digest_len = 0;
4776   int ok = FALSE, res = 0;
4777 
4778   len = sftp_msg_read_int2(p, &signature, &signature_len, &sig_len);
4779   if (len == 0) {
4780     errno = EINVAL;
4781     return -1;
4782   }
4783 
4784   /* A DSA signature string is composed of 2 20 character parts. */
4785   if (sig_len != 40) {
4786     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4787       "bad DSA signature len (%lu)", (unsigned long) sig_len);
4788   }
4789 
4790   len = sftp_msg_read_data2(p, &signature, &signature_len, sig_len, &sig);
4791   if (len == 0) {
4792     errno = EINVAL;
4793     return -1;
4794   }
4795 
4796   if (sig == NULL) {
4797     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4798       "error verifying DSA signature: missing signature data");
4799     errno = EINVAL;
4800     return -1;
4801   }
4802 
4803   dsa = EVP_PKEY_get1_DSA(pkey);
4804 
4805   if (keys_dsa_min_nbits > 0) {
4806     int dsa_nbits;
4807 
4808     dsa_nbits = DSA_size(dsa) * 8;
4809     if (dsa_nbits < keys_dsa_min_nbits) {
4810       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4811         "DSA key size (%d bits) less than required minimum (%d bits)",
4812         dsa_nbits, keys_dsa_min_nbits);
4813       DSA_free(dsa);
4814 
4815       errno = EINVAL;
4816       return -1;
4817     }
4818   }
4819 
4820   dsa_sig = DSA_SIG_new();
4821 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4822     !defined(HAVE_LIBRESSL)
4823   DSA_SIG_get0(dsa_sig, &sig_r, &sig_s);
4824 #else
4825   sig_r = dsa_sig->r;
4826   sig_s = dsa_sig->s;
4827 #endif /* prior to OpenSSL-1.1.0 */
4828 
4829   sig_r = BN_bin2bn(sig, 20, sig_r);
4830   if (sig_r == NULL) {
4831     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4832       "error obtaining 'r' DSA signature component: %s",
4833       sftp_crypto_get_errors());
4834     DSA_free(dsa);
4835     DSA_SIG_free(dsa_sig);
4836     return -1;
4837   }
4838 
4839   sig_s = BN_bin2bn(sig + 20, 20, sig_s);
4840   if (sig_s == NULL) {
4841     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4842       "error obtaining 's' DSA signature component: %s",
4843       sftp_crypto_get_errors());
4844     BN_clear_free(sig_r);
4845     DSA_free(dsa);
4846     DSA_SIG_free(dsa_sig);
4847     return -1;
4848   }
4849 
4850 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4851     !defined(HAVE_LIBRESSL)
4852   pctx = EVP_MD_CTX_new();
4853 #else
4854   pctx = &ctx;
4855 #endif /* prior to OpenSSL-1.1.0 */
4856 
4857   EVP_DigestInit(pctx, EVP_sha1());
4858   EVP_DigestUpdate(pctx, sig_data, sig_datalen);
4859   EVP_DigestFinal(pctx, digest, &digest_len);
4860 
4861 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4862     !defined(HAVE_LIBRESSL)
4863   EVP_MD_CTX_free(pctx);
4864 #endif /* OpenSSL-1.1.0 and later */
4865 
4866 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4867     !defined(HAVE_LIBRESSL)
4868 # if OPENSSL_VERSION_NUMBER >= 0x10100006L
4869   DSA_SIG_set0(dsa_sig, sig_r, sig_s);
4870 # else
4871   /* XXX What to do here? */
4872 # endif /* prior to OpenSSL-1.1.0-pre6 */
4873 #else
4874   dsa_sig->r = sig_r;
4875   dsa_sig->s = sig_s;
4876 #endif /* prior to OpenSSL-1.1.0 */
4877 
4878   ok = DSA_do_verify(digest, digest_len, dsa_sig, dsa);
4879   if (ok == 1) {
4880     res = 0;
4881 
4882   } else {
4883     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4884       "error verifying DSA signature: %s", sftp_crypto_get_errors());
4885     res = -1;
4886   }
4887 
4888   pr_memscrub(digest, digest_len);
4889   DSA_free(dsa);
4890   DSA_SIG_free(dsa_sig);
4891   return res;
4892 }
4893 #endif /* !OPENSSL_NO_DSA */
4894 
4895 #ifdef PR_USE_OPENSSL_ECC
4896 static int ecdsa_verify_signed_data(pool *p, EVP_PKEY *pkey,
4897     unsigned char *signature, uint32_t signature_len,
4898     unsigned char *sig_data, size_t sig_datalen, char *sig_type) {
4899 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
4900     defined(HAVE_LIBRESSL)
4901   EVP_MD_CTX ctx;
4902 #endif /* prior to OpenSSL-1.1.0 */
4903   EVP_MD_CTX *pctx;
4904   const EVP_MD *md = NULL;
4905   EC_KEY *ec;
4906   ECDSA_SIG *ecdsa_sig;
4907   BIGNUM *sig_r, *sig_s;
4908   uint32_t len, sig_len;
4909   unsigned char digest[EVP_MAX_MD_SIZE], *sig;
4910   unsigned int digest_len = 0;
4911   int ok = FALSE, res = 0;
4912 
4913   if (keys_ec_min_nbits > 0) {
4914     int ec_nbits;
4915 
4916     ec_nbits = EVP_PKEY_bits(pkey) * 8;
4917     if (ec_nbits < keys_ec_min_nbits) {
4918       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4919         "EC key size (%d bits) less than required minimum (%d bits)",
4920         ec_nbits, keys_ec_min_nbits);
4921       errno = EINVAL;
4922       return -1;
4923     }
4924   }
4925 
4926   len = sftp_msg_read_int2(p, &signature, &signature_len, &sig_len);
4927   if (len == 0) {
4928     errno = EINVAL;
4929     return -1;
4930   }
4931 
4932   len = sftp_msg_read_data2(p, &signature, &signature_len, sig_len, &sig);
4933   if (len == 0) {
4934     errno = EINVAL;
4935     return -1;
4936   }
4937 
4938   if (sig == NULL) {
4939     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4940       "error verifying ECDSA signature: missing signature data");
4941     errno = EINVAL;
4942     return -1;
4943   }
4944 
4945   ecdsa_sig = ECDSA_SIG_new();
4946   if (ecdsa_sig == NULL) {
4947     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4948       "error allocating new ECDSA_SIG: %s", sftp_crypto_get_errors());
4949     return -1;
4950   }
4951 
4952 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4953     !defined(HAVE_LIBRESSL)
4954   ECDSA_SIG_get0(ecdsa_sig, &sig_r, &sig_s);
4955 #else
4956   sig_r = ecdsa_sig->r;
4957   sig_s = ecdsa_sig->s;
4958 #endif /* prior to OpenSSL-1.1.0 */
4959 
4960   len = sftp_msg_read_mpint2(p, &sig, &sig_len, &sig_r);
4961   if (len == 0) {
4962     ECDSA_SIG_free(ecdsa_sig);
4963     errno = EINVAL;
4964     return -1;
4965   }
4966 
4967   if (sig_r == NULL) {
4968     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4969       "error reading 'r' ECDSA signature component: %s",
4970       sftp_crypto_get_errors());
4971     ECDSA_SIG_free(ecdsa_sig);
4972     return -1;
4973   }
4974 
4975   len = sftp_msg_read_mpint2(p, &sig, &sig_len, &sig_s);
4976   if (len == 0) {
4977     ECDSA_SIG_free(ecdsa_sig);
4978     errno = EINVAL;
4979     return -1;
4980   }
4981 
4982   if (sig_s == NULL) {
4983     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
4984       "error reading 's' ECDSA signature component: %s",
4985       sftp_crypto_get_errors());
4986     ECDSA_SIG_free(ecdsa_sig);
4987     return -1;
4988   }
4989 
4990   /* Skip past the common leading prefix "ecdsa-sha2-" to compare just
4991    * last 9 characters.
4992    */
4993 
4994   if (strncmp(sig_type + 11, "nistp256", 9) == 0) {
4995     md = EVP_sha256();
4996 
4997   } else if (strncmp(sig_type + 11, "nistp384", 9) == 0) {
4998     md = EVP_sha384();
4999 
5000   } else if (strncmp(sig_type + 11, "nistp521", 9) == 0) {
5001     md = EVP_sha512();
5002   }
5003 
5004 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
5005     !defined(HAVE_LIBRESSL)
5006   pctx = EVP_MD_CTX_new();
5007 #else
5008   pctx = &ctx;
5009 #endif /* prior to OpenSSL-1.1.0 */
5010 
5011   EVP_DigestInit(pctx, md);
5012   EVP_DigestUpdate(pctx, sig_data, sig_datalen);
5013   EVP_DigestFinal(pctx, digest, &digest_len);
5014 
5015 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
5016     !defined(HAVE_LIBRESSL)
5017   EVP_MD_CTX_free(pctx);
5018 #endif /* OpenSSL-1.1.0 and later */
5019 
5020   ec = EVP_PKEY_get1_EC_KEY(pkey);
5021 
5022 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
5023     !defined(HAVE_LIBRESSL)
5024 # if OPENSSL_VERSION_NUMBER >= 0x10100006L
5025   ECDSA_SIG_set0(ecdsa_sig, sig_r, sig_s);
5026 # else
5027   /* XXX What to do here? */
5028 # endif /* prior to OpenSSL-1.1.0-pre6 */
5029 #else
5030   ecdsa_sig->r = sig_r;
5031   ecdsa_sig->s = sig_s;
5032 #endif /* prior to OpenSSL-1.1.0 */
5033 
5034   ok = ECDSA_do_verify(digest, digest_len, ecdsa_sig, ec);
5035   if (ok == 1) {
5036     res = 0;
5037 
5038   } else {
5039     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5040       "error verifying ECDSA signature: %s", sftp_crypto_get_errors());
5041     res = -1;
5042   }
5043 
5044   pr_memscrub(digest, digest_len);
5045   EC_KEY_free(ec);
5046   ECDSA_SIG_free(ecdsa_sig);
5047   return res;
5048 }
5049 #endif /* PR_USE_OPENSSL_ECC */
5050 
5051 #if defined(PR_USE_SODIUM)
5052 static int ed25519_verify_signed_data(pool *p,
5053     unsigned char *pubkey_data, uint32_t pubkey_datalen,
5054     unsigned char *signature, uint32_t signature_len,
5055     unsigned char *sig_data, size_t sig_datalen) {
5056   char *pkey_type;
5057   uint32_t len, public_keylen, sig_len;
5058   unsigned char *msg, *public_key, *signed_msg, *sig;
5059   unsigned long long msg_len, signed_msglen;
5060   int res;
5061 
5062   len = sftp_msg_read_string2(p, &pubkey_data, &pubkey_datalen, &pkey_type);
5063   if (len == 0) {
5064     errno = EINVAL;
5065     return -1;
5066   }
5067 
5068   if (strcmp(pkey_type, "ssh-ed25519") != 0) {
5069     pr_trace_msg(trace_channel, 17,
5070       "public key type '%s' does not match expected key type 'ssh-ed25519'",
5071       pkey_type);
5072     errno = EINVAL;
5073     return -1;
5074   }
5075 
5076   len = sftp_msg_read_int2(p, &pubkey_data, &pubkey_datalen, &public_keylen);
5077   if (len == 0) {
5078     errno = EINVAL;
5079     return -1;
5080   }
5081 
5082   if (public_keylen != crypto_sign_ed25519_PUBLICKEYBYTES) {
5083     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5084       "invalid Ed25519 public key length (%lu bytes), expected %lu bytes",
5085       (unsigned long) public_keylen,
5086       (unsigned long) crypto_sign_ed25519_PUBLICKEYBYTES);
5087     errno = EINVAL;
5088     return -1;
5089   }
5090 
5091   len = sftp_msg_read_data2(p, &pubkey_data, &pubkey_datalen, public_keylen,
5092     &public_key);
5093   if (len == 0) {
5094     errno = EINVAL;
5095     return -1;
5096   }
5097 
5098   len = sftp_msg_read_int2(p, &signature, &signature_len, &sig_len);
5099   if (len == 0) {
5100     errno = EINVAL;
5101     return -1;
5102   }
5103 
5104   len = sftp_msg_read_data2(p, &signature, &signature_len, sig_len, &sig);
5105   if (len == 0) {
5106     errno = EINVAL;
5107     return -1;
5108   }
5109 
5110   if (sig == NULL) {
5111     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5112       "error verifying Ed25519 signature: missing signature data");
5113     errno = EINVAL;
5114     return -1;
5115   }
5116 
5117   if (sig_len > crypto_sign_ed25519_BYTES) {
5118     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5119       "Ed25519 signature length (%lu bytes) exceeds valid length (%lu bytes)",
5120       (unsigned long) sig_len, (unsigned long) crypto_sign_ed25519_BYTES);
5121     errno = EINVAL;
5122     return -1;
5123   }
5124 
5125   signed_msglen = sig_len + sig_datalen;
5126   signed_msg = palloc(p, signed_msglen);
5127   memcpy(signed_msg, sig, sig_len);
5128   memcpy(signed_msg + sig_len, sig_data, sig_datalen);
5129 
5130   msg_len = signed_msglen;
5131   msg = palloc(p, msg_len);
5132 
5133   res = crypto_sign_ed25519_open(msg, &msg_len, signed_msg, signed_msglen,
5134     public_key);
5135   if (res != 0) {
5136     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5137       "failed Ed25519 signature verification (%d)", res);
5138     res = -1;
5139   }
5140 
5141   if (res == 0) {
5142     if (msg_len != sig_datalen) {
5143       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5144         "invalid Ed25519 signature length (%lu bytes), expected %lu bytes",
5145         (unsigned long) sig_datalen, (unsigned long) msg_len);
5146       errno = EINVAL;
5147       res = -1;
5148     }
5149   }
5150 
5151   if (res == 0) {
5152     if (sodium_memcmp(msg, sig_data, msg_len) != 0) {
5153       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5154         "invalid Ed25519 signature (mismatched data)");
5155       errno = EINVAL;
5156       res = -1;
5157     }
5158   }
5159 
5160   pr_memscrub(signed_msg, signed_msglen);
5161   pr_memscrub(msg, msg_len);
5162   return res;
5163 }
5164 #endif /* PR_USE_SODIUM */
5165 
5166 int sftp_keys_verify_signed_data(pool *p, const char *pubkey_algo,
5167     unsigned char *pubkey_data, uint32_t pubkey_datalen,
5168     unsigned char *signature, uint32_t signature_len,
5169     unsigned char *sig_data, size_t sig_datalen) {
5170   EVP_PKEY *pkey = NULL;
5171   char *sig_type;
5172   uint32_t len;
5173   int res = 0;
5174 
5175   if (pubkey_algo == NULL ||
5176       pubkey_data == NULL ||
5177       signature == NULL ||
5178       sig_data == NULL ||
5179       sig_datalen == 0) {
5180     errno = EINVAL;
5181     return -1;
5182   }
5183 
5184   len = read_pkey_from_data(p, pubkey_data, pubkey_datalen, &pkey, NULL, FALSE);
5185   if (len == 0) {
5186     return -1;
5187   }
5188 
5189   if (strncmp(pubkey_algo, "ssh-dss", 8) == 0) {
5190     if (sftp_interop_supports_feature(SFTP_SSH2_FEAT_HAVE_PUBKEY_ALGO_IN_DSA_SIG)) {
5191       len = sftp_msg_read_string2(p, &signature, &signature_len, &sig_type);
5192       if (len == 0) {
5193         errno = EINVAL;
5194         return -1;
5195       }
5196 
5197     } else {
5198       /* The client did not prepend the public key algorithm name to their
5199        * signature data, so there is no need to extract that string.
5200        * We will ASSUME that the public key algorithm provided elsewhere
5201        * in the 'publickey' USERAUTH_REQUEST is accurate.
5202        */
5203       pr_trace_msg(trace_channel, 9, "assuming client did not prepend public "
5204         "key algorithm name to DSA signature");
5205       sig_type = "ssh-dss";
5206     }
5207 
5208   } else {
5209     len = sftp_msg_read_string2(p, &signature, &signature_len, &sig_type);
5210     if (len == 0) {
5211       errno = EINVAL;
5212       return -1;
5213     }
5214   }
5215 
5216   if (strncmp(sig_type, "ssh-rsa", 8) == 0) {
5217     res = rsa_verify_signed_data(p, pkey, signature, signature_len, sig_data,
5218       sig_datalen);
5219 
5220 #if defined(HAVE_SHA256_OPENSSL)
5221   } else if (strncmp(sig_type, "rsa-sha2-256", 13) == 0) {
5222     if (strcmp(pubkey_algo, sig_type) != 0) {
5223       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5224         "unable to verify signed data: signature type '%s' does not match "
5225         "publickey algorithm '%s'", sig_type, pubkey_algo);
5226       errno = EINVAL;
5227       return -1;
5228     }
5229 
5230     res = rsa_sha256_verify_signed_data(p, pkey, signature, signature_len,
5231       sig_data, sig_datalen);
5232 #endif /* HAVE_SHA256_OPENSSL */
5233 
5234 #if defined(HAVE_SHA512_OPENSSL)
5235   } else if (strncmp(sig_type, "rsa-sha2-512", 13) == 0) {
5236     if (strcmp(pubkey_algo, sig_type) != 0) {
5237       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5238         "unable to verify signed data: signature type '%s' does not match "
5239         "publickey algorithm '%s'", sig_type, pubkey_algo);
5240       errno = EINVAL;
5241       return -1;
5242     }
5243 
5244     res = rsa_sha512_verify_signed_data(p, pkey, signature, signature_len,
5245       sig_data, sig_datalen);
5246 #endif /* HAVE_SHA512_OPENSSL */
5247 
5248 #if !defined(OPENSSL_NO_DSA)
5249   } else if (strncmp(sig_type, "ssh-dss", 8) == 0) {
5250     res = dsa_verify_signed_data(p, pkey, signature, signature_len, sig_data,
5251       sig_datalen);
5252 #endif /* !OPENSSL_NO_DSA */
5253 
5254 #ifdef PR_USE_OPENSSL_ECC
5255   } else if (strncmp(sig_type, "ecdsa-sha2-nistp256", 20) == 0 ||
5256              strncmp(sig_type, "ecdsa-sha2-nistp384", 20) == 0 ||
5257              strncmp(sig_type, "ecdsa-sha2-nistp521", 20) == 0) {
5258 
5259     if (strcmp(pubkey_algo, sig_type) != 0) {
5260       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5261         "unable to verify signed data: public key algorithm '%s' does not "
5262         "match signature algorithm '%s'", pubkey_algo, sig_type);
5263       return -1;
5264     }
5265 
5266     res = ecdsa_verify_signed_data(p, pkey, signature, signature_len, sig_data,
5267       sig_datalen, sig_type);
5268 #endif /* PR_USE_OPENSSL_ECC */
5269 
5270 #if defined(PR_USE_SODIUM)
5271   } else if (strncmp(sig_type, "ssh-ed25519", 12) == 0) {
5272     res = ed25519_verify_signed_data(p, pubkey_data, pubkey_datalen, signature,
5273       signature_len, sig_data, sig_datalen);
5274 #endif /* PR_USE_SODIUM */
5275 
5276   } else {
5277     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
5278       "unable to verify signed data: unsupported signature algorithm '%s'",
5279       sig_type);
5280     errno = EINVAL;
5281     return -1;
5282   }
5283 
5284   if (pkey != NULL) {
5285     EVP_PKEY_free(pkey);
5286   }
5287 
5288   return res;
5289 }
5290 
5291 int sftp_keys_set_key_limits(int rsa_min, int dsa_min, int ec_min) {
5292   /* Ignore any negative values. */
5293 
5294   if (rsa_min >= 0) {
5295     keys_rsa_min_nbits = (unsigned int) rsa_min;
5296   }
5297 
5298   if (dsa_min >= 0) {
5299     keys_dsa_min_nbits = (unsigned int) dsa_min;
5300   }
5301 
5302   if (ec_min >= 0) {
5303     keys_ec_min_nbits = (unsigned int) ec_min;
5304   }
5305 
5306   return 0;
5307 }
5308 
5309 int sftp_keys_set_passphrase_provider(const char *provider) {
5310   if (provider == NULL) {
5311     errno = EINVAL;
5312     return -1;
5313   }
5314 
5315   passphrase_provider = provider;
5316   return 0;
5317 }
5318 
5319 void sftp_keys_get_passphrases(void) {
5320   server_rec *s = NULL;
5321 
5322   for (s = (server_rec *) server_list->xas_list; s; s = s->next) {
5323     config_rec *c;
5324     struct sftp_pkey *k;
5325 
5326     c = find_config(s->conf, CONF_PARAM, "SFTPHostKey", FALSE);
5327     while (c != NULL) {
5328       int flags;
5329 
5330       pr_signals_handle();
5331 
5332       flags = *((int *) c->argv[1]);
5333 
5334       /* Skip any agent-provided SFTPHostKey directives, as well as any
5335        * "disabling key" directives.
5336        */
5337       if (flags != 0 ||
5338           strncmp(c->argv[0], "agent:", 6) == 0) {
5339         c = find_config_next(c, c->next, CONF_PARAM, "SFTPHostKey", FALSE);
5340         continue;
5341       }
5342 
5343       k = pcalloc(s->pool, sizeof(struct sftp_pkey));
5344       k->pkeysz = PEM_BUFSIZE-1;
5345       k->server = s;
5346 
5347       if (get_passphrase(k, c->argv[0]) < 0) {
5348         int xerrno = errno;
5349         const char *errstr;
5350 
5351         errstr = sftp_crypto_get_errors();
5352 
5353         pr_log_pri(PR_LOG_WARNING, MOD_SFTP_VERSION
5354           ": error reading passphrase for SFTPHostKey '%s': %s",
5355           (const char *) c->argv[0], errstr ? errstr : strerror(xerrno));
5356 
5357         pr_log_pri(PR_LOG_ERR, MOD_SFTP_VERSION
5358           ": unable to use key in SFTPHostKey '%s', exiting",
5359           (const char *) c->argv[0]);
5360         pr_session_disconnect(&sftp_module, PR_SESS_DISCONNECT_BAD_CONFIG,
5361           NULL);
5362       }
5363 
5364       k->next = sftp_pkey_list;
5365       sftp_pkey_list = k;
5366       sftp_npkeys++;
5367 
5368       c = find_config_next(c, c->next, CONF_PARAM, "SFTPHostKey", FALSE);
5369     }
5370   }
5371 }
5372 
5373 /* Make sure that no valuable information can be inadvertently written
5374  * out to swap.
5375  */
5376 void sftp_keys_free(void) {
5377   scrub_pkeys();
5378 
5379   sftp_keys_clear_dsa_hostkey();
5380   sftp_keys_clear_ecdsa_hostkey();
5381   sftp_keys_clear_rsa_hostkey();
5382 }
5383