- Improved information provided about current Hashing, Cipher and Suite capabilities

diff --git a/ChangeLog b/ChangeLog
index 364f2a5..86dd340 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,16 +4,19 @@
 Features
 Note: Most of these features have been donated by Fox-IT
    * Added Doxygen source code documentation parts
-   * Added generic message digest and cipher wrapper
-     for integration with OpenVPN
    * Added reading of DHM context from memory and file
-   * Added verification callback on certificate chain
-     verification to allow external blacklisting
    * Improved X509 certificate parsing to include extended
      certificate fields, including Key Usage
    * Improved certificate verification and verification
      against the available CRLs
    * Detection for DES weak keys and parity bits added
+   * Improvements to support integration in other
+     applications:
+       + Added generic message digest and cipher wrapper
+       + Improved information about current capabilities,
+         status, objects and configuration
+       + Added verification callback on certificate chain
+         verification to allow external blacklisting
 
 = Version 0.14.0 released on 2010-08-16
 Features
diff --git a/include/polarssl/cipher.h b/include/polarssl/cipher.h
index b8587f4..2e19eae 100644
--- a/include/polarssl/cipher.h
+++ b/include/polarssl/cipher.h
@@ -152,6 +152,14 @@
 #endif
 
 /**
+ * \brief Returns the list of ciphers supported by the generic cipher module.
+ *
+ * \return              a statically allocated array of ciphers, the last entry
+ *                      is 0.
+ */
+const int *cipher_list( void );
+
+/**
  * \brief               Returns the cipher information structure associated
  *                      with the given cipher name.
  *
diff --git a/include/polarssl/md.h b/include/polarssl/md.h
index 13250dd..05f6eb0 100644
--- a/include/polarssl/md.h
+++ b/include/polarssl/md.h
@@ -119,6 +119,14 @@
 #endif
 
 /**
+ * \brief Returns the list of digests supported by the generic digest module.
+ *
+ * \return          a statically allocated array of digests, the last entry
+ *                  is 0.
+ */
+const int *md_list( void );
+
+/**
  * \brief           Returns the message digest information associated with the
  *                  given digest name.
  *
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 6d7b495..7ddf7b1 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -320,6 +320,26 @@
 extern int ssl_default_ciphers[];
 
 /**
+ * \brief Returns the list of ciphers supported by the SSL/TLS module.
+ *
+ * \return              a statically allocated array of ciphers, the last entry
+ *                      is 0.
+ */
+static inline const int *ssl_list_ciphers( void )
+{
+    return ssl_default_ciphers;
+}
+
+/**
+ * \brief          Return the name of the cipher associated with the given ID
+ *
+ * \param cipher_id     SSL cipher ID
+ *
+ * \return              a string containing the cipher name
+ */
+const char *ssl_get_cipher_name( const int cipher_id );
+
+/**
  * \brief          Initialize an SSL context
  *
  * \param ssl      SSL context
diff --git a/library/cipher.c b/library/cipher.c
index 5e995ed..545b2da 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -37,6 +37,34 @@
 #include <string.h>
 #include <stdlib.h>
 
+static const int supported_ciphers[] = {
+
+#if defined(POLARSSL_AES_C)
+        POLARSSL_CIPHER_AES_128_CBC,
+        POLARSSL_CIPHER_AES_192_CBC,
+        POLARSSL_CIPHER_AES_256_CBC,
+#endif /* defined(POLARSSL_AES_C) */
+
+#if defined(POLARSSL_CAMELLIA_C)
+        POLARSSL_CIPHER_CAMELLIA_128_CBC,
+        POLARSSL_CIPHER_CAMELLIA_192_CBC,
+        POLARSSL_CIPHER_CAMELLIA_256_CBC,
+#endif /* defined(POLARSSL_CAMELLIA_C) */
+
+#if defined(POLARSSL_DES_C)
+        POLARSSL_CIPHER_DES_CBC,
+        POLARSSL_CIPHER_DES_EDE_CBC,
+        POLARSSL_CIPHER_DES_EDE3_CBC,
+#endif /* defined(POLARSSL_DES_C) */
+
+        0
+};
+
+const int *cipher_list( void )
+{
+    return supported_ciphers;
+}
+
 const cipher_info_t *cipher_info_from_type( cipher_type_t cipher_type )
 {
     /* Find static cipher information */
diff --git a/library/md.c b/library/md.c
index c36cd4e..9aa7b38 100644
--- a/library/md.c
+++ b/library/md.c
@@ -37,6 +37,42 @@
 #include <string.h>
 #include <stdlib.h>
 
+static const int supported_digests[] = {
+
+#if defined(POLARSSL_MD2_C)
+        POLARSSL_MD_MD2,
+#endif
+
+#if defined(POLARSSL_MD4_C)
+        POLARSSL_MD_MD4,
+#endif
+
+#if defined(POLARSSL_MD5_C)
+        POLARSSL_MD_MD5,
+#endif
+
+#if defined(POLARSSL_SHA1_C)
+        POLARSSL_MD_SHA1,
+#endif
+
+#if defined(POLARSSL_SHA2_C)
+        POLARSSL_MD_SHA224,
+        POLARSSL_MD_SHA256,
+#endif
+
+#if defined(POLARSSL_SHA4_C)
+        POLARSSL_MD_SHA384,
+        POLARSSL_MD_SHA512,
+#endif
+
+        0
+};
+
+const int *md_list( void )
+{
+    return supported_digests;
+}
+
 const md_info_t *md_info_from_string( const char *md_name )
 {
     if( NULL == md_name )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 74e51a3..4eb0b68 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1863,52 +1863,52 @@
     return( ssl->verify_result );
 }
 
-const char *ssl_get_cipher( const ssl_context *ssl )
+const char *ssl_get_cipher_name( const int cipher_id )
 {
-    switch( ssl->session->cipher )
+    switch( cipher_id )
     {
 #if defined(POLARSSL_ARC4_C)
         case SSL_RSA_RC4_128_MD5:
-            return( "SSL_RSA_RC4_128_MD5" );
+            return( "SSL-RSA-RC4-128-MD5" );
 
         case SSL_RSA_RC4_128_SHA:
-            return( "SSL_RSA_RC4_128_SHA" );
+            return( "SSL-RSA-RC4-128-SHA" );
 #endif
 
 #if defined(POLARSSL_DES_C)
         case SSL_RSA_DES_168_SHA:
-            return( "SSL_RSA_DES_168_SHA" );
+            return( "SSL-RSA-DES-168-SHA" );
 
         case SSL_EDH_RSA_DES_168_SHA:
-            return( "SSL_EDH_RSA_DES_168_SHA" );
+            return( "SSL-EDH-RSA-DES-168-SHA" );
 #endif
 
 #if defined(POLARSSL_AES_C)
         case SSL_RSA_AES_128_SHA:
-            return( "SSL_RSA_AES_128_SHA" );
+            return( "SSL-RSA-AES-128-SHA" );
 
         case SSL_EDH_RSA_AES_128_SHA:
-            return( "SSL_EDH_RSA_AES_128_SHA" );
+            return( "SSL-EDH-RSA-AES-128-SHA" );
 
         case SSL_RSA_AES_256_SHA:
-            return( "SSL_RSA_AES_256_SHA" );
+            return( "SSL-RSA-AES-256-SHA" );
 
         case SSL_EDH_RSA_AES_256_SHA:
-            return( "SSL_EDH_RSA_AES_256_SHA" );
+            return( "SSL-EDH-RSA-AES-256-SHA" );
 #endif
 
 #if defined(POLARSSL_CAMELLIA_C)
         case SSL_RSA_CAMELLIA_128_SHA:
-            return( "SSL_RSA_CAMELLIA_128_SHA" );
+            return( "SSL-RSA-CAMELLIA-128-SHA" );
 
         case SSL_EDH_RSA_CAMELLIA_128_SHA:
-            return( "SSL_EDH_RSA_CAMELLIA_128_SHA" );
+            return( "SSL-EDH-RSA-CAMELLIA-128-SHA" );
 
         case SSL_RSA_CAMELLIA_256_SHA:
-            return( "SSL_RSA_CAMELLIA_256_SHA" );
+            return( "SSL-RSA-CAMELLIA-256-SHA" );
 
         case SSL_EDH_RSA_CAMELLIA_256_SHA:
-            return( "SSL_EDH_RSA_CAMELLIA_256_SHA" );
+            return( "SSL-EDH-RSA-CAMELLIA-256-SHA" );
 #endif
 
     default:
@@ -1918,6 +1918,52 @@
     return( "unknown" );
 }
 
+int ssl_get_cipher_id( const char *cipher_name )
+{
+#if defined(POLARSSL_ARC4_C)
+    if (0 == strcasecmp(cipher_name, "SSL-RSA-RC4-128-MD5"))
+        return( SSL_RSA_RC4_128_MD5 );
+    if (0 == strcasecmp(cipher_name, "SSL-RSA-RC4-128-SHA"))
+        return( SSL_RSA_RC4_128_SHA );
+#endif
+
+#if defined(POLARSSL_DES_C)
+    if (0 == strcasecmp(cipher_name, "SSL-RSA-DES-168-SHA"))
+        return( SSL_RSA_DES_168_SHA );
+    if (0 == strcasecmp(cipher_name, "SSL-EDH-RSA-DES-168-SHA"))
+        return( SSL_EDH_RSA_DES_168_SHA );
+#endif
+
+#if defined(POLARSSL_AES_C)
+    if (0 == strcasecmp(cipher_name, "SSL-RSA-AES-128-SHA"))
+        return( SSL_RSA_AES_128_SHA );
+    if (0 == strcasecmp(cipher_name, "SSL-EDH-RSA-AES-128-SHA"))
+        return( SSL_EDH_RSA_AES_128_SHA );
+    if (0 == strcasecmp(cipher_name, "SSL-RSA-AES-256-SHA"))
+        return( SSL_RSA_AES_256_SHA );
+    if (0 == strcasecmp(cipher_name, "SSL-EDH-RSA-AES-256-SHA"))
+        return( SSL_EDH_RSA_AES_256_SHA );
+#endif
+
+#if defined(POLARSSL_CAMELLIA_C)
+    if (0 == strcasecmp(cipher_name, "SSL-RSA-CAMELLIA-128-SHA"))
+        return( SSL_RSA_CAMELLIA_128_SHA );
+    if (0 == strcasecmp(cipher_name, "SSL-EDH-RSA-CAMELLIA-128-SHA"))
+        return( SSL_EDH_RSA_CAMELLIA_128_SHA );
+    if (0 == strcasecmp(cipher_name, "SSL-RSA-CAMELLIA-256-SHA"))
+        return( SSL_RSA_CAMELLIA_256_SHA );
+    if (0 == strcasecmp(cipher_name, "SSL-EDH-RSA-CAMELLIA-256-SHA"))
+        return( SSL_EDH_RSA_CAMELLIA_256_SHA );
+#endif
+
+    return( 0 );
+}
+
+const char *ssl_get_cipher( const ssl_context *ssl )
+{
+    return ssl_get_cipher_name( ssl->session->cipher );
+}
+
 const char *ssl_get_version( const ssl_context *ssl )
 {
     switch( ssl->minor_ver )