[MBEDTLS] Update mbedtls to v2.1.1. By Ismael Ferreras Morezuelas with a fix by Roy...
[reactos.git] / reactos / dll / 3rdparty / mbedtls / x509_crt.c
index d1d7d73..f6879dd 100644 (file)
@@ -1,23 +1,22 @@
 /*
  *  X.509 certificate parsing and verification
  *
- *  Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
  *
- *  This file is part of mbed TLS (https://polarssl.org)
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
+ *  http://www.apache.org/licenses/LICENSE-2.0
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 /*
  *  The ITU-T X.509 standard defines a certificate format for PKI.
  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  */
 
-#if !defined(POLARSSL_CONFIG_FILE)
-#include "polarssl/config.h"
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
 #else
-#include POLARSSL_CONFIG_FILE
+#include MBEDTLS_CONFIG_FILE
 #endif
 
-#if defined(POLARSSL_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
 
-#include "polarssl/x509_crt.h"
-#include "polarssl/oid.h"
-#if defined(POLARSSL_PEM_PARSE_C)
-#include "polarssl/pem.h"
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/oid.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+#include "mbedtls/pem.h"
 #endif
 
-#if defined(POLARSSL_PLATFORM_C)
-#include "polarssl/platform.h"
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
 #else
-#define polarssl_malloc     malloc
-#define polarssl_free       free
+#include <stdlib.h>
+#define mbedtls_free       free
+#define mbedtls_calloc    calloc
+#define mbedtls_snprintf   snprintf
 #endif
 
-#if defined(POLARSSL_THREADING_C)
-#include "polarssl/threading.h"
+#if defined(MBEDTLS_THREADING_C)
+#include "mbedtls/threading.h"
 #endif
 
-#include <string.h>
-#include <stdlib.h>
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 #include <windows.h>
 #else
 #include <time.h>
 #endif
 
+#if defined(MBEDTLS_FS_IO)
 #include <stdio.h>
-
-#if defined(POLARSSL_FS_IO)
 #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dirent.h>
-#endif
+#endif /* !_WIN32 || EFIX64 || EFI32 */
 #endif
 
 /* Implementation that should never be optimized out by the compiler */
-static void polarssl_zeroize( void *v, size_t n ) {
+static void mbedtls_zeroize( void *v, size_t n ) {
     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
 }
 
+/*
+ * Default profile
+ */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
+{
+    /* Hashes from SHA-1 and above */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
+    0xFFFFFFF, /* Any PK alg    */
+    0xFFFFFFF, /* Any curve     */
+    2048,
+};
+
+/*
+ * Next-default profile
+ */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
+{
+    /* Hashes from SHA-256 and above */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
+    0xFFFFFFF, /* Any PK alg    */
+#if defined(MBEDTLS_ECP_C)
+    /* Curves at or above 128-bit security level */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ),
+#else
+    0,
+#endif
+    2048,
+};
+
+/*
+ * NSA Suite B Profile
+ */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
+{
+    /* Only SHA-256 and 384 */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
+    /* Only ECDSA */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ),
+#if defined(MBEDTLS_ECP_C)
+    /* Only NIST P-256 and P-384 */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
+#else
+    0,
+#endif
+    0,
+};
+
+/*
+ * Check md_alg against profile
+ * Return 0 if md_alg acceptable for this profile, -1 otherwise
+ */
+static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
+                                      mbedtls_md_type_t md_alg )
+{
+    if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
+        return( 0 );
+
+    return( -1 );
+}
+
+/*
+ * Check pk_alg against profile
+ * Return 0 if pk_alg acceptable for this profile, -1 otherwise
+ */
+static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
+                                      mbedtls_pk_type_t pk_alg )
+{
+    if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
+        return( 0 );
+
+    return( -1 );
+}
+
+/*
+ * Check key against profile
+ * Return 0 if pk_alg acceptable for this profile, -1 otherwise
+ */
+static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
+                                   mbedtls_pk_type_t pk_alg,
+                                   const mbedtls_pk_context *pk )
+{
+#if defined(MBEDTLS_RSA_C)
+    if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS )
+    {
+        if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen )
+            return( 0 );
+
+        return( -1 );
+    }
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+    if( pk_alg == MBEDTLS_PK_ECDSA )
+    {
+        mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
+
+        if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
+            return( 0 );
+
+        return( -1 );
+    }
+#endif
+
+    return( -1 );
+}
+
 /*
  *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
  */
@@ -88,10 +211,10 @@ static int x509_get_version( unsigned char **p,
     int ret;
     size_t len;
 
-    if( ( ret = asn1_get_tag( p, end, &len,
-            ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 )
     {
-        if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
         {
             *ver = 0;
             return( 0 );
@@ -102,12 +225,12 @@ static int x509_get_version( unsigned char **p,
 
     end = *p + len;
 
-    if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
-        return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
+    if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
 
     if( *p != end )
-        return( POLARSSL_ERR_X509_INVALID_VERSION +
-                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+        return( MBEDTLS_ERR_X509_INVALID_VERSION +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
     return( 0 );
 }
@@ -119,27 +242,27 @@ static int x509_get_version( unsigned char **p,
  */
 static int x509_get_dates( unsigned char **p,
                            const unsigned char *end,
-                           x509_time *from,
-                           x509_time *to )
+                           mbedtls_x509_time *from,
+                           mbedtls_x509_time *to )
 {
     int ret;
     size_t len;
 
-    if( ( ret = asn1_get_tag( p, end, &len,
-            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
-        return( POLARSSL_ERR_X509_INVALID_DATE + ret );
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
 
     end = *p + len;
 
-    if( ( ret = x509_get_time( p, end, from ) ) != 0 )
+    if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 )
         return( ret );
 
-    if( ( ret = x509_get_time( p, end, to ) ) != 0 )
+    if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 )
         return( ret );
 
     if( *p != end )
-        return( POLARSSL_ERR_X509_INVALID_DATE +
-                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+        return( MBEDTLS_ERR_X509_INVALID_DATE +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
     return( 0 );
 }
@@ -149,7 +272,7 @@ static int x509_get_dates( unsigned char **p,
  */
 static int x509_get_uid( unsigned char **p,
                          const unsigned char *end,
-                         x509_buf *uid, int n )
+                         mbedtls_x509_buf *uid, int n )
 {
     int ret;
 
@@ -158,10 +281,10 @@ static int x509_get_uid( unsigned char **p,
 
     uid->tag = **p;
 
-    if( ( ret = asn1_get_tag( p, end, &uid->len,
-            ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len,
+            MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 )
     {
-        if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
             return( 0 );
 
         return( ret );
@@ -189,20 +312,20 @@ static int x509_get_basic_constraints( unsigned char **p,
     *ca_istrue = 0; /* DEFAULT FALSE */
     *max_pathlen = 0; /* endless */
 
-    if( ( ret = asn1_get_tag( p, end, &len,
-            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
     if( *p == end )
         return( 0 );
 
-    if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
+    if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 )
     {
-        if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
-            ret = asn1_get_int( p, end, ca_istrue );
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+            ret = mbedtls_asn1_get_int( p, end, ca_istrue );
 
         if( ret != 0 )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
         if( *ca_istrue != 0 )
             *ca_istrue = 1;
@@ -211,12 +334,12 @@ static int x509_get_basic_constraints( unsigned char **p,
     if( *p == end )
         return( 0 );
 
-    if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+    if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
     if( *p != end )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
     (*max_pathlen)++;
 
@@ -228,14 +351,14 @@ static int x509_get_ns_cert_type( unsigned char **p,
                                        unsigned char *ns_cert_type)
 {
     int ret;
-    x509_bitstring bs = { 0, 0, NULL };
+    mbedtls_x509_bitstring bs = { 0, 0, NULL };
 
-    if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+    if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
     if( bs.len != 1 )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                POLARSSL_ERR_ASN1_INVALID_LENGTH );
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_INVALID_LENGTH );
 
     /* Get actual bitstring */
     *ns_cert_type = *bs.p;
@@ -244,20 +367,26 @@ static int x509_get_ns_cert_type( unsigned char **p,
 
 static int x509_get_key_usage( unsigned char **p,
                                const unsigned char *end,
-                               unsigned char *key_usage)
+                               unsigned int *key_usage)
 {
     int ret;
-    x509_bitstring bs = { 0, 0, NULL };
+    size_t i;
+    mbedtls_x509_bitstring bs = { 0, 0, NULL };
 
-    if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+    if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
     if( bs.len < 1 )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                POLARSSL_ERR_ASN1_INVALID_LENGTH );
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_INVALID_LENGTH );
 
     /* Get actual bitstring */
-    *key_usage = *bs.p;
+    *key_usage = 0;
+    for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ )
+    {
+        *key_usage |= (unsigned int) bs.p[i] << (8*i);
+    }
+
     return( 0 );
 }
 
@@ -268,17 +397,17 @@ static int x509_get_key_usage( unsigned char **p,
  */
 static int x509_get_ext_key_usage( unsigned char **p,
                                const unsigned char *end,
-                               x509_sequence *ext_key_usage)
+                               mbedtls_x509_sequence *ext_key_usage)
 {
     int ret;
 
-    if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+    if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
     /* Sequence length must be >= 1 */
     if( ext_key_usage->buf.p == NULL )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                POLARSSL_ERR_ASN1_INVALID_LENGTH );
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_INVALID_LENGTH );
 
     return( 0 );
 }
@@ -311,40 +440,40 @@ static int x509_get_ext_key_usage( unsigned char **p,
  */
 static int x509_get_subject_alt_name( unsigned char **p,
                                       const unsigned char *end,
-                                      x509_sequence *subject_alt_name )
+                                      mbedtls_x509_sequence *subject_alt_name )
 {
     int ret;
     size_t len, tag_len;
-    asn1_buf *buf;
+    mbedtls_asn1_buf *buf;
     unsigned char tag;
-    asn1_sequence *cur = subject_alt_name;
+    mbedtls_asn1_sequence *cur = subject_alt_name;
 
     /* Get main sequence tag */
-    if( ( ret = asn1_get_tag( p, end, &len,
-            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
     if( *p + len != end )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
     while( *p < end )
     {
         if( ( end - *p ) < 1 )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                    POLARSSL_ERR_ASN1_OUT_OF_DATA );
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                    MBEDTLS_ERR_ASN1_OUT_OF_DATA );
 
         tag = **p;
         (*p)++;
-        if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+        if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
-        if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                    POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
+        if( ( tag & MBEDTLS_ASN1_CONTEXT_SPECIFIC ) != MBEDTLS_ASN1_CONTEXT_SPECIFIC )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                    MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
 
         /* Skip everything but DNS name */
-        if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
+        if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
         {
             *p += tag_len;
             continue;
@@ -354,16 +483,14 @@ static int x509_get_subject_alt_name( unsigned char **p,
         if( cur->buf.p != NULL )
         {
             if( cur->next != NULL )
-                return( POLARSSL_ERR_X509_INVALID_EXTENSIONS );
+                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
 
-            cur->next = (asn1_sequence *) polarssl_malloc(
-                 sizeof( asn1_sequence ) );
+            cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
 
             if( cur->next == NULL )
-                return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                        POLARSSL_ERR_ASN1_MALLOC_FAILED );
+                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                        MBEDTLS_ERR_ASN1_ALLOC_FAILED );
 
-            memset( cur->next, 0, sizeof( asn1_sequence ) );
             cur = cur->next;
         }
 
@@ -378,8 +505,8 @@ static int x509_get_subject_alt_name( unsigned char **p,
     cur->next = NULL;
 
     if( *p != end )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
     return( 0 );
 }
@@ -393,15 +520,15 @@ static int x509_get_subject_alt_name( unsigned char **p,
  */
 static int x509_get_crt_ext( unsigned char **p,
                              const unsigned char *end,
-                             x509_crt *crt )
+                             mbedtls_x509_crt *crt )
 {
     int ret;
     size_t len;
     unsigned char *end_ext_data, *end_ext_octet;
 
-    if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
+    if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
     {
-        if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
             return( 0 );
 
         return( ret );
@@ -415,61 +542,61 @@ static int x509_get_crt_ext( unsigned char **p,
          *      critical    BOOLEAN DEFAULT FALSE,
          *      extnValue   OCTET STRING  }
          */
-        x509_buf extn_oid = {0, 0, NULL};
+        mbedtls_x509_buf extn_oid = {0, 0, NULL};
         int is_critical = 0; /* DEFAULT FALSE */
         int ext_type = 0;
 
-        if( ( ret = asn1_get_tag( p, end, &len,
-                ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+        if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
         end_ext_data = *p + len;
 
         /* Get extension ID */
         extn_oid.tag = **p;
 
-        if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+        if( ( ret = mbedtls_asn1_get_tag( p, end, &extn_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
         extn_oid.p = *p;
         *p += extn_oid.len;
 
         if( ( end - *p ) < 1 )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                    POLARSSL_ERR_ASN1_OUT_OF_DATA );
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                    MBEDTLS_ERR_ASN1_OUT_OF_DATA );
 
         /* Get optional critical */
-        if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
-            ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+        if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
+            ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
         /* Data should be octet string type */
-        if( ( ret = asn1_get_tag( p, end_ext_data, &len,
-                ASN1_OCTET_STRING ) ) != 0 )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
+        if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
+                MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
         end_ext_octet = *p + len;
 
         if( end_ext_octet != end_ext_data )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                    POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
         /*
          * Detect supported extensions
          */
-        ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
+        ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
 
         if( ret != 0 )
         {
             /* No parser found, skip extension */
             *p = end_ext_octet;
 
-#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
+#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
             if( is_critical )
             {
                 /* Data is marked as critical: fail */
-                return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                        POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
+                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                        MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
             }
 #endif
             continue;
@@ -477,41 +604,41 @@ static int x509_get_crt_ext( unsigned char **p,
 
         /* Forbid repeated extensions */
         if( ( crt->ext_types & ext_type ) != 0 )
-            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS );
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
 
         crt->ext_types |= ext_type;
 
         switch( ext_type )
         {
-        case EXT_BASIC_CONSTRAINTS:
+        case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
             /* Parse basic constraints */
             if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
                     &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
                 return( ret );
             break;
 
-        case EXT_KEY_USAGE:
+        case MBEDTLS_X509_EXT_KEY_USAGE:
             /* Parse key usage */
             if( ( ret = x509_get_key_usage( p, end_ext_octet,
                     &crt->key_usage ) ) != 0 )
                 return( ret );
             break;
 
-        case EXT_EXTENDED_KEY_USAGE:
+        case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
             /* Parse extended key usage */
             if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
                     &crt->ext_key_usage ) ) != 0 )
                 return( ret );
             break;
 
-        case EXT_SUBJECT_ALT_NAME:
+        case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
             /* Parse subject alt name */
             if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
                     &crt->subject_alt_names ) ) != 0 )
                 return( ret );
             break;
 
-        case EXT_NS_CERT_TYPE:
+        case MBEDTLS_X509_EXT_NS_CERT_TYPE:
             /* Parse netscape certificate type */
             if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
                     &crt->ns_cert_type ) ) != 0 )
@@ -519,13 +646,13 @@ static int x509_get_crt_ext( unsigned char **p,
             break;
 
         default:
-            return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
+            return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
         }
     }
 
     if( *p != end )
-        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
-                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
 
     return( 0 );
 }
@@ -533,27 +660,27 @@ static int x509_get_crt_ext( unsigned char **p,
 /*
  * Parse and fill a single X.509 certificate in DER format
  */
-static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
+static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
                                     size_t buflen )
 {
     int ret;
     size_t len;
     unsigned char *p, *end, *crt_end;
-    x509_buf sig_params1, sig_params2;
+    mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
 
-    memset( &sig_params1, 0, sizeof( x509_buf ) );
-    memset( &sig_params2, 0, sizeof( x509_buf ) );
+    memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
+    memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
+    memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
 
     /*
      * Check for valid input
      */
     if( crt == NULL || buf == NULL )
-        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
-
-    p = (unsigned char *) polarssl_malloc( len = buflen );
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
+    p = mbedtls_calloc( 1, len = buflen );
     if( p == NULL )
-        return( POLARSSL_ERR_X509_MALLOC_FAILED );
+        return( MBEDTLS_ERR_X509_ALLOC_FAILED );
 
     memcpy( p, buf, buflen );
 
@@ -567,18 +694,18 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
      *      signatureAlgorithm   AlgorithmIdentifier,
      *      signatureValue       BIT STRING  }
      */
-    if( ( ret = asn1_get_tag( &p, end, &len,
-            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
     {
-        x509_crt_free( crt );
-        return( POLARSSL_ERR_X509_INVALID_FORMAT );
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT );
     }
 
     if( len > (size_t) ( end - p ) )
     {
-        x509_crt_free( crt );
-        return( POLARSSL_ERR_X509_INVALID_FORMAT +
-                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
     }
     crt_end = p + len;
 
@@ -587,11 +714,11 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
      */
     crt->tbs.p = p;
 
-    if( ( ret = asn1_get_tag( &p, end, &len,
-            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
     {
-        x509_crt_free( crt );
-        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
     }
 
     end = p + len;
@@ -605,11 +732,11 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
      * signature            AlgorithmIdentifier
      */
     if( ( ret = x509_get_version(  &p, end, &crt->version  ) ) != 0 ||
-        ( ret = x509_get_serial(   &p, end, &crt->serial   ) ) != 0 ||
-        ( ret = x509_get_alg(      &p, end, &crt->sig_oid1,
+        ( ret = mbedtls_x509_get_serial(   &p, end, &crt->serial   ) ) != 0 ||
+        ( ret = mbedtls_x509_get_alg(      &p, end, &crt->sig_oid,
                                             &sig_params1 ) ) != 0 )
     {
-        x509_crt_free( crt );
+        mbedtls_x509_crt_free( crt );
         return( ret );
     }
 
@@ -617,15 +744,15 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
 
     if( crt->version > 3 )
     {
-        x509_crt_free( crt );
-        return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
     }
 
-    if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &sig_params1,
+    if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1,
                                   &crt->sig_md, &crt->sig_pk,
                                   &crt->sig_opts ) ) != 0 )
     {
-        x509_crt_free( crt );
+        mbedtls_x509_crt_free( crt );
         return( ret );
     }
 
@@ -634,16 +761,16 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
      */
     crt->issuer_raw.p = p;
 
-    if( ( ret = asn1_get_tag( &p, end, &len,
-            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
     {
-        x509_crt_free( crt );
-        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
     }
 
-    if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
+    if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
     {
-        x509_crt_free( crt );
+        mbedtls_x509_crt_free( crt );
         return( ret );
     }
 
@@ -658,7 +785,7 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
     if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
                                          &crt->valid_to ) ) != 0 )
     {
-        x509_crt_free( crt );
+        mbedtls_x509_crt_free( crt );
         return( ret );
     }
 
@@ -667,16 +794,16 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
      */
     crt->subject_raw.p = p;
 
-    if( ( ret = asn1_get_tag( &p, end, &len,
-            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
     {
-        x509_crt_free( crt );
-        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
     }
 
-    if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
+    if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
     {
-        x509_crt_free( crt );
+        mbedtls_x509_crt_free( crt );
         return( ret );
     }
 
@@ -685,9 +812,9 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
     /*
      * SubjectPublicKeyInfo
      */
-    if( ( ret = pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
+    if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
     {
-        x509_crt_free( crt );
+        mbedtls_x509_crt_free( crt );
         return( ret );
     }
 
@@ -704,7 +831,7 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
         ret = x509_get_uid( &p, end, &crt->issuer_id,  1 );
         if( ret != 0 )
         {
-            x509_crt_free( crt );
+            mbedtls_x509_crt_free( crt );
             return( ret );
         }
     }
@@ -714,30 +841,28 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
         ret = x509_get_uid( &p, end, &crt->subject_id,  2 );
         if( ret != 0 )
         {
-            x509_crt_free( crt );
+            mbedtls_x509_crt_free( crt );
             return( ret );
         }
     }
 
-#if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
+#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
     if( crt->version == 3 )
-    {
 #endif
+    {
         ret = x509_get_crt_ext( &p, end, crt );
         if( ret != 0 )
         {
-            x509_crt_free( crt );
+            mbedtls_x509_crt_free( crt );
             return( ret );
         }
-#if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
     }
-#endif
 
     if( p != end )
     {
-        x509_crt_free( crt );
-        return( POLARSSL_ERR_X509_INVALID_FORMAT +
-                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
     }
 
     end = crt_end;
@@ -749,32 +874,33 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
      *  signatureAlgorithm   AlgorithmIdentifier,
      *  signatureValue       BIT STRING
      */
-    if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, &sig_params2 ) ) != 0 )
+    if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
     {
-        x509_crt_free( crt );
+        mbedtls_x509_crt_free( crt );
         return( ret );
     }
 
-    if( crt->sig_oid1.len != crt->sig_oid2.len ||
-        memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 ||
+    if( crt->sig_oid.len != sig_oid2.len ||
+        memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
         sig_params1.len != sig_params2.len ||
-        memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 )
+        ( sig_params1.len != 0 &&
+          memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
     {
-        x509_crt_free( crt );
-        return( POLARSSL_ERR_X509_SIG_MISMATCH );
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_SIG_MISMATCH );
     }
 
-    if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
+    if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 )
     {
-        x509_crt_free( crt );
+        mbedtls_x509_crt_free( crt );
         return( ret );
     }
 
     if( p != end )
     {
-        x509_crt_free( crt );
-        return( POLARSSL_ERR_X509_INVALID_FORMAT +
-                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
     }
 
     return( 0 );
@@ -784,17 +910,17 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
  * Parse one X.509 certificate in DER format from a buffer and add them to a
  * chained list
  */
-int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
+int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
                         size_t buflen )
 {
     int ret;
-    x509_crt *crt = chain, *prev = NULL;
+    mbedtls_x509_crt *crt = chain, *prev = NULL;
 
     /*
      * Check for valid input
      */
     if( crt == NULL || buf == NULL )
-        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
     while( crt->version != 0 && crt->next != NULL )
     {
@@ -807,13 +933,13 @@ int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
      */
     if( crt->version != 0 && crt->next == NULL )
     {
-        crt->next = (x509_crt *) polarssl_malloc( sizeof( x509_crt ) );
+        crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
 
         if( crt->next == NULL )
-            return( POLARSSL_ERR_X509_MALLOC_FAILED );
+            return( MBEDTLS_ERR_X509_ALLOC_FAILED );
 
         prev = crt;
-        x509_crt_init( crt->next );
+        mbedtls_x509_crt_init( crt->next );
         crt = crt->next;
     }
 
@@ -823,7 +949,7 @@ int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
             prev->next = NULL;
 
         if( crt != chain )
-            polarssl_free( crt );
+            mbedtls_free( crt );
 
         return( ret );
     }
@@ -835,41 +961,46 @@ int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
  * Parse one or more PEM certificates from a buffer and add them to the chained
  * list
  */
-int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen )
+int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
 {
     int success = 0, first_error = 0, total_failed = 0;
-    int buf_format = X509_FORMAT_DER;
+    int buf_format = MBEDTLS_X509_FORMAT_DER;
 
     /*
      * Check for valid input
      */
     if( chain == NULL || buf == NULL )
-        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
     /*
      * Determine buffer content. Buffer contains either one DER certificate or
      * one or more PEM certificates.
      */
-#if defined(POLARSSL_PEM_PARSE_C)
-    if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
-        buf_format = X509_FORMAT_PEM;
+#if defined(MBEDTLS_PEM_PARSE_C)
+    if( buflen != 0 && buf[buflen - 1] == '\0' &&
+        strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
+    {
+        buf_format = MBEDTLS_X509_FORMAT_PEM;
+    }
 #endif
 
-    if( buf_format == X509_FORMAT_DER )
-        return x509_crt_parse_der( chain, buf, buflen );
+    if( buf_format == MBEDTLS_X509_FORMAT_DER )
+        return mbedtls_x509_crt_parse_der( chain, buf, buflen );
 
-#if defined(POLARSSL_PEM_PARSE_C)
-    if( buf_format == X509_FORMAT_PEM )
+#if defined(MBEDTLS_PEM_PARSE_C)
+    if( buf_format == MBEDTLS_X509_FORMAT_PEM )
     {
         int ret;
-        pem_context pem;
+        mbedtls_pem_context pem;
 
-        while( buflen > 0 )
+        /* 1 rather than 0 since the terminating NULL byte is counted in */
+        while( buflen > 1 )
         {
             size_t use_len;
-            pem_init( &pem );
+            mbedtls_pem_init( &pem );
 
-            ret = pem_read_buffer( &pem,
+            /* If we get there, we know the string is null-terminated */
+            ret = mbedtls_pem_read_buffer( &pem,
                            "-----BEGIN CERTIFICATE-----",
                            "-----END CERTIFICATE-----",
                            buf, NULL, 0, &use_len );
@@ -882,13 +1013,13 @@ int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen )
                 buflen -= use_len;
                 buf += use_len;
             }
-            else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
+            else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA )
             {
                 return( ret );
             }
-            else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+            else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
             {
-                pem_free( &pem );
+                mbedtls_pem_free( &pem );
 
                 /*
                  * PEM header and footer were found
@@ -905,16 +1036,16 @@ int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen )
             else
                 break;
 
-            ret = x509_crt_parse_der( chain, pem.buf, pem.buflen );
+            ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen );
 
-            pem_free( &pem );
+            mbedtls_pem_free( &pem );
 
             if( ret != 0 )
             {
                 /*
                  * Quit parsing on a memory error
                  */
-                if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
+                if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED )
                     return( ret );
 
                 if( first_error == 0 )
@@ -927,42 +1058,38 @@ int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen )
             success = 1;
         }
     }
-#endif /* POLARSSL_PEM_PARSE_C */
+#endif /* MBEDTLS_PEM_PARSE_C */
 
     if( success )
         return( total_failed );
     else if( first_error )
         return( first_error );
     else
-        return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
+        return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
 }
 
-#if defined(POLARSSL_FS_IO)
+#if defined(MBEDTLS_FS_IO)
 /*
  * Load one or more certificates and add them to the chained list
  */
-int x509_crt_parse_file( x509_crt *chain, const char *path )
+int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
 {
     int ret;
     size_t n;
     unsigned char *buf;
 
-    if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
+    if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
         return( ret );
 
-    ret = x509_crt_parse( chain, buf, n );
+    ret = mbedtls_x509_crt_parse( chain, buf, n );
 
-    polarssl_zeroize( buf, n + 1 );
-    polarssl_free( buf );
+    mbedtls_zeroize( buf, n );
+    mbedtls_free( buf );
 
     return( ret );
 }
 
-#if defined(POLARSSL_THREADING_PTHREAD)
-static threading_mutex_t readdir_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-int x509_crt_parse_path( x509_crt *chain, const char *path )
+int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
 {
     int ret = 0;
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
@@ -976,7 +1103,7 @@ int x509_crt_parse_path( x509_crt *chain, const char *path )
     HANDLE hFind;
 
     if( len > MAX_PATH - 3 )
-        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
     memset( szDir, 0, sizeof(szDir) );
     memset( filename, 0, MAX_PATH );
@@ -988,11 +1115,11 @@ int x509_crt_parse_path( x509_crt *chain, const char *path )
     w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir,
                                  MAX_PATH - 3 );
     if( w_ret == 0 )
-        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
     hFind = FindFirstFileW( szDir, &file_data );
     if( hFind == INVALID_HANDLE_VALUE )
-        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
+        return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
 
     len = MAX_PATH - len;
     do
@@ -1007,9 +1134,9 @@ int x509_crt_parse_path( x509_crt *chain, const char *path )
                                      p, len - 1,
                                      NULL, NULL );
         if( w_ret == 0 )
-            return( POLARSSL_ERR_X509_FILE_IO_ERROR );
+            return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
 
-        w_ret = x509_crt_parse_file( chain, filename );
+        w_ret = mbedtls_x509_crt_parse_file( chain, filename );
         if( w_ret < 0 )
             ret++;
         else
@@ -1018,7 +1145,7 @@ int x509_crt_parse_path( x509_crt *chain, const char *path )
     while( FindNextFileW( hFind, &file_data ) != 0 );
 
     if( GetLastError() != ERROR_NO_MORE_FILES )
-        ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
+        ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
 
     FindClose( hFind );
 #else /* _WIN32 */
@@ -1029,21 +1156,24 @@ int x509_crt_parse_path( x509_crt *chain, const char *path )
     DIR *dir = opendir( path );
 
     if( dir == NULL )
-        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
+        return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
 
-#if defined(POLARSSL_THREADING_PTHREAD)
-    if( ( ret = polarssl_mutex_lock( &readdir_mutex ) ) != 0 )
+#if defined(MBEDTLS_THREADING_PTHREAD)
+    if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 )
+    {
+        closedir( dir );
         return( ret );
+    }
 #endif
 
     while( ( entry = readdir( dir ) ) != NULL )
     {
-        snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name );
+        mbedtls_snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name );
 
         if( stat( entry_name, &sb ) == -1 )
         {
             closedir( dir );
-            ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
+            ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
             goto cleanup;
         }
 
@@ -1052,7 +1182,7 @@ int x509_crt_parse_path( x509_crt *chain, const char *path )
 
         // Ignore parse errors
         //
-        t_ret = x509_crt_parse_file( chain, entry_name );
+        t_ret = mbedtls_x509_crt_parse_file( chain, entry_name );
         if( t_ret < 0 )
             ret++;
         else
@@ -1061,76 +1191,24 @@ int x509_crt_parse_path( x509_crt *chain, const char *path )
     closedir( dir );
 
 cleanup:
-#if defined(POLARSSL_THREADING_PTHREAD)
-    if( polarssl_mutex_unlock( &readdir_mutex ) != 0 )
-        ret = POLARSSL_ERR_THREADING_MUTEX_ERROR;
+#if defined(MBEDTLS_THREADING_PTHREAD)
+    if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
+        ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
 #endif
 
 #endif /* _WIN32 */
 
     return( ret );
 }
-#endif /* POLARSSL_FS_IO */
-
-#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
-    !defined(EFI32)
-#include <stdarg.h>
-
-#if !defined vsnprintf
-#define vsnprintf _vsnprintf
-#endif // vsnprintf
-
-/*
- * Windows _snprintf and _vsnprintf are not compatible to linux versions.
- * Result value is not size of buffer needed, but -1 if no fit is possible.
- *
- * This fuction tries to 'fix' this by at least suggesting enlarging the
- * size by 20.
- */
-static int compat_snprintf( char *str, size_t size, const char *format, ... )
-{
-    va_list ap;
-    int res = -1;
-
-    va_start( ap, format );
-
-    res = vsnprintf( str, size, format, ap );
-
-    va_end( ap );
-
-    // No quick fix possible
-    if( res < 0 )
-        return( (int) size + 20 );
-
-    return( res );
-}
-
-#define snprintf compat_snprintf
-#endif /* _MSC_VER  && !snprintf && !EFIX64 && !EFI32 */
-
-#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL    -2
-
-#define SAFE_SNPRINTF()                             \
-{                                                   \
-    if( ret == -1 )                                 \
-        return( -1 );                               \
-                                                    \
-    if( (unsigned int) ret > n ) {                  \
-        p[n - 1] = '\0';                            \
-        return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
-    }                                               \
-                                                    \
-    n -= (unsigned int) ret;                        \
-    p += (unsigned int) ret;                        \
-}
+#endif /* MBEDTLS_FS_IO */
 
 static int x509_info_subject_alt_name( char **buf, size_t *size,
-                                       const x509_sequence *subject_alt_name )
+                                       const mbedtls_x509_sequence *subject_alt_name )
 {
     size_t i;
     size_t n = *size;
     char *p = *buf;
-    const x509_sequence *cur = subject_alt_name;
+    const mbedtls_x509_sequence *cur = subject_alt_name;
     const char *sep = "";
     size_t sep_len = 0;
 
@@ -1139,7 +1217,7 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
         if( cur->buf.len + sep_len >= n )
         {
             *p = '\0';
-            return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
+            return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
         }
 
         n -= cur->buf.len + sep_len;
@@ -1164,8 +1242,8 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
 
 #define PRINT_ITEM(i)                           \
     {                                           \
-        ret = snprintf( p, n, "%s" i, sep );    \
-        SAFE_SNPRINTF();                        \
+        ret = mbedtls_snprintf( p, n, "%s" i, sep );    \
+        MBEDTLS_X509_SAFE_SNPRINTF;                        \
         sep = ", ";                             \
     }
 
@@ -1181,14 +1259,14 @@ static int x509_info_cert_type( char **buf, size_t *size,
     char *p = *buf;
     const char *sep = "";
 
-    CERT_TYPE( NS_CERT_TYPE_SSL_CLIENT,         "SSL Client" );
-    CERT_TYPE( NS_CERT_TYPE_SSL_SERVER,         "SSL Server" );
-    CERT_TYPE( NS_CERT_TYPE_EMAIL,              "Email" );
-    CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing" );
-    CERT_TYPE( NS_CERT_TYPE_RESERVED,           "Reserved" );
-    CERT_TYPE( NS_CERT_TYPE_SSL_CA,             "SSL CA" );
-    CERT_TYPE( NS_CERT_TYPE_EMAIL_CA,           "Email CA" );
-    CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA" );
 
     *size = n;
     *buf = p;
@@ -1201,20 +1279,22 @@ static int x509_info_cert_type( char **buf, size_t *size,
         PRINT_ITEM( name );
 
 static int x509_info_key_usage( char **buf, size_t *size,
-                                unsigned char key_usage )
+                                unsigned int key_usage )
 {
     int ret;
     size_t n = *size;
     char *p = *buf;
     const char *sep = "";
 
-    KEY_USAGE( KU_DIGITAL_SIGNATURE,    "Digital Signature" );
-    KEY_USAGE( KU_NON_REPUDIATION,      "Non Repudiation" );
-    KEY_USAGE( KU_KEY_ENCIPHERMENT,     "Key Encipherment" );
-    KEY_USAGE( KU_DATA_ENCIPHERMENT,    "Data Encipherment" );
-    KEY_USAGE( KU_KEY_AGREEMENT,        "Key Agreement" );
-    KEY_USAGE( KU_KEY_CERT_SIGN,        "Key Cert Sign" );
-    KEY_USAGE( KU_CRL_SIGN,             "CRL Sign" );
+    KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature" );
+    KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation" );
+    KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment" );
+    KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment" );
+    KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement" );
+    KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign" );
+    KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign" );
+    KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only" );
+    KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only" );
 
     *size = n;
     *buf = p;
@@ -1223,22 +1303,22 @@ static int x509_info_key_usage( char **buf, size_t *size,
 }
 
 static int x509_info_ext_key_usage( char **buf, size_t *size,
-                                    const x509_sequence *extended_key_usage )
+                                    const mbedtls_x509_sequence *extended_key_usage )
 {
     int ret;
     const char *desc;
     size_t n = *size;
     char *p = *buf;
-    const x509_sequence *cur = extended_key_usage;
+    const mbedtls_x509_sequence *cur = extended_key_usage;
     const char *sep = "";
 
     while( cur != NULL )
     {
-        if( oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
+        if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
             desc = "???";
 
-        ret = snprintf( p, n, "%s%s", sep, desc );
-        SAFE_SNPRINTF();
+        ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
+        MBEDTLS_X509_SAFE_SNPRINTF;
 
         sep = ", ";
 
@@ -1256,8 +1336,8 @@ static int x509_info_ext_key_usage( char **buf, size_t *size,
  */
 #define BEFORE_COLON    18
 #define BC              "18"
-int x509_crt_info( char *buf, size_t size, const char *prefix,
-                   const x509_crt *crt )
+int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
+                   const mbedtls_x509_crt *crt )
 {
     int ret;
     size_t n;
@@ -1267,139 +1347,210 @@ int x509_crt_info( char *buf, size_t size, const char *prefix,
     p = buf;
     n = size;
 
-    ret = snprintf( p, n, "%scert. version     : %d\n",
+    ret = mbedtls_snprintf( p, n, "%scert. version     : %d\n",
                                prefix, crt->version );
-    SAFE_SNPRINTF();
-    ret = snprintf( p, n, "%sserial number     : ",
+    MBEDTLS_X509_SAFE_SNPRINTF;
+    ret = mbedtls_snprintf( p, n, "%sserial number     : ",
                                prefix );
-    SAFE_SNPRINTF();
+    MBEDTLS_X509_SAFE_SNPRINTF;
 
-    ret = x509_serial_gets( p, n, &crt->serial );
-    SAFE_SNPRINTF();
+    ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
+    MBEDTLS_X509_SAFE_SNPRINTF;
 
-    ret = snprintf( p, n, "\n%sissuer name       : ", prefix );
-    SAFE_SNPRINTF();
-    ret = x509_dn_gets( p, n, &crt->issuer  );
-    SAFE_SNPRINTF();
+    ret = mbedtls_snprintf( p, n, "\n%sissuer name       : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+    ret = mbedtls_x509_dn_gets( p, n, &crt->issuer  );
+    MBEDTLS_X509_SAFE_SNPRINTF;
 
-    ret = snprintf( p, n, "\n%ssubject name      : ", prefix );
-    SAFE_SNPRINTF();
-    ret = x509_dn_gets( p, n, &crt->subject );
-    SAFE_SNPRINTF();
+    ret = mbedtls_snprintf( p, n, "\n%ssubject name      : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+    ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
+    MBEDTLS_X509_SAFE_SNPRINTF;
 
-    ret = snprintf( p, n, "\n%sissued  on        : " \
+    ret = mbedtls_snprintf( p, n, "\n%sissued  on        : " \
                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
                    crt->valid_from.year, crt->valid_from.mon,
                    crt->valid_from.day,  crt->valid_from.hour,
                    crt->valid_from.min,  crt->valid_from.sec );
-    SAFE_SNPRINTF();
+    MBEDTLS_X509_SAFE_SNPRINTF;
 
-    ret = snprintf( p, n, "\n%sexpires on        : " \
+    ret = mbedtls_snprintf( p, n, "\n%sexpires on        : " \
                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
                    crt->valid_to.year, crt->valid_to.mon,
                    crt->valid_to.day,  crt->valid_to.hour,
                    crt->valid_to.min,  crt->valid_to.sec );
-    SAFE_SNPRINTF();
+    MBEDTLS_X509_SAFE_SNPRINTF;
 
-    ret = snprintf( p, n, "\n%ssigned using      : ", prefix );
-    SAFE_SNPRINTF();
+    ret = mbedtls_snprintf( p, n, "\n%ssigned using      : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
 
-    ret = x509_sig_alg_gets( p, n, &crt->sig_oid1, crt->sig_pk,
+    ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk,
                              crt->sig_md, crt->sig_opts );
-    SAFE_SNPRINTF();
+    MBEDTLS_X509_SAFE_SNPRINTF;
 
     /* Key size */
-    if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
-                                      pk_get_name( &crt->pk ) ) ) != 0 )
+    if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
+                                      mbedtls_pk_get_name( &crt->pk ) ) ) != 0 )
     {
         return( ret );
     }
 
-    ret = snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
-                          (int) pk_get_size( &crt->pk ) );
-    SAFE_SNPRINTF();
+    ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
+                          (int) mbedtls_pk_get_bitlen( &crt->pk ) );
+    MBEDTLS_X509_SAFE_SNPRINTF;
 
     /*
      * Optional extensions
      */
 
-    if( crt->ext_types & EXT_BASIC_CONSTRAINTS )
+    if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS )
     {
-        ret = snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
+        ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
                         crt->ca_istrue ? "true" : "false" );
-        SAFE_SNPRINTF();
+        MBEDTLS_X509_SAFE_SNPRINTF;
 
         if( crt->max_pathlen > 0 )
         {
-            ret = snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
-            SAFE_SNPRINTF();
+            ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
+            MBEDTLS_X509_SAFE_SNPRINTF;
         }
     }
 
-    if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
+    if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
     {
-        ret = snprintf( p, n, "\n%ssubject alt name  : ", prefix );
-        SAFE_SNPRINTF();
+        ret = mbedtls_snprintf( p, n, "\n%ssubject alt name  : ", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
 
         if( ( ret = x509_info_subject_alt_name( &p, &n,
                                             &crt->subject_alt_names ) ) != 0 )
             return( ret );
     }
 
-    if( crt->ext_types & EXT_NS_CERT_TYPE )
+    if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE )
     {
-        ret = snprintf( p, n, "\n%scert. type        : ", prefix );
-        SAFE_SNPRINTF();
+        ret = mbedtls_snprintf( p, n, "\n%scert. type        : ", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
 
         if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 )
             return( ret );
     }
 
-    if( crt->ext_types & EXT_KEY_USAGE )
+    if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE )
     {
-        ret = snprintf( p, n, "\n%skey usage         : ", prefix );
-        SAFE_SNPRINTF();
+        ret = mbedtls_snprintf( p, n, "\n%skey usage         : ", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
 
         if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 )
             return( ret );
     }
 
-    if( crt->ext_types & EXT_EXTENDED_KEY_USAGE )
+    if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE )
     {
-        ret = snprintf( p, n, "\n%sext key usage     : ", prefix );
-        SAFE_SNPRINTF();
+        ret = mbedtls_snprintf( p, n, "\n%sext key usage     : ", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
 
         if( ( ret = x509_info_ext_key_usage( &p, &n,
                                              &crt->ext_key_usage ) ) != 0 )
             return( ret );
     }
 
-    ret = snprintf( p, n, "\n" );
-    SAFE_SNPRINTF();
+    ret = mbedtls_snprintf( p, n, "\n" );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    return( (int) ( size - n ) );
+}
+
+struct x509_crt_verify_string {
+    int code;
+    const char *string;
+};
+
+static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
+    { MBEDTLS_X509_BADCERT_EXPIRED,       "The certificate validity has expired" },
+    { MBEDTLS_X509_BADCERT_REVOKED,       "The certificate has been revoked (is on a CRL)" },
+    { MBEDTLS_X509_BADCERT_CN_MISMATCH,   "The certificate Common Name (CN) does not match with the expected CN" },
+    { MBEDTLS_X509_BADCERT_NOT_TRUSTED,   "The certificate is not correctly signed by the trusted CA" },
+    { MBEDTLS_X509_BADCRL_NOT_TRUSTED,    "The CRL is not correctly signed by the trusted CA" },
+    { MBEDTLS_X509_BADCRL_EXPIRED,        "The CRL is expired" },
+    { MBEDTLS_X509_BADCERT_MISSING,       "Certificate was missing" },
+    { MBEDTLS_X509_BADCERT_SKIP_VERIFY,   "Certificate verification was skipped" },
+    { MBEDTLS_X509_BADCERT_OTHER,         "Other reason (can be used by verify callback)" },
+    { MBEDTLS_X509_BADCERT_FUTURE,        "The certificate validity starts in the future" },
+    { MBEDTLS_X509_BADCRL_FUTURE,         "The CRL is from the future" },
+    { MBEDTLS_X509_BADCERT_KEY_USAGE,     "Usage does not match the keyUsage extension" },
+    { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
+    { MBEDTLS_X509_BADCERT_NS_CERT_TYPE,  "Usage does not match the nsCertType extension" },
+    { MBEDTLS_X509_BADCERT_BAD_MD,        "The certificate is signed with an unacceptable hash." },
+    { MBEDTLS_X509_BADCERT_BAD_PK,        "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
+    { MBEDTLS_X509_BADCERT_BAD_KEY,       "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
+    { MBEDTLS_X509_BADCRL_BAD_MD,         "The CRL is signed with an unacceptable hash." },
+    { MBEDTLS_X509_BADCRL_BAD_PK,         "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
+    { MBEDTLS_X509_BADCRL_BAD_KEY,        "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
+    { 0, NULL }
+};
+
+int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
+                          uint32_t flags )
+{
+    int ret;
+    const struct x509_crt_verify_string *cur;
+    char *p = buf;
+    size_t n = size;
+
+    for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
+    {
+        if( ( flags & cur->code ) == 0 )
+            continue;
+
+        ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+        flags ^= cur->code;
+    }
+
+    if( flags != 0 )
+    {
+        ret = mbedtls_snprintf( p, n, "%sUnknown reason "
+                                       "(this should not happen)\n", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+    }
 
     return( (int) ( size - n ) );
 }
 
-#if defined(POLARSSL_X509_CHECK_KEY_USAGE)
-int x509_crt_check_key_usage( const x509_crt *crt, int usage )
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
+                                      unsigned int usage )
 {
-    if( ( crt->ext_types & EXT_KEY_USAGE ) != 0 &&
-        ( crt->key_usage & usage ) != usage )
-        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
+    unsigned int usage_must, usage_may;
+    unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
+                          | MBEDTLS_X509_KU_DECIPHER_ONLY;
+
+    if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 )
+        return( 0 );
+
+    usage_must = usage & ~may_mask;
+
+    if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    usage_may = usage & may_mask;
+
+    if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
     return( 0 );
 }
 #endif
 
-#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE)
-int x509_crt_check_extended_key_usage( const x509_crt *crt,
+#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
+int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
                                        const char *usage_oid,
                                        size_t usage_len )
 {
-    const x509_sequence *cur;
+    const mbedtls_x509_sequence *cur;
 
     /* Extension is not mandatory, absent means no restriction */
-    if( ( crt->ext_types & EXT_EXTENDED_KEY_USAGE ) == 0 )
+    if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 )
         return( 0 );
 
     /*
@@ -1407,7 +1558,7 @@ int x509_crt_check_extended_key_usage( const x509_crt *crt,
      */
     for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next )
     {
-        const x509_buf *cur_oid = &cur->buf;
+        const mbedtls_x509_buf *cur_oid = &cur->buf;
 
         if( cur_oid->len == usage_len &&
             memcmp( cur_oid->p, usage_oid, usage_len ) == 0 )
@@ -1415,28 +1566,28 @@ int x509_crt_check_extended_key_usage( const x509_crt *crt,
             return( 0 );
         }
 
-        if( OID_CMP( OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) )
+        if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 )
             return( 0 );
     }
 
-    return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
+    return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 }
-#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */
+#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
 
-#if defined(POLARSSL_X509_CRL_PARSE_C)
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
 /*
  * Return 1 if the certificate is revoked, or 0 otherwise.
  */
-int x509_crt_revoked( const x509_crt *crt, const x509_crl *crl )
+int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl )
 {
-    const x509_crl_entry *cur = &crl->entry;
+    const mbedtls_x509_crl_entry *cur = &crl->entry;
 
     while( cur != NULL && cur->serial.len != 0 )
     {
         if( crt->serial.len == cur->serial.len &&
             memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
         {
-            if( x509_time_expired( &cur->revocation_date ) )
+            if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
                 return( 1 );
         }
 
@@ -1449,12 +1600,13 @@ int x509_crt_revoked( const x509_crt *crt, const x509_crl *crl )
 /*
  * Check that the given certificate is valid according to the CRL.
  */
-static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
-                               x509_crl *crl_list)
+static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
+                               mbedtls_x509_crl *crl_list,
+                               const mbedtls_x509_crt_profile *profile )
 {
     int flags = 0;
-    unsigned char hash[POLARSSL_MD_MAX_SIZE];
-    const md_info_t *md_info;
+    unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info;
 
     if( ca == NULL )
         return( flags );
@@ -1479,10 +1631,10 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
         /*
          * Check if the CA is configured to sign CRLs
          */
-#if defined(POLARSSL_X509_CHECK_KEY_USAGE)
-        if( x509_crt_check_key_usage( ca, KU_CRL_SIGN ) != 0 )
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+        if( mbedtls_x509_crt_check_key_usage( ca, MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
         {
-            flags |= BADCRL_NOT_TRUSTED;
+            flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
             break;
         }
 #endif
@@ -1490,49 +1642,59 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
         /*
          * Check if CRL is correctly signed by the trusted CA
          */
-        md_info = md_info_from_type( crl_list->sig_md );
+        if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 )
+            flags |= MBEDTLS_X509_BADCRL_BAD_MD;
+
+        if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 )
+            flags |= MBEDTLS_X509_BADCRL_BAD_PK;
+
+        md_info = mbedtls_md_info_from_type( crl_list->sig_md );
         if( md_info == NULL )
         {
             /*
              * Cannot check 'unknown' hash
              */
-            flags |= BADCRL_NOT_TRUSTED;
+            flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
             break;
         }
 
-        md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
+        mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
+
+        if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 )
+            flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
 
-        if( pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
-                           crl_list->sig_md, hash, md_info->size,
+        if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
+                           crl_list->sig_md, hash, mbedtls_md_get_size( md_info ),
                            crl_list->sig.p, crl_list->sig.len ) != 0 )
         {
-            flags |= BADCRL_NOT_TRUSTED;
+            flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
             break;
         }
 
         /*
          * Check for validity of CRL (Do not drop out)
          */
-        if( x509_time_expired( &crl_list->next_update ) )
-            flags |= BADCRL_EXPIRED;
+        if( mbedtls_x509_time_is_past( &crl_list->next_update ) )
+            flags |= MBEDTLS_X509_BADCRL_EXPIRED;
 
-        if( x509_time_future( &crl_list->this_update ) )
-            flags |= BADCRL_FUTURE;
+        if( mbedtls_x509_time_is_future( &crl_list->this_update ) )
+            flags |= MBEDTLS_X509_BADCRL_FUTURE;
 
         /*
          * Check if certificate is revoked
          */
-        if( x509_crt_revoked( crt, crl_list ) )
+        if( mbedtls_x509_crt_is_revoked( crt, crl_list ) )
         {
-            flags |= BADCERT_REVOKED;
+            flags |= MBEDTLS_X509_BADCERT_REVOKED;
             break;
         }
 
         crl_list = crl_list->next;
     }
+
     return( flags );
 }
-#endif /* POLARSSL_X509_CRL_PARSE_C */
+#endif /* MBEDTLS_X509_CRL_PARSE_C */
 
 /*
  * Like memcmp, but case-insensitive and always returns -1 if different
@@ -1564,10 +1726,9 @@ static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
 }
 
 /*
- * Return 1 if match, 0 if not
- * TODO: inverted return value!
+ * Return 0 if name matches wildcard, -1 otherwise
  */
-static int x509_wildcard_verify( const char *cn, x509_buf *name )
+static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name )
 {
     size_t i;
     size_t cn_idx = 0, cn_len = strlen( cn );
@@ -1585,15 +1746,15 @@ static int x509_wildcard_verify( const char *cn, x509_buf *name )
     }
 
     if( cn_idx == 0 )
-        return( 0 );
+        return( -1 );
 
     if( cn_len - cn_idx == name->len - 1 &&
         x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
     {
-        return( 1 );
+        return( 0 );
     }
 
-    return( 0 );
+    return( -1 );
 }
 
 /*
@@ -1602,7 +1763,7 @@ static int x509_wildcard_verify( const char *cn, x509_buf *name )
  *
  * Return 0 if equal, -1 otherwise.
  */
-static int x509_string_cmp( const x509_buf *a, const x509_buf *b )
+static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
 {
     if( a->tag == b->tag &&
         a->len == b->len &&
@@ -1611,8 +1772,8 @@ static int x509_string_cmp( const x509_buf *a, const x509_buf *b )
         return( 0 );
     }
 
-    if( ( a->tag == ASN1_UTF8_STRING || a->tag == ASN1_PRINTABLE_STRING ) &&
-        ( b->tag == ASN1_UTF8_STRING || b->tag == ASN1_PRINTABLE_STRING ) &&
+    if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
+        ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
         a->len == b->len &&
         x509_memcasecmp( a->p, b->p, b->len ) == 0 )
     {
@@ -1632,7 +1793,7 @@ static int x509_string_cmp( const x509_buf *a, const x509_buf *b )
  *
  * Return 0 if equal, -1 otherwise.
  */
-static int x509_name_cmp( const x509_name *a, const x509_name *b )
+static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
 {
     /* Avoid recursion, it might not be optimised by the compiler */
     while( a != NULL || b != NULL )
@@ -1671,8 +1832,8 @@ static int x509_name_cmp( const x509_name *a, const x509_name *b )
  * top means parent is a locally-trusted certificate
  * bottom means child is the end entity cert
  */
-static int x509_crt_check_parent( const x509_crt *child,
-                                  const x509_crt *parent,
+static int x509_crt_check_parent( const mbedtls_x509_crt *child,
+                                  const mbedtls_x509_crt *parent,
                                   int top, int bottom )
 {
     int need_ca_bit;
@@ -1699,9 +1860,9 @@ static int x509_crt_check_parent( const x509_crt *child,
     if( need_ca_bit && ! parent->ca_istrue )
         return( -1 );
 
-#if defined(POLARSSL_X509_CHECK_KEY_USAGE)
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
     if( need_ca_bit &&
-        x509_crt_check_key_usage( parent, KU_KEY_CERT_SIGN ) != 0 )
+        mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 )
     {
         return( -1 );
     }
@@ -1711,28 +1872,37 @@ static int x509_crt_check_parent( const x509_crt *child,
 }
 
 static int x509_crt_verify_top(
-                x509_crt *child, x509_crt *trust_ca,
-                x509_crl *ca_crl, int path_cnt, int *flags,
-                int (*f_vrfy)(void *, x509_crt *, int, int *),
+                mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca,
+                mbedtls_x509_crl *ca_crl,
+                const mbedtls_x509_crt_profile *profile,
+                int path_cnt, uint32_t *flags,
+                int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
                 void *p_vrfy )
 {
     int ret;
-    int ca_flags = 0, check_path_cnt = path_cnt + 1;
-    unsigned char hash[POLARSSL_MD_MAX_SIZE];
-    const md_info_t *md_info;
+    uint32_t ca_flags = 0;
+    int check_path_cnt;
+    unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info;
+
+    if( mbedtls_x509_time_is_past( &child->valid_to ) )
+        *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
+
+    if( mbedtls_x509_time_is_future( &child->valid_from ) )
+        *flags |= MBEDTLS_X509_BADCERT_FUTURE;
 
-    if( x509_time_expired( &child->valid_to ) )
-        *flags |= BADCERT_EXPIRED;
+    if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
+        *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
 
-    if( x509_time_future( &child->valid_from ) )
-        *flags |= BADCERT_FUTURE;
+    if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
+        *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
 
     /*
      * Child is the top of the chain. Check against the trust_ca list.
      */
-    *flags |= BADCERT_NOT_TRUSTED;
+    *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
 
-    md_info = md_info_from_type( child->sig_md );
+    md_info = mbedtls_md_info_from_type( child->sig_md );
     if( md_info == NULL )
     {
         /*
@@ -1741,15 +1911,17 @@ static int x509_crt_verify_top(
         trust_ca = NULL;
     }
     else
-        md( md_info, child->tbs.p, child->tbs.len, hash );
+        mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
 
     for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next )
     {
         if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 )
             continue;
 
+        check_path_cnt = path_cnt + 1;
+
         /*
-         * Reduce path_len to check against if top of the chain is
+         * Reduce check_path_cnt to check against if top of the chain is
          * the same as the trusted CA
          */
         if( child->subject_raw.len == trust_ca->subject_raw.len &&
@@ -1765,8 +1937,8 @@ static int x509_crt_verify_top(
             continue;
         }
 
-        if( pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
-                           child->sig_md, hash, md_info->size,
+        if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
+                           child->sig_md, hash, mbedtls_md_get_size( md_info ),
                            child->sig.p, child->sig.len ) != 0 )
         {
             continue;
@@ -1775,7 +1947,11 @@ static int x509_crt_verify_top(
         /*
          * Top of chain is signed by a trusted CA
          */
-        *flags &= ~BADCERT_NOT_TRUSTED;
+        *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
+
+        if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 )
+            *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
+
         break;
     }
 
@@ -1789,18 +1965,18 @@ static int x509_crt_verify_top(
           memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
                             child->issuer_raw.len ) != 0 ) )
     {
-#if defined(POLARSSL_X509_CRL_PARSE_C)
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
         /* Check trusted CA's CRL for the chain's top crt */
-        *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl );
+        *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl, profile );
 #else
         ((void) ca_crl);
 #endif
 
-        if( x509_time_expired( &trust_ca->valid_to ) )
-            ca_flags |= BADCERT_EXPIRED;
+        if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
+            ca_flags |= MBEDTLS_X509_BADCERT_EXPIRED;
 
-        if( x509_time_future( &trust_ca->valid_from ) )
-            ca_flags |= BADCERT_FUTURE;
+        if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
+            ca_flags |= MBEDTLS_X509_BADCERT_FUTURE;
 
         if( NULL != f_vrfy )
         {
@@ -1825,57 +2001,68 @@ static int x509_crt_verify_top(
 }
 
 static int x509_crt_verify_child(
-                x509_crt *child, x509_crt *parent, x509_crt *trust_ca,
-                x509_crl *ca_crl, int path_cnt, int *flags,
-                int (*f_vrfy)(void *, x509_crt *, int, int *),
+                mbedtls_x509_crt *child, mbedtls_x509_crt *parent,
+                mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl,
+                const mbedtls_x509_crt_profile *profile,
+                int path_cnt, uint32_t *flags,
+                int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
                 void *p_vrfy )
 {
     int ret;
-    int parent_flags = 0;
-    unsigned char hash[POLARSSL_MD_MAX_SIZE];
-    x509_crt *grandparent;
-    const md_info_t *md_info;
+    uint32_t parent_flags = 0;
+    unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+    mbedtls_x509_crt *grandparent;
+    const mbedtls_md_info_t *md_info;
 
     /* path_cnt is 0 for the first intermediate CA */
-    if( 1 + path_cnt > POLARSSL_X509_MAX_INTERMEDIATE_CA )
+    if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
     {
-        *flags |= BADCERT_NOT_TRUSTED;
-        return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
+        *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
+        return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
     }
 
-    if( x509_time_expired( &child->valid_to ) )
-        *flags |= BADCERT_EXPIRED;
+    if( mbedtls_x509_time_is_past( &child->valid_to ) )
+        *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
+
+    if( mbedtls_x509_time_is_future( &child->valid_from ) )
+        *flags |= MBEDTLS_X509_BADCERT_FUTURE;
+
+    if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
+        *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
 
-    if( x509_time_future( &child->valid_from ) )
-        *flags |= BADCERT_FUTURE;
+    if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
+        *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
 
-    md_info = md_info_from_type( child->sig_md );
+    md_info = mbedtls_md_info_from_type( child->sig_md );
     if( md_info == NULL )
     {
         /*
          * Cannot check 'unknown' hash
          */
-        *flags |= BADCERT_NOT_TRUSTED;
+        *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
     }
     else
     {
-        md( md_info, child->tbs.p, child->tbs.len, hash );
+        mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
 
-        if( pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
-                           child->sig_md, hash, md_info->size,
+        if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 )
+            *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
+
+        if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
+                           child->sig_md, hash, mbedtls_md_get_size( md_info ),
                            child->sig.p, child->sig.len ) != 0 )
         {
-            *flags |= BADCERT_NOT_TRUSTED;
+            *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
         }
     }
 
-#if defined(POLARSSL_X509_CRL_PARSE_C)
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
     /* Check trusted CA's CRL for the given crt */
-    *flags |= x509_crt_verifycrl(child, parent, ca_crl);
+    *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile );
 #endif
 
-    /* Look for a grandparent upwards the chain */
-    for( grandparent = parent->next;
+    /* Look for a grandparent in trusted CAs */
+    for( grandparent = trust_ca;
          grandparent != NULL;
          grandparent = grandparent->next )
     {
@@ -1884,20 +2071,42 @@ static int x509_crt_verify_child(
             break;
     }
 
-    /* Is our parent part of the chain or at the top? */
     if( grandparent != NULL )
     {
-        ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl,
+        ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile,
                                 path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
         if( ret != 0 )
             return( ret );
     }
     else
     {
-        ret = x509_crt_verify_top( parent, trust_ca, ca_crl,
-                                path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
-        if( ret != 0 )
-            return( ret );
+        /* Look for a grandparent upwards the chain */
+        for( grandparent = parent->next;
+             grandparent != NULL;
+             grandparent = grandparent->next )
+        {
+            if( x509_crt_check_parent( parent, grandparent,
+                                       0, path_cnt == 0 ) == 0 )
+                break;
+        }
+
+        /* Is our parent part of the chain or at the top? */
+        if( grandparent != NULL )
+        {
+            ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl,
+                                         profile, path_cnt + 1, &parent_flags,
+                                         f_vrfy, p_vrfy );
+            if( ret != 0 )
+                return( ret );
+        }
+        else
+        {
+            ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile,
+                                       path_cnt + 1, &parent_flags,
+                                       f_vrfy, p_vrfy );
+            if( ret != 0 )
+                return( ret );
+        }
     }
 
     /* child is verified to be a child of the parent, call verify callback */
@@ -1913,19 +2122,38 @@ static int x509_crt_verify_child(
 /*
  * Verify the certificate validity
  */
-int x509_crt_verify( x509_crt *crt,
-                     x509_crt *trust_ca,
-                     x509_crl *ca_crl,
-                     const char *cn, int *flags,
-                     int (*f_vrfy)(void *, x509_crt *, int, int *),
+int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
+                     mbedtls_x509_crt *trust_ca,
+                     mbedtls_x509_crl *ca_crl,
+                     const char *cn, uint32_t *flags,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy )
+{
+    return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl,
+                &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) );
+}
+
+
+/*
+ * Verify the certificate validity, with profile
+ */
+int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
+                     mbedtls_x509_crt *trust_ca,
+                     mbedtls_x509_crl *ca_crl,
+                     const mbedtls_x509_crt_profile *profile,
+                     const char *cn, uint32_t *flags,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
                      void *p_vrfy )
 {
     size_t cn_len;
     int ret;
     int pathlen = 0;
-    x509_crt *parent;
-    x509_name *name;
-    x509_sequence *cur = NULL;
+    mbedtls_x509_crt *parent;
+    mbedtls_x509_name *name;
+    mbedtls_x509_sequence *cur = NULL;
+
+    if( profile == NULL )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 
     *flags = 0;
 
@@ -1934,7 +2162,7 @@ int x509_crt_verify( x509_crt *crt,
         name = &crt->subject;
         cn_len = strlen( cn );
 
-        if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
+        if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
         {
             cur = &crt->subject_alt_names;
 
@@ -1946,20 +2174,22 @@ int x509_crt_verify( x509_crt *crt,
 
                 if( cur->buf.len > 2 &&
                     memcmp( cur->buf.p, "*.", 2 ) == 0 &&
-                            x509_wildcard_verify( cn, &cur->buf ) )
+                    x509_check_wildcard( cn, &cur->buf ) == 0 )
+                {
                     break;
+                }
 
                 cur = cur->next;
             }
 
             if( cur == NULL )
-                *flags |= BADCERT_CN_MISMATCH;
+                *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
         }
         else
         {
             while( name != NULL )
             {
-                if( OID_CMP( OID_AT_CN, &name->oid ) )
+                if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 )
                 {
                     if( name->val.len == cn_len &&
                         x509_memcasecmp( name->val.p, cn, cn_len ) == 0 )
@@ -1967,7 +2197,7 @@ int x509_crt_verify( x509_crt *crt,
 
                     if( name->val.len > 2 &&
                         memcmp( name->val.p, "*.", 2 ) == 0 &&
-                                x509_wildcard_verify( cn, &name->val ) )
+                        x509_check_wildcard( cn, &name->val ) == 0 )
                         break;
                 }
 
@@ -1975,35 +2205,52 @@ int x509_crt_verify( x509_crt *crt,
             }
 
             if( name == NULL )
-                *flags |= BADCERT_CN_MISMATCH;
+                *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
         }
     }
 
-    /* Look for a parent upwards the chain */
-    for( parent = crt->next; parent != NULL; parent = parent->next )
+    /* Look for a parent in trusted CAs */
+    for( parent = trust_ca; parent != NULL; parent = parent->next )
     {
         if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
             break;
     }
 
-    /* Are we part of the chain or at the top? */
     if( parent != NULL )
     {
-        ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl,
-                                     pathlen, flags, f_vrfy, p_vrfy );
+        ret = x509_crt_verify_top( crt, parent, ca_crl, profile,
+                                   pathlen, flags, f_vrfy, p_vrfy );
         if( ret != 0 )
             return( ret );
     }
     else
     {
-        ret = x509_crt_verify_top( crt, trust_ca, ca_crl,
-                                   pathlen, flags, f_vrfy, p_vrfy );
-        if( ret != 0 )
-            return( ret );
+        /* Look for a parent upwards the chain */
+        for( parent = crt->next; parent != NULL; parent = parent->next )
+        {
+            if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
+                break;
+        }
+
+        /* Are we part of the chain or at the top? */
+        if( parent != NULL )
+        {
+            ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile,
+                                         pathlen, flags, f_vrfy, p_vrfy );
+            if( ret != 0 )
+                return( ret );
+        }
+        else
+        {
+            ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile,
+                                       pathlen, flags, f_vrfy, p_vrfy );
+            if( ret != 0 )
+                return( ret );
+        }
     }
 
     if( *flags != 0 )
-        return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
+        return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
 
     return( 0 );
 }
@@ -2011,32 +2258,32 @@ int x509_crt_verify( x509_crt *crt,
 /*
  * Initialize a certificate chain
  */
-void x509_crt_init( x509_crt *crt )
+void mbedtls_x509_crt_init( mbedtls_x509_crt *crt )
 {
-    memset( crt, 0, sizeof(x509_crt) );
+    memset( crt, 0, sizeof(mbedtls_x509_crt) );
 }
 
 /*
  * Unallocate all certificate data
  */
-void x509_crt_free( x509_crt *crt )
+void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
 {
-    x509_crt *cert_cur = crt;
-    x509_crt *cert_prv;
-    x509_name *name_cur;
-    x509_name *name_prv;
-    x509_sequence *seq_cur;
-    x509_sequence *seq_prv;
+    mbedtls_x509_crt *cert_cur = crt;
+    mbedtls_x509_crt *cert_prv;
+    mbedtls_x509_name *name_cur;
+    mbedtls_x509_name *name_prv;
+    mbedtls_x509_sequence *seq_cur;
+    mbedtls_x509_sequence *seq_prv;
 
     if( crt == NULL )
         return;
 
     do
     {
-        pk_free( &cert_cur->pk );
+        mbedtls_pk_free( &cert_cur->pk );
 
-#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
-        polarssl_free( cert_cur->sig_opts );
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+        mbedtls_free( cert_cur->sig_opts );
 #endif
 
         name_cur = cert_cur->issuer.next;
@@ -2044,8 +2291,8 @@ void x509_crt_free( x509_crt *crt )
         {
             name_prv = name_cur;
             name_cur = name_cur->next;
-            polarssl_zeroize( name_prv, sizeof( x509_name ) );
-            polarssl_free( name_prv );
+            mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+            mbedtls_free( name_prv );
         }
 
         name_cur = cert_cur->subject.next;
@@ -2053,8 +2300,8 @@ void x509_crt_free( x509_crt *crt )
         {
             name_prv = name_cur;
             name_cur = name_cur->next;
-            polarssl_zeroize( name_prv, sizeof( x509_name ) );
-            polarssl_free( name_prv );
+            mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+            mbedtls_free( name_prv );
         }
 
         seq_cur = cert_cur->ext_key_usage.next;
@@ -2062,8 +2309,8 @@ void x509_crt_free( x509_crt *crt )
         {
             seq_prv = seq_cur;
             seq_cur = seq_cur->next;
-            polarssl_zeroize( seq_prv, sizeof( x509_sequence ) );
-            polarssl_free( seq_prv );
+            mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
+            mbedtls_free( seq_prv );
         }
 
         seq_cur = cert_cur->subject_alt_names.next;
@@ -2071,14 +2318,14 @@ void x509_crt_free( x509_crt *crt )
         {
             seq_prv = seq_cur;
             seq_cur = seq_cur->next;
-            polarssl_zeroize( seq_prv, sizeof( x509_sequence ) );
-            polarssl_free( seq_prv );
+            mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
+            mbedtls_free( seq_prv );
         }
 
         if( cert_cur->raw.p != NULL )
         {
-            polarssl_zeroize( cert_cur->raw.p, cert_cur->raw.len );
-            polarssl_free( cert_cur->raw.p );
+            mbedtls_zeroize( cert_cur->raw.p, cert_cur->raw.len );
+            mbedtls_free( cert_cur->raw.p );
         }
 
         cert_cur = cert_cur->next;
@@ -2091,11 +2338,11 @@ void x509_crt_free( x509_crt *crt )
         cert_prv = cert_cur;
         cert_cur = cert_cur->next;
 
-        polarssl_zeroize( cert_prv, sizeof( x509_crt ) );
+        mbedtls_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
         if( cert_prv != crt )
-            polarssl_free( cert_prv );
+            mbedtls_free( cert_prv );
     }
     while( cert_cur != NULL );
 }
 
-#endif /* POLARSSL_X509_CRT_PARSE_C */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */