Merge remote-tracking branch 'origin/pr/652' into baremetal
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 662ec68..f0eed05 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -32,7 +32,6 @@
 
 #include "x509.h"
 #include "x509_crl.h"
-#include "x509_internal.h"
 
 /**
  * \addtogroup x509_module
@@ -48,6 +47,22 @@
  * \{
  */
 
+typedef struct mbedtls_x509_crt_cache
+{
+#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
+    defined(MBEDTLS_THREADING_C)
+    uint32_t frame_readers;
+    uint32_t pk_readers;
+#endif /* !MBEDTLS_X509_ALWAYS_FLUSH || MBEDTLS_THREADING_C */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t frame_mutex;
+    mbedtls_threading_mutex_t pk_mutex;
+#endif
+    mbedtls_x509_buf_raw pk_raw;
+    struct mbedtls_x509_crt_frame *frame;
+    struct mbedtls_pk_context *pk;
+} mbedtls_x509_crt_cache;
+
 typedef struct mbedtls_x509_crt_frame
 {
     /* Keep these 8-bit fields at the front of the structure to allow them to
@@ -879,37 +894,8 @@
  *               to hold the address of a frame for the given CRT.
  * \return       A negative error code on failure.
  */
-static inline int mbedtls_x509_crt_frame_acquire( mbedtls_x509_crt const *crt,
-                                          mbedtls_x509_crt_frame const **dst )
-{
-    int ret = 0;
-#if defined(MBEDTLS_THREADING_C)
-    if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-#endif /* MBEDTLS_THREADING_C */
-
-#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
-    defined(MBEDTLS_THREADING_C)
-    if( crt->cache->frame_readers == 0 )
-#endif
-        ret = mbedtls_x509_crt_cache_provide_frame( crt );
-
-#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
-    defined(MBEDTLS_THREADING_C)
-    if( crt->cache->frame_readers == MBEDTLS_X509_CACHE_FRAME_READERS_MAX )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-
-    crt->cache->frame_readers++;
-#endif
-
-#if defined(MBEDTLS_THREADING_C)
-    if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-#endif /* MBEDTLS_THREADING_C */
-
-    *dst = crt->cache->frame;
-    return( ret );
-}
+int mbedtls_x509_crt_frame_acquire( mbedtls_x509_crt const *crt,
+                                          mbedtls_x509_crt_frame const **dst );
 
 /**
  * \brief        Release access to a certificate frame acquired
@@ -918,36 +904,7 @@
  * \param crt    The certificate for which a certificate frame has
  *               previously been acquired.
  */
-static inline int mbedtls_x509_crt_frame_release( mbedtls_x509_crt const *crt )
-{
-#if defined(MBEDTLS_THREADING_C)
-    if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-#endif /* MBEDTLS_THREADING_C */
-
-#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
-    defined(MBEDTLS_THREADING_C)
-    if( crt->cache->frame_readers == 0 )
-        return( MBEDTLS_ERR_X509_FATAL_ERROR );
-
-    crt->cache->frame_readers--;
-#endif
-
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_unlock( &crt->cache->frame_mutex );
-#endif /* MBEDTLS_THREADING_C */
-
-#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
-    (void) mbedtls_x509_crt_flush_cache_frame( crt );
-#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
-
-#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
-    !defined(MBEDTLS_THREADING_C)
-    ((void) crt);
-#endif
-
-    return( 0 );
-}
+int mbedtls_x509_crt_frame_release( mbedtls_x509_crt const *crt );
 
 /**
  * \brief        Request temporary access to a public key context
@@ -981,37 +938,8 @@
  *               certificate.
  * \return       A negative error code on failure.
  */
-static inline int mbedtls_x509_crt_pk_acquire( mbedtls_x509_crt const *crt,
-                                               mbedtls_pk_context **dst )
-{
-    int ret = 0;
-#if defined(MBEDTLS_THREADING_C)
-    if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-#endif /* MBEDTLS_THREADING_C */
-
-#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
-    defined(MBEDTLS_THREADING_C)
-    if( crt->cache->pk_readers == 0 )
-#endif
-        ret = mbedtls_x509_crt_cache_provide_pk( crt );
-
-#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
-    defined(MBEDTLS_THREADING_C)
-    if( crt->cache->pk_readers == MBEDTLS_X509_CACHE_PK_READERS_MAX )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-
-    crt->cache->pk_readers++;
-#endif
-
-#if defined(MBEDTLS_THREADING_C)
-    if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-#endif /* MBEDTLS_THREADING_C */
-
-    *dst = crt->cache->pk;
-    return( ret );
-}
+int mbedtls_x509_crt_pk_acquire( mbedtls_x509_crt const *crt,
+                                               mbedtls_pk_context **dst );
 
 /**
  * \brief        Release access to a public key context acquired
@@ -1020,36 +948,7 @@
  * \param crt    The certificate for which a certificate frame has
  *               previously been acquired.
  */
-static inline int mbedtls_x509_crt_pk_release( mbedtls_x509_crt const *crt )
-{
-#if defined(MBEDTLS_THREADING_C)
-    if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-#endif /* MBEDTLS_THREADING_C */
-
-#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
-    defined(MBEDTLS_THREADING_C)
-    if( crt->cache->pk_readers == 0 )
-        return( MBEDTLS_ERR_X509_FATAL_ERROR );
-
-    crt->cache->pk_readers--;
-#endif
-
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_unlock( &crt->cache->pk_mutex );
-#endif /* MBEDTLS_THREADING_C */
-
-#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
-    (void) mbedtls_x509_crt_flush_cache_pk( crt );
-#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
-
-#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
-    !defined(MBEDTLS_THREADING_C)
-    ((void) crt);
-#endif
-
-    return( 0 );
-}
+int mbedtls_x509_crt_pk_release( mbedtls_x509_crt const *crt );
 
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
diff --git a/include/mbedtls/x509_internal.h b/include/mbedtls/x509_internal.h
index 6ca3db5..c69c542 100644
--- a/include/mbedtls/x509_internal.h
+++ b/include/mbedtls/x509_internal.h
@@ -35,83 +35,87 @@
 struct mbedtls_x509_crt_frame;
 #define MBEDTLS_X509_CACHE_PK_READERS_MAX    ((uint32_t) -1)
 #define MBEDTLS_X509_CACHE_FRAME_READERS_MAX ((uint32_t) -1)
-typedef struct mbedtls_x509_crt_cache
-{
-#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
-    defined(MBEDTLS_THREADING_C)
-    uint32_t frame_readers;
-    uint32_t pk_readers;
-#endif /* !MBEDTLS_X509_ALWAYS_FLUSH || MBEDTLS_THREADING_C */
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_threading_mutex_t frame_mutex;
-    mbedtls_threading_mutex_t pk_mutex;
-#endif
-    mbedtls_x509_buf_raw pk_raw;
-    struct mbedtls_x509_crt_frame *frame;
-    struct mbedtls_pk_context *pk;
-} mbedtls_x509_crt_cache;
 
 /* Internal X.509 CRT cache handling functions. */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+static int mbedtls_x509_crt_flush_cache_frame( struct mbedtls_x509_crt const *crt );
+static int mbedtls_x509_crt_flush_cache_pk( struct mbedtls_x509_crt const *crt );
 
-int mbedtls_x509_crt_flush_cache_frame( struct mbedtls_x509_crt const *crt );
-int mbedtls_x509_crt_flush_cache_pk( struct mbedtls_x509_crt const *crt );
-
-int mbedtls_x509_crt_cache_provide_frame( struct mbedtls_x509_crt const *crt );
-int mbedtls_x509_crt_cache_provide_pk( struct mbedtls_x509_crt const *crt );
+static int mbedtls_x509_crt_cache_provide_frame( struct mbedtls_x509_crt const *crt );
+static int mbedtls_x509_crt_cache_provide_pk( struct mbedtls_x509_crt const *crt );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
 
 /* Uncategorized internal X.509 functions */
-
-int mbedtls_x509_get_name( unsigned char *p, size_t len,
+static int mbedtls_x509_get_name( unsigned char *p, size_t len,
                            mbedtls_x509_name *cur );
-int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
-                       mbedtls_x509_buf *alg );
-int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
+
+#if defined(MBEDTLS_X509_CRL_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C) || \
+    ( !defined(MBEDTLS_X509_ON_DEMAND_PARSING) && defined(MBEDTLS_X509_CRT_PARSE_C) )
+static int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
                   mbedtls_x509_buf *alg, mbedtls_x509_buf *params );
+#endif /* defined(MBEDTLS_X509_CRL_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C) ||
+          ( !defined(MBEDTLS_X509_ON_DEMAND_PARSING) && defined(MBEDTLS_X509_CRT_PARSE_C) ) */
+
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
-int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
+static int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
+                       mbedtls_x509_buf *alg );
+static int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
                                 mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
                                 int *salt_len );
 #endif
-int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig );
-int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end,
+static int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig );
+static int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end,
                                   mbedtls_md_type_t *md_alg,
                                   mbedtls_pk_type_t *pk_alg,
                                   void **sig_opts );
-int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
+static int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
                       mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
                       void **sig_opts );
-int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
+
+#if ( !defined(MBEDTLS_X509_CRT_REMOVE_TIME) && defined(MBEDTLS_X509_CRT_PARSE_C) ) || \
+    defined(MBEDTLS_X509_CRL_PARSE_C)
+static int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
                    mbedtls_x509_time *t );
-int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
+#endif /* ( !defined(MBEDTLS_X509_CRT_REMOVE_TIME) && defined(MBEDTLS_X509_CRT_PARSE_C) ) ||
+          defined(MBEDTLS_X509_CRL_PARSE_C) */
+
+static int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
                      mbedtls_x509_buf *serial );
-int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a,
+static int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a,
                                mbedtls_x509_buf_raw const *b,
                                int (*check)( void *ctx,
                                              mbedtls_x509_buf *oid,
                                              mbedtls_x509_buf *val,
                                              int next_merged ),
                                void *check_ctx );
-int mbedtls_x509_memcasecmp( const void *s1, const void *s2,
+static int mbedtls_x509_memcasecmp( const void *s1, const void *s2,
                              size_t len1, size_t len2 );
-int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
+
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
+static int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
                   mbedtls_x509_buf *ext, int tag );
+#endif /* defined(MBEDTLS_X509_CRL_PARSE_C) */
 
 #if !defined(MBEDTLS_X509_REMOVE_INFO)
-int mbedtls_x509_sig_alg_gets( char *buf, size_t size,
+static int mbedtls_x509_sig_alg_gets( char *buf, size_t size,
                        mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
                        const void *sig_opts );
 #endif
-int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name );
-int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name );
-int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
+#if !defined(MBEDTLS_X509_REMOVE_INFO)
+static int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name );
+#endif /* !defined(MBEDTLS_X509_REMOVE_INFO) */
+
+#if defined(MBEDTLS_X509_CREATE_C)
+static int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name );
+static int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
                         int critical, const unsigned char *val,
                         size_t val_len );
-int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
+static int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
                            mbedtls_asn1_named_data *first );
 int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
                       mbedtls_asn1_named_data *first );
-int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
+static int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
                     const char *oid, size_t oid_len,
                     unsigned char *sig, size_t size );
-
+#endif /* MBEDTLS_X509_CREATE_C */
 #endif /* MBEDTLS_X509_INTERNAL_H */
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 1da5a2e..89f7275 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -68,12 +68,6 @@
     certs.c
     pkcs11.c
     x509.c
-    x509_create.c
-    x509_crl.c
-    x509_crt.c
-    x509_csr.c
-    x509write_crt.c
-    x509write_csr.c
 )
 
 set(src_tls
diff --git a/library/Makefile b/library/Makefile
index 341888a..fc67329 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -89,9 +89,7 @@
 		version_features.o		xtea.o		\
 		ecc.o		ecc_dh.o	ecc_dsa.o
 
-OBJS_X509=	certs.o		pkcs11.o	x509.o		\
-		x509_create.o	x509_crl.o	x509_crt.o	\
-		x509_csr.o	x509write_crt.o	x509write_csr.o
+OBJS_X509=	certs.o		pkcs11.o	x509.o
 
 OBJS_TLS=	debug.o		net_sockets.o		\
 		ssl_cache.o	ssl_ciphersuites.o	\
diff --git a/library/x509.c b/library/x509.c
index d570f71..270d526 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -42,6 +42,18 @@
 #include "mbedtls/asn1.h"
 #include "mbedtls/oid.h"
 
+/* We include x509xxx.c files here so that x509.c is one compilation unit including
+ * all the x509 files. This is done because some of the internal functions are shared.
+ * For code size savings internal functions should be static so that compiler can do better job
+ * when optimizing. We don't wan't x509.c file to get too big so including .c files.
+ */
+#include "x509_crl.c"
+#include "x509_crt.c"
+#include "x509_csr.c"
+#include "x509_create.c"
+#include "x509write_crt.c"
+#include "x509write_csr.c"
+
 #include <stdio.h>
 #include <string.h>
 
@@ -81,7 +93,7 @@
 /*
  *  CertificateSerialNumber  ::=  INTEGER
  */
-int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
+static int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
                      mbedtls_x509_buf *serial )
 {
     int ret;
@@ -106,13 +118,32 @@
     return( 0 );
 }
 
+#if defined(MBEDTLS_X509_CRL_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C) || \
+    ( !defined(MBEDTLS_X509_ON_DEMAND_PARSING) && defined(MBEDTLS_X509_CRT_PARSE_C) )
+/*
+ * Parse an algorithm identifier with (optional) parameters
+ */
+static int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
+                  mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
+{
+    int ret;
+
+    if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    return( 0 );
+}
+#endif /* defined(MBEDTLS_X509_CRL_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C) ||
+         ( !defined(MBEDTLS_X509_ON_DEMAND_PARSING) && defined(MBEDTLS_X509_CRT_PARSE_C) ) */
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
 /* Get an algorithm identifier without parameters (eg for signatures)
  *
  *  AlgorithmIdentifier  ::=  SEQUENCE  {
  *       algorithm               OBJECT IDENTIFIER,
  *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
  */
-int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
+static int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
                        mbedtls_x509_buf *alg )
 {
     int ret;
@@ -124,21 +155,6 @@
 }
 
 /*
- * Parse an algorithm identifier with (optional) parameters
- */
-int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
-                  mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
-{
-    int ret;
-
-    if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
-        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
-
-    return( 0 );
-}
-
-#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
-/*
  * HashAlgorithm ::= AlgorithmIdentifier
  *
  * AlgorithmIdentifier  ::=  SEQUENCE  {
@@ -206,7 +222,7 @@
  * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
  * option. Enfore this at parsing time.
  */
-int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
+static int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
                                 mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
                                 int *salt_len )
 {
@@ -459,7 +475,7 @@
 /*
  * Like memcmp, but case-insensitive and always returns -1 if different
  */
-int mbedtls_x509_memcasecmp( const void *s1, const void *s2,
+static int mbedtls_x509_memcasecmp( const void *s1, const void *s2,
                              size_t len1, size_t len2 )
 {
     size_t i;
@@ -540,7 +556,7 @@
  * This function can be used to verify that a buffer contains a well-formed
  * ASN.1 encoded X.509 name by calling it with equal parameters.
  */
-int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a,
+static int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a,
                                mbedtls_x509_buf_raw const *b,
                                int (*abort_check)( void *ctx,
                                                    mbedtls_x509_buf *oid,
@@ -645,7 +661,7 @@
     return( 0 );
 }
 
-int mbedtls_x509_get_name( unsigned char *p,
+static int mbedtls_x509_get_name( unsigned char *p,
                            size_t len,
                            mbedtls_x509_name *cur )
 {
@@ -656,6 +672,8 @@
                                        &cur ) );
 }
 
+#if ( !defined(MBEDTLS_X509_CRT_REMOVE_TIME) && defined(MBEDTLS_X509_CRT_PARSE_C) ) || \
+    defined(MBEDTLS_X509_CRL_PARSE_C)
 static int x509_parse_int( unsigned char **p, size_t n, int *res )
 {
     *res = 0;
@@ -774,7 +792,7 @@
  *       utcTime        UTCTime,
  *       generalTime    GeneralizedTime }
  */
-int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
+static int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
                            mbedtls_x509_time *tm )
 {
     int ret;
@@ -803,8 +821,10 @@
 
     return x509_parse_time( p, len, year_len, tm );
 }
+#endif /* ( !defined(MBEDTLS_X509_CRT_REMOVE_TIME) && defined(MBEDTLS_X509_CRT_PARSE_C) ) ||
+          defined(MBEDTLS_X509_CRL_PARSE_C) */
 
-int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
+static int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
 {
     int ret;
     size_t len;
@@ -828,7 +848,7 @@
     return( 0 );
 }
 
-int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end,
+static int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end,
                                   mbedtls_md_type_t *md_alg,
                                   mbedtls_pk_type_t *pk_alg,
                                   void **sig_opts )
@@ -846,7 +866,7 @@
 /*
  * Get signature algorithm from alg OID and optional parameters
  */
-int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
+static int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
                       mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
                       void **sig_opts )
 {
@@ -894,11 +914,12 @@
     return( 0 );
 }
 
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
 /*
  * X.509 Extensions (No parsing of extensions, pointer should
  * be either manually updated or extensions should be parsed!)
  */
-int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
+static int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
                           mbedtls_x509_buf *ext, int tag )
 {
     int ret;
@@ -929,7 +950,7 @@
 
     return( 0 );
 }
-
+#endif /* defined(MBEDTLS_X509_CRL_PARSE_C) */
 /*
  * Store the name in printable form into buf; no more
  * than size characters will be written
@@ -1031,7 +1052,7 @@
 /*
  * Helper for writing signature algorithms
  */
-int mbedtls_x509_sig_alg_gets( char *buf, size_t size, mbedtls_pk_type_t pk_alg,
+static int mbedtls_x509_sig_alg_gets( char *buf, size_t size, mbedtls_pk_type_t pk_alg,
                                mbedtls_md_type_t md_alg, const void *sig_opts )
 {
     int ret;
@@ -1086,12 +1107,11 @@
 
     return( (int)( size - n ) );
 }
-#endif /* !MBEDTLS_X509_REMOVE_INFO */
 
 /*
  * Helper for writing "RSA key size", "EC key size", etc
  */
-int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
+static int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
 {
     char *p = buf;
     size_t n = buf_size;
@@ -1102,6 +1122,7 @@
 
     return( 0 );
 }
+#endif /* !MBEDTLS_X509_REMOVE_INFO */
 
 #if defined(MBEDTLS_HAVE_TIME_DATE)
 /*
diff --git a/library/x509_create.c b/library/x509_create.c
index 1639630..88148a6 100644
--- a/library/x509_create.c
+++ b/library/x509_create.c
@@ -126,7 +126,7 @@
     return( cur );
 }
 
-int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name )
+static int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name )
 {
     int ret = 0;
     const char *s = name, *c = s;
@@ -211,7 +211,7 @@
 /* The first byte of the value in the mbedtls_asn1_named_data structure is reserved
  * to store the critical boolean for us
  */
-int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
+static int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
                         int critical, const unsigned char *val, size_t val_len )
 {
     mbedtls_asn1_named_data *cur;
@@ -292,7 +292,7 @@
     return( (int) len );
 }
 
-int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
+static int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
                     const char *oid, size_t oid_len,
                     unsigned char *sig, size_t size )
 {
@@ -361,7 +361,7 @@
  *                 -- by extnID
  *     }
  */
-int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
+static int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
                            mbedtls_asn1_named_data *first )
 {
     int ret;
diff --git a/library/x509_crl.c b/library/x509_crl.c
index 3113de4..0da871a 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -624,11 +624,6 @@
 
 #if !defined(MBEDTLS_X509_REMOVE_INFO)
 /*
- * Return an informational string about the certificate.
- */
-#define BEFORE_COLON    14
-#define BC              "14"
-/*
  * Return an informational string about the CRL.
  */
 int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 1923abf..8bf0ea4 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -109,7 +109,7 @@
 static int x509_crt_ext_key_usage_from_frame( mbedtls_x509_crt_frame const *frame,
                                         mbedtls_x509_sequence *ext_key_usage );
 
-int mbedtls_x509_crt_flush_cache_pk( mbedtls_x509_crt const *crt )
+static int mbedtls_x509_crt_flush_cache_pk( mbedtls_x509_crt const *crt )
 {
 #if defined(MBEDTLS_THREADING_C)
     if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
@@ -145,7 +145,7 @@
     return( 0 );
 }
 
-int mbedtls_x509_crt_flush_cache_frame( mbedtls_x509_crt const *crt )
+static int mbedtls_x509_crt_flush_cache_frame( mbedtls_x509_crt const *crt )
 {
 #if defined(MBEDTLS_THREADING_C)
     if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
@@ -188,7 +188,7 @@
 
 static int x509_crt_frame_parse_ext( mbedtls_x509_crt_frame *frame );
 
-int mbedtls_x509_crt_cache_provide_frame( mbedtls_x509_crt const *crt )
+static int mbedtls_x509_crt_cache_provide_frame( mbedtls_x509_crt const *crt )
 {
     mbedtls_x509_crt_cache *cache = crt->cache;
     mbedtls_x509_crt_frame *frame;
@@ -255,7 +255,7 @@
 #endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */
 }
 
-int mbedtls_x509_crt_cache_provide_pk( mbedtls_x509_crt const *crt )
+static int mbedtls_x509_crt_cache_provide_pk( mbedtls_x509_crt const *crt )
 {
     mbedtls_x509_crt_cache *cache = crt->cache;
     mbedtls_pk_context *pk;
@@ -2248,15 +2248,15 @@
 /*
  * Return an informational string about the certificate.
  */
-#define BEFORE_COLON    18
-#define BC              "18"
+#define BEFORE_COLON_CRT    18
+#define BC_CRT              "18"
 int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
                            const mbedtls_x509_crt *crt )
 {
     int ret;
     size_t n;
     char *p;
-    char key_size_str[BEFORE_COLON];
+    char key_size_str[BEFORE_COLON_CRT];
     mbedtls_x509_crt_frame frame;
     mbedtls_pk_context pk;
 
@@ -2382,13 +2382,13 @@
     MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
 
     /* Key size */
-    if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
+    if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON_CRT,
                                       mbedtls_pk_get_name( &pk ) ) ) != 0 )
     {
         return( ret );
     }
 
-    ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
+    ret = mbedtls_snprintf( p, n, "\n%s%-" BC_CRT "s: %d bits", prefix, key_size_str,
                           (int) mbedtls_pk_get_bitlen( &pk ) );
     MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
 
@@ -3927,4 +3927,129 @@
 }
 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
 
+int mbedtls_x509_crt_frame_acquire( mbedtls_x509_crt const *crt,
+                                          mbedtls_x509_crt_frame const **dst )
+{
+    int ret = 0;
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif /* MBEDTLS_THREADING_C */
+
+#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
+    defined(MBEDTLS_THREADING_C)
+    if( crt->cache->frame_readers == 0 )
+#endif
+        ret = mbedtls_x509_crt_cache_provide_frame( crt );
+
+#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
+    defined(MBEDTLS_THREADING_C)
+    if( crt->cache->frame_readers == MBEDTLS_X509_CACHE_FRAME_READERS_MAX )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+
+    crt->cache->frame_readers++;
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif /* MBEDTLS_THREADING_C */
+
+    *dst = crt->cache->frame;
+    return( ret );
+}
+
+int mbedtls_x509_crt_frame_release( mbedtls_x509_crt const *crt )
+{
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif /* MBEDTLS_THREADING_C */
+
+#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
+    defined(MBEDTLS_THREADING_C)
+    if( crt->cache->frame_readers == 0 )
+        return( MBEDTLS_ERR_X509_FATAL_ERROR );
+
+    crt->cache->frame_readers--;
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_unlock( &crt->cache->frame_mutex );
+#endif /* MBEDTLS_THREADING_C */
+
+#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
+    (void) mbedtls_x509_crt_flush_cache_frame( crt );
+#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
+
+#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
+    !defined(MBEDTLS_THREADING_C)
+    ((void) crt);
+#endif
+
+    return( 0 );
+}
+
+int mbedtls_x509_crt_pk_acquire( mbedtls_x509_crt const *crt,
+                                               mbedtls_pk_context **dst )
+{
+    int ret = 0;
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif /* MBEDTLS_THREADING_C */
+
+#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
+    defined(MBEDTLS_THREADING_C)
+    if( crt->cache->pk_readers == 0 )
+#endif
+        ret = mbedtls_x509_crt_cache_provide_pk( crt );
+
+#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
+    defined(MBEDTLS_THREADING_C)
+    if( crt->cache->pk_readers == MBEDTLS_X509_CACHE_PK_READERS_MAX )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+
+    crt->cache->pk_readers++;
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif /* MBEDTLS_THREADING_C */
+
+    *dst = crt->cache->pk;
+    return( ret );
+}
+
+int mbedtls_x509_crt_pk_release( mbedtls_x509_crt const *crt )
+{
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif /* MBEDTLS_THREADING_C */
+
+#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) ||      \
+    defined(MBEDTLS_THREADING_C)
+    if( crt->cache->pk_readers == 0 )
+        return( MBEDTLS_ERR_X509_FATAL_ERROR );
+
+    crt->cache->pk_readers--;
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_unlock( &crt->cache->pk_mutex );
+#endif /* MBEDTLS_THREADING_C */
+
+#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
+    (void) mbedtls_x509_crt_flush_cache_pk( crt );
+#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
+
+#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
+    !defined(MBEDTLS_THREADING_C)
+    ((void) crt);
+#endif
+
+    return( 0 );
+}
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
diff --git a/library/x509_csr.c b/library/x509_csr.c
index 9b58a86..283f69d 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -332,8 +332,8 @@
 #endif /* MBEDTLS_FS_IO */
 
 #if !defined(MBEDTLS_X509_REMOVE_INFO)
-#define BEFORE_COLON    14
-#define BC              "14"
+#define BEFORE_COLON_CSR    14
+#define BC_CSR              "14"
 /*
  * Return an informational string about the CSR.
  */
@@ -343,7 +343,7 @@
     int ret;
     size_t n;
     char *p;
-    char key_size_str[BEFORE_COLON];
+    char key_size_str[BEFORE_COLON_CSR];
 
     p = buf;
     n = size;
@@ -364,13 +364,13 @@
                                      csr->sig_md, csr->sig_opts );
     MBEDTLS_X509_SAFE_SNPRINTF;
 
-    if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
+    if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON_CSR,
                                       mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
     {
         return( ret );
     }
 
-    ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
+    ret = mbedtls_snprintf( p, n, "\n%s%-" BC_CSR "s: %d bits\n", prefix, key_size_str,
                           (int) mbedtls_pk_get_bitlen( &csr->pk ) );
     MBEDTLS_X509_SAFE_SNPRINTF;
 
diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl
index 9913976..51ad69b 100755
--- a/scripts/generate_visualc_files.pl
+++ b/scripts/generate_visualc_files.pl
@@ -195,12 +195,31 @@
     my @app_list = get_app_list();
     my @headers = <$header_dir/*.h>;
     my @sources = <$source_dir/*.c>;
+
+    # exclude files from the sources
+    my @excluded_files = ("library/x509_create.c", "library/x509_crt.c", "library/x509_crl.c", "library/x509_csr.c", "library/x509write_crt.c", "library/x509write_csr.c");
+    my @tmp_sources;
+    my $add_to_array = 1;
+    for my $i ( @sources ) {
+        for my $x ( @excluded_files ) {
+            if( $i eq $x ) {
+                $add_to_array = 0;
+            }
+        }
+
+        if( $add_to_array == 1 ) {
+            push(@tmp_sources, $i);
+        }
+        $add_to_array = 1;
+    }
+
+
     map { s!/!\\!g } @headers;
-    map { s!/!\\!g } @sources;
+    map { s!/!\\!g } @tmp_sources;
 
     gen_app_files( @app_list );
 
-    gen_main_file( \@headers, \@sources,
+    gen_main_file( \@headers, \@tmp_sources,
                    $vsx_hdr_tpl, $vsx_src_tpl,
                    $vsx_main_tpl_file, $vsx_main_file );
 
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 130d90f..feb8f79 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -9,6 +9,10 @@
 #include "mbedtls/oid.h"
 #include "mbedtls/base64.h"
 #include "string.h"
+/* We need to include x509.c because we are testing x509 internal
+ * functions from x509_internal.h which are static. With this include
+ * we get the tested functions defined. */
+#include "../library/x509.c"
 
 #if MBEDTLS_X509_MAX_INTERMEDIATE_CA > 19
 #error "The value of MBEDTLS_X509_MAX_INTERMEDIATE_C is larger \
@@ -1002,7 +1006,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C */
+/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C:!MBEDTLS_X509_CRT_REMOVE_TIME */
 void x509_get_time( int tag, char * time_str, int ret, int year, int mon,
                     int day, int hour, int min, int sec )
 {
diff --git a/tests/suites/test_suite_x509parse_pthread.function b/tests/suites/test_suite_x509parse_pthread.function
index 2728e96..5ce0bf5 100644
--- a/tests/suites/test_suite_x509parse_pthread.function
+++ b/tests/suites/test_suite_x509parse_pthread.function
@@ -4,7 +4,6 @@
 #include "mbedtls/x509_crt.h"
 #include "mbedtls/x509_crl.h"
 #include "mbedtls/x509_csr.h"
-#include "mbedtls/x509_internal.h"
 #include "mbedtls/pem.h"
 #include "mbedtls/oid.h"
 #include "mbedtls/base64.h"
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index 3b9f20f..b0e0969 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -6,6 +6,10 @@
 #include "mbedtls/pem.h"
 #include "mbedtls/oid.h"
 #include "mbedtls/rsa.h"
+/* We need to include x509.c because we are testing x509 internal
+ * functions from x509_internal.h which are static. With this include
+ * we get the tested functions defined. */
+#include "../library/x509.c"
 
 #if defined(MBEDTLS_RSA_C)
 int mbedtls_rsa_decrypt_func( void *ctx, int mode, size_t *olen,
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index 0596aff..27813da 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -297,12 +297,6 @@
     <ClCompile Include="..\..\library\version.c" />

     <ClCompile Include="..\..\library\version_features.c" />

     <ClCompile Include="..\..\library\x509.c" />

-    <ClCompile Include="..\..\library\x509_create.c" />

-    <ClCompile Include="..\..\library\x509_crl.c" />

-    <ClCompile Include="..\..\library\x509_crt.c" />

-    <ClCompile Include="..\..\library\x509_csr.c" />

-    <ClCompile Include="..\..\library\x509write_crt.c" />

-    <ClCompile Include="..\..\library\x509write_csr.c" />

     <ClCompile Include="..\..\library\xtea.c" />

   </ItemGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />