1 /*
2  * pki.c
3  * This file is part of the SSH Library
4  *
5  * Copyright (c) 2010 by Aris Adamantiadis
6  * Copyright (c) 2011-2013 Andreas Schneider <asn@cryptomilk.org>
7  *
8  * The SSH Library is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or (at your
11  * option) any later version.
12  *
13  * The SSH Library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16  * License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with the SSH Library; see the file COPYING.  If not, write to
20  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21  * MA 02111-1307, USA.
22  */
23 
24 /**
25  * @defgroup libssh_pki The SSH Public Key Infrastructure
26  * @ingroup libssh
27  *
28  * Functions for the creation, importation and manipulation of public and
29  * private keys in the context of the SSH protocol
30  *
31  * @{
32  */
33 
34 #include "config.h"
35 
36 #include <errno.h>
37 #include <ctype.h>
38 #include <stdio.h>
39 #include <fcntl.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 
43 #ifdef _WIN32
44 # ifdef HAVE_IO_H
45 #  include <io.h>
46 #  undef open
47 #  define open _open
48 #  undef close
49 #  define close _close
50 #  undef read
51 #  define read _read
52 #  undef unlink
53 #  define unlink _unlink
54 # endif /* HAVE_IO_H */
55 #endif
56 
57 #include "libssh/libssh.h"
58 #include "libssh/session.h"
59 #include "libssh/priv.h"
60 #include "libssh/pki.h"
61 #include "libssh/pki_priv.h"
62 #include "libssh/keys.h"
63 #include "libssh/buffer.h"
64 #include "libssh/misc.h"
65 #include "libssh/agent.h"
66 
pki_privatekey_type_from_string(const char * privkey)67 enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey)
68 {
69     char *start = NULL;
70 
71     start = strstr(privkey, DSA_HEADER_BEGIN);
72     if (start != NULL) {
73         return SSH_KEYTYPE_DSS;
74     }
75 
76     start = strstr(privkey, RSA_HEADER_BEGIN);
77     if (start != NULL) {
78         return SSH_KEYTYPE_RSA;
79     }
80 
81     start = strstr(privkey, ECDSA_HEADER_BEGIN);
82     if (start != 0) {
83         /* We don't know what the curve is at this point, so we don't actually
84          * know the type. We figure out the actual curve and fix things up in
85          * pki_private_key_from_base64 */
86         return SSH_KEYTYPE_ECDSA_P256;
87     }
88 
89     return SSH_KEYTYPE_UNKNOWN;
90 }
91 
92 /**
93  * @brief returns the ECDSA key name ("ecdsa-sha2-nistp256" for example)
94  *
95  * @param[in] key the ssh_key whose ECDSA name to get
96  *
97  * @returns the ECDSA key name ("ecdsa-sha2-nistp256" for example)
98  *
99  * @returns "unknown" if the ECDSA key name is not known
100  */
ssh_pki_key_ecdsa_name(const ssh_key key)101 const char *ssh_pki_key_ecdsa_name(const ssh_key key)
102 {
103     if (key == NULL) {
104         return NULL;
105     }
106 
107 #ifdef HAVE_ECC /* FIXME Better ECC check needed */
108     return pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
109 #else
110     return NULL;
111 #endif
112 }
113 
114 /**
115  * @brief creates a new empty SSH key
116  * @returns an empty ssh_key handle, or NULL on error.
117  */
ssh_key_new(void)118 ssh_key ssh_key_new (void) {
119   ssh_key ptr = malloc (sizeof (struct ssh_key_struct));
120   if (ptr == NULL) {
121       return NULL;
122   }
123   ZERO_STRUCTP(ptr);
124   return ptr;
125 }
126 
ssh_key_dup(const ssh_key key)127 ssh_key ssh_key_dup(const ssh_key key)
128 {
129     if (key == NULL) {
130         return NULL;
131     }
132 
133     return pki_key_dup(key, 0);
134 }
135 
136 /**
137  * @brief clean up the key and deallocate all existing keys
138  * @param[in] key ssh_key to clean
139  */
ssh_key_clean(ssh_key key)140 void ssh_key_clean (ssh_key key){
141     if(key == NULL)
142         return;
143 #ifdef HAVE_LIBGCRYPT
144     if(key->dsa) gcry_sexp_release(key->dsa);
145     if(key->rsa) gcry_sexp_release(key->rsa);
146     if(key->ecdsa) gcry_sexp_release(key->ecdsa);
147 #elif defined HAVE_LIBCRYPTO
148     if(key->dsa) DSA_free(key->dsa);
149     if(key->rsa) RSA_free(key->rsa);
150 #ifdef HAVE_OPENSSL_ECC
151     if(key->ecdsa) EC_KEY_free(key->ecdsa);
152 #endif /* HAVE_OPENSSL_ECC */
153 #elif defined HAVE_LIBMBEDCRYPTO
154     if (key->rsa != NULL) {
155         mbedtls_pk_free(key->rsa);
156         SAFE_FREE(key->rsa);
157     }
158 
159     if (key->ecdsa != NULL) {
160         mbedtls_ecdsa_free(key->ecdsa);
161         SAFE_FREE(key->ecdsa);
162     }
163 #endif
164     if (key->ed25519_privkey != NULL){
165 #ifdef HAVE_OPENSSL_ED25519
166         /* In OpenSSL implementation the private key is only the private
167          * original seed. In the internal implementation the private key is the
168          * concatenation of the original private seed with the public key.*/
169         explicit_bzero(key->ed25519_privkey, ED25519_KEY_LEN);
170 #else
171         explicit_bzero(key->ed25519_privkey, sizeof(ed25519_privkey));
172 #endif
173         SAFE_FREE(key->ed25519_privkey);
174     }
175     SAFE_FREE(key->ed25519_pubkey);
176     if (key->cert != NULL) {
177         SSH_BUFFER_FREE(key->cert);
178     }
179     key->cert_type = SSH_KEYTYPE_UNKNOWN;
180     key->flags=SSH_KEY_FLAG_EMPTY;
181     key->type=SSH_KEYTYPE_UNKNOWN;
182     key->ecdsa_nid = 0;
183     key->type_c=NULL;
184     key->dsa = NULL;
185     key->rsa = NULL;
186     key->ecdsa = NULL;
187 }
188 
189 /**
190  * @brief deallocate a SSH key
191  * @param[in] key ssh_key handle to free
192  */
ssh_key_free(ssh_key key)193 void ssh_key_free (ssh_key key){
194     if(key){
195         ssh_key_clean(key);
196         SAFE_FREE(key);
197     }
198 }
199 
200 /**
201  * @brief returns the type of a ssh key
202  * @param[in] key the ssh_key handle
203  * @returns one of SSH_KEYTYPE_RSA, SSH_KEYTYPE_DSS,
204  *          SSH_KEYTYPE_ECDSA_P256, SSH_KEYTYPE_ECDSA_P384,
205  *          SSH_KEYTYPE_ECDSA_P521, SSH_KEYTYPE_ED25519, SSH_KEYTYPE_DSS_CERT01,
206  *          SSH_KEYTYPE_RSA_CERT01, SSH_KEYTYPE_ECDSA_P256_CERT01,
207  *          SSH_KEYTYPE_ECDSA_P384_CERT01, SSH_KEYTYPE_ECDSA_P521_CERT01, or
208  *          SSH_KEYTYPE_ED25519_CERT01.
209  * @returns SSH_KEYTYPE_UNKNOWN if the type is unknown
210  */
ssh_key_type(const ssh_key key)211 enum ssh_keytypes_e ssh_key_type(const ssh_key key){
212     if (key == NULL) {
213         return SSH_KEYTYPE_UNKNOWN;
214     }
215     return key->type;
216 }
217 
218 /**
219  * @brief Convert a signature type to a string.
220  *
221  * @param[in]  type     The algorithm type to convert.
222  *
223  * @return              A string for the keytype or NULL if unknown.
224  */
225 const char *
ssh_key_signature_to_char(enum ssh_keytypes_e type,enum ssh_digest_e hash_type)226 ssh_key_signature_to_char(enum ssh_keytypes_e type,
227                           enum ssh_digest_e hash_type)
228 {
229     switch (type) {
230     case SSH_KEYTYPE_RSA:
231         switch (hash_type) {
232         case SSH_DIGEST_SHA256:
233             return "rsa-sha2-256";
234         case SSH_DIGEST_SHA512:
235             return "rsa-sha2-512";
236         case SSH_DIGEST_SHA1:
237         case SSH_DIGEST_AUTO:
238             return "ssh-rsa";
239         default:
240             return NULL;
241         }
242         break;
243     case SSH_KEYTYPE_RSA_CERT01:
244         switch (hash_type) {
245         case SSH_DIGEST_SHA256:
246             return "rsa-sha2-256-cert-v01@openssh.com";
247         case SSH_DIGEST_SHA512:
248             return "rsa-sha2-512-cert-v01@openssh.com";
249         case SSH_DIGEST_SHA1:
250         case SSH_DIGEST_AUTO:
251             return "ssh-rsa-cert-v01@openssh.com";
252         default:
253             return NULL;
254         }
255         break;
256     default:
257         return ssh_key_type_to_char(type);
258     }
259 
260     /* We should never reach this */
261     return NULL;
262 }
263 
264 /**
265  * @brief Convert a key type to a string.
266  *
267  * @param[in]  type     The type to convert.
268  *
269  * @return              A string for the keytype or NULL if unknown.
270  */
ssh_key_type_to_char(enum ssh_keytypes_e type)271 const char *ssh_key_type_to_char(enum ssh_keytypes_e type) {
272   switch (type) {
273     case SSH_KEYTYPE_DSS:
274       return "ssh-dss";
275     case SSH_KEYTYPE_RSA:
276       return "ssh-rsa";
277     case SSH_KEYTYPE_ECDSA:
278       return "ssh-ecdsa"; /* deprecated. invalid value */
279     case SSH_KEYTYPE_ECDSA_P256:
280       return "ecdsa-sha2-nistp256";
281     case SSH_KEYTYPE_ECDSA_P384:
282       return "ecdsa-sha2-nistp384";
283     case SSH_KEYTYPE_ECDSA_P521:
284       return "ecdsa-sha2-nistp521";
285     case SSH_KEYTYPE_ED25519:
286       return "ssh-ed25519";
287     case SSH_KEYTYPE_DSS_CERT01:
288       return "ssh-dss-cert-v01@openssh.com";
289     case SSH_KEYTYPE_RSA_CERT01:
290       return "ssh-rsa-cert-v01@openssh.com";
291     case SSH_KEYTYPE_ECDSA_P256_CERT01:
292       return "ecdsa-sha2-nistp256-cert-v01@openssh.com";
293     case SSH_KEYTYPE_ECDSA_P384_CERT01:
294       return "ecdsa-sha2-nistp384-cert-v01@openssh.com";
295     case SSH_KEYTYPE_ECDSA_P521_CERT01:
296       return "ecdsa-sha2-nistp521-cert-v01@openssh.com";
297     case SSH_KEYTYPE_ED25519_CERT01:
298       return "ssh-ed25519-cert-v01@openssh.com";
299     case SSH_KEYTYPE_RSA1:
300     case SSH_KEYTYPE_UNKNOWN:
301       return NULL;
302   }
303 
304   /* We should never reach this */
305   return NULL;
306 }
307 
ssh_key_hash_from_name(const char * name)308 enum ssh_digest_e ssh_key_hash_from_name(const char *name)
309 {
310     if (name == NULL) {
311         /* TODO we should rather fail */
312         return SSH_DIGEST_AUTO;
313     }
314 
315     if (strcmp(name, "ssh-rsa") == 0) {
316         return SSH_DIGEST_SHA1;
317     } else if (strcmp(name, "ssh-dss") == 0) {
318         return SSH_DIGEST_SHA1;
319     } else if (strcmp(name, "rsa-sha2-256") == 0) {
320         return SSH_DIGEST_SHA256;
321     } else if (strcmp(name, "rsa-sha2-512") == 0) {
322         return SSH_DIGEST_SHA512;
323     } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
324         return SSH_DIGEST_SHA256;
325     } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
326         return SSH_DIGEST_SHA384;
327     } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
328         return SSH_DIGEST_SHA512;
329     } else if (strcmp(name, "ssh-ed25519") == 0) {
330         return SSH_DIGEST_AUTO;
331     }
332 
333     SSH_LOG(SSH_LOG_WARN, "Unknown signature name %s", name);
334 
335     /* TODO we should rather fail */
336     return SSH_DIGEST_AUTO;
337 }
338 
339 /**
340  * @brief Checks the given key against the configured allowed
341  * public key algorithm types
342  *
343  * @param[in] session The SSH session
344  * @param[in] type    The key algorithm to check
345  * @returns           1 if the key algorithm is allowed, 0 otherwise
346  */
ssh_key_algorithm_allowed(ssh_session session,const char * type)347 int ssh_key_algorithm_allowed(ssh_session session, const char *type)
348 {
349     const char *allowed_list;
350 
351     if (session->client) {
352         allowed_list = session->opts.pubkey_accepted_types;
353         if (allowed_list == NULL) {
354             if (ssh_fips_mode()) {
355                 allowed_list = ssh_kex_get_fips_methods(SSH_HOSTKEYS);
356             } else {
357                 allowed_list = ssh_kex_get_default_methods(SSH_HOSTKEYS);
358             }
359         }
360     }
361 #ifdef WITH_SERVER
362     else if (session->server) {
363         allowed_list = session->opts.wanted_methods[SSH_HOSTKEYS];
364         if (allowed_list == NULL) {
365             SSH_LOG(SSH_LOG_WARN, "Session invalid: no host key available");
366             return 0;
367         }
368     }
369 #endif
370     else {
371         SSH_LOG(SSH_LOG_WARN, "Session invalid: not set as client nor server");
372         return 0;
373     }
374 
375     SSH_LOG(SSH_LOG_DEBUG, "Checking %s with list <%s>", type, allowed_list);
376     return ssh_match_group(allowed_list, type);
377 }
378 
379 /**
380  * @brief Convert a key type to a hash type. This is usually unambiguous
381  * for all the key types, unless the SHA2 extension (RFC 8332) is
382  * negotiated during key exchange.
383  *
384  * @param[in]  session  SSH Session.
385  *
386  * @param[in]  type     The type to convert.
387  *
388  * @return              A hash type to be used.
389  */
ssh_key_type_to_hash(ssh_session session,enum ssh_keytypes_e type)390 enum ssh_digest_e ssh_key_type_to_hash(ssh_session session,
391                                        enum ssh_keytypes_e type)
392 {
393     switch (type) {
394     case SSH_KEYTYPE_DSS_CERT01:
395     case SSH_KEYTYPE_DSS:
396         return SSH_DIGEST_SHA1;
397     case SSH_KEYTYPE_RSA_CERT01:
398         /* If we are talking to an old OpenSSH version which does not support
399          * SHA2 in certificates */
400         if ((session->openssh > 0) &&
401             (session->openssh < SSH_VERSION_INT(7, 2, 0)))
402         {
403             SSH_LOG(SSH_LOG_DEBUG,
404                     "We are talking to an old OpenSSH (%x); "
405                     "returning SSH_DIGEST_SHA1",
406                     session->openssh);
407 
408             return SSH_DIGEST_SHA1;
409         }
410         FALL_THROUGH;
411     case SSH_KEYTYPE_RSA:
412         if (ssh_key_algorithm_allowed(session, "rsa-sha2-512") &&
413             (session->extensions & SSH_EXT_SIG_RSA_SHA512)) {
414             return SSH_DIGEST_SHA512;
415         }
416 
417         if (ssh_key_algorithm_allowed(session, "rsa-sha2-256") &&
418             (session->extensions & SSH_EXT_SIG_RSA_SHA256)) {
419             return SSH_DIGEST_SHA256;
420         }
421 
422         /* Default algorithm for RSA is SHA1 */
423         return SSH_DIGEST_SHA1;
424 
425     case SSH_KEYTYPE_ECDSA_P256_CERT01:
426     case SSH_KEYTYPE_ECDSA_P256:
427         return SSH_DIGEST_SHA256;
428     case SSH_KEYTYPE_ECDSA_P384_CERT01:
429     case SSH_KEYTYPE_ECDSA_P384:
430         return SSH_DIGEST_SHA384;
431     case SSH_KEYTYPE_ECDSA_P521_CERT01:
432     case SSH_KEYTYPE_ECDSA_P521:
433         return SSH_DIGEST_SHA512;
434     case SSH_KEYTYPE_ED25519_CERT01:
435     case SSH_KEYTYPE_ED25519:
436         return SSH_DIGEST_AUTO;
437     case SSH_KEYTYPE_RSA1:
438     case SSH_KEYTYPE_ECDSA:
439     case SSH_KEYTYPE_UNKNOWN:
440     default:
441         SSH_LOG(SSH_LOG_WARN, "Digest algorithm to be used with key type %u "
442                 "is not defined", type);
443     }
444 
445     /* We should never reach this */
446     return SSH_DIGEST_AUTO;
447 }
448 
449 /**
450  * @brief Gets signature algorithm name to be used with the given
451  *        key type.
452  *
453  * @param[in]  session  SSH session.
454  * @param[in]  type     The algorithm type to convert.
455  *
456  * @return              A string for the keytype or NULL if unknown.
457  */
458 const char *
ssh_key_get_signature_algorithm(ssh_session session,enum ssh_keytypes_e type)459 ssh_key_get_signature_algorithm(ssh_session session,
460                                 enum ssh_keytypes_e type)
461 {
462     enum ssh_digest_e hash_type;
463 
464     if (type == SSH_KEYTYPE_RSA_CERT01) {
465         /* If we are talking to an old OpenSSH version which does not support
466          * rsa-sha2-{256,512}-cert-v01@openssh.com */
467         if ((session->openssh > 0) &&
468             (session->openssh < SSH_VERSION_INT(7, 8, 0)))
469         {
470             SSH_LOG(SSH_LOG_DEBUG,
471                     "We are talking to an old OpenSSH (%x); "
472                     "using old cert format",
473                     session->openssh);
474 
475             return "ssh-rsa-cert-v01@openssh.com";
476         }
477     }
478 
479     hash_type = ssh_key_type_to_hash(session, type);
480 
481     return ssh_key_signature_to_char(type, hash_type);
482 }
483 
484 /**
485  * @brief Convert a ssh key algorithm name to a ssh key algorithm type.
486  *
487  * @param[in] name      The name to convert.
488  *
489  * @return              The enum ssh key algorithm type.
490  */
ssh_key_type_from_signature_name(const char * name)491 enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name) {
492     if (name == NULL) {
493         return SSH_KEYTYPE_UNKNOWN;
494     }
495 
496     if ((strcmp(name, "rsa-sha2-256") == 0) ||
497         (strcmp(name, "rsa-sha2-512") == 0)) {
498         return SSH_KEYTYPE_RSA;
499     }
500 
501     /* Otherwise the key type matches the signature type */
502     return ssh_key_type_from_name(name);
503 }
504 
505 /**
506  * @brief Convert a ssh key name to a ssh key type.
507  *
508  * @param[in] name      The name to convert.
509  *
510  * @return              The enum ssh key type.
511  */
ssh_key_type_from_name(const char * name)512 enum ssh_keytypes_e ssh_key_type_from_name(const char *name) {
513     if (name == NULL) {
514         return SSH_KEYTYPE_UNKNOWN;
515     }
516 
517     if (strcmp(name, "rsa") == 0) {
518         return SSH_KEYTYPE_RSA;
519     } else if (strcmp(name, "dsa") == 0) {
520         return SSH_KEYTYPE_DSS;
521     } else if (strcmp(name, "ssh-rsa") == 0) {
522         return SSH_KEYTYPE_RSA;
523     } else if (strcmp(name, "ssh-dss") == 0) {
524         return SSH_KEYTYPE_DSS;
525     } else if (strcmp(name, "ssh-ecdsa") == 0
526             || strcmp(name, "ecdsa") == 0
527             || strcmp(name, "ecdsa-sha2-nistp256") == 0) {
528         return SSH_KEYTYPE_ECDSA_P256;
529     } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
530         return SSH_KEYTYPE_ECDSA_P384;
531     } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
532         return SSH_KEYTYPE_ECDSA_P521;
533     } else if (strcmp(name, "ssh-ed25519") == 0){
534         return SSH_KEYTYPE_ED25519;
535     } else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) {
536         return SSH_KEYTYPE_DSS_CERT01;
537     } else if (strcmp(name, "ssh-rsa-cert-v01@openssh.com") == 0) {
538         return SSH_KEYTYPE_RSA_CERT01;
539     } else if (strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0) {
540         return SSH_KEYTYPE_ECDSA_P256_CERT01;
541     } else if (strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0) {
542         return SSH_KEYTYPE_ECDSA_P384_CERT01;
543     } else if (strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) {
544         return SSH_KEYTYPE_ECDSA_P521_CERT01;
545     } else if (strcmp(name, "ssh-ed25519-cert-v01@openssh.com") == 0) {
546         return SSH_KEYTYPE_ED25519_CERT01;
547     }
548 
549     return SSH_KEYTYPE_UNKNOWN;
550 }
551 
552 /**
553  * @brief Get the pubic key type corresponding to a certificate type.
554  *
555  * @param[in] type   The certificate or public key type.
556  *
557  * @return           The matching public key type.
558  */
ssh_key_type_plain(enum ssh_keytypes_e type)559 enum ssh_keytypes_e ssh_key_type_plain(enum ssh_keytypes_e type) {
560     switch (type) {
561         case SSH_KEYTYPE_DSS_CERT01:
562             return SSH_KEYTYPE_DSS;
563         case SSH_KEYTYPE_RSA_CERT01:
564             return SSH_KEYTYPE_RSA;
565         case SSH_KEYTYPE_ECDSA_P256_CERT01:
566             return SSH_KEYTYPE_ECDSA_P256;
567         case SSH_KEYTYPE_ECDSA_P384_CERT01:
568             return SSH_KEYTYPE_ECDSA_P384;
569         case SSH_KEYTYPE_ECDSA_P521_CERT01:
570             return SSH_KEYTYPE_ECDSA_P521;
571         case SSH_KEYTYPE_ED25519_CERT01:
572             return SSH_KEYTYPE_ED25519;
573         default:
574             return type;
575     }
576 }
577 
578 /**
579  * @brief Check if the key has/is a public key.
580  *
581  * @param[in] k         The key to check.
582  *
583  * @return              1 if it is a public key, 0 if not.
584  */
ssh_key_is_public(const ssh_key k)585 int ssh_key_is_public(const ssh_key k) {
586     if (k == NULL) {
587         return 0;
588     }
589 
590     return (k->flags & SSH_KEY_FLAG_PUBLIC) == SSH_KEY_FLAG_PUBLIC;
591 }
592 
593 /**
594  * @brief Check if the key is a private key.
595  *
596  * @param[in] k         The key to check.
597  *
598  * @return              1 if it is a private key, 0 if not.
599  */
ssh_key_is_private(const ssh_key k)600 int ssh_key_is_private(const ssh_key k) {
601     if (k == NULL) {
602         return 0;
603     }
604 
605     return (k->flags & SSH_KEY_FLAG_PRIVATE) == SSH_KEY_FLAG_PRIVATE;
606 }
607 
608 /**
609  * @brief Compare keys if they are equal.
610  *
611  * @param[in] k1        The first key to compare.
612  *
613  * @param[in] k2        The second key to compare.
614  *
615  * @param[in] what      What part or type of the key do you want to compare.
616  *
617  * @return              0 if equal, 1 if not.
618  */
ssh_key_cmp(const ssh_key k1,const ssh_key k2,enum ssh_keycmp_e what)619 int ssh_key_cmp(const ssh_key k1,
620                 const ssh_key k2,
621                 enum ssh_keycmp_e what)
622 {
623     if (k1 == NULL || k2 == NULL) {
624         return 1;
625     }
626 
627     if (k1->type != k2->type) {
628         SSH_LOG(SSH_LOG_WARN, "key types don't match!");
629         return 1;
630     }
631 
632     if (what == SSH_KEY_CMP_PRIVATE) {
633         if (!ssh_key_is_private(k1) ||
634             !ssh_key_is_private(k2)) {
635             return 1;
636         }
637     }
638 
639     if (k1->type == SSH_KEYTYPE_ED25519) {
640         return pki_ed25519_key_cmp(k1, k2, what);
641     }
642 
643     return pki_key_compare(k1, k2, what);
644 }
645 
ssh_signature_new(void)646 ssh_signature ssh_signature_new(void)
647 {
648     struct ssh_signature_struct *sig;
649 
650     sig = malloc(sizeof(struct ssh_signature_struct));
651     if (sig == NULL) {
652         return NULL;
653     }
654     ZERO_STRUCTP(sig);
655 
656     return sig;
657 }
658 
ssh_signature_free(ssh_signature sig)659 void ssh_signature_free(ssh_signature sig)
660 {
661     if (sig == NULL) {
662         return;
663     }
664 
665     switch(sig->type) {
666         case SSH_KEYTYPE_DSS:
667 #ifdef HAVE_LIBGCRYPT
668             gcry_sexp_release(sig->dsa_sig);
669 #endif
670             break;
671         case SSH_KEYTYPE_RSA:
672 #ifdef HAVE_LIBGCRYPT
673             gcry_sexp_release(sig->rsa_sig);
674 #elif defined HAVE_LIBMBEDCRYPTO
675             SAFE_FREE(sig->rsa_sig);
676 #endif
677             break;
678         case SSH_KEYTYPE_ECDSA_P256:
679         case SSH_KEYTYPE_ECDSA_P384:
680         case SSH_KEYTYPE_ECDSA_P521:
681 #ifdef HAVE_GCRYPT_ECC
682             gcry_sexp_release(sig->ecdsa_sig);
683 #elif defined HAVE_LIBMBEDCRYPTO
684             bignum_safe_free(sig->ecdsa_sig.r);
685             bignum_safe_free(sig->ecdsa_sig.s);
686 #endif
687             break;
688         case SSH_KEYTYPE_ED25519:
689 #ifndef HAVE_OPENSSL_ED25519
690             /* When using OpenSSL, the signature is stored in sig->raw_sig */
691             SAFE_FREE(sig->ed25519_sig);
692 #endif
693             break;
694         case SSH_KEYTYPE_DSS_CERT01:
695         case SSH_KEYTYPE_RSA_CERT01:
696         case SSH_KEYTYPE_ECDSA_P256_CERT01:
697         case SSH_KEYTYPE_ECDSA_P384_CERT01:
698         case SSH_KEYTYPE_ECDSA_P521_CERT01:
699         case SSH_KEYTYPE_ED25519_CERT01:
700         case SSH_KEYTYPE_RSA1:
701         case SSH_KEYTYPE_ECDSA:
702         case SSH_KEYTYPE_UNKNOWN:
703             break;
704     }
705 
706     /* Explicitly zero the signature content before free */
707     ssh_string_burn(sig->raw_sig);
708     SSH_STRING_FREE(sig->raw_sig);
709     SAFE_FREE(sig);
710 }
711 
712 /**
713  * @brief import a base64 formated key from a memory c-string
714  *
715  * @param[in]  b64_key  The c-string holding the base64 encoded key
716  *
717  * @param[in]  passphrase The passphrase to decrypt the key, or NULL
718  *
719  * @param[in]  auth_fn  An auth function you may want to use or NULL.
720  *
721  * @param[in]  auth_data Private data passed to the auth function.
722  *
723  * @param[out] pkey     A pointer where the allocated key can be stored. You
724  *                      need to free the memory.
725  *
726  * @return  SSH_ERROR in case of error, SSH_OK otherwise.
727  *
728  * @see ssh_key_free()
729  */
ssh_pki_import_privkey_base64(const char * b64_key,const char * passphrase,ssh_auth_callback auth_fn,void * auth_data,ssh_key * pkey)730 int ssh_pki_import_privkey_base64(const char *b64_key,
731                                   const char *passphrase,
732                                   ssh_auth_callback auth_fn,
733                                   void *auth_data,
734                                   ssh_key *pkey)
735 {
736     ssh_key key;
737     char *openssh_header = NULL;
738 
739     if (b64_key == NULL || pkey == NULL) {
740         return SSH_ERROR;
741     }
742 
743     if (b64_key == NULL || !*b64_key) {
744         return SSH_ERROR;
745     }
746 
747     SSH_LOG(SSH_LOG_INFO,
748             "Trying to decode privkey passphrase=%s",
749             passphrase ? "true" : "false");
750 
751     /* Test for OpenSSH key format first */
752     openssh_header = strstr(b64_key, OPENSSH_HEADER_BEGIN);
753     if (openssh_header != NULL) {
754         key = ssh_pki_openssh_privkey_import(openssh_header,
755                                              passphrase,
756                                              auth_fn,
757                                              auth_data);
758     } else {
759         /* fallback on PEM decoder */
760         key = pki_private_key_from_base64(b64_key,
761                                           passphrase,
762                                           auth_fn,
763                                           auth_data);
764     }
765     if (key == NULL) {
766         return SSH_ERROR;
767     }
768 
769     *pkey = key;
770 
771     return SSH_OK;
772 }
773  /**
774  * @brief Convert a private key to a pem base64 encoded key, or OpenSSH format for
775  *        keytype ssh-ed25519
776  *
777  * @param[in]  privkey  The private key to export.
778  *
779  * @param[in]  passphrase The passphrase to use to encrypt the key with or
780  *             NULL. An empty string means no passphrase.
781  *
782  * @param[in]  auth_fn  An auth function you may want to use or NULL.
783  *
784  * @param[in]  auth_data Private data passed to the auth function.
785  *
786  * @param[out] b64_key  A pointer to store the allocated base64 encoded key. You
787  *                      need to free the buffer.
788  *
789  * @return     SSH_OK on success, SSH_ERROR on error.
790  */
ssh_pki_export_privkey_base64(const ssh_key privkey,const char * passphrase,ssh_auth_callback auth_fn,void * auth_data,char ** b64_key)791 int ssh_pki_export_privkey_base64(const ssh_key privkey,
792                                   const char *passphrase,
793                                   ssh_auth_callback auth_fn,
794                                   void *auth_data,
795                                   char **b64_key)
796 {
797     ssh_string blob = NULL;
798     char *b64 = NULL;
799 
800     if (privkey == NULL || !ssh_key_is_private(privkey)) {
801         return SSH_ERROR;
802     }
803 
804     if (privkey->type == SSH_KEYTYPE_ED25519){
805         blob = ssh_pki_openssh_privkey_export(privkey,
806                                               passphrase,
807                                               auth_fn,
808                                               auth_data);
809     } else {
810         blob = pki_private_key_to_pem(privkey,
811                                       passphrase,
812                                       auth_fn,
813                                       auth_data);
814     }
815     if (blob == NULL) {
816         return SSH_ERROR;
817     }
818 
819     b64 = strndup(ssh_string_data(blob), ssh_string_len(blob));
820     SSH_STRING_FREE(blob);
821     if (b64 == NULL) {
822         return SSH_ERROR;
823     }
824 
825     *b64_key = b64;
826 
827     return SSH_OK;
828 }
829 
830 /**
831  * @brief Import a key from a file.
832  *
833  * @param[in]  filename The filename of the the private key.
834  *
835  * @param[in]  passphrase The passphrase to decrypt the private key. Set to NULL
836  *                        if none is needed or it is unknown.
837  *
838  * @param[in]  auth_fn  An auth function you may want to use or NULL.
839  *
840  * @param[in]  auth_data Private data passed to the auth function.
841  *
842  * @param[out] pkey     A pointer to store the allocated ssh_key. You need to
843  *                      free the key.
844  *
845  * @returns SSH_OK on success, SSH_EOF if the file doesn't exist or permission
846  *          denied, SSH_ERROR otherwise.
847  *
848  * @see ssh_key_free()
849  **/
ssh_pki_import_privkey_file(const char * filename,const char * passphrase,ssh_auth_callback auth_fn,void * auth_data,ssh_key * pkey)850 int ssh_pki_import_privkey_file(const char *filename,
851                                 const char *passphrase,
852                                 ssh_auth_callback auth_fn,
853                                 void *auth_data,
854                                 ssh_key *pkey) {
855     struct stat sb;
856     char *key_buf;
857     FILE *file;
858     off_t size;
859     int rc;
860 
861     if (pkey == NULL || filename == NULL || *filename == '\0') {
862         return SSH_ERROR;
863     }
864 
865     file = fopen(filename, "rb");
866     if (file == NULL) {
867         SSH_LOG(SSH_LOG_WARN,
868                 "Error opening %s: %s",
869                 filename,
870                 strerror(errno));
871         return SSH_EOF;
872     }
873 
874     rc = fstat(fileno(file), &sb);
875     if (rc < 0) {
876         fclose(file);
877         SSH_LOG(SSH_LOG_WARN,
878                 "Error getting stat of %s: %s",
879                 filename,
880                 strerror(errno));
881         switch (errno) {
882             case ENOENT:
883             case EACCES:
884                 return SSH_EOF;
885         }
886 
887         return SSH_ERROR;
888     }
889 
890     if (sb.st_size > MAX_PRIVKEY_SIZE) {
891         SSH_LOG(SSH_LOG_WARN,
892                 "Private key is bigger than 4M.");
893         fclose(file);
894         return SSH_ERROR;
895     }
896 
897     key_buf = malloc(sb.st_size + 1);
898     if (key_buf == NULL) {
899         fclose(file);
900         SSH_LOG(SSH_LOG_WARN, "Out of memory!");
901         return SSH_ERROR;
902     }
903 
904     size = fread(key_buf, 1, sb.st_size, file);
905     fclose(file);
906 
907     if (size != sb.st_size) {
908         SAFE_FREE(key_buf);
909         SSH_LOG(SSH_LOG_WARN,
910                 "Error reading %s: %s",
911                 filename,
912                 strerror(errno));
913         return SSH_ERROR;
914     }
915     key_buf[size] = 0;
916 
917     rc = ssh_pki_import_privkey_base64(key_buf,
918                                        passphrase,
919                                        auth_fn,
920                                        auth_data,
921                                        pkey);
922 
923     SAFE_FREE(key_buf);
924     return rc;
925 }
926 
927 /**
928  * @brief Export a private key to a pem file on disk, or OpenSSH format for
929  *        keytype ssh-ed25519
930  *
931  * @param[in]  privkey  The private key to export.
932  *
933  * @param[in]  passphrase The passphrase to use to encrypt the key with or
934  *             NULL. An empty string means no passphrase.
935  *
936  * @param[in]  auth_fn  An auth function you may want to use or NULL.
937  *
938  * @param[in]  auth_data Private data passed to the auth function.
939  *
940  * @param[in]  filename  The path where to store the pem file.
941  *
942  * @return     SSH_OK on success, SSH_ERROR on error.
943  */
ssh_pki_export_privkey_file(const ssh_key privkey,const char * passphrase,ssh_auth_callback auth_fn,void * auth_data,const char * filename)944 int ssh_pki_export_privkey_file(const ssh_key privkey,
945                                 const char *passphrase,
946                                 ssh_auth_callback auth_fn,
947                                 void *auth_data,
948                                 const char *filename)
949 {
950     ssh_string blob;
951     FILE *fp;
952     int rc;
953 
954     if (privkey == NULL || !ssh_key_is_private(privkey)) {
955         return SSH_ERROR;
956     }
957 
958     fp = fopen(filename, "wb");
959     if (fp == NULL) {
960         SSH_LOG(SSH_LOG_FUNCTIONS, "Error opening %s: %s",
961                 filename, strerror(errno));
962         return SSH_EOF;
963     }
964 
965     if (privkey->type == SSH_KEYTYPE_ED25519){
966         blob = ssh_pki_openssh_privkey_export(privkey,
967                                               passphrase,
968                                               auth_fn,
969                                               auth_data);
970     } else {
971         blob = pki_private_key_to_pem(privkey,
972                                       passphrase,
973                                       auth_fn,
974                                       auth_data);
975     }
976     if (blob == NULL) {
977         fclose(fp);
978         return -1;
979     }
980 
981     rc = fwrite(ssh_string_data(blob), ssh_string_len(blob), 1, fp);
982     SSH_STRING_FREE(blob);
983     if (rc != 1 || ferror(fp)) {
984         fclose(fp);
985         unlink(filename);
986         return SSH_ERROR;
987     }
988     fclose(fp);
989 
990     return SSH_OK;
991 }
992 
993 /* temporary function to migrate seemlessly to ssh_key */
ssh_pki_convert_key_to_publickey(const ssh_key key)994 ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key) {
995     ssh_public_key pub;
996     ssh_key tmp;
997 
998     if(key == NULL) {
999         return NULL;
1000     }
1001 
1002     tmp = ssh_key_dup(key);
1003     if (tmp == NULL) {
1004         return NULL;
1005     }
1006 
1007     pub = malloc(sizeof(struct ssh_public_key_struct));
1008     if (pub == NULL) {
1009         ssh_key_free(tmp);
1010         return NULL;
1011     }
1012     ZERO_STRUCTP(pub);
1013 
1014     pub->type = tmp->type;
1015     pub->type_c = tmp->type_c;
1016 
1017     pub->dsa_pub = tmp->dsa;
1018     tmp->dsa = NULL;
1019     pub->rsa_pub = tmp->rsa;
1020     tmp->rsa = NULL;
1021 
1022     ssh_key_free(tmp);
1023 
1024     return pub;
1025 }
1026 
ssh_pki_convert_key_to_privatekey(const ssh_key key)1027 ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key) {
1028     ssh_private_key privkey;
1029 
1030     privkey = malloc(sizeof(struct ssh_private_key_struct));
1031     if (privkey == NULL) {
1032         ssh_key_free(key);
1033         return NULL;
1034     }
1035 
1036     privkey->type = key->type;
1037     privkey->dsa_priv = key->dsa;
1038     privkey->rsa_priv = key->rsa;
1039 
1040     return privkey;
1041 }
1042 
pki_import_privkey_buffer(enum ssh_keytypes_e type,ssh_buffer buffer,ssh_key * pkey)1043 int pki_import_privkey_buffer(enum ssh_keytypes_e type,
1044                               ssh_buffer buffer,
1045                               ssh_key *pkey)
1046 {
1047     ssh_key key = NULL;
1048     int rc;
1049 
1050     key = ssh_key_new();
1051     if (key == NULL) {
1052         return SSH_ERROR;
1053     }
1054 
1055     key->type = type;
1056     key->type_c = ssh_key_type_to_char(type);
1057     key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
1058 
1059     switch (type) {
1060         case SSH_KEYTYPE_DSS:
1061             {
1062                 ssh_string p = NULL;
1063                 ssh_string q = NULL;
1064                 ssh_string g = NULL;
1065                 ssh_string pubkey = NULL;
1066                 ssh_string privkey = NULL;
1067 
1068                 rc = ssh_buffer_unpack(buffer, "SSSSS", &p, &q, &g,
1069                                        &pubkey, &privkey);
1070                 if (rc != SSH_OK) {
1071                     SSH_LOG(SSH_LOG_WARN, "Unpack error");
1072                     goto fail;
1073                 }
1074 
1075                 rc = pki_privkey_build_dss(key, p, q, g, pubkey, privkey);
1076 #ifdef DEBUG_CRYPTO
1077                 ssh_log_hexdump("p", ssh_string_data(p), ssh_string_len(p));
1078                 ssh_log_hexdump("q", ssh_string_data(q), ssh_string_len(q));
1079                 ssh_log_hexdump("g", ssh_string_data(g), ssh_string_len(g));
1080                 ssh_log_hexdump("pubkey", ssh_string_data(pubkey),
1081                                ssh_string_len(pubkey));
1082                 ssh_log_hexdump("privkey", ssh_string_data(privkey),
1083                                ssh_string_len(privkey));
1084 #endif
1085                 ssh_string_burn(p);
1086                 SSH_STRING_FREE(p);
1087                 ssh_string_burn(q);
1088                 SSH_STRING_FREE(q);
1089                 ssh_string_burn(g);
1090                 SSH_STRING_FREE(g);
1091                 ssh_string_burn(pubkey);
1092                 SSH_STRING_FREE(pubkey);
1093                 ssh_string_burn(privkey);
1094                 SSH_STRING_FREE(privkey);
1095                 if (rc == SSH_ERROR) {
1096                     goto fail;
1097                 }
1098             }
1099             break;
1100         case SSH_KEYTYPE_RSA:
1101             {
1102                 ssh_string n = NULL;
1103                 ssh_string e = NULL;
1104                 ssh_string d = NULL;
1105                 ssh_string iqmp = NULL;
1106                 ssh_string p = NULL;
1107                 ssh_string q = NULL;
1108 
1109                 rc = ssh_buffer_unpack(buffer, "SSSSSS", &n, &e, &d,
1110                                        &iqmp, &p, &q);
1111                 if (rc != SSH_OK) {
1112                     SSH_LOG(SSH_LOG_WARN, "Unpack error");
1113                     goto fail;
1114                 }
1115 
1116                 rc = pki_privkey_build_rsa(key, n, e, d, iqmp, p, q);
1117 #ifdef DEBUG_CRYPTO
1118                 ssh_log_hexdump("n", ssh_string_data(n), ssh_string_len(n));
1119                 ssh_log_hexdump("e", ssh_string_data(e), ssh_string_len(e));
1120                 ssh_log_hexdump("d", ssh_string_data(d), ssh_string_len(d));
1121                 ssh_log_hexdump("iqmp", ssh_string_data(iqmp),
1122                                ssh_string_len(iqmp));
1123                 ssh_log_hexdump("p", ssh_string_data(p), ssh_string_len(p));
1124                 ssh_log_hexdump("q", ssh_string_data(q), ssh_string_len(q));
1125 #endif
1126                 ssh_string_burn(n);
1127                 SSH_STRING_FREE(n);
1128                 ssh_string_burn(e);
1129                 SSH_STRING_FREE(e);
1130                 ssh_string_burn(d);
1131                 SSH_STRING_FREE(d);
1132                 ssh_string_burn(iqmp);
1133                 SSH_STRING_FREE(iqmp);
1134                 ssh_string_burn(p);
1135                 SSH_STRING_FREE(p);
1136                 ssh_string_burn(q);
1137                 SSH_STRING_FREE(q);
1138                 if (rc == SSH_ERROR) {
1139                     SSH_LOG(SSH_LOG_WARN, "Failed to build RSA private key");
1140                     goto fail;
1141                 }
1142             }
1143             break;
1144 #ifdef HAVE_ECC
1145         case SSH_KEYTYPE_ECDSA_P256:
1146         case SSH_KEYTYPE_ECDSA_P384:
1147         case SSH_KEYTYPE_ECDSA_P521:
1148             {
1149                 ssh_string e = NULL;
1150                 ssh_string exp = NULL;
1151                 ssh_string i = NULL;
1152                 int nid;
1153 
1154                 rc = ssh_buffer_unpack(buffer, "SSS", &i, &e, &exp);
1155                 if (rc != SSH_OK) {
1156                     SSH_LOG(SSH_LOG_WARN, "Unpack error");
1157                     goto fail;
1158                 }
1159 
1160                 nid = pki_key_ecdsa_nid_from_name(ssh_string_get_char(i));
1161                 SSH_STRING_FREE(i);
1162                 if (nid == -1) {
1163                     ssh_string_burn(e);
1164                     SSH_STRING_FREE(e);
1165                     ssh_string_burn(exp);
1166                     SSH_STRING_FREE(exp);
1167                     goto fail;
1168                 }
1169 
1170                 rc = pki_privkey_build_ecdsa(key, nid, e, exp);
1171                 ssh_string_burn(e);
1172                 SSH_STRING_FREE(e);
1173                 ssh_string_burn(exp);
1174                 SSH_STRING_FREE(exp);
1175                 if (rc < 0) {
1176                     SSH_LOG(SSH_LOG_WARN, "Failed to build ECDSA private key");
1177                     goto fail;
1178                 }
1179             }
1180             break;
1181 #endif
1182         case SSH_KEYTYPE_ED25519:
1183             {
1184                 ssh_string pubkey = NULL, privkey = NULL;
1185 
1186                 rc = ssh_buffer_unpack(buffer, "SS", &pubkey, &privkey);
1187                 if (rc != SSH_OK){
1188                     SSH_LOG(SSH_LOG_WARN, "Unpack error");
1189                     goto fail;
1190                 }
1191 
1192                 rc = pki_privkey_build_ed25519(key, pubkey, privkey);
1193                 ssh_string_burn(privkey);
1194                 SSH_STRING_FREE(privkey);
1195                 SSH_STRING_FREE(pubkey);
1196                 if (rc != SSH_OK) {
1197                     SSH_LOG(SSH_LOG_WARN, "Failed to build ed25519 key");
1198                     goto fail;
1199                 }
1200             }
1201             break;
1202         case SSH_KEYTYPE_DSS_CERT01:
1203         case SSH_KEYTYPE_RSA_CERT01:
1204         case SSH_KEYTYPE_ECDSA_P256_CERT01:
1205         case SSH_KEYTYPE_ECDSA_P384_CERT01:
1206         case SSH_KEYTYPE_ECDSA_P521_CERT01:
1207         case SSH_KEYTYPE_ED25519_CERT01:
1208         case SSH_KEYTYPE_RSA1:
1209         case SSH_KEYTYPE_UNKNOWN:
1210         default:
1211             SSH_LOG(SSH_LOG_WARN, "Unknown private key type (%d)", type);
1212             goto fail;
1213     }
1214 
1215     *pkey = key;
1216     return SSH_OK;
1217 fail:
1218     ssh_key_free(key);
1219 
1220     return SSH_ERROR;
1221 }
1222 
pki_import_pubkey_buffer(ssh_buffer buffer,enum ssh_keytypes_e type,ssh_key * pkey)1223 static int pki_import_pubkey_buffer(ssh_buffer buffer,
1224                                     enum ssh_keytypes_e type,
1225                                     ssh_key *pkey) {
1226     ssh_key key = NULL;
1227     int rc;
1228 
1229     key = ssh_key_new();
1230     if (key == NULL) {
1231         return SSH_ERROR;
1232     }
1233 
1234     key->type = type;
1235     key->type_c = ssh_key_type_to_char(type);
1236     key->flags = SSH_KEY_FLAG_PUBLIC;
1237 
1238     switch (type) {
1239         case SSH_KEYTYPE_DSS:
1240             {
1241                 ssh_string p = NULL;
1242                 ssh_string q = NULL;
1243                 ssh_string g = NULL;
1244                 ssh_string pubkey = NULL;
1245 
1246                 rc = ssh_buffer_unpack(buffer, "SSSS", &p, &q, &g, &pubkey);
1247                 if (rc != SSH_OK) {
1248                     SSH_LOG(SSH_LOG_WARN, "Unpack error");
1249                     goto fail;
1250                 }
1251 
1252                 rc = pki_pubkey_build_dss(key, p, q, g, pubkey);
1253 #ifdef DEBUG_CRYPTO
1254                 ssh_log_hexdump("p", ssh_string_data(p), ssh_string_len(p));
1255                 ssh_log_hexdump("q", ssh_string_data(q), ssh_string_len(q));
1256                 ssh_log_hexdump("g", ssh_string_data(g), ssh_string_len(g));
1257 #endif
1258                 ssh_string_burn(p);
1259                 SSH_STRING_FREE(p);
1260                 ssh_string_burn(q);
1261                 SSH_STRING_FREE(q);
1262                 ssh_string_burn(g);
1263                 SSH_STRING_FREE(g);
1264                 ssh_string_burn(pubkey);
1265                 SSH_STRING_FREE(pubkey);
1266                 if (rc == SSH_ERROR) {
1267                     SSH_LOG(SSH_LOG_WARN, "Failed to build DSA public key");
1268                     goto fail;
1269                 }
1270             }
1271             break;
1272         case SSH_KEYTYPE_RSA:
1273             {
1274                 ssh_string e = NULL;
1275                 ssh_string n = NULL;
1276 
1277                 rc = ssh_buffer_unpack(buffer, "SS", &e, &n);
1278                 if (rc != SSH_OK) {
1279                     SSH_LOG(SSH_LOG_WARN, "Unpack error");
1280                     goto fail;
1281                 }
1282 
1283                 rc = pki_pubkey_build_rsa(key, e, n);
1284 #ifdef DEBUG_CRYPTO
1285                 ssh_log_hexdump("e", ssh_string_data(e), ssh_string_len(e));
1286                 ssh_log_hexdump("n", ssh_string_data(n), ssh_string_len(n));
1287 #endif
1288                 ssh_string_burn(e);
1289                 SSH_STRING_FREE(e);
1290                 ssh_string_burn(n);
1291                 SSH_STRING_FREE(n);
1292                 if (rc == SSH_ERROR) {
1293                     SSH_LOG(SSH_LOG_WARN, "Failed to build RSA public key");
1294                     goto fail;
1295                 }
1296             }
1297             break;
1298 #ifdef HAVE_ECC
1299         case SSH_KEYTYPE_ECDSA: /* deprecated */
1300         case SSH_KEYTYPE_ECDSA_P256:
1301         case SSH_KEYTYPE_ECDSA_P384:
1302         case SSH_KEYTYPE_ECDSA_P521:
1303             {
1304                 ssh_string e = NULL;
1305                 ssh_string i = NULL;
1306                 int nid;
1307 
1308                 rc = ssh_buffer_unpack(buffer, "SS", &i, &e);
1309                 if (rc != SSH_OK) {
1310                     SSH_LOG(SSH_LOG_WARN, "Unpack error");
1311                     goto fail;
1312                 }
1313 
1314                 nid = pki_key_ecdsa_nid_from_name(ssh_string_get_char(i));
1315                 SSH_STRING_FREE(i);
1316                 if (nid == -1) {
1317                     goto fail;
1318                 }
1319 
1320                 rc = pki_pubkey_build_ecdsa(key, nid, e);
1321                 ssh_string_burn(e);
1322                 SSH_STRING_FREE(e);
1323                 if (rc < 0) {
1324                     SSH_LOG(SSH_LOG_WARN, "Failed to build ECDSA public key");
1325                     goto fail;
1326                 }
1327 
1328                 /* Update key type */
1329                 if (type == SSH_KEYTYPE_ECDSA) {
1330                     key->type_c = ssh_pki_key_ecdsa_name(key);
1331                 }
1332             }
1333             break;
1334 #endif
1335         case SSH_KEYTYPE_ED25519:
1336         {
1337             ssh_string pubkey = ssh_buffer_get_ssh_string(buffer);
1338             if (ssh_string_len(pubkey) != ED25519_KEY_LEN) {
1339                 SSH_LOG(SSH_LOG_WARN, "Invalid public key length");
1340                 ssh_string_burn(pubkey);
1341                 SSH_STRING_FREE(pubkey);
1342                 goto fail;
1343             }
1344 
1345             key->ed25519_pubkey = malloc(ED25519_KEY_LEN);
1346             if (key->ed25519_pubkey == NULL) {
1347                 ssh_string_burn(pubkey);
1348                 SSH_STRING_FREE(pubkey);
1349                 goto fail;
1350             }
1351 
1352             memcpy(key->ed25519_pubkey, ssh_string_data(pubkey), ED25519_KEY_LEN);
1353             ssh_string_burn(pubkey);
1354             SSH_STRING_FREE(pubkey);
1355         }
1356         break;
1357         case SSH_KEYTYPE_DSS_CERT01:
1358         case SSH_KEYTYPE_RSA_CERT01:
1359         case SSH_KEYTYPE_ECDSA_P256_CERT01:
1360         case SSH_KEYTYPE_ECDSA_P384_CERT01:
1361         case SSH_KEYTYPE_ECDSA_P521_CERT01:
1362         case SSH_KEYTYPE_ED25519_CERT01:
1363         case SSH_KEYTYPE_RSA1:
1364         case SSH_KEYTYPE_UNKNOWN:
1365         default:
1366             SSH_LOG(SSH_LOG_WARN, "Unknown public key protocol %d", type);
1367             goto fail;
1368     }
1369 
1370     *pkey = key;
1371     return SSH_OK;
1372 fail:
1373     ssh_key_free(key);
1374 
1375     return SSH_ERROR;
1376 }
1377 
pki_import_cert_buffer(ssh_buffer buffer,enum ssh_keytypes_e type,ssh_key * pkey)1378 static int pki_import_cert_buffer(ssh_buffer buffer,
1379                                   enum ssh_keytypes_e type,
1380                                   ssh_key *pkey) {
1381     ssh_buffer cert;
1382     ssh_string tmp_s;
1383     const char *type_c;
1384     ssh_key key = NULL;
1385     int rc;
1386 
1387     /*
1388      * The cert blob starts with the key type as an ssh_string, but this
1389      * string has been read out of the buffer to identify the key type.
1390      * Simply add it again as first element before copying the rest.
1391      */
1392     cert = ssh_buffer_new();
1393     if (cert == NULL) {
1394         goto fail;
1395     }
1396     type_c = ssh_key_type_to_char(type);
1397     tmp_s = ssh_string_from_char(type_c);
1398     if (tmp_s == NULL) {
1399         goto fail;
1400     }
1401     rc = ssh_buffer_add_ssh_string(cert, tmp_s);
1402     SSH_STRING_FREE(tmp_s);
1403     if (rc != 0) {
1404         goto fail;
1405     }
1406     rc = ssh_buffer_add_buffer(cert, buffer);
1407     if (rc != 0) {
1408         goto fail;
1409     }
1410 
1411     /*
1412      * After the key type, comes an ssh_string nonce. Just after this comes the
1413      * cert public key, which can be parsed out of the buffer.
1414      */
1415     tmp_s = ssh_buffer_get_ssh_string(buffer);
1416     if (tmp_s == NULL) {
1417         goto fail;
1418     }
1419     SSH_STRING_FREE(tmp_s);
1420 
1421     switch (type) {
1422         case SSH_KEYTYPE_DSS_CERT01:
1423             rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_DSS, &key);
1424             break;
1425         case SSH_KEYTYPE_RSA_CERT01:
1426             rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_RSA, &key);
1427             break;
1428         case SSH_KEYTYPE_ECDSA_P256_CERT01:
1429             rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_ECDSA_P256, &key);
1430             break;
1431         case SSH_KEYTYPE_ECDSA_P384_CERT01:
1432             rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_ECDSA_P384, &key);
1433             break;
1434         case SSH_KEYTYPE_ECDSA_P521_CERT01:
1435             rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_ECDSA_P521, &key);
1436             break;
1437         case SSH_KEYTYPE_ED25519_CERT01:
1438             rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_ED25519, &key);
1439             break;
1440         default:
1441             key = ssh_key_new();
1442     }
1443     if (rc != 0 || key == NULL) {
1444         goto fail;
1445     }
1446 
1447     key->type = type;
1448     key->type_c = type_c;
1449     key->cert = (void*) cert;
1450 
1451     *pkey = key;
1452     return SSH_OK;
1453 
1454 fail:
1455     ssh_key_free(key);
1456     SSH_BUFFER_FREE(cert);
1457     return SSH_ERROR;
1458 }
1459 
1460 /**
1461  * @brief Import a base64 formated public key from a memory c-string.
1462  *
1463  * @param[in]  b64_key  The base64 key to format.
1464  *
1465  * @param[in]  type     The type of the key to format.
1466  *
1467  * @param[out] pkey     A pointer where the allocated key can be stored. You
1468  *                      need to free the memory.
1469  *
1470  * @return              SSH_OK on success, SSH_ERROR on error.
1471  *
1472  * @see ssh_key_free()
1473  */
ssh_pki_import_pubkey_base64(const char * b64_key,enum ssh_keytypes_e type,ssh_key * pkey)1474 int ssh_pki_import_pubkey_base64(const char *b64_key,
1475                                  enum ssh_keytypes_e type,
1476                                  ssh_key *pkey) {
1477     ssh_buffer buffer = NULL;
1478     ssh_string type_s = NULL;
1479     int rc;
1480 
1481     if (b64_key == NULL || pkey == NULL) {
1482         return SSH_ERROR;
1483     }
1484 
1485     buffer = base64_to_bin(b64_key);
1486     if (buffer == NULL) {
1487         return SSH_ERROR;
1488     }
1489 
1490     type_s = ssh_buffer_get_ssh_string(buffer);
1491     if (type_s == NULL) {
1492         SSH_BUFFER_FREE(buffer);
1493         return SSH_ERROR;
1494     }
1495     SSH_STRING_FREE(type_s);
1496 
1497     if (is_cert_type(type)) {
1498         rc = pki_import_cert_buffer(buffer, type, pkey);
1499     } else {
1500         rc = pki_import_pubkey_buffer(buffer, type, pkey);
1501     }
1502     SSH_BUFFER_FREE(buffer);
1503 
1504     return rc;
1505 }
1506 
1507 /**
1508  * @internal
1509  *
1510  * @brief Import a public key from a ssh string.
1511  *
1512  * @param[in]  key_blob The key blob to import as specified in RFC 4253 section
1513  *                      6.6 "Public Key Algorithms".
1514  *
1515  * @param[out] pkey     A pointer where the allocated key can be stored. You
1516  *                      need to free the memory.
1517  *
1518  * @return              SSH_OK on success, SSH_ERROR on error.
1519  *
1520  * @see ssh_key_free()
1521  */
ssh_pki_import_pubkey_blob(const ssh_string key_blob,ssh_key * pkey)1522 int ssh_pki_import_pubkey_blob(const ssh_string key_blob,
1523                                ssh_key *pkey) {
1524     ssh_buffer buffer = NULL;
1525     ssh_string type_s = NULL;
1526     enum ssh_keytypes_e type;
1527     int rc;
1528 
1529     if (key_blob == NULL || pkey == NULL) {
1530         return SSH_ERROR;
1531     }
1532 
1533     buffer = ssh_buffer_new();
1534     if (buffer == NULL) {
1535         SSH_LOG(SSH_LOG_WARN, "Out of memory!");
1536         return SSH_ERROR;
1537     }
1538 
1539     rc = ssh_buffer_add_data(buffer, ssh_string_data(key_blob),
1540             ssh_string_len(key_blob));
1541     if (rc < 0) {
1542         SSH_LOG(SSH_LOG_WARN, "Out of memory!");
1543         goto fail;
1544     }
1545 
1546     type_s = ssh_buffer_get_ssh_string(buffer);
1547     if (type_s == NULL) {
1548         SSH_LOG(SSH_LOG_WARN, "Out of memory!");
1549         goto fail;
1550     }
1551 
1552     type = ssh_key_type_from_name(ssh_string_get_char(type_s));
1553     if (type == SSH_KEYTYPE_UNKNOWN) {
1554         SSH_LOG(SSH_LOG_WARN, "Unknown key type found!");
1555         goto fail;
1556     }
1557     SSH_STRING_FREE(type_s);
1558 
1559     if (is_cert_type(type)) {
1560         rc = pki_import_cert_buffer(buffer, type, pkey);
1561     } else {
1562         rc = pki_import_pubkey_buffer(buffer, type, pkey);
1563     }
1564 
1565     SSH_BUFFER_FREE(buffer);
1566 
1567     return rc;
1568 fail:
1569     SSH_BUFFER_FREE(buffer);
1570     SSH_STRING_FREE(type_s);
1571 
1572     return SSH_ERROR;
1573 }
1574 
1575 /**
1576  * @brief Import a public key from the given filename.
1577  *
1578  * @param[in]  filename The path to the public key.
1579  *
1580  * @param[out] pkey     A pointer to store the allocated public key. You need to
1581  *                      free the memory.
1582  *
1583  * @returns SSH_OK on success, SSH_EOF if the file doesn't exist or permission
1584  *          denied, SSH_ERROR otherwise.
1585  *
1586  * @see ssh_key_free()
1587  */
ssh_pki_import_pubkey_file(const char * filename,ssh_key * pkey)1588 int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey)
1589 {
1590     enum ssh_keytypes_e type;
1591     struct stat sb;
1592     char *key_buf, *p;
1593     size_t buflen, i;
1594     const char *q;
1595     FILE *file;
1596     off_t size;
1597     int rc, cmp;
1598 
1599     if (pkey == NULL || filename == NULL || *filename == '\0') {
1600         return SSH_ERROR;
1601     }
1602 
1603     file = fopen(filename, "rb");
1604     if (file == NULL) {
1605         SSH_LOG(SSH_LOG_WARN, "Error opening %s: %s",
1606                     filename, strerror(errno));
1607         return SSH_EOF;
1608     }
1609 
1610     rc = fstat(fileno(file), &sb);
1611     if (rc < 0) {
1612         fclose(file);
1613         SSH_LOG(SSH_LOG_WARN, "Error gettint stat of %s: %s",
1614                     filename, strerror(errno));
1615         switch (errno) {
1616             case ENOENT:
1617             case EACCES:
1618                 return SSH_EOF;
1619         }
1620         return SSH_ERROR;
1621     }
1622 
1623     if (sb.st_size > MAX_PUBKEY_SIZE) {
1624         fclose(file);
1625         return SSH_ERROR;
1626     }
1627 
1628     key_buf = malloc(sb.st_size + 1);
1629     if (key_buf == NULL) {
1630         fclose(file);
1631         SSH_LOG(SSH_LOG_WARN, "Out of memory!");
1632         return SSH_ERROR;
1633     }
1634 
1635     size = fread(key_buf, 1, sb.st_size, file);
1636     fclose(file);
1637 
1638     if (size != sb.st_size) {
1639         SAFE_FREE(key_buf);
1640         SSH_LOG(SSH_LOG_WARN, "Error reading %s: %s",
1641                     filename, strerror(errno));
1642         return SSH_ERROR;
1643     }
1644     key_buf[size] = '\0';
1645     buflen = strlen(key_buf);
1646 
1647     /* Test for new OpenSSH key format first */
1648     cmp = strncmp(key_buf, OPENSSH_HEADER_BEGIN, strlen(OPENSSH_HEADER_BEGIN));
1649     if (cmp == 0) {
1650         *pkey = ssh_pki_openssh_pubkey_import(key_buf);
1651         SAFE_FREE(key_buf);
1652         if (*pkey == NULL) {
1653             SSH_LOG(SSH_LOG_WARN, "Failed to import public key from OpenSSH"
1654                                   " private key file");
1655             return SSH_ERROR;
1656         }
1657         return SSH_OK;
1658     }
1659 
1660     /* This the old one-line public key format */
1661     q = p = key_buf;
1662     for (i = 0; i < buflen; i++) {
1663         if (isspace((int)p[i])) {
1664             p[i] = '\0';
1665             break;
1666         }
1667     }
1668 
1669     type = ssh_key_type_from_name(q);
1670     if (type == SSH_KEYTYPE_UNKNOWN) {
1671         SAFE_FREE(key_buf);
1672         return SSH_ERROR;
1673     }
1674 
1675     q = &p[i + 1];
1676     for (; i < buflen; i++) {
1677         if (isspace((int)p[i])) {
1678             p[i] = '\0';
1679             break;
1680         }
1681     }
1682 
1683     rc = ssh_pki_import_pubkey_base64(q, type, pkey);
1684     SAFE_FREE(key_buf);
1685 
1686     return rc;
1687 }
1688 
1689 /**
1690  * @brief Import a base64 formated certificate from a memory c-string.
1691  *
1692  * @param[in]  b64_cert  The base64 cert to format.
1693  *
1694  * @param[in]  type     The type of the cert to format.
1695  *
1696  * @param[out] pkey     A pointer where the allocated key can be stored. You
1697  *                      need to free the memory.
1698  *
1699  * @return              SSH_OK on success, SSH_ERROR on error.
1700  *
1701  * @see ssh_key_free()
1702  */
ssh_pki_import_cert_base64(const char * b64_cert,enum ssh_keytypes_e type,ssh_key * pkey)1703 int ssh_pki_import_cert_base64(const char *b64_cert,
1704                                enum ssh_keytypes_e type,
1705                                ssh_key *pkey) {
1706     return ssh_pki_import_pubkey_base64(b64_cert, type, pkey);
1707 }
1708 
1709 /**
1710  * @internal
1711  *
1712  * @brief Import a certificate from a ssh string.
1713  *
1714  * @param[in]  cert_blob The cert blob to import as specified in RFC 4253 section
1715  *                      6.6 "Public Key Algorithms".
1716  *
1717  * @param[out] pkey     A pointer where the allocated key can be stored. You
1718  *                      need to free the memory.
1719  *
1720  * @return              SSH_OK on success, SSH_ERROR on error.
1721  *
1722  * @see ssh_key_free()
1723  */
ssh_pki_import_cert_blob(const ssh_string cert_blob,ssh_key * pkey)1724 int ssh_pki_import_cert_blob(const ssh_string cert_blob,
1725                              ssh_key *pkey) {
1726     return ssh_pki_import_pubkey_blob(cert_blob, pkey);
1727 }
1728 
1729 /**
1730  * @brief Import a certificate from the given filename.
1731  *
1732  * @param[in]  filename The path to the certificate.
1733  *
1734  * @param[out] pkey     A pointer to store the allocated certificate. You need to
1735  *                      free the memory.
1736  *
1737  * @returns SSH_OK on success, SSH_EOF if the file doesn't exist or permission
1738  *          denied, SSH_ERROR otherwise.
1739  *
1740  * @see ssh_key_free()
1741  */
ssh_pki_import_cert_file(const char * filename,ssh_key * pkey)1742 int ssh_pki_import_cert_file(const char *filename, ssh_key *pkey)
1743 {
1744     return ssh_pki_import_pubkey_file(filename, pkey);
1745 }
1746 
1747 /**
1748  * @brief Generates a keypair.
1749  *
1750  * @param[in] type      Type of key to create
1751  *
1752  * @param[in] parameter Parameter to the creation of key:
1753  *                      rsa : length of the key in bits (e.g. 1024, 2048, 4096)
1754  *                      dsa : length of the key in bits (e.g. 1024, 2048, 3072)
1755  * @param[out] pkey     A pointer to store the allocated private key. You need
1756  *                      to free the memory.
1757  *
1758  * @return              SSH_OK on success, SSH_ERROR on error.
1759  *
1760  * @warning             Generating a key pair may take some time.
1761  */
ssh_pki_generate(enum ssh_keytypes_e type,int parameter,ssh_key * pkey)1762 int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
1763         ssh_key *pkey){
1764     int rc;
1765     ssh_key key = ssh_key_new();
1766 
1767     if (key == NULL) {
1768         return SSH_ERROR;
1769     }
1770 
1771     key->type = type;
1772     key->type_c = ssh_key_type_to_char(type);
1773     key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
1774 
1775     switch(type){
1776         case SSH_KEYTYPE_RSA:
1777             rc = pki_key_generate_rsa(key, parameter);
1778             if(rc == SSH_ERROR)
1779                 goto error;
1780             break;
1781         case SSH_KEYTYPE_DSS:
1782             rc = pki_key_generate_dss(key, parameter);
1783             if(rc == SSH_ERROR)
1784                 goto error;
1785             break;
1786 #ifdef HAVE_ECC
1787         case SSH_KEYTYPE_ECDSA: /* deprecated */
1788             rc = pki_key_generate_ecdsa(key, parameter);
1789             if (rc == SSH_ERROR) {
1790                 goto error;
1791             }
1792 
1793             /* Update key type */
1794             key->type_c = ssh_pki_key_ecdsa_name(key);
1795             break;
1796         case SSH_KEYTYPE_ECDSA_P256:
1797             rc = pki_key_generate_ecdsa(key, 256);
1798             if (rc == SSH_ERROR) {
1799                 goto error;
1800             }
1801             break;
1802         case SSH_KEYTYPE_ECDSA_P384:
1803             rc = pki_key_generate_ecdsa(key, 384);
1804             if (rc == SSH_ERROR) {
1805                 goto error;
1806             }
1807             break;
1808         case SSH_KEYTYPE_ECDSA_P521:
1809             rc = pki_key_generate_ecdsa(key, 521);
1810             if (rc == SSH_ERROR) {
1811                 goto error;
1812             }
1813             break;
1814 #endif
1815         case SSH_KEYTYPE_ED25519:
1816             rc = pki_key_generate_ed25519(key);
1817             if (rc == SSH_ERROR) {
1818                 goto error;
1819             }
1820             break;
1821         case SSH_KEYTYPE_DSS_CERT01:
1822         case SSH_KEYTYPE_RSA_CERT01:
1823         case SSH_KEYTYPE_ECDSA_P256_CERT01:
1824         case SSH_KEYTYPE_ECDSA_P384_CERT01:
1825         case SSH_KEYTYPE_ECDSA_P521_CERT01:
1826         case SSH_KEYTYPE_ED25519_CERT01:
1827         case SSH_KEYTYPE_RSA1:
1828         case SSH_KEYTYPE_UNKNOWN:
1829         default:
1830             goto error;
1831     }
1832 
1833     *pkey = key;
1834     return SSH_OK;
1835 error:
1836     ssh_key_free(key);
1837     return SSH_ERROR;
1838 }
1839 
1840 /**
1841  * @brief Create a public key from a private key.
1842  *
1843  * @param[in]  privkey  The private key to get the public key from.
1844  *
1845  * @param[out] pkey     A pointer to store the newly allocated public key. You
1846  *                      NEED to free the key.
1847  *
1848  * @return              SSH_OK on success, SSH_ERROR on error.
1849  *
1850  * @see ssh_key_free()
1851  */
ssh_pki_export_privkey_to_pubkey(const ssh_key privkey,ssh_key * pkey)1852 int ssh_pki_export_privkey_to_pubkey(const ssh_key privkey,
1853                                      ssh_key *pkey)
1854 {
1855     ssh_key pubkey;
1856 
1857     if (privkey == NULL || !ssh_key_is_private(privkey)) {
1858         return SSH_ERROR;
1859     }
1860 
1861     pubkey = pki_key_dup(privkey, 1);
1862     if (pubkey == NULL) {
1863         return SSH_ERROR;
1864     }
1865 
1866     *pkey = pubkey;
1867     return SSH_OK;
1868 }
1869 
1870 /**
1871  * @internal
1872  *
1873  * @brief Create a key_blob from a public key.
1874  *
1875  * The "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
1876  * Algorithms" for any of the supported protocol 2 key types.
1877  * Encoding of EC keys is described in RFC 5656 section 3.1 "Key
1878  * Format".
1879  *
1880  * @param[in]  key      A public or private key to create the public ssh_string
1881  *                      from.
1882  *
1883  * @param[out] pblob    A pointer to store the newly allocated key blob. You
1884  *                      NEED to free it.
1885  *
1886  * @return              SSH_OK on success, SSH_ERROR otherwise.
1887  *
1888  * @see SSH_STRING_FREE()
1889  */
ssh_pki_export_pubkey_blob(const ssh_key key,ssh_string * pblob)1890 int ssh_pki_export_pubkey_blob(const ssh_key key,
1891                                ssh_string *pblob)
1892 {
1893     ssh_string blob;
1894 
1895     if (key == NULL) {
1896         return SSH_OK;
1897     }
1898 
1899     blob = pki_publickey_to_blob(key);
1900     if (blob == NULL) {
1901         return SSH_ERROR;
1902     }
1903 
1904     *pblob = blob;
1905     return SSH_OK;
1906 }
1907 
1908 /**
1909  * @brief Convert a public key to a base64 encoded key.
1910  *
1911  * @param[in] key       The key to hash
1912  *
1913  * @param[out] b64_key  A pointer to store the allocated base64 encoded key. You
1914  *                      need to free the buffer.
1915  *
1916  * @return              SSH_OK on success, SSH_ERROR on error.
1917  *
1918  * @see SSH_STRING_FREE_CHAR()
1919  */
ssh_pki_export_pubkey_base64(const ssh_key key,char ** b64_key)1920 int ssh_pki_export_pubkey_base64(const ssh_key key,
1921                                  char **b64_key)
1922 {
1923     ssh_string key_blob;
1924     unsigned char *b64;
1925 
1926     if (key == NULL || b64_key == NULL) {
1927         return SSH_ERROR;
1928     }
1929 
1930     key_blob = pki_publickey_to_blob(key);
1931     if (key_blob == NULL) {
1932         return SSH_ERROR;
1933     }
1934 
1935     b64 = bin_to_base64(ssh_string_data(key_blob), ssh_string_len(key_blob));
1936     SSH_STRING_FREE(key_blob);
1937     if (b64 == NULL) {
1938         return SSH_ERROR;
1939     }
1940 
1941     *b64_key = (char *)b64;
1942 
1943     return SSH_OK;
1944 }
1945 
ssh_pki_export_pubkey_file(const ssh_key key,const char * filename)1946 int ssh_pki_export_pubkey_file(const ssh_key key,
1947                                const char *filename)
1948 {
1949     char key_buf[4096];
1950     char host[256];
1951     char *b64_key;
1952     char *user;
1953     FILE *fp;
1954     int rc;
1955 
1956     if (key == NULL || filename == NULL || *filename == '\0') {
1957         return SSH_ERROR;
1958     }
1959 
1960     user = ssh_get_local_username();
1961     if (user == NULL) {
1962         return SSH_ERROR;
1963     }
1964 
1965     rc = gethostname(host, sizeof(host));
1966     if (rc < 0) {
1967         free(user);
1968         return SSH_ERROR;
1969     }
1970 
1971     rc = ssh_pki_export_pubkey_base64(key, &b64_key);
1972     if (rc < 0) {
1973         free(user);
1974         return SSH_ERROR;
1975     }
1976 
1977     rc = snprintf(key_buf, sizeof(key_buf),
1978                   "%s %s %s@%s\n",
1979                   key->type_c,
1980                   b64_key,
1981                   user,
1982                   host);
1983     free(user);
1984     free(b64_key);
1985     if (rc < 0) {
1986         return SSH_ERROR;
1987     }
1988 
1989     fp = fopen(filename, "wb+");
1990     if (fp == NULL) {
1991         return SSH_ERROR;
1992     }
1993     rc = fwrite(key_buf, strlen(key_buf), 1, fp);
1994     if (rc != 1 || ferror(fp)) {
1995         fclose(fp);
1996         unlink(filename);
1997         return SSH_ERROR;
1998     }
1999     fclose(fp);
2000 
2001     return SSH_OK;
2002 }
2003 
2004 /**
2005  * @brief Copy the certificate part of a public key into a private key.
2006  *
2007  * @param[in]  certkey  The certificate key.
2008  *
2009  * @param[in]  privkey  The target private key to copy the certificate to.
2010  *
2011  * @returns SSH_OK on success, SSH_ERROR otherwise.
2012  **/
ssh_pki_copy_cert_to_privkey(const ssh_key certkey,ssh_key privkey)2013 int ssh_pki_copy_cert_to_privkey(const ssh_key certkey, ssh_key privkey) {
2014   ssh_buffer cert_buffer;
2015   int rc;
2016 
2017   if (certkey == NULL || privkey == NULL) {
2018       return SSH_ERROR;
2019   }
2020 
2021   if (privkey->cert != NULL) {
2022       return SSH_ERROR;
2023   }
2024 
2025   if (certkey->cert == NULL) {
2026       return SSH_ERROR;
2027   }
2028 
2029   cert_buffer = ssh_buffer_new();
2030   if (cert_buffer == NULL) {
2031       return SSH_ERROR;
2032   }
2033 
2034   rc = ssh_buffer_add_buffer(cert_buffer, certkey->cert);
2035   if (rc != 0) {
2036       SSH_BUFFER_FREE(cert_buffer);
2037       return SSH_ERROR;
2038   }
2039 
2040   privkey->cert = cert_buffer;
2041   privkey->cert_type = certkey->type;
2042   return SSH_OK;
2043 }
2044 
ssh_pki_export_signature_blob(const ssh_signature sig,ssh_string * sig_blob)2045 int ssh_pki_export_signature_blob(const ssh_signature sig,
2046                                   ssh_string *sig_blob)
2047 {
2048     ssh_buffer buf = NULL;
2049     ssh_string str;
2050     int rc;
2051 
2052     if (sig == NULL || sig_blob == NULL) {
2053         return SSH_ERROR;
2054     }
2055 
2056     buf = ssh_buffer_new();
2057     if (buf == NULL) {
2058         return SSH_ERROR;
2059     }
2060 
2061     str = ssh_string_from_char(sig->type_c);
2062     if (str == NULL) {
2063         SSH_BUFFER_FREE(buf);
2064         return SSH_ERROR;
2065     }
2066 
2067     rc = ssh_buffer_add_ssh_string(buf, str);
2068     SSH_STRING_FREE(str);
2069     if (rc < 0) {
2070         SSH_BUFFER_FREE(buf);
2071         return SSH_ERROR;
2072     }
2073 
2074     str = pki_signature_to_blob(sig);
2075     if (str == NULL) {
2076         SSH_BUFFER_FREE(buf);
2077         return SSH_ERROR;
2078     }
2079 
2080     rc = ssh_buffer_add_ssh_string(buf, str);
2081     SSH_STRING_FREE(str);
2082     if (rc < 0) {
2083         SSH_BUFFER_FREE(buf);
2084         return SSH_ERROR;
2085     }
2086 
2087     str = ssh_string_new(ssh_buffer_get_len(buf));
2088     if (str == NULL) {
2089         SSH_BUFFER_FREE(buf);
2090         return SSH_ERROR;
2091     }
2092 
2093     rc = ssh_string_fill(str, ssh_buffer_get(buf), ssh_buffer_get_len(buf));
2094     SSH_BUFFER_FREE(buf);
2095     if (rc < 0) {
2096         SSH_STRING_FREE(str);
2097         return SSH_ERROR;
2098     }
2099 
2100     *sig_blob = str;
2101 
2102     return SSH_OK;
2103 }
2104 
ssh_pki_import_signature_blob(const ssh_string sig_blob,const ssh_key pubkey,ssh_signature * psig)2105 int ssh_pki_import_signature_blob(const ssh_string sig_blob,
2106                                   const ssh_key pubkey,
2107                                   ssh_signature *psig)
2108 {
2109     ssh_signature sig = NULL;
2110     enum ssh_keytypes_e type;
2111     enum ssh_digest_e hash_type;
2112     ssh_string algorithm = NULL, blob = NULL;
2113     ssh_buffer buf;
2114     const char *alg = NULL;
2115     int rc;
2116 
2117     if (sig_blob == NULL || psig == NULL) {
2118         return SSH_ERROR;
2119     }
2120 
2121     buf = ssh_buffer_new();
2122     if (buf == NULL) {
2123         return SSH_ERROR;
2124     }
2125 
2126     rc = ssh_buffer_add_data(buf,
2127                              ssh_string_data(sig_blob),
2128                              ssh_string_len(sig_blob));
2129     if (rc < 0) {
2130         SSH_BUFFER_FREE(buf);
2131         return SSH_ERROR;
2132     }
2133 
2134     algorithm = ssh_buffer_get_ssh_string(buf);
2135     if (algorithm == NULL) {
2136         SSH_BUFFER_FREE(buf);
2137         return SSH_ERROR;
2138     }
2139 
2140     alg = ssh_string_get_char(algorithm);
2141     type = ssh_key_type_from_signature_name(alg);
2142     hash_type = ssh_key_hash_from_name(alg);
2143     SSH_STRING_FREE(algorithm);
2144 
2145     blob = ssh_buffer_get_ssh_string(buf);
2146     SSH_BUFFER_FREE(buf);
2147     if (blob == NULL) {
2148         return SSH_ERROR;
2149     }
2150 
2151     sig = pki_signature_from_blob(pubkey, blob, type, hash_type);
2152     SSH_STRING_FREE(blob);
2153     if (sig == NULL) {
2154         return SSH_ERROR;
2155     }
2156 
2157     *psig = sig;
2158     return SSH_OK;
2159 }
2160 
2161 /**
2162  * @internal
2163  *
2164  * @brief Check if the provided key can be used with the provided hash type for
2165  * data signing or signature verification.
2166  *
2167  * @param[in]   key         The key to be checked.
2168  * @param[in]   hash_type   The digest algorithm to be checked.
2169  *
2170  * @return  SSH_OK if compatible; SSH_ERROR otherwise
2171  */
pki_key_check_hash_compatible(ssh_key key,enum ssh_digest_e hash_type)2172 int pki_key_check_hash_compatible(ssh_key key,
2173                                   enum ssh_digest_e hash_type)
2174 {
2175     if (key == NULL) {
2176         SSH_LOG(SSH_LOG_TRACE, "Null pointer provided as key to "
2177                                "pki_key_check_hash_compatible()");
2178         return SSH_ERROR;
2179     }
2180 
2181     switch(key->type) {
2182     case SSH_KEYTYPE_DSS_CERT01:
2183     case SSH_KEYTYPE_DSS:
2184         if (hash_type == SSH_DIGEST_SHA1) {
2185             if (ssh_fips_mode()) {
2186                 SSH_LOG(SSH_LOG_WARN, "SHA1 is not allowed in FIPS mode");
2187                 return SSH_ERROR;
2188             } else {
2189                 return SSH_OK;
2190             }
2191         }
2192         break;
2193     case SSH_KEYTYPE_RSA_CERT01:
2194     case SSH_KEYTYPE_RSA:
2195         if (hash_type == SSH_DIGEST_SHA1) {
2196             if (ssh_fips_mode()) {
2197                 SSH_LOG(SSH_LOG_WARN, "SHA1 is not allowed in FIPS mode");
2198                 return SSH_ERROR;
2199             } else {
2200                 return SSH_OK;
2201             }
2202         }
2203 
2204         if (hash_type == SSH_DIGEST_SHA256 ||
2205             hash_type == SSH_DIGEST_SHA512)
2206         {
2207             return SSH_OK;
2208         }
2209         break;
2210     case SSH_KEYTYPE_ECDSA_P256_CERT01:
2211     case SSH_KEYTYPE_ECDSA_P256:
2212         if (hash_type == SSH_DIGEST_SHA256) {
2213             return SSH_OK;
2214         }
2215         break;
2216     case SSH_KEYTYPE_ECDSA_P384_CERT01:
2217     case SSH_KEYTYPE_ECDSA_P384:
2218         if (hash_type == SSH_DIGEST_SHA384) {
2219             return SSH_OK;
2220         }
2221         break;
2222     case SSH_KEYTYPE_ECDSA_P521_CERT01:
2223     case SSH_KEYTYPE_ECDSA_P521:
2224         if (hash_type == SSH_DIGEST_SHA512) {
2225             return SSH_OK;
2226         }
2227         break;
2228     case SSH_KEYTYPE_ED25519_CERT01:
2229     case SSH_KEYTYPE_ED25519:
2230         if (hash_type == SSH_DIGEST_AUTO) {
2231             return SSH_OK;
2232         }
2233         break;
2234     case SSH_KEYTYPE_RSA1:
2235     case SSH_KEYTYPE_ECDSA:
2236     case SSH_KEYTYPE_UNKNOWN:
2237         SSH_LOG(SSH_LOG_WARN, "Unknown key type %d", key->type);
2238         return SSH_ERROR;
2239     }
2240 
2241     SSH_LOG(SSH_LOG_WARN, "Key type %d incompatible with hash type  %d",
2242             key->type, hash_type);
2243 
2244     return SSH_ERROR;
2245 }
2246 
ssh_pki_signature_verify(ssh_session session,ssh_signature sig,const ssh_key key,const unsigned char * input,size_t input_len)2247 int ssh_pki_signature_verify(ssh_session session,
2248                              ssh_signature sig,
2249                              const ssh_key key,
2250                              const unsigned char *input,
2251                              size_t input_len)
2252 {
2253     int rc;
2254     enum ssh_keytypes_e key_type;
2255 
2256     if (session == NULL || sig == NULL || key == NULL || input == NULL) {
2257         SSH_LOG(SSH_LOG_TRACE, "Bad parameter provided to "
2258                                "ssh_pki_signature_verify()");
2259         return SSH_ERROR;
2260     }
2261     key_type = ssh_key_type_plain(key->type);
2262 
2263     SSH_LOG(SSH_LOG_FUNCTIONS,
2264             "Going to verify a %s type signature",
2265             sig->type_c);
2266 
2267     if (key_type != sig->type) {
2268         SSH_LOG(SSH_LOG_WARN,
2269                 "Can not verify %s signature with %s key",
2270                 sig->type_c, key->type_c);
2271         return SSH_ERROR;
2272     }
2273 
2274     /* Check if public key and hash type are compatible */
2275     rc = pki_key_check_hash_compatible(key, sig->hash_type);
2276     if (rc != SSH_OK) {
2277         return SSH_ERROR;
2278     }
2279 
2280     rc = pki_verify_data_signature(sig, key, input, input_len);
2281 
2282     return rc;
2283 }
2284 
pki_do_sign(const ssh_key privkey,const unsigned char * input,size_t input_len,enum ssh_digest_e hash_type)2285 ssh_signature pki_do_sign(const ssh_key privkey,
2286                           const unsigned char *input,
2287                           size_t input_len,
2288                           enum ssh_digest_e hash_type)
2289 {
2290     int rc;
2291 
2292     if (privkey == NULL || input == NULL) {
2293         SSH_LOG(SSH_LOG_TRACE, "Bad parameter provided to "
2294                                "pki_do_sign()");
2295         return NULL;
2296     }
2297 
2298     /* Check if public key and hash type are compatible */
2299     rc = pki_key_check_hash_compatible(privkey, hash_type);
2300     if (rc != SSH_OK) {
2301         return NULL;
2302     }
2303 
2304     return pki_sign_data(privkey, hash_type, input, input_len);
2305 }
2306 
2307 /*
2308  * This function signs the session id as a string then
2309  * the content of sigbuf */
ssh_pki_do_sign(ssh_session session,ssh_buffer sigbuf,const ssh_key privkey,enum ssh_digest_e hash_type)2310 ssh_string ssh_pki_do_sign(ssh_session session,
2311                            ssh_buffer sigbuf,
2312                            const ssh_key privkey,
2313                            enum ssh_digest_e hash_type)
2314 {
2315     struct ssh_crypto_struct *crypto = NULL;
2316 
2317     ssh_signature sig = NULL;
2318     ssh_string sig_blob = NULL;
2319 
2320     ssh_string session_id = NULL;
2321     ssh_buffer sign_input = NULL;
2322 
2323     int rc;
2324 
2325     if (session == NULL || sigbuf == NULL || privkey == NULL ||
2326         !ssh_key_is_private(privkey))
2327     {
2328         SSH_LOG(SSH_LOG_TRACE, "Bad parameter provided to "
2329                                "ssh_pki_do_sign()");
2330         return NULL;
2331     }
2332 
2333     crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH);
2334     if (crypto == NULL) {
2335         return NULL;
2336     }
2337 
2338     /* Get the session ID */
2339     session_id = ssh_string_new(crypto->session_id_len);
2340     if (session_id == NULL) {
2341         return NULL;
2342     }
2343     rc = ssh_string_fill(session_id, crypto->session_id, crypto->session_id_len);
2344     if (rc < 0) {
2345         goto end;
2346     }
2347 
2348     /* Fill the input */
2349     sign_input = ssh_buffer_new();
2350     if (sign_input == NULL) {
2351         goto end;
2352     }
2353     ssh_buffer_set_secure(sign_input);
2354 
2355     rc = ssh_buffer_pack(sign_input,
2356                          "SP",
2357                          session_id,
2358                          ssh_buffer_get_len(sigbuf), ssh_buffer_get(sigbuf));
2359     if (rc != SSH_OK) {
2360         goto end;
2361     }
2362 
2363     /* Generate the signature */
2364     sig = pki_do_sign(privkey,
2365             ssh_buffer_get(sign_input),
2366             ssh_buffer_get_len(sign_input),
2367             hash_type);
2368     if (sig == NULL) {
2369         goto end;
2370     }
2371 
2372     /* Convert the signature to blob */
2373     rc = ssh_pki_export_signature_blob(sig, &sig_blob);
2374     if (rc < 0) {
2375         sig_blob = NULL;
2376     }
2377 
2378 end:
2379     ssh_signature_free(sig);
2380     SSH_BUFFER_FREE(sign_input);
2381     SSH_STRING_FREE(session_id);
2382 
2383     return sig_blob;
2384 }
2385 
2386 #ifndef _WIN32
ssh_pki_do_sign_agent(ssh_session session,struct ssh_buffer_struct * buf,const ssh_key pubkey)2387 ssh_string ssh_pki_do_sign_agent(ssh_session session,
2388                                  struct ssh_buffer_struct *buf,
2389                                  const ssh_key pubkey)
2390 {
2391     struct ssh_crypto_struct *crypto = NULL;
2392     ssh_string session_id;
2393     ssh_string sig_blob;
2394     ssh_buffer sig_buf;
2395     int rc;
2396 
2397     crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH);
2398     if (crypto == NULL) {
2399         return NULL;
2400     }
2401 
2402     /* prepend session identifier */
2403     session_id = ssh_string_new(crypto->session_id_len);
2404     if (session_id == NULL) {
2405         return NULL;
2406     }
2407     rc = ssh_string_fill(session_id, crypto->session_id, crypto->session_id_len);
2408     if (rc < 0) {
2409         SSH_STRING_FREE(session_id);
2410         return NULL;
2411     }
2412 
2413     sig_buf = ssh_buffer_new();
2414     if (sig_buf == NULL) {
2415         SSH_STRING_FREE(session_id);
2416         return NULL;
2417     }
2418 
2419     rc = ssh_buffer_add_ssh_string(sig_buf, session_id);
2420     if (rc < 0) {
2421         SSH_STRING_FREE(session_id);
2422         SSH_BUFFER_FREE(sig_buf);
2423         return NULL;
2424     }
2425     SSH_STRING_FREE(session_id);
2426 
2427     /* append out buffer */
2428     if (ssh_buffer_add_buffer(sig_buf, buf) < 0) {
2429         SSH_BUFFER_FREE(sig_buf);
2430         return NULL;
2431     }
2432 
2433     /* create signature */
2434     sig_blob = ssh_agent_sign_data(session, pubkey, sig_buf);
2435 
2436     SSH_BUFFER_FREE(sig_buf);
2437 
2438     return sig_blob;
2439 }
2440 #endif /* _WIN32 */
2441 
2442 #ifdef WITH_SERVER
ssh_srv_pki_do_sign_sessionid(ssh_session session,const ssh_key privkey,const enum ssh_digest_e digest)2443 ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
2444                                          const ssh_key privkey,
2445                                          const enum ssh_digest_e digest)
2446 {
2447     struct ssh_crypto_struct *crypto = NULL;
2448 
2449     ssh_signature sig = NULL;
2450     ssh_string sig_blob = NULL;
2451 
2452     ssh_buffer sign_input = NULL;
2453 
2454     int rc;
2455 
2456     if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) {
2457         return NULL;
2458     }
2459 
2460     crypto = session->next_crypto ? session->next_crypto :
2461                                     session->current_crypto;
2462 
2463     if (crypto->secret_hash == NULL){
2464         ssh_set_error(session,SSH_FATAL,"Missing secret_hash");
2465         return NULL;
2466     }
2467 
2468     /* Fill the input */
2469     sign_input = ssh_buffer_new();
2470     if (sign_input == NULL) {
2471         goto end;
2472     }
2473     ssh_buffer_set_secure(sign_input);
2474 
2475     rc = ssh_buffer_pack(sign_input,
2476                          "P",
2477                          crypto->digest_len,
2478                          crypto->secret_hash);
2479     if (rc != SSH_OK) {
2480         goto end;
2481     }
2482 
2483     /* Generate the signature */
2484     sig = pki_do_sign(privkey,
2485             ssh_buffer_get(sign_input),
2486             ssh_buffer_get_len(sign_input),
2487             digest);
2488     if (sig == NULL) {
2489         goto end;
2490     }
2491 
2492     /* Convert the signature to blob */
2493     rc = ssh_pki_export_signature_blob(sig, &sig_blob);
2494     if (rc < 0) {
2495         sig_blob = NULL;
2496     }
2497 
2498 end:
2499     ssh_signature_free(sig);
2500     SSH_BUFFER_FREE(sign_input);
2501 
2502     return sig_blob;
2503 }
2504 #endif /* WITH_SERVER */
2505 
2506 /**
2507  * @}
2508  */
2509