diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 577ddb71..7357129b 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -429,6 +429,10 @@ LIBSSH_API int ssh_pki_import_privkey_base64(ssh_session session, const char *b64_key, const char *passphrase, ssh_key *pkey); +LIBSSH_API int ssh_key_import_private(ssh_session session, + const char *filename, + const char *passphrase, + ssh_key *pkey); LIBSSH_API int ssh_userauth_pki_pubkey(ssh_session session, const char *username, ssh_string publickey, ssh_key privatekey); LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len); diff --git a/include/libssh/pki.h b/include/libssh/pki.h index 32e084f4..dd629897 100644 --- a/include/libssh/pki.h +++ b/include/libssh/pki.h @@ -47,8 +47,6 @@ struct ssh_key_struct { }; void ssh_key_clean (ssh_key key); -int ssh_key_import_private(ssh_key key, ssh_session session, - const char *filename, const char *passphrase); ssh_key ssh_pki_publickey_from_privatekey(ssh_key privkey); ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf, @@ -62,4 +60,5 @@ enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey); ssh_key pki_private_key_from_base64(ssh_session session, const char *b64_key, const char *passphrase); + #endif /* PKI_H_ */ diff --git a/src/legacy.c b/src/legacy.c index 678b0658..8655f319 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -263,6 +263,34 @@ ssh_private_key privatekey_from_base64(ssh_session session, return privkey; } +ssh_private_key privatekey_from_file(ssh_session session, + const char *filename, + int type, + const char *passphrase) { + ssh_key key; + ssh_private_key privkey; + int rc; + + (void) type; /* unused */ + + rc = ssh_key_import_private(session, filename, passphrase, &key); + if (rc == SSH_ERROR) { + return NULL; + } + + privkey = malloc(sizeof(struct ssh_private_key_struct)); + if (privkey == NULL) { + ssh_key_free(key); + return NULL; + } + + privkey->type = key->type; + privkey->dsa_priv = key->dsa; + privkey->rsa_priv = key->rsa; + + return privkey; +} + /**************************************************************************** * SERVER SUPPORT ****************************************************************************/ diff --git a/src/pki.c b/src/pki.c index 1966ca9d..a0770a90 100644 --- a/src/pki.c +++ b/src/pki.c @@ -30,6 +30,13 @@ * @{ */ +#include "config.h" + +#include +#include +#include +#include + #include "libssh/libssh.h" #include "libssh/session.h" #include "libssh/priv.h" @@ -202,18 +209,66 @@ int ssh_key_is_private(ssh_key k) { * if none is needed or it is unknown. * @returns SSH_OK on success, SSH_ERROR otherwise. **/ -int ssh_key_import_private(ssh_key key, ssh_session session, const char *filename, const char *passphrase){ - ssh_private_key priv=privatekey_from_file(session,filename,0,passphrase); - if(priv==NULL) - return SSH_ERROR; - ssh_key_clean(key); - key->dsa=priv->dsa_priv; - key->rsa=priv->rsa_priv; - key->type=priv->type; - key->flags=SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; - key->type_c=ssh_type_to_char(key->type); - SAFE_FREE(priv); - return SSH_OK; +int ssh_key_import_private(ssh_session session, + const char *filename, + const char *passphrase, + ssh_key *pkey) { + struct stat sb; + char *key_buf; + ssh_key key; + FILE *file; + off_t size; + int rc; + + if (session == NULL || pkey == NULL) { + return SSH_ERROR; + } + + if (filename == NULL || *filename == '\0') { + return SSH_ERROR; + } + + rc = stat(filename, &sb); + if (rc < 0) { + ssh_set_error(session, SSH_REQUEST_DENIED, + "Error gettint stat of %s: %s", + filename, strerror(errno)); + return SSH_ERROR; + } + + file = fopen(filename, "r"); + if (file == NULL) { + ssh_set_error(session, SSH_REQUEST_DENIED, + "Error opening %s: %s", + filename, strerror(errno)); + return SSH_ERROR; + } + + key_buf = malloc(sb.st_size + 1); + if (key_buf == NULL) { + ssh_set_error_oom(session); + return SSH_ERROR; + } + + size = fread(key_buf, 1, sb.st_size, file); + fclose(file); + + if (size != sb.st_size) { + SAFE_FREE(key_buf); + ssh_set_error(session, SSH_FATAL, + "Error reading %s: %s", + filename, strerror(errno)); + return SSH_ERROR; + } + + key = pki_private_key_from_base64(session, key_buf, passphrase); + SAFE_FREE(key_buf); + if (key == NULL) { + return SSH_ERROR; + } + + *pkey = key; + return SSH_OK; } /* temporary function to migrate seemlessly to ssh_key */ diff --git a/src/pki_crypto.c b/src/pki_crypto.c index db29a2eb..4d095220 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -25,8 +25,6 @@ #ifndef _PKI_CRYPTO_H #define _PKI_CRYPTO_H -#include "config.h" - #include #include #include diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c index f160a805..4c1ec4b2 100644 --- a/src/pki_gcrypt.c +++ b/src/pki_gcrypt.c @@ -967,68 +967,6 @@ fail: * @{ */ -/** - * @brief Reads a SSH private key from a file. - * - * @param[in] session The SSH Session to use. - * - * @param[in] filename The filename of the the private key. - * - * @param[in] type The type of the private key. This could be SSH_KEYTYPE_DSS or - * SSH_KEYTYPE_RSA. Pass 0 to automatically detect the type. - * - * @param[in] passphrase The passphrase to decrypt the private key. Set to null - * if none is needed or it is unknown. - * - * @return A private_key object containing the private key, or - * NULL on error. - * @see privatekey_free() - * @see publickey_from_privatekey() - */ -ssh_private_key privatekey_from_file(ssh_session session, const char *filename, - int type, const char *passphrase) { - ssh_private_key privkey = NULL; - FILE *file = NULL; - struct stat buf; - char *key_buf; - off_t size; - /* TODO Implement to read both DSA and RSA at once. */ - - if(filename == NULL || !*filename) { - return NULL; - } - - stat(filename, &buf); - key_buf = malloc(buf.st_size + 1); - if(key_buf == NULL) { - ssh_set_error_oom(session); - return NULL; - } - file = fopen(filename,"r"); - - if (file == NULL) { - ssh_set_error(session, SSH_REQUEST_DENIED, - "Error opening %s: %s", filename, strerror(errno)); - SAFE_FREE(key_buf); - return NULL; - } - - size = fread(key_buf, 1, buf.st_size, file); - fclose(file); - if(size != buf.st_size) { - SAFE_FREE(key_buf); - ssh_set_error(session, SSH_FATAL, - "Error Reading %s: %s", filename, strerror(errno)); - return NULL; - } - - - privkey = privatekey_from_base64(session, key_buf, type, passphrase); - - SAFE_FREE(key_buf); - return privkey; -} - /** * @brief returns the type of a private key * @param[in] privatekey the private key handle