OpenVAS Libraries  9.0.3
openvas_ssh.c
Go to the documentation of this file.
1 /* openvas-libraries/base
2  * $Id$
3  * Description: Implementation of OpenVAS SSH related API.
4  *
5  * Authors:
6  * Hani Benhabiles <hani.benhabiles@greenbone.net>
7  *
8  * Copyright:
9  * Copyright (C) 2015 Greenbone Networks GmbH
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #include <string.h>
27 #include <libssh/libssh.h>
28 #include <gnutls/x509.h>
29 #include <glib/gstdio.h>
30 
39 char *
40 openvas_ssh_pkcs8_decrypt (const char *pkcs8_key, const char *passphrase)
41 {
42  gnutls_datum_t data;
43  gnutls_x509_privkey_t key;
44  char buffer[16 * 2048];
45  int rc;
46  size_t size = sizeof (buffer);
47 
48  rc = gnutls_x509_privkey_init (&key);
49  if (rc)
50  return NULL;
51  data.size = strlen (pkcs8_key);
52  data.data = (void *) g_strdup (pkcs8_key);
53  rc = gnutls_x509_privkey_import_pkcs8 (key, &data, GNUTLS_X509_FMT_PEM,
54  passphrase?: "", 0);
55  if (rc)
56  {
57  gnutls_x509_privkey_deinit (key);
58  return NULL;
59  }
60  g_free (data.data);
61  rc = gnutls_x509_privkey_export (key, GNUTLS_X509_FMT_PEM, buffer, &size);
62  gnutls_x509_privkey_deinit (key);
63  if (rc)
64  return NULL;
65  return g_strdup (buffer);
66 }
67 
77 char *
78 openvas_ssh_public_from_private (const char *private_key, const char *passphrase)
79 {
80 #if LIBSSH_VERSION_INT >= SSH_VERSION_INT (0, 6, 0)
81  ssh_key priv;
82  char *pub_key, *decrypted_priv, *pub_str = NULL;
83  const char *type;
84  int ret;
85 
86  decrypted_priv = openvas_ssh_pkcs8_decrypt (private_key, passphrase);
87  ret = ssh_pki_import_privkey_base64
88  (decrypted_priv ?: private_key, passphrase, NULL, NULL, &priv);
89  g_free (decrypted_priv);
90  if (ret)
91  return NULL;
92  ret = ssh_pki_export_pubkey_base64 (priv, &pub_key);
93  type = ssh_key_type_to_char (ssh_key_type (priv));
94 #if LIBSSH_VERSION_INT >= SSH_VERSION_INT (0, 6, 4)
95  if (!strcmp (type, "ssh-ecdsa"))
96  type = ssh_pki_key_ecdsa_name (priv);
97 #endif
98  ssh_key_free (priv);
99  if (ret)
100  return NULL;
101  pub_str = g_strdup_printf ("%s %s", type, pub_key);
102  g_free (pub_key);
103  return pub_str;
104 
105 #else
106  char key_dir[] = "/tmp/openvas_key_XXXXXX", *base64, *data;
107  char filename[1024], *decrypted_priv;
108  ssh_private_key ssh_privkey;
109  ssh_public_key ssh_pubkey;
110  ssh_session session;
111  ssh_string sstring;
112  size_t datalen;
113 
114  if (!private_key || !g_mkdtemp_full (key_dir, S_IRUSR|S_IWUSR|S_IXUSR))
115  return NULL;
116  g_snprintf (filename, sizeof (filename), "%s/key.tmp", key_dir);
117  decrypted_priv = openvas_ssh_pkcs8_decrypt (private_key, passphrase);
118  if (!g_file_set_contents (filename, decrypted_priv ?: private_key, -1, NULL))
119  {
120  g_free (decrypted_priv);
121  g_rmdir (key_dir);
122  return NULL;
123  }
124  g_free (decrypted_priv);
125  session = ssh_new ();
126  ssh_privkey = privatekey_from_file (session, filename, 0, passphrase);
127  ssh_free (session);
128  g_remove (filename);
129  g_rmdir (key_dir);
130  if (!ssh_privkey)
131  return NULL;
132  /* Return as base64 encoded public key. */
133  ssh_pubkey = publickey_from_privatekey (ssh_privkey);
134  privatekey_free (ssh_privkey);
135  if (!ssh_pubkey)
136  return NULL;
137  sstring = publickey_to_string (ssh_pubkey);
138  publickey_free (ssh_pubkey);
139  if (!sstring)
140  return NULL;
141  data = ssh_string_to_char (sstring);
142  datalen = ssh_string_len (sstring);
143  /* LibSSH 0.5 supports ssh-rsa only. */
144  base64 = g_strdup_printf ("ssh-rsa %s",
145  g_base64_encode ((guchar *) data, datalen));
146  ssh_string_free (sstring);
147  g_free (data);
148  return base64;
149 #endif
150 }
char * openvas_ssh_pkcs8_decrypt(const char *pkcs8_key, const char *passphrase)
Decrypts a base64 encrypted ssh private key.
Definition: openvas_ssh.c:40
char * openvas_ssh_public_from_private(const char *private_key, const char *passphrase)
Exports a base64 encoded public key from a private key and its passphrase.
Definition: openvas_ssh.c:78