Subject: [libssh2] #228: List of supported algorithms

[libssh2] #228: List of supported algorithms

From: libssh2 Trac <trac_at_libssh2.stuge.se>
Date: Fri, 16 Sep 2011 22:17:54 -0000

#228: List of supported algorithms
--------------------+--------------------
 Reporter: dzejk | Owner:
     Type: defect | Status: new
 Priority: normal | Milestone:
Component: API | Version: 1.2.9
 Keywords: | Blocked By:
   Blocks: |
--------------------+--------------------
 List of supported algorithms depends on the cryptographic library,
 configure options etc. and is not always straightforward to guess
 beforehand. Sometimes the application might need such a list, so it would
 be nice to add something like this to the API. The lists already exist
 somewhere in LIBSSH2_SESSION, so it's only necessary to pass their
 pointers. My implementation is as follows:

 libssh2.h: insert the following declaration anywhere:
 {{{
 LIBSSH2_API int libssh2_session_supported_algs(int method_type, char**
 algs, unsigned int nalgs);
 }}}

 As it will be evident at implementation, method_type has exactly the same
 meaning as as at libssh2_session_method_pref (of course, *_SC methods are
 equal to *_CS). algs is a prepared list (it must be preallocated by the
 user) of pointers to strings with algorithms' names, filled by the
 function and NULL terminated. nalgs (an input parameter) is the number of
 preallocated elements in this array. Note: this would be typically called
 before establishing a session, so no session handler is passed. A number
 of returned algorithms is returned. In other words, any positive number
 (or zero) returned indicates the function was successful. An error code (a
 negative number) is returned in any case of failure.

 The function is implemented in kex.c:
 {{{
 /*
  * libssh2_session_supported_algs()
  */

 LIBSSH2_API int libssh2_session_supported_algs(int method_type, char**
 algs, unsigned int nalgs)
 {
     /*
         TODO: do more appropriate error codes exist?
     */
     unsigned int i;
     unsigned int ialg;
     const LIBSSH2_COMMON_METHOD **mlist;

     if ( nalgs<=0 )
     {
         return LIBSSH2_ERROR_BAD_USE; /* invalid nalgs */
     }

     switch (method_type)
     {
         case LIBSSH2_METHOD_KEX:
             mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods;
             break;

         case LIBSSH2_METHOD_HOSTKEY:
             mlist = (const LIBSSH2_COMMON_METHOD **)
 libssh2_hostkey_methods();
             break;

         case LIBSSH2_METHOD_CRYPT_CS:
         case LIBSSH2_METHOD_CRYPT_SC:
             mlist = (const LIBSSH2_COMMON_METHOD **)
 libssh2_crypt_methods();
             break;

         case LIBSSH2_METHOD_MAC_CS:
         case LIBSSH2_METHOD_MAC_SC:
             mlist = (const LIBSSH2_COMMON_METHOD **)
 _libssh2_mac_methods();
             break;

         case LIBSSH2_METHOD_COMP_CS:
         case LIBSSH2_METHOD_COMP_SC:
             mlist = (const LIBSSH2_COMMON_METHOD **)
 _libssh2_comp_methods(NULL);
             break;

         default:
             return ERROR_METHOD_NOT_SUPPORTED; /* unknown method type */
     } /* switch */

     if ( NULL==mlist )
     {
         return LIBSSH2_ERROR_INVAL ; /* weird situation */
     }

     for ( i=0, ialg=0; ialg<nalgs-1 && NULL!=mlist[i]; i++ )
     {
         if ( NULL==mlist[i]->name )
         {
             /* probably this shouldn't occur but handle it gently anyway
 */
             continue;
         }

         algs[ialg++] = mlist[i]->name;
     } /* for i, ialg */

     /* as mentioned, the returned list is NULL terminated */
     algs[ialg] = NULL;
     if ( ialg == nalgs-1 )
     {
         return LIBSSH2_ERROR_BUFFER_TOO_SMALL; /* buffer too short */
     }

     return ialg;
 }
 }}}

 comp.c:
 add the following at the beginning of _libssh2_comp_methods:

 {{{
 const LIBSSH2_COMP_METHOD **
 _libssh2_comp_methods(LIBSSH2_SESSION *session)
 {
     /* start of inserted part */
     /*
        Looks like the original implementation expects a non-NULL session
 only.
        When asking for supported algorithms, however, session will
 typically be NULL,
        so the following is necessary to avoid NULL dereferrencing caused
 core dumps.
     */
     if ( NULL==session )
     {
         return comp_methods;
     }
     /* end of inserted part*/

     if(session->flag.compress)
         return comp_methods;
     else
         return no_comp_methods;
 }
 }}}

 Tested on FreeBSD 8.2/i386 (well, this should be OS independent), libssh2
 compiled with OpenSSL 1.0.0d and --enable-crypt-none, received the
 following supported algorithms (as expected):
 KEX: diffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha1,
 diffie-hellman-group1-sha1
 Hostkey: ssh-rsa, ssh-dss
 Symetric encryption: aes128-ctr, aes192-ctr, aes256-ctr, aes256-cbc,
 rijndael-cbc_at_lysator.liu.se, aes192-cbc, aes128-cbc, blowfish-cbc,
 arcfour128, arcfour, cast128-cbc, 3des-cbc, none
 HMAC: hmac-sha1, hmac-sha1-96, hmac-md5, hmac-md5-96, hmac-ripemd160,
 hmac-ripemd160_at_openssh.com,
 Compression: zlib, none,

-- 
Ticket URL: <http://trac.libssh2.org/ticket/228>
libssh2 <http://trac.libssh2.org/>
C library for writing portable SSH2 clients
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2011-09-17