Add opaque context to mbedtls_x509_crt_ext_cb_t

Signed-off-by: Nicola Di Lieto <nicola.dilieto@gmail.com>
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index cdcc651..296b472 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -310,6 +310,7 @@
  *                 mbedtls_x509_crt_parse_der_with_ext_cb() routine when
  *                 it encounters an unsupported extension.
  *
+ * \param p_ctx    An opaque context passed to the callback.
  * \param crt      The certificate being parsed.
  * \param oid      The OID of the extension.
  * \param critical Whether the extension is critical.
@@ -323,7 +324,8 @@
  * \return         \c 0 on success.
  * \return         A negative error code on failure.
  */
-typedef int (*mbedtls_x509_crt_ext_cb_t)( mbedtls_x509_crt const *crt,
+typedef int (*mbedtls_x509_crt_ext_cb_t)( void *p_ctx,
+                                          mbedtls_x509_crt const *crt,
                                           mbedtls_x509_buf const *oid,
                                           int critical,
                                           const unsigned char *p,
@@ -347,6 +349,7 @@
  *                   is destroyed (like mbedtls_x509_crt_parse_der_nocopy())
  * \param cb         A callback invoked for every unsupported certificate
  *                   extension.
+ * \param p_ctx      An opaque context passed to the callback.
  *
  * \note             This call is functionally equivalent to
  *                   mbedtls_x509_crt_parse_der(), and/or
@@ -363,7 +366,8 @@
                                             const unsigned char *buf,
                                             size_t buflen,
                                             int make_copy,
-                                            mbedtls_x509_crt_ext_cb_t cb );
+                                            mbedtls_x509_crt_ext_cb_t cb,
+                                            void *p_ctx );
 
 /**
  * \brief          Parse a single DER formatted certificate and add it
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 5543522..99d3be2 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -893,7 +893,8 @@
 static int x509_get_crt_ext( unsigned char **p,
                              const unsigned char *end,
                              mbedtls_x509_crt *crt,
-                             mbedtls_x509_crt_ext_cb_t cb )
+                             mbedtls_x509_crt_ext_cb_t cb,
+                             void *p_ctx )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t len;
@@ -959,7 +960,7 @@
             /* Give the callback (if any) a chance to handle the extension */
             if( cb != NULL )
             {
-                ret = cb( crt, &extn_oid, is_critical, *p, end_ext_octet );
+                ret = cb( p_ctx, crt, &extn_oid, is_critical, *p, end_ext_octet );
                 if( ret != 0 )
                     return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
                 *p = end_ext_octet;
@@ -1073,7 +1074,8 @@
                                     const unsigned char *buf,
                                     size_t buflen,
                                     int make_copy,
-                                    mbedtls_x509_crt_ext_cb_t cb )
+                                    mbedtls_x509_crt_ext_cb_t cb,
+                                    void *p_ctx )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t len;
@@ -1272,7 +1274,7 @@
     if( crt->version == 3 )
 #endif
     {
-        ret = x509_get_crt_ext( &p, end, crt, cb );
+        ret = x509_get_crt_ext( &p, end, crt, cb, p_ctx );
         if( ret != 0 )
         {
             mbedtls_x509_crt_free( crt );
@@ -1336,7 +1338,8 @@
                                                 const unsigned char *buf,
                                                 size_t buflen,
                                                 int make_copy,
-                                                mbedtls_x509_crt_ext_cb_t cb )
+                                                mbedtls_x509_crt_ext_cb_t cb,
+                                                void *p_ctx )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_x509_crt *crt = chain, *prev = NULL;
@@ -1368,7 +1371,7 @@
         crt = crt->next;
     }
 
-    ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy, cb );
+    ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy, cb, p_ctx );
     if( ret != 0 )
     {
         if( prev )
@@ -1387,23 +1390,24 @@
                                        const unsigned char *buf,
                                        size_t buflen )
 {
-    return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0, NULL ) );
+    return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0, NULL, NULL ) );
 }
 
 int mbedtls_x509_crt_parse_der_with_ext_cb( mbedtls_x509_crt *chain,
                                             const unsigned char *buf,
                                             size_t buflen,
                                             int make_copy,
-                                            mbedtls_x509_crt_ext_cb_t cb )
+                                            mbedtls_x509_crt_ext_cb_t cb,
+                                            void *p_ctx )
 {
-    return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, make_copy, cb ) );
+    return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, make_copy, cb, p_ctx ) );
 }
 
 int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
                                 const unsigned char *buf,
                                 size_t buflen )
 {
-    return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1, NULL ) );
+    return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1, NULL, NULL ) );
 }
 
 /*
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index c52af76..0e2719d 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -302,9 +302,10 @@
     return( 0 );
 }
 
-int parse_crt_ext_cb( mbedtls_x509_crt const *crt, mbedtls_x509_buf const *oid, int critical,
-                      const unsigned char *p, const unsigned char *end )
+int parse_crt_ext_cb( void *p_ctx, mbedtls_x509_crt const *crt, mbedtls_x509_buf const *oid,
+                      int critical, const unsigned char *p, const unsigned char *end )
 {
+    ( void ) p_ctx;
     ( void ) crt;
     ( void ) p;
     ( void ) end;
@@ -786,7 +787,7 @@
     mbedtls_x509_crt_init( &crt );
     memset( output, 0, 2000 );
 
-    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 0, NULL ) == ( result ) );
+    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 0, NULL, NULL ) == ( result ) );
     if( ( result ) == 0 )
     {
         res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
@@ -801,7 +802,7 @@
     mbedtls_x509_crt_init( &crt );
     memset( output, 0, 2000 );
 
-    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 1, NULL ) == ( result ) );
+    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 1, NULL, NULL ) == ( result ) );
     if( ( result ) == 0 )
     {
         res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
@@ -827,7 +828,7 @@
     mbedtls_x509_crt_init( &crt );
     memset( output, 0, 2000 );
 
-    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 0, parse_crt_ext_cb ) == ( result ) );
+    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 0, parse_crt_ext_cb, NULL ) == ( result ) );
     if( ( result ) == 0 )
     {
         res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
@@ -842,7 +843,7 @@
     mbedtls_x509_crt_init( &crt );
     memset( output, 0, 2000 );
 
-    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 1, parse_crt_ext_cb ) == ( result ) );
+    TEST_ASSERT( mbedtls_x509_crt_parse_der_with_ext_cb( &crt, buf->x, buf->len, 1, parse_crt_ext_cb, NULL ) == ( result ) );
     if( ( result ) == 0 )
     {
         res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );