[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question on privatekey_from_file


Hi Andreas,

OK, there's the patch for privatekey_from_file. I use the value 0 for
keytype detection since the minimum valid value is 1.

I only tested on 0.4 branch, since I have connection problem with master
(see another mail thread).

If that is ok I will try to take a look at the auth function.

Thanks,

Vic

On Tue, 2009-12-22 at 08:30 +0800, Vic Lee wrote:
> I tried to write some codes outside of libssh and it works. I will try
> to merge these codes into libssh and submit a patch.
> 
> On Mon, 2009-12-21 at 10:10 +0100, Andreas Schneider wrote:
> > On Monday 21 December 2009 05:21:29 you wrote:
> > > Hi,
> > 
> > Hi,
> > 
> > > Recently I am trying to use privatekey_from_file without a public key. I
> > > think I can do it by:
> > > 
> > > privatekey_from_file -> publickey_from_privatekey -> publickey_to_string
> > >
> > 
> > yes, this is the way, but it doesn't work.
> >  
> > > But in order to call privatekey_from_file, I have to tell it the key
> > > type (RSA or DSS). Previously I could get the key type from
> > > publickey_from_file, but now I can't since I don't have the public key
> > > file.
> > 
> > That's more or less the problem, we should read the first line and then 
> > comapre it with RSA_HEADER_BEGIN and DSA_HEADER_BEGIN to find out the type. It 
> > is on my todo list but I haven't had the time to do it.
> > 
> > > 
> > > I know it's quite easy to tell the keytype from the private key file by
> > > simply read the first line... but any reason why this cannot be done
> > > automatically inside libssh?
> > >
> > 
> > It should be implemented this way but it isn't. I wanted to do that for 0.4.1. 
> > If you have time feel free to fix it.
> > 
> > Read the first line and then comapre it with RSA_HEADER_BEGIN and 
> > DSA_HEADER_BEGIN. Then set the type.
> > 
> > The next step should be in the auth functions to check for public keys. If 
> > there is none get it from the private key ...
> > 
> > If you have time, feel free to implement it. I don't know when I will have the 
> > time to fix it. There is more stuff which needs to be cleaned up.
> >  
> > Cheers,
> > 
> > 
> > 	-- andreas
> > 
> 
> 
> 
> 

From 369fe36cfb82f4f2e145a13126690e51a4face6e Mon Sep 17 00:00:00 2001
From: Vic Lee <llyzs@xxxxxxx>
Date: Tue, 22 Dec 2009 11:49:38 +0800
Subject: [PATCH] Added private key type detection feature in privatekey_from_file


Signed-off-by: Vic Lee <llyzs@xxxxxxx>
---
 libssh/keyfiles.c |   34 +++++++++++++++++++++++++++++-----
 1 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/libssh/keyfiles.c b/libssh/keyfiles.c
index 8dc2f10..b13643a 100644
--- a/libssh/keyfiles.c
+++ b/libssh/keyfiles.c
@@ -59,15 +59,15 @@
 #endif /* HAVE_LIBCRYPTO */
 
 #define MAXLINESIZE 80
+#define RSA_HEADER_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
+#define RSA_HEADER_END "-----END RSA PRIVATE KEY-----"
+#define DSA_HEADER_BEGIN "-----BEGIN DSA PRIVATE KEY-----"
+#define DSA_HEADER_END "-----END DSA PRIVATE KEY-----"
 
 #ifdef HAVE_LIBGCRYPT
 
 #define MAX_KEY_SIZE 32
 #define MAX_PASSPHRASE_SIZE 1024
-#define RSA_HEADER_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
-#define RSA_HEADER_END "-----END RSA PRIVATE KEY-----"
-#define DSA_HEADER_BEGIN "-----BEGIN DSA PRIVATE KEY-----"
-#define DSA_HEADER_END "-----END DSA PRIVATE KEY-----"
 #define ASN1_INTEGER 2
 #define ASN1_SEQUENCE 48
 #define PKCS5_SALT_LEN 8
@@ -611,6 +611,22 @@ static int pem_get_password(char *buf, int size, int rwflag, void *userdata) {
 }
 #endif /* HAVE_LIBCRYPTO */
 
+static int privatekey_type_from_file(FILE *fp) {
+  char buffer[MAXLINESIZE] = {0};
+
+  if (!fgets(buffer, MAXLINESIZE, fp)) {
+    return 0;
+  }
+  fseek(fp, 0, SEEK_SET);
+  if (strncmp(buffer, DSA_HEADER_BEGIN, strlen(DSA_HEADER_BEGIN)) == 0) {
+    return TYPE_DSS;
+  }
+  if (strncmp(buffer, RSA_HEADER_BEGIN, strlen(RSA_HEADER_BEGIN)) == 0) {
+    return TYPE_RSA;
+  }
+  return 0;
+}
+
 /** \addtogroup ssh_auth
  * @{
  */
@@ -618,7 +634,7 @@ static int pem_get_password(char *buf, int size, int rwflag, void *userdata) {
 /** \brief Reads a SSH private key from a file
  * \param session SSH Session
  * \param filename Filename containing the private key
- * \param type Type of the private key. One of TYPE_DSS or TYPE_RSA.
+ * \param type Type of the private key. One of TYPE_DSS or TYPE_RSA. Pass 0 to automatically detect the type.
  * \param passphrase Passphrase to decrypt the private key. Set to null if none is needed or it is unknown.
  * \returns a PRIVATE_KEY object containing the private key, or NULL if it failed.
  * \see privatekey_free()
@@ -649,6 +665,14 @@ ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
   ssh_log(session, SSH_LOG_RARE, "Trying to read %s, passphase=%s, authcb=%s",
       filename, passphrase ? "true" : "false",
       session->callbacks && session->callbacks->auth_function ? "true" : "false");
+
+  if (type == 0) {
+    type = privatekey_type_from_file(file);
+    if (type == 0) {
+      ssh_set_error(session, SSH_FATAL, "Invalid private key file.");
+      return NULL;
+    }
+  }
   switch (type) {
     case TYPE_DSS:
       if (passphrase == NULL) {
-- 
1.6.5


Follow-Ups:
Re: Question on privatekey_from_fileAndreas Schneider <mail@xxxxxxxxxxxx>
References:
Question on privatekey_from_fileVic Lee <llyzs@xxxxxxx>
Re: Question on privatekey_from_fileAndreas Schneider <mail@xxxxxxxxxxxx>
Re: Question on privatekey_from_fileVic Lee <llyzs@xxxxxxx>
Archive administrator: postmaster@lists.cynapses.org