Test and fix x509_oid functions
diff --git a/ChangeLog b/ChangeLog
index 4e2d97b..b9d44d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,6 +19,8 @@
      Gergely Budai).
    * Fix #include path in ecdsa.h which wasn't accepted by some compilers.
      (found by Gergely Budai)
+   * oid_get_numeric_string() used to truncate the output without returning an
+     error if the output buffer was just 1 byte too small.
 
 = PolarSSL 1.3.5 released on 2014-03-26
 Features
diff --git a/include/polarssl/error.h b/include/polarssl/error.h
index feba67b..23c0ed7 100644
--- a/include/polarssl/error.h
+++ b/include/polarssl/error.h
@@ -60,7 +60,7 @@
  * CAMELLIA  2  0x0024-0x0026
  * XTEA      1  0x0028-0x0028
  * BASE64    2  0x002A-0x002C
- * OID       1  0x002E-0x002E
+ * OID       1  0x002E-0x002E   0x000B-0x000B
  * PADLOCK   1  0x0030-0x0030
  * DES       1  0x0032-0x0032
  * CTR_DBRG  4  0x0034-0x003A
diff --git a/include/polarssl/oid.h b/include/polarssl/oid.h
index 2470d5e..0c471c5 100644
--- a/include/polarssl/oid.h
+++ b/include/polarssl/oid.h
@@ -44,6 +44,7 @@
 #endif
 
 #define POLARSSL_ERR_OID_NOT_FOUND                         -0x002E  /**< OID is not found. */
+#define POLARSSL_ERR_OID_BUF_TOO_SMALL                     -0x000B  /**< output buffer is too small */
 
 /*
  * Top level OID tuples
@@ -376,7 +377,8 @@
  * \param size      size of the buffer
  * \param oid       OID to translate
  *
- * \return          POLARSSL_ERR_DEBUG_BUF_TOO_SMALL or actual length used
+ * \return          Length of the string written (excluding final NULL) or
+ *                  POLARSSL_ERR_OID_BUF_TO_SMALL in case of error
  */
 int oid_get_numeric_string( char *buf, size_t size, const asn1_buf *oid );
 
diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h
index ad8049a..003154b 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -212,6 +212,8 @@
 
 /**
  * \brief          Give an known OID, return its descriptive string.
+ *                 (Deprecated. Use oid_get_extended_key_usage() instead.)
+ *                 Warning: only works for extended_key_usage OIDs!
  *
  * \param oid      buffer containing the oid
  *
@@ -228,8 +230,8 @@
  * \param size     Maximum size of buffer
  * \param oid      Buffer containing the OID
  *
- * \return         The amount of data written to the buffer, or -1 in
- *                 case of an error.
+ * \return         Length of the string written (exluding final NULL) or
+ *                 POLARSSL_ERR_OID_BUF_TO_SMALL in case of error
  */
 int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid );
 
diff --git a/library/error.c b/library/error.c
index 9980a91..2ca755c 100644
--- a/library/error.c
+++ b/library/error.c
@@ -655,6 +655,8 @@
 #if defined(POLARSSL_OID_C)
     if( use_ret == -(POLARSSL_ERR_OID_NOT_FOUND) )
         snprintf( buf, buflen, "OID - OID is not found" );
+    if( use_ret == -(POLARSSL_ERR_OID_BUF_TOO_SMALL) )
+        snprintf( buf, buflen, "OID - output buffer is too small" );
 #endif /* POLARSSL_OID_C */
 
 #if defined(POLARSSL_PADLOCK_C)
diff --git a/library/oid.c b/library/oid.c
index f943c6d..a2b929b 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -590,16 +590,14 @@
 #define snprintf compat_snprintf
 #endif
 
-#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL    -2
-
 #define SAFE_SNPRINTF()                         \
 {                                               \
     if( ret == -1 )                             \
-        return( -1 );                           \
+        return POLARSSL_ERR_OID_BUF_TOO_SMALL;  \
                                                 \
-    if ( (unsigned int) ret > n ) {             \
+    if ( (unsigned int) ret >= n ) {            \
         p[n - 1] = '\0';                        \
-        return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
+        return POLARSSL_ERR_OID_BUF_TOO_SMALL;  \
     }                                           \
                                                 \
     n -= (unsigned int) ret;                    \
@@ -630,7 +628,7 @@
     {
         /* Prevent overflow in value. */
         if ( ( ( value << 7 ) >> 7 ) != value )
-            return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
+            return( POLARSSL_ERR_OID_BUF_TOO_SMALL );
 
         value <<= 7;
         value += oid->p[i] & 0x7F;
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 03caa74..ef9a331 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -802,3 +802,27 @@
 X509 CRT parse path #4 (two certs, one non-cert)
 depends_on:POLARSSL_SHA1_C:POLARSSL_RSA_C:POLARSSL_SHA256_C:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP384R1_ENABLED
 x509_crt_parse_path:"data_files/dir3":1:2
+
+X509 OID description #1
+x509_oid_desc:"2B06010505070301":"TLS Web Server Authentication"
+
+X509 OID description #2
+x509_oid_desc:"2B0601050507030f":"notfound"
+
+X509 OID description #3
+x509_oid_desc:"2B0601050507030100":"notfound"
+
+X509 OID numstring #1 (wide buffer)
+x509_oid_numstr:"2B06010505070301":"1.3.6.1.5.5.7.3.1":20:17
+
+X509 OID numstring #2 (buffer just fits)
+x509_oid_numstr:"2B06010505070301":"1.3.6.1.5.5.7.3.1":18:17
+
+X509 OID numstring #3 (buffer too small)
+x509_oid_numstr:"2B06010505070301":"1.3.6.1.5.5.7.3.1":17:POLARSSL_ERR_OID_BUF_TOO_SMALL
+
+X509 OID numstring #4 (larger number)
+x509_oid_numstr:"2A864886F70D":"1.2.840.113549":15:14
+
+X509 OID numstring #5 (arithmetic overflow)
+x509_oid_numstr:"2A8648F9F8F7F6F5F4F3F2F1F001":"":100:POLARSSL_ERR_OID_BUF_TOO_SMALL
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 8638235..effa4cc 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -265,6 +265,57 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void x509_oid_desc( char *oid_str, char *ref_desc )
+{
+    x509_buf oid;
+    const char *desc;
+    unsigned char buf[20];
+
+    memset( buf, 0, sizeof buf );
+
+    oid.tag = ASN1_OID;
+    oid.len = unhexify( buf, oid_str );
+    oid.p   = buf;
+
+    desc = x509_oid_get_description( &oid );
+
+    if( strcmp( ref_desc, "notfound" ) == 0 )
+        TEST_ASSERT( desc == NULL );
+    else
+    {
+        TEST_ASSERT( desc != NULL );
+        TEST_ASSERT( strcmp( desc, ref_desc ) == 0 );
+    }
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void x509_oid_numstr( char *oid_str, char *numstr, int blen, int ret )
+{
+    x509_buf oid;
+    unsigned char oid_buf[20];
+    char num_buf[100];
+
+    memset( oid_buf, 0x00, sizeof oid_buf );
+    memset( num_buf, 0x2a, sizeof num_buf );
+
+    oid.tag = ASN1_OID;
+    oid.len = unhexify( oid_buf, oid_str );
+    oid.p   = oid_buf;
+
+    TEST_ASSERT( (size_t) blen <= sizeof num_buf );
+
+    TEST_ASSERT( x509_oid_get_numeric_string( num_buf, blen, &oid ) == ret );
+
+    if( ret >= 0 )
+    {
+        TEST_ASSERT( num_buf[ret] == 0 );
+        TEST_ASSERT( strcmp( num_buf, numstr ) == 0 );
+    }
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:POLARSSL_X509_CRT_PARSE_C:POLARSSL_SELF_TEST */
 void x509_selftest()
 {