]> granicus.if.org Git - pdns/commitdiff
update polarssl to 1.3.9
authorKees Monshouwer <mind04@monshouwer.org>
Sat, 13 Dec 2014 23:59:59 +0000 (00:59 +0100)
committermind04 <mind04@monshouwer.org>
Mon, 22 Dec 2014 19:34:08 +0000 (20:34 +0100)
32 files changed:
pdns/ext/polarssl/CMakeLists.txt
pdns/ext/polarssl/ChangeLog
pdns/ext/polarssl/include/polarssl/bignum.h
pdns/ext/polarssl/include/polarssl/bn_mul.h
pdns/ext/polarssl/include/polarssl/config.h
pdns/ext/polarssl/include/polarssl/error.h
pdns/ext/polarssl/include/polarssl/ssl.h
pdns/ext/polarssl/include/polarssl/version.h
pdns/ext/polarssl/include/polarssl/x509.h
pdns/ext/polarssl/library/CMakeLists.txt
pdns/ext/polarssl/library/asn1parse.c
pdns/ext/polarssl/library/base64.c
pdns/ext/polarssl/library/bignum.c
pdns/ext/polarssl/library/cipher_wrap.c
pdns/ext/polarssl/library/ecp.c
pdns/ext/polarssl/library/error.c
pdns/ext/polarssl/library/gcm.c
pdns/ext/polarssl/library/md.c
pdns/ext/polarssl/library/memory_buffer_alloc.c
pdns/ext/polarssl/library/net.c
pdns/ext/polarssl/library/pk.c
pdns/ext/polarssl/library/pkcs5.c
pdns/ext/polarssl/library/pkwrite.c
pdns/ext/polarssl/library/rsa.c
pdns/ext/polarssl/library/ssl_ciphersuites.c
pdns/ext/polarssl/library/ssl_cli.c
pdns/ext/polarssl/library/ssl_srv.c
pdns/ext/polarssl/library/ssl_tls.c
pdns/ext/polarssl/library/timing.c
pdns/ext/polarssl/library/x509.c
pdns/ext/polarssl/library/x509_create.c
pdns/ext/polarssl/library/x509_crt.c

index 86439ada42a22163ddb1fcb9f8fb97d56caf9443..9e1158c777d0043ce04a20cf6b1dd5851ff55a6c 100644 (file)
@@ -4,22 +4,22 @@ project(POLARSSL C)
 string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
 
 if(CMAKE_COMPILER_IS_GNUCC)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement")
+  set(CMAKE_C_FLAGS "-Wall -Wextra -W -Wdeclaration-after-statement -Wlogical-op -Wwrite-strings")
   set(CMAKE_C_FLAGS_RELEASE "-O2")
   set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
   set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage")
-  set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-omit-frame-pointer -g3 -O1")
-  set(CMAKE_C_FLAGS_CHECK "${CMAKE_C_FLAGS} -Werror -O1 -Wlogical-op -Wwrite-strings")
+  set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-omit-frame-pointer -g3 -O1 -Werror")
+  set(CMAKE_C_FLAGS_CHECK "-O1 -Werror")
   set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
 endif(CMAKE_COMPILER_IS_GNUCC)
 
 if(CMAKE_COMPILER_IS_CLANG)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wpointer-arith -Wwrite-strings -Wdocumentation -Wunreachable-code")
   set(CMAKE_C_FLAGS_RELEASE "-O2")
   set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
   set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage")
-  set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-omit-frame-pointer -g3 -O1")
-  set(CMAKE_C_FLAGS_CHECK "${CMAKE_C_FLAGS} -Werror -O1 -Wpointer-arith -Wwrite-strings -Wdocumentation -Wunreachable-code")
+  set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-omit-frame-pointer -g3 -O1 -Werror")
+  set(CMAKE_C_FLAGS_CHECK "-O1 -Werror")
 endif(CMAKE_COMPILER_IS_CLANG)
 
 set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
index 163bdb796eeb6c7f273634a49b9266668385eee1..bef1abea59aa821e970c7a7352e66a44eb19aa4d 100644 (file)
@@ -1,5 +1,52 @@
 PolarSSL ChangeLog (Sorted per branch, date)
 
+= PolarSSL 1.3.9 released 2014-10-20
+Security
+   * Lowest common hash was selected from signature_algorithms extension in
+     TLS 1.2 (found by Darren Bane) (introduced in 1.3.8).
+   * Remotely-triggerable memory leak when parsing some X.509 certificates
+     (server is not affected if it doesn't ask for a client certificate)
+     (found using Codenomicon Defensics).
+   * Remotely-triggerable memory leak when parsing crafted ClientHello
+     (not affected if ECC support was compiled out) (found using Codenomicon
+     Defensics).
+
+Bugfix
+   * Support escaping of commas in x509_string_to_names()
+   * Fix compile error in ssl_pthread_server (found by Julian Ospald).
+   * Fix net_accept() regarding non-blocking sockets (found by Luca Pesce).
+   * Don't print uninitialised buffer in ssl_mail_client (found by Marc Abel).
+   * Fix warnings from Clang's scan-build (contributed by Alfred Klomp).
+   * Fix compile error in timing.c when POLARSSL_NET_C and POLARSSL_SELFTEST
+     are defined but not POLARSSL_HAVE_TIME (found by Stephane Di Vito).
+   * Remove non-existent file from VS projects (found by Peter Vaskovic).
+   * ssl_read() could return non-application data records on server while
+     renegotation was pending, and on client when a HelloRequest was received.
+   * Server-initiated renegotiation would fail with non-blocking I/O if the
+     write callback returned WANT_WRITE when requesting renegotiation.
+   * ssl_close_notify() could send more than one message in some circumstances
+     with non-blocking I/O.
+   * Fix compiler warnings on iOS (found by Sander Niemeijer).
+   * x509_crt_parse() did not increase total_failed on PEM error
+   * Fix compile error with armcc in mpi_is_prime()
+   * Fix potential bad read in parsing ServerHello (found by Adrien
+     Vialletelle).
+
+Changes
+   * Ciphersuites using SHA-256 or SHA-384 now require TLS 1.x (there is no
+     standard defining how to use SHA-2 with SSL 3.0).
+   * Ciphersuites using RSA-PSK key exchange new require TLS 1.x (the spec is
+     ambiguous on how to encode some packets with SSL 3.0).
+   * Made buffer size in pk_write_(pub)key_pem() more dynamic, eg smaller if
+     RSA is disabled, larger if POLARSSL_MPI_MAX_SIZE is larger.
+   * ssl_read() now returns POLARSSL_ERR_NET_WANT_READ rather than
+     POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE on harmless alerts.
+   * POLARSSL_MPI_MAX_SIZE now defaults to 1024 in order to allow 8192 bits
+     RSA keys.
+   * Accept spaces at end of line or end of buffer in base64_decode().
+   * X.509 certificates with more than one AttributeTypeAndValue per
+     RelativeDistinguishedName are not accepted any more.
+
 = PolarSSL 1.3.8 released 2014-07-11
 Security
    * Fix length checking for AEAD ciphersuites (found by Codenomicon).
index cd7592c4fbb079e3a4e3aba1a9eab76cccdcd69f..992ed8e6f34c991258cdab239821dbdf0864f8d9 100644 (file)
@@ -90,7 +90,7 @@ typedef UINT64 uint64_t;
  * Note: Calculations can results temporarily in larger MPIs. So the number
  * of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher.
  */
-#define POLARSSL_MPI_MAX_SIZE                              512      /**< Maximum number of bytes for usable MPIs. */
+#define POLARSSL_MPI_MAX_SIZE                              1024     /**< Maximum number of bytes for usable MPIs. */
 #endif /* !POLARSSL_MPI_MAX_SIZE */
 
 #define POLARSSL_MPI_MAX_BITS                              ( 8 * POLARSSL_MPI_MAX_SIZE )    /**< Maximum number of bits for usable MPIs. */
index 64b59ff1e35f8437b5ab107d5a242604608e8dbe..a8f0d22a012c97d880b03259dc0b625b5e1975ae 100644 (file)
 
 #define MULADDC_CORE                    \
     r   = *(s++) * (t_udbl) b;          \
-    r0  = r;                            \
-    r1  = r >> biL;                     \
+    r0  = (t_uint) r;                   \
+    r1  = (t_uint)( r >> biL );         \
     r0 += c;  r1 += (r0 <  c);          \
     r0 += *d; r1 += (r0 < *d);          \
     c = r1; *(d++) = r0;
index 7acefad1d002871dba3e3aae5604860dc08dcc43..09a6ce0efed2a92bda0feaa528369845cf59b737 100644 (file)
 
 /* MPI / BIGNUM options */
 //#define POLARSSL_MPI_WINDOW_SIZE            6 /**< Maximum windows size used. */
-//#define POLARSSL_MPI_MAX_SIZE             512 /**< Maximum number of bytes for usable MPIs. */
+//#define POLARSSL_MPI_MAX_SIZE            1024 /**< Maximum number of bytes for usable MPIs. */
 
 /* CTR_DRBG options */
 //#define CTR_DRBG_ENTROPY_LEN               48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
index cdee952e0691bdb5900534aed3c6a02209522b7d..7ce2828b27cb8873bffb1225478751b886af9300 100644 (file)
@@ -91,7 +91,7 @@
  * ECP       4   8 (Started from top)
  * MD        5   4
  * CIPHER    6   6
- * SSL       6   9 (Started from top)
+ * SSL       6   10 (Started from top)
  * SSL       7   31
  *
  * Module dependent error code (5 bits 0x.00.-0x.F8.)
index bd7f1f775bef8f919afd263a84ccdb1382239d71..194e944718552400b478d50a738b43d27dddf6a4 100644 (file)
 #define POLARSSL_ERR_SSL_UNKNOWN_IDENTITY                  -0x6C80  /**< Unknown identity received (eg, PSK identity) */
 #define POLARSSL_ERR_SSL_INTERNAL_ERROR                    -0x6C00  /**< Internal error (eg, unexpected failure in lower-level module) */
 #define POLARSSL_ERR_SSL_COUNTER_WRAPPING                  -0x6B80  /**< A counter would wrap (eg, too many messages exchanged). */
+#define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO       -0x6B00  /**< Unexpected message at ServerHello in renegotiation. */
 
 /*
  * Various constants
 
 #define SSL_IS_CLIENT                   0
 #define SSL_IS_SERVER                   1
+
 #define SSL_COMPRESS_NULL               0
 #define SSL_COMPRESS_DEFLATE            1
 
@@ -560,8 +562,8 @@ struct _ssl_transform
 
 #if defined(POLARSSL_SSL_PROTO_SSL3)
     /* Needed only for SSL v3.0 secret */
-    unsigned char mac_enc[48];          /*!<  SSL v3.0 secret (enc)   */
-    unsigned char mac_dec[48];          /*!<  SSL v3.0 secret (dec)   */
+    unsigned char mac_enc[20];          /*!<  SSL v3.0 secret (enc)   */
+    unsigned char mac_dec[20];          /*!<  SSL v3.0 secret (dec)   */
 #endif /* POLARSSL_SSL_PROTO_SSL3 */
 
     md_context_t md_ctx_enc;            /*!<  MAC (encryption)        */
@@ -1491,23 +1493,26 @@ void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy );
 /**
  * \brief          Enforce server-requested renegotiation.
  *                 (Default: enforced, max_records = 16)
- *                 (No effect on client.)
  *
- *                 When a server requests a renegotiation, the client can
- *                 comply or ignore the request. This function allows the
- *                 server to decide if it should enforce its renegotiation
- *                 requests by closing the connection if the client doesn't
- *                 initiate a renegotiation.
+ *                 When we request a renegotiation, the peer can comply or
+ *                 ignore the request. This function allows us to decide
+ *                 whether to enforce our renegotiation requests by closing
+ *                 the connection if the peer doesn't comply.
  *
- *                 However, records could already be in transit from the
- *                 client to the server when the request is emitted. In order
- *                 to increase reliability, the server can accept a number of
- *                 records containing application data before the ClientHello
- *                 that was requested.
+ *                 However, records could already be in transit from the peer
+ *                 when the request is emitted. In order to increase
+ *                 reliability, we can accept a number of records before the
+ *                 expected handshake records.
  *
  *                 The optimal value is highly dependent on the specific usage
  *                 scenario.
  *
+ * \warning        On client, the grace period can only happen during
+ *                 ssl_read(), as opposed to ssl_write() and ssl_renegotiate()
+ *                 which always behave as if max_record was 0. The reason is,
+ *                 if we receive application data from the server, we need a
+ *                 place to write it, which only happens during ssl_read().
+ *
  * \param ssl      SSL context
  * \param max_records Use SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to
  *                 enforce renegotiation, or a non-negative value to enforce
@@ -1632,7 +1637,7 @@ int ssl_renegotiate( ssl_context *ssl );
  *
  * \param ssl      SSL context
  * \param buf      buffer that will hold the data
- * \param len      how many bytes must be read
+ * \param len      maximum number of bytes to read
  *
  * \return         This function returns the number of bytes read, 0 for EOF,
  *                 or a negative error code.
index 1ee2a3b5ac4108fdbc56b73db45d2e350022fef8..b00687f123b3b2d80bdd8e209d4154bbf14865c6 100644 (file)
  */
 #define POLARSSL_VERSION_MAJOR  1
 #define POLARSSL_VERSION_MINOR  3
-#define POLARSSL_VERSION_PATCH  8
+#define POLARSSL_VERSION_PATCH  9
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define POLARSSL_VERSION_NUMBER         0x01030800
-#define POLARSSL_VERSION_STRING         "1.3.8"
-#define POLARSSL_VERSION_STRING_FULL    "PolarSSL 1.3.8"
+#define POLARSSL_VERSION_NUMBER         0x01030900
+#define POLARSSL_VERSION_STRING         "1.3.9"
+#define POLARSSL_VERSION_STRING_FULL    "PolarSSL 1.3.9"
 
 #if defined(POLARSSL_VERSION_C)
 
index 583cb83205a85729a55192e6372f568ddc353ba1..9b0bcb78a942729aac59741a09a48338334ed5cd 100644 (file)
 #define X509_FORMAT_DER                 1
 #define X509_FORMAT_PEM                 2
 
+#define X509_MAX_DN_NAME_SIZE         256 /**< Maximum value size of a DN entry */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
index bc986eee44abd0b69570a047f90f741bb22a2f89..33d96b47f9394eb030252a778c22fa3450f365c7 100644 (file)
@@ -118,7 +118,7 @@ endif()
 
 if(USE_SHARED_POLARSSL_LIBRARY)
        add_library(polarssl SHARED ${src})
-       set_target_properties(polarssl PROPERTIES VERSION 1.3.8 SOVERSION 7)
+       set_target_properties(polarssl PROPERTIES VERSION 1.3.9 SOVERSION 7)
 
        target_link_libraries(polarssl ${libs})
 
index 97443529a8e599fcc47846fdd298ea89fa04f6b4..a3a2b56a2bcfb8bda6eb45895ffc77af78cc0f13 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 
+/* Implementation that should never be optimized out by the compiler */
+static void polarssl_zeroize( void *v, size_t n ) {
+    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+
 /*
  * ASN.1 DER decoding routines
  */
@@ -311,7 +316,7 @@ int asn1_get_alg( unsigned char **p,
 
     if( *p == end )
     {
-        memset( params, 0, sizeof(asn1_buf) );
+        polarssl_zeroize( params, sizeof(asn1_buf) );
         return( 0 );
     }
 
@@ -356,7 +361,7 @@ void asn1_free_named_data( asn1_named_data *cur )
     polarssl_free( cur->oid.p );
     polarssl_free( cur->val.p );
 
-    memset( cur, 0, sizeof( asn1_named_data ) );
+    polarssl_zeroize( cur, sizeof( asn1_named_data ) );
 }
 
 void asn1_free_named_data_list( asn1_named_data **head )
index 39a8323e8391e6c435bd0bd6150068b03c85f23e..e6c3569b898fdd985c089a10c516c63c8f4421fb 100644 (file)
@@ -147,8 +147,21 @@ int base64_decode( unsigned char *dst, size_t *dlen,
     uint32_t j, x;
     unsigned char *p;
 
+    /* First pass: check for validity and get output length */
     for( i = n = j = 0; i < slen; i++ )
     {
+        /* Skip spaces before checking for EOL */
+        x = 0;
+        while( i < slen && src[i] == ' ' )
+        {
+            ++i;
+            ++x;
+        }
+
+        /* Spaces at end of buffer are OK */
+        if( i == slen )
+            break;
+
         if( ( slen - i ) >= 2 &&
             src[i] == '\r' && src[i + 1] == '\n' )
             continue;
@@ -156,6 +169,10 @@ int base64_decode( unsigned char *dst, size_t *dlen,
         if( src[i] == '\n' )
             continue;
 
+        /* Space inside a line is an error */
+        if( x != 0 )
+            return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
+
         if( src[i] == '=' && ++j > 2 )
             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
 
@@ -182,7 +199,7 @@ int base64_decode( unsigned char *dst, size_t *dlen,
 
    for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
    {
-        if( *src == '\r' || *src == '\n' )
+        if( *src == '\r' || *src == '\n' || *src == ' ' )
             continue;
 
         j -= ( base64_dec_map[*src] == 64 );
index 80cf0f800825d41a1bffcbeb8505b0b6a5f19890..448e743d4c47455c3995861ead959eab20f6d227 100644 (file)
@@ -2057,7 +2057,11 @@ int mpi_is_prime( mpi *X,
                   void *p_rng )
 {
     int ret;
-    const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
+    mpi XX;
+
+    XX.s = 1;
+    XX.n = X->n;
+    XX.p = X->p;
 
     if( mpi_cmp_int( &XX, 0 ) == 0 ||
         mpi_cmp_int( &XX, 1 ) == 0 )
index 47a69a97b2392c9648bc9648dc5029040c423768..ab2f9bc6ee9aa5f52c34b526ef3198d9d59c9c70 100644 (file)
@@ -1313,7 +1313,7 @@ static int null_setkey( void *ctx, const unsigned char *key,
 
 static void * null_ctx_alloc( void )
 {
-    return( (void *) 1 )
+    return( (void *) 1 );
 }
 
 static void null_ctx_free( void *ctx )
index afa795525d0bbfce883d6f6feedef349be460b18..ece781d5ed87dc38a9a20388292f02026e21a88d 100644 (file)
@@ -495,7 +495,7 @@ int ecp_point_read_binary( const ecp_group *grp, ecp_point *pt,
     int ret;
     size_t plen;
 
-    if ( ilen < 1 )
+    if( ilen < 1 )
         return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
 
     if( buf[0] == 0x00 )
@@ -952,7 +952,9 @@ static int ecp_double_jac( const ecp_group *grp, ecp_point *R,
         MOD_SUB( X3 );
     }
     else
+    {
         MPI_CHK( mpi_mul_mpi( &X3,  &X3,    &grp->A ) ); MOD_MUL( X3 );
+    }
 
     MPI_CHK( mpi_add_mpi( &T3,  &T3,    &X3     ) ); MOD_ADD( T3 );
     MPI_CHK( mpi_mul_mpi( &X3,  &T3,    &T3     ) ); MOD_MUL( X3 );
index 22234cf28dfa4ffc6904cbc3b875dcfdaeb5e2af..73504d450d87f262ef850108712f0d9c6370caf5 100644 (file)
@@ -450,6 +450,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen )
             snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" );
         if( use_ret == -(POLARSSL_ERR_SSL_COUNTER_WRAPPING) )
             snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
+        if( use_ret == -(POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
+            snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
 #endif /* POLARSSL_SSL_TLS_C */
 
 #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
index 77b1e0fb68358138dc06474f3d01e66e5c2b2811..d48f318d3b9e7cffd43aa81f2150765c5bcae95e 100644 (file)
@@ -220,7 +220,6 @@ static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
 #endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
 
     lo = x[15] & 0xf;
-    hi = x[15] >> 4;
 
     zh = ctx->HH[lo];
     zl = ctx->HL[lo];
@@ -354,7 +353,7 @@ int gcm_update( gcm_context *ctx,
     /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
      * Also check for possible overflow */
     if( ctx->len + length < ctx->len ||
-        (uint64_t) ctx->len + length > 0x03FFFFE0llu )
+        (uint64_t) ctx->len + length > 0x03FFFFE0ull )
     {
         return( POLARSSL_ERR_GCM_BAD_INPUT );
     }
index 7f9c5dc843d52b9f314ae6414504d58315c6b059..5f3f32db3f275d347b70a4e3aedff64c8cf73d58 100644 (file)
@@ -53,13 +53,13 @@ static void polarssl_zeroize( void *v, size_t n ) {
 static const int supported_digests[] = {
 
 #if defined(POLARSSL_SHA512_C)
-        POLARSSL_MD_SHA384,
         POLARSSL_MD_SHA512,
+        POLARSSL_MD_SHA384,
 #endif
 
 #if defined(POLARSSL_SHA256_C)
-        POLARSSL_MD_SHA224,
         POLARSSL_MD_SHA256,
+        POLARSSL_MD_SHA224,
 #endif
 
 #if defined(POLARSSL_SHA1_C)
index 7710ba52b13cfd6a36fe63b0866c798b6227b932..00ac3f138528850923483c0b6504dc8609153fe2 100644 (file)
 
 #if defined(POLARSSL_MEMORY_DEBUG)
 #include <stdio.h>
+#endif
 #if defined(POLARSSL_MEMORY_BACKTRACE)
 #include <execinfo.h>
 #endif
-#endif
 
 #if defined(POLARSSL_THREADING_C)
 #include "polarssl/threading.h"
@@ -109,11 +109,11 @@ static void debug_header( memory_header *hdr )
     size_t i;
 #endif
 
-    polarssl_fprintf( stderr, "HDR:  PTR(%10u), PREV(%10u), NEXT(%10u), "
-                              "ALLOC(%u), SIZE(%10u)\n",
+    polarssl_fprintf( stderr, "HDR:  PTR(%10zu), PREV(%10zu), NEXT(%10zu), "
+                              "ALLOC(%zu), SIZE(%10zu)\n",
                       (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next,
                       hdr->alloc, hdr->size );
-    polarssl_fprintf( stderr, "      FPREV(%10u), FNEXT(%10u)\n",
+    polarssl_fprintf( stderr, "      FPREV(%10zu), FNEXT(%10zu)\n",
                       (size_t) hdr->prev_free, (size_t) hdr->next_free );
 
 #if defined(POLARSSL_MEMORY_BACKTRACE)
@@ -511,8 +511,8 @@ int memory_buffer_alloc_verify()
 void memory_buffer_alloc_status()
 {
     polarssl_fprintf( stderr,
-                      "Current use: %u blocks / %u bytes, max: %u blocks / "
-                      "%u bytes (total %u bytes), malloc / free: %u / %u\n",
+                      "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
+                      "%zu bytes (total %zu bytes), malloc / free: %zu / %zu\n",
                       heap.header_count, heap.total_used,
                       heap.maximum_header_count, heap.maximum_used,
                       heap.maximum_header_count * sizeof( memory_header )
index ad4b8921c57100f7fccb1d48f0eb12c510084034..3f0e448ba93cbafb31fbdf3907f0426e2b453bb3 100644 (file)
@@ -434,7 +434,7 @@ int net_accept( int bind_fd, int *client_fd, void *client_ip )
 
     if( *client_fd < 0 )
     {
-        if( net_would_block( *client_fd ) != 0 )
+        if( net_would_block( bind_fd ) != 0 )
             return( POLARSSL_ERR_NET_WANT_READ );
 
         return( POLARSSL_ERR_NET_ACCEPT_FAILED );
@@ -497,7 +497,12 @@ void net_usleep( unsigned long usec )
 {
     struct timeval tv;
     tv.tv_sec  = 0;
+#if !defined(_WIN32) && ( defined(__unix__) || defined(__unix) || \
+    ( defined(__APPLE__) && defined(__MACH__) ) )
+    tv.tv_usec = (suseconds_t) usec;
+#else
     tv.tv_usec = usec;
+#endif
     select( 0, NULL, NULL, NULL, &tv );
 }
 #endif /* POLARSSL_HAVE_TIME */
@@ -508,7 +513,7 @@ void net_usleep( unsigned long usec )
 int net_recv( void *ctx, unsigned char *buf, size_t len )
 {
     int fd = *((int *) ctx);
-    int ret = read( fd, buf, len );
+    int ret = (int) read( fd, buf, len );
 
     if( ret < 0 )
     {
@@ -539,7 +544,7 @@ int net_recv( void *ctx, unsigned char *buf, size_t len )
 int net_send( void *ctx, const unsigned char *buf, size_t len )
 {
     int fd = *((int *) ctx);
-    int ret = write( fd, buf, len );
+    int ret = (int) write( fd, buf, len );
 
     if( ret < 0 )
     {
index 11faf3c8d96622317fd2a7b3d0fcdb84a15ba67e..4aba3aa6d82924d00cd3b2bb1b2dac4fbf2077b0 100644 (file)
@@ -222,7 +222,7 @@ int pk_verify_ext( pk_type_t type, const void *options,
 
         ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ),
                 NULL, NULL, RSA_PUBLIC,
-                md_alg, hash_len, hash,
+                md_alg, (unsigned int) hash_len, hash,
                 pss_opts->mgf1_hash_id,
                 pss_opts->expected_salt_len,
                 sig );
index e769783eef44e513f2e71fbb8db99772a77a8525..e2c4e48c798019bd84451448abc3d6b8fee80833 100644 (file)
@@ -408,7 +408,7 @@ int pkcs5_self_test( int verbose )
 exit:
     md_free( &sha1_ctx );
 
-    return( 0 );
+    return( ret );
 }
 #endif /* POLARSSL_SHA1_C */
 
index 3b0bbdb4e5969e921915881548b5d45d8c63e452..d6273807b2b966b14d75e3f69e743cd55a4b3963 100644 (file)
@@ -294,10 +294,93 @@ int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size )
 #define PEM_BEGIN_PRIVATE_KEY_EC    "-----BEGIN EC PRIVATE KEY-----\n"
 #define PEM_END_PRIVATE_KEY_EC      "-----END EC PRIVATE KEY-----\n"
 
+/*
+ * Max sizes of key per types. Shown as tag + len (+ content).
+ */
+
+#if defined(POLARSSL_RSA_C)
+/*
+ * RSA public keys:
+ *  SubjectPublicKeyInfo  ::=  SEQUENCE  {          1 + 3
+ *       algorithm            AlgorithmIdentifier,  1 + 1 (sequence)
+ *                                                + 1 + 1 + 9 (rsa oid)
+ *                                                + 1 + 1 (params null)
+ *       subjectPublicKey     BIT STRING }          1 + 3 + (1 + below)
+ *  RSAPublicKey ::= SEQUENCE {                     1 + 3
+ *      modulus           INTEGER,  -- n            1 + 3 + MPI_MAX + 1
+ *      publicExponent    INTEGER   -- e            1 + 3 + MPI_MAX + 1
+ *  }
+ */
+#define RSA_PUB_DER_MAX_BYTES   38 + 2 * POLARSSL_MPI_MAX_SIZE
+
+/*
+ * RSA private keys:
+ *  RSAPrivateKey ::= SEQUENCE {                    1 + 3
+ *      version           Version,                  1 + 1 + 1
+ *      modulus           INTEGER,                  1 + 3 + MPI_MAX + 1
+ *      publicExponent    INTEGER,                  1 + 3 + MPI_MAX + 1
+ *      privateExponent   INTEGER,                  1 + 3 + MPI_MAX + 1
+ *      prime1            INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      prime2            INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      exponent1         INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      exponent2         INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      coefficient       INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      otherPrimeInfos   OtherPrimeInfos OPTIONAL  0 (not supported)
+ *  }
+ */
+#define MPI_MAX_SIZE_2          POLARSSL_MPI_MAX_SIZE / 2 + \
+                                POLARSSL_MPI_MAX_SIZE % 2
+#define RSA_PRV_DER_MAX_BYTES   47 + 3 * POLARSSL_MPI_MAX_SIZE \
+                                   + 5 * MPI_MAX_SIZE_2
+
+#else /* POLARSSL_RSA_C */
+
+#define RSA_PUB_DER_MAX_BYTES   0
+#define RSA_PRV_DER_MAX_BYTES   0
+
+#endif /* POLARSSL_RSA_C */
+
+#if defined(POLARSSL_ECP_C)
+/*
+ * EC public keys:
+ *  SubjectPublicKeyInfo  ::=  SEQUENCE  {      1 + 2
+ *    algorithm         AlgorithmIdentifier,    1 + 1 (sequence)
+ *                                            + 1 + 1 + 7 (ec oid)
+ *                                            + 1 + 1 + 9 (namedCurve oid)
+ *    subjectPublicKey  BIT STRING              1 + 2 + 1               [1]
+ *                                            + 1 (point format)        [1]
+ *                                            + 2 * ECP_MAX (coords)    [1]
+ *  }
+ */
+#define ECP_PUB_DER_MAX_BYTES   30 + 2 * POLARSSL_ECP_MAX_BYTES
+
+/*
+ * EC private keys:
+ * ECPrivateKey ::= SEQUENCE {                  1 + 2
+ *      version        INTEGER ,                1 + 1 + 1
+ *      privateKey     OCTET STRING,            1 + 1 + ECP_MAX
+ *      parameters [0] ECParameters OPTIONAL,   1 + 1 + (1 + 1 + 9)
+ *      publicKey  [1] BIT STRING OPTIONAL      1 + 2 + [1] above
+ *    }
+ */
+#define ECP_PRV_DER_MAX_BYTES   29 + 3 * POLARSSL_ECP_MAX_BYTES
+
+#else /* POLARSSL_ECP_C */
+
+#define ECP_PUB_DER_MAX_BYTES   0
+#define ECP_PRV_DER_MAX_BYTES   0
+
+#endif /* POLARSSL_ECP_C */
+
+#define PUB_DER_MAX_BYTES   RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
+                            RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
+#define PRV_DER_MAX_BYTES   RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
+                            RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
+
 int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size )
 {
     int ret;
-    unsigned char output_buf[4096];
+    unsigned char output_buf[PUB_DER_MAX_BYTES];
     size_t olen = 0;
 
     if( ( ret = pk_write_pubkey_der( key, output_buf,
@@ -319,7 +402,7 @@ int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size )
 int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size )
 {
     int ret;
-    unsigned char output_buf[4096];
+    unsigned char output_buf[PRV_DER_MAX_BYTES];
     const char *begin, *end;
     size_t olen = 0;
 
index 0fd5199b2ab5b17f7c1af341d9bbff1547992029..958085c8abe17bf03689d209d090284be5aa0e6f 100644 (file)
@@ -1005,7 +1005,7 @@ int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
 {
     size_t nb_pad, olen, oid_size = 0;
     unsigned char *p = sig;
-    const char *oid;
+    const char *oid = NULL;
 
     if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
index df838e260571755b6a774db9232ed800470e039d..7907980cd47a6b01266dcffdc9b3e30c28bbaefb 100644 (file)
@@ -260,7 +260,7 @@ static const int ciphersuite_preference[] =
     TLS_PSK_WITH_NULL_SHA256,
     TLS_PSK_WITH_NULL_SHA,
 
-#endif
+#endif /* SSL_CIPHERSUITES */
     0
 };
 
@@ -1077,7 +1077,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256",
       POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA256_C */
@@ -1085,7 +1085,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA512_C)
     { TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384",
       POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA512_C */
@@ -1133,7 +1133,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256",
       POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA256_C */
@@ -1141,7 +1141,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA512_C)
     { TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384",
       POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA512_C */
@@ -1213,7 +1213,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256",
       POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA256_C */
@@ -1221,7 +1221,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA512_C)
     { TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384",
       POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA512_C */
@@ -1269,7 +1269,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
       POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA256_C */
@@ -1277,7 +1277,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA512_C)
     { TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
       POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA512_C */
@@ -1428,7 +1428,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256",
       POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA256_C */
@@ -1436,7 +1436,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA512_C)
     { TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384",
       POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA512_C */
@@ -1444,13 +1444,13 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA1_C)
     { TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA",
       POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 
     { TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA",
       POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA1_C */
@@ -1462,7 +1462,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256",
       POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA256_C */
@@ -1470,7 +1470,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA512_C)
     { TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384",
       POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA512_C */
@@ -1500,7 +1500,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA1_C)
     { TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA",
       POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA1_C */
@@ -1511,7 +1511,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA1_C)
     { TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA",
       POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       0 },
 #endif /* POLARSSL_SHA1_C */
@@ -1540,7 +1540,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256",
       POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       POLARSSL_CIPHERSUITE_WEAK },
 #endif
@@ -1558,7 +1558,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256",
       POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       POLARSSL_CIPHERSUITE_WEAK },
 #endif
@@ -1566,7 +1566,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA512_C)
     { TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384",
       POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       POLARSSL_CIPHERSUITE_WEAK },
 #endif
@@ -1584,7 +1584,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256",
       POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       POLARSSL_CIPHERSUITE_WEAK },
 #endif
@@ -1592,7 +1592,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA512_C)
     { TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384",
       POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       POLARSSL_CIPHERSUITE_WEAK },
 #endif
@@ -1628,7 +1628,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA1_C)
     { TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA",
       POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       POLARSSL_CIPHERSUITE_WEAK },
 #endif /* POLARSSL_SHA1_C */
@@ -1636,7 +1636,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA256_C)
     { TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256",
       POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       POLARSSL_CIPHERSUITE_WEAK },
 #endif
@@ -1644,7 +1644,7 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
 #if defined(POLARSSL_SHA512_C)
     { TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384",
       POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK,
-      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       POLARSSL_CIPHERSUITE_WEAK },
 #endif
index d38d769551e01a45f6f6d9928e2e8bdb21ace091..27abb3efe49904d6ec4cbac2cba2e39932843855 100644 (file)
@@ -875,7 +875,7 @@ static int ssl_parse_server_hello( ssl_context *ssl )
 {
     int ret, i, comp;
     size_t n;
-    size_t ext_len = 0;
+    size_t ext_len;
     unsigned char *buf, *ext;
     int renegotiation_info_seen = 0;
     int handshake_failure = 0;
@@ -902,6 +902,22 @@ static int ssl_parse_server_hello( ssl_context *ssl )
 
     if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
     {
+        if( ssl->renegotiation == SSL_RENEGOTIATION )
+        {
+            ssl->renego_records_seen++;
+
+            if( ssl->renego_max_records >= 0 &&
+                ssl->renego_records_seen > ssl->renego_max_records )
+            {
+                SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
+                                    "but not honored by server" ) );
+                return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
+            }
+
+            SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
+            return( POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
+        }
+
         SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
     }
@@ -965,7 +981,7 @@ static int ssl_parse_server_hello( ssl_context *ssl )
      *   42+n . 43+n  extensions length
      *   44+n . 44+n+m extensions
      */
-    if( ssl->in_hslen > 42 + n )
+    if( ssl->in_hslen > 43 + n )
     {
         ext_len = ( ( buf[42 + n] <<  8 )
                   | ( buf[43 + n]       ) );
@@ -977,6 +993,15 @@ static int ssl_parse_server_hello( ssl_context *ssl )
             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
         }
     }
+    else if( ssl->in_hslen == 42 + n )
+    {
+        ext_len = 0;
+    }
+    else
+    {
+        SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
 
     i = ( buf[39 + n] << 8 ) | buf[40 + n];
     comp = buf[41 + n];
index 25be98826739ff7e91498f08d21ec094f8353c2f..01b0aca2072f0d086fc8ebd46efe0d6bc8e15ec6 100644 (file)
@@ -494,11 +494,16 @@ static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
         for( p = buf + 2; p < end; p += 2 ) {
             if( *md_cur == (int) ssl_md_alg_from_hash( p[0] ) ) {
                 ssl->handshake->sig_alg = p[0];
-                break;
+                goto have_sig_alg;
             }
         }
     }
 
+    /* Some key echanges do not need signatures at all */
+    SSL_DEBUG_MSG( 3, ( "no signature_algorithm in common" ) );
+    return( 0 );
+
+have_sig_alg:
     SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
                    ssl->handshake->sig_alg ) );
 
@@ -523,6 +528,13 @@ static int ssl_parse_supported_elliptic_curves( ssl_context *ssl,
         return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
+    /* Should never happen unless client duplicates the extension */
+    if( ssl->handshake->curves != NULL )
+    {
+        SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
     /* Don't allow our peer to make us allocate too much memory,
      * and leave room for a final 0 */
     our_size = list_size / 2 + 1;
index 8613b8d0e3d9b2c5b372fc3f51692076cc44661b..5f080defea4c33a39e5b21c41e7f63fc716c3a83 100644 (file)
@@ -991,18 +991,15 @@ static void ssl_mac( md_context_t *md_ctx, unsigned char *secret,
 {
     unsigned char header[11];
     unsigned char padding[48];
-    int padlen = 0;
+    int padlen;
     int md_size = md_get_size( md_ctx->md_info );
     int md_type = md_get_type( md_ctx->md_info );
 
+    /* Only MD5 and SHA-1 supported */
     if( md_type == POLARSSL_MD_MD5 )
         padlen = 48;
-    else if( md_type == POLARSSL_MD_SHA1 )
+    else
         padlen = 40;
-    else if( md_type == POLARSSL_MD_SHA256 )
-        padlen = 32;
-    else if( md_type == POLARSSL_MD_SHA384 )
-        padlen = 16;
 
     memcpy( header, ctr, 8 );
     header[ 8] = (unsigned char)  type;
@@ -2230,10 +2227,6 @@ int ssl_read_record( ssl_context *ssl )
         {
             SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
                            ssl->in_msg[1] ) );
-            /**
-             * Subtract from error code as ssl->in_msg[1] is 7-bit positive
-             * error identifier.
-             */
             return( POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE );
         }
 
@@ -3345,7 +3338,7 @@ static int ssl_handshake_init( ssl_context *ssl )
             (ssl_session *) polarssl_malloc( sizeof(ssl_session) );
     }
 
-    if( ssl->handshake == NULL)
+    if( ssl->handshake == NULL )
     {
         ssl->handshake = (ssl_handshake_params *)
             polarssl_malloc( sizeof(ssl_handshake_params) );
@@ -4174,8 +4167,6 @@ static int ssl_write_hello_request( ssl_context *ssl )
         return( ret );
     }
 
-    ssl->renegotiation = SSL_RENEGOTIATION_PENDING;
-
     SSL_DEBUG_MSG( 2, ( "<= write hello request" ) );
 
     return( 0 );
@@ -4184,10 +4175,10 @@ static int ssl_write_hello_request( ssl_context *ssl )
 
 /*
  * Actually renegotiate current connection, triggered by either:
- * - calling ssl_renegotiate() on client,
- * - receiving a HelloRequest on client during ssl_read(),
- * - receiving any handshake message on server during ssl_read() after the
- *   initial handshake is completed
+ * - any side: calling ssl_renegotiate(),
+ * - client: receiving a HelloRequest during ssl_read(),
+ * - server: receiving any handshake message on server during ssl_read() after
+ *   the initial handshake is completed.
  * If the handshake doesn't complete due to waiting for I/O, it will continue
  * during the next calls to ssl_renegotiate() or ssl_read() respectively.
  */
@@ -4229,6 +4220,12 @@ int ssl_renegotiate( ssl_context *ssl )
         if( ssl->state != SSL_HANDSHAKE_OVER )
             return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
 
+        ssl->renegotiation = SSL_RENEGOTIATION_PENDING;
+
+        /* Did we already try/start sending HelloRequest? */
+        if( ssl->out_left != 0 )
+            return( ssl_flush_output( ssl ) );
+
         return( ssl_write_hello_request( ssl ) );
     }
 #endif /* POLARSSL_SSL_SRV_C */
@@ -4267,14 +4264,19 @@ int ssl_renegotiate( ssl_context *ssl )
  */
 int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
 {
-    int ret;
+    int ret, record_read = 0;
     size_t n;
 
     SSL_DEBUG_MSG( 2, ( "=> read" ) );
 
     if( ssl->state != SSL_HANDSHAKE_OVER )
     {
-        if( ( ret = ssl_handshake( ssl ) ) != 0 )
+        ret = ssl_handshake( ssl );
+        if( ret == POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO )
+        {
+            record_read = 1;
+        }
+        else if( ret != 0 )
         {
             SSL_DEBUG_RET( 1, "ssl_handshake", ret );
             return( ret );
@@ -4283,13 +4285,16 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
 
     if( ssl->in_offt == NULL )
     {
-        if( ( ret = ssl_read_record( ssl ) ) != 0 )
+        if( ! record_read )
         {
-            if( ret == POLARSSL_ERR_SSL_CONN_EOF )
-                return( 0 );
+            if( ( ret = ssl_read_record( ssl ) ) != 0 )
+            {
+                if( ret == POLARSSL_ERR_SSL_CONN_EOF )
+                    return( 0 );
 
-            SSL_DEBUG_RET( 1, "ssl_read_record", ret );
-            return( ret );
+                SSL_DEBUG_RET( 1, "ssl_read_record", ret );
+                return( ret );
+            }
         }
 
         if( ssl->in_msglen  == 0 &&
@@ -4359,14 +4364,22 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
             }
             else
             {
-                if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
+                ret = ssl_start_renegotiation( ssl );
+                if( ret == POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO )
+                {
+                    record_read = 1;
+                }
+                else if( ret != 0 )
                 {
                     SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
                     return( ret );
                 }
+            }
 
+            /* If a non-handshake record was read during renego, fallthrough,
+             * else tell the user they should call ssl_read() again */
+            if( ! record_read )
                 return( POLARSSL_ERR_NET_WANT_READ );
-            }
         }
         else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING )
         {
@@ -4380,7 +4393,15 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
                 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
             }
         }
-        else if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA )
+
+        /* Fatal and closure alerts handled by ssl_read_record() */
+        if( ssl->in_msgtype == SSL_MSG_ALERT )
+        {
+            SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
+            return( POLARSSL_ERR_NET_WANT_READ );
+        }
+
+        if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA )
         {
             SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
             return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
@@ -4480,11 +4501,8 @@ int ssl_close_notify( ssl_context *ssl )
 
     SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
 
-    if( ( ret = ssl_flush_output( ssl ) ) != 0 )
-    {
-        SSL_DEBUG_RET( 1, "ssl_flush_output", ret );
-        return( ret );
-    }
+    if( ssl->out_left != 0 )
+        return( ssl_flush_output( ssl ) );
 
     if( ssl->state == SSL_HANDSHAKE_OVER )
     {
@@ -4492,13 +4510,14 @@ int ssl_close_notify( ssl_context *ssl )
                         SSL_ALERT_LEVEL_WARNING,
                         SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
         {
+            SSL_DEBUG_RET( 1, "ssl_send_alert_message", ret );
             return( ret );
         }
     }
 
     SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
 
-    return( ret );
+    return( 0 );
 }
 
 void ssl_transform_free( ssl_transform *transform )
index 6c1dfa46b1802433032ac9c71f50793c1e5a4e9f..b387bd87fe3190de458f34a070882267a7813428 100644 (file)
@@ -283,15 +283,16 @@ unsigned long get_timer( struct hr_time *val, int reset )
 
     gettimeofday( &offset, NULL );
 
-    delta = ( offset.tv_sec  - t->start.tv_sec  ) * 1000
-          + ( offset.tv_usec - t->start.tv_usec ) / 1000;
-
     if( reset )
     {
         t->start.tv_sec  = offset.tv_sec;
         t->start.tv_usec = offset.tv_usec;
+        return( 0 );
     }
 
+    delta = ( offset.tv_sec  - t->start.tv_sec  ) * 1000
+          + ( offset.tv_usec - t->start.tv_usec ) / 1000;
+
     return( delta );
 }
 
@@ -332,7 +333,7 @@ void m_sleep( int milliseconds )
 #if defined(POLARSSL_SELF_TEST)
 
 /* To test net_usleep against our functions */
-#if defined(POLARSSL_NET_C)
+#if defined(POLARSSL_NET_C) && defined(POLARSSL_HAVE_TIME)
 #include "polarssl/net.h"
 #endif
 
@@ -378,7 +379,7 @@ int timing_self_test( int verbose )
     {
         (void) get_timer( &hires, 1 );
 
-        m_sleep( 500 * secs );
+        m_sleep( (int)( 500 * secs ) );
 
         millisecs = get_timer( &hires, 0 );
 
@@ -401,7 +402,7 @@ int timing_self_test( int verbose )
     {
         (void) get_timer( &hires, 1 );
 
-        set_alarm( secs );
+        set_alarm( (int) secs );
         while( !alarmed )
             ;
 
@@ -464,7 +465,7 @@ hard_test:
     if( verbose != 0 )
         polarssl_printf( "passed\n" );
 
-#if defined(POLARSSL_NET_C)
+#if defined(POLARSSL_NET_C) && defined(POLARSSL_HAVE_TIME)
     if( verbose != 0 )
         polarssl_printf( "  TIMING test #4 (net_usleep/ get_timer): " );
 
index 17c7a7db04a957df443966aaf651cf49185abee5..941472c9de77b31449a99857ab627b5b80554221 100644 (file)
@@ -409,58 +409,47 @@ static int x509_get_attr_type_value( unsigned char **p,
  *  AttributeType ::= OBJECT IDENTIFIER
  *
  *  AttributeValue ::= ANY DEFINED BY AttributeType
+ *
+ *  We restrict RelativeDistinguishedName to be a set of 1 element. This is
+ *  the most common case, and our x509_name structure currently can't handle
+ *  more than that.
  */
 int x509_get_name( unsigned char **p, const unsigned char *end,
                    x509_name *cur )
 {
     int ret;
-    size_t len;
-    const unsigned char *end2;
-    x509_name *use;
+    size_t set_len;
+    const unsigned char *end_set;
 
-    if( ( ret = asn1_get_tag( p, end, &len,
+    /*
+     * parse first SET, restricted to 1 element
+     */
+    if( ( ret = asn1_get_tag( p, end, &set_len,
             ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
         return( POLARSSL_ERR_X509_INVALID_NAME + ret );
 
-    end2 = end;
-    end  = *p + len;
-    use = cur;
-
-    do
-    {
-        if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
-            return( ret );
+    end_set  = *p + set_len;
 
-        if( *p != end )
-        {
-            use->next = (x509_name *) polarssl_malloc(
-                    sizeof( x509_name ) );
-
-            if( use->next == NULL )
-                return( POLARSSL_ERR_X509_MALLOC_FAILED );
+    if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
+        return( ret );
 
-            memset( use->next, 0, sizeof( x509_name ) );
-
-            use = use->next;
-        }
-    }
-    while( *p != end );
+    if( *p != end_set )
+        return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
 
     /*
      * recurse until end of SEQUENCE is reached
      */
-    if( *p == end2 )
+    if( *p == end )
         return( 0 );
 
-    cur->next = (x509_name *) polarssl_malloc(
-         sizeof( x509_name ) );
+    cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) );
 
     if( cur->next == NULL )
         return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
     memset( cur->next, 0, sizeof( x509_name ) );
 
-    return( x509_get_name( p, end2, cur->next ) );
+    return( x509_get_name( p, end, cur->next ) );
 }
 
 /*
@@ -750,7 +739,7 @@ int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
     unsigned char c;
     const x509_name *name;
     const char *short_name = NULL;
-    char s[128], *p;
+    char s[X509_MAX_DN_NAME_SIZE], *p;
 
     memset( s, 0, sizeof( s ) );
 
@@ -876,7 +865,7 @@ int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid,
     ((void) sig_opts);
 #endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
 
-    return( (int) size - n );
+    return( (int)( size - n ) );
 }
 
 /*
index 1019313327c74c09640942dfbfdc25fd02d3ab9a..747dc82800054aa4019200ac38b0d248aeb5ba2a 100644 (file)
@@ -100,6 +100,8 @@ int x509_string_to_names( asn1_named_data **head, const char *name )
     const char *end = s + strlen( s );
     const char *oid = NULL;
     int in_tag = 1;
+    char data[X509_MAX_DN_NAME_SIZE];
+    char *d = data;
 
     /* Clear existing chain if present */
     asn1_free_named_data_list( head );
@@ -116,13 +118,25 @@ int x509_string_to_names( asn1_named_data **head, const char *name )
 
             s = c + 1;
             in_tag = 0;
+            d = data;
         }
 
-        if( !in_tag && ( *c == ',' || c == end ) )
+        if( !in_tag && *c == '\\' && c != end )
+        {
+            c++;
+
+            /* Check for valid escaped characters */
+            if( c == end || *c != ',' )
+            {
+                ret = POLARSSL_ERR_X509_INVALID_NAME;
+                goto exit;
+            }
+        }
+        else if( !in_tag && ( *c == ',' || c == end ) )
         {
             if( asn1_store_named_data( head, oid, strlen( oid ),
-                                       (unsigned char *) s,
-                                       c - s ) == NULL )
+                                       (unsigned char *) data,
+                                       d - data ) == NULL )
             {
                 return( POLARSSL_ERR_X509_MALLOC_FAILED );
             }
@@ -133,6 +147,18 @@ int x509_string_to_names( asn1_named_data **head, const char *name )
             s = c + 1;
             in_tag = 1;
         }
+
+        if( !in_tag && s != c + 1 )
+        {
+            *(d++) = *c;
+
+            if( d - data == X509_MAX_DN_NAME_SIZE )
+            {
+                ret = POLARSSL_ERR_X509_INVALID_NAME;
+                goto exit;
+            }
+        }
+
         c++;
     }
 
index 03cdda807909f677ece242e98a60a0f086c9a8c6..88d7f04c7a4052963063eaf186421c711dfc0b78 100644 (file)
@@ -898,6 +898,7 @@ int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen )
                 if( first_error == 0 )
                     first_error = ret;
 
+                total_failed++;
                 continue;
             }
             else
@@ -1528,8 +1529,10 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
 }
 #endif /* POLARSSL_X509_CRL_PARSE_C */
 
-// Equal == 0, inequal == 1
-static int x509_name_cmp( const void *s1, const void *s2, size_t len )
+/*
+ * Like memcmp, but case-insensitive and always returns -1 if different
+ */
+static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
 {
     size_t i;
     unsigned char diff;
@@ -1549,12 +1552,16 @@ static int x509_name_cmp( const void *s1, const void *s2, size_t len )
             continue;
         }
 
-        return( 1 );
+        return( -1 );
     }
 
     return( 0 );
 }
 
+/*
+ * Return 1 if match, 0 if not
+ * TODO: inverted return value!
+ */
 static int x509_wildcard_verify( const char *cn, x509_buf *name )
 {
     size_t i;
@@ -1576,7 +1583,7 @@ static int x509_wildcard_verify( const char *cn, x509_buf *name )
         return( 0 );
 
     if( cn_len - cn_idx == name->len - 1 &&
-        x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
+        x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
     {
         return( 1 );
     }
@@ -1584,6 +1591,65 @@ static int x509_wildcard_verify( const char *cn, x509_buf *name )
     return( 0 );
 }
 
+/*
+ * Compare two X.509 strings, case-insensitive, and allowing for some encoding
+ * variations (but not all).
+ *
+ * Return 0 if equal, -1 otherwise.
+ */
+static int x509_string_cmp( const x509_buf *a, const x509_buf *b )
+{
+    if( a->tag == b->tag &&
+        a->len == b->len &&
+        memcmp( a->p, b->p, b->len ) == 0 )
+    {
+        return( 0 );
+    }
+
+    if( ( a->tag == ASN1_UTF8_STRING || a->tag == ASN1_PRINTABLE_STRING ) &&
+        ( b->tag == ASN1_UTF8_STRING || b->tag == ASN1_PRINTABLE_STRING ) &&
+        a->len == b->len &&
+        x509_memcasecmp( a->p, b->p, b->len ) == 0 )
+    {
+        return( 0 );
+    }
+
+    return( -1 );
+}
+
+/*
+ * Compare two X.509 Names (aka rdnSequence).
+ *
+ * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
+ * we sometimes return unequal when the full algorithm would return equal,
+ * but never the other way. (In particular, we don't do Unicode normalisation
+ * or space folding.)
+ *
+ * Return 0 if equal, -1 otherwise.
+ */
+static int x509_name_cmp( const x509_name *a, const x509_name *b )
+{
+    if( a == NULL && b == NULL )
+        return( 0 );
+
+    if( a == NULL || b == NULL )
+        return( -1 );
+
+    /* type */
+    if( a->oid.tag != b->oid.tag ||
+        a->oid.len != b->oid.len ||
+        memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
+    {
+        return( -1 );
+    }
+
+    /* value */
+    if( x509_string_cmp( &a->val, &b->val ) != 0 )
+        return( -1 );
+
+    return( x509_name_cmp( a->next, b->next ) );
+}
+
 /*
  * Check if 'parent' is a suitable parent (signing CA) for 'child'.
  * Return 0 if yes, -1 if not.
@@ -1598,12 +1664,8 @@ static int x509_crt_check_parent( const x509_crt *child,
     int need_ca_bit;
 
     /* Parent must be the issuer */
-    if( child->issuer_raw.len != parent->subject_raw.len ||
-        memcmp( child->issuer_raw.p, parent->subject_raw.p,
-                child->issuer_raw.len ) != 0 )
-    {
+    if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 )
         return( -1 );
-    }
 
     /* Parent must have the basicConstraints CA bit set as a general rule */
     need_ca_bit = 1;
@@ -1858,7 +1920,7 @@ int x509_crt_verify( x509_crt *crt,
             while( cur != NULL )
             {
                 if( cur->buf.len == cn_len &&
-                    x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
+                    x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 )
                     break;
 
                 if( cur->buf.len > 2 &&
@@ -1879,7 +1941,7 @@ int x509_crt_verify( x509_crt *crt,
                 if( OID_CMP( OID_AT_CN, &name->oid ) )
                 {
                     if( name->val.len == cn_len &&
-                        x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
+                        x509_memcasecmp( name->val.p, cn, cn_len ) == 0 )
                         break;
 
                     if( name->val.len > 2 &&