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}
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).
* 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. */
#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;
/* 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) */
* 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.)
#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
#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) */
/**
* \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
*
* \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.
*/
#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)
#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
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})
#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
*/
if( *p == end )
{
- memset( params, 0, sizeof(asn1_buf) );
+ polarssl_zeroize( params, sizeof(asn1_buf) );
return( 0 );
}
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 )
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;
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 );
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 );
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 )
static void * null_ctx_alloc( void )
{
- return( (void *) 1 )
+ return( (void *) 1 );
}
static void null_ctx_free( void *ctx )
int ret;
size_t plen;
- if ( ilen < 1 )
+ if( ilen < 1 )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( buf[0] == 0x00 )
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 );
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)
#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
lo = x[15] & 0xf;
- hi = x[15] >> 4;
zh = ctx->HH[lo];
zl = ctx->HL[lo];
/* 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 );
}
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)
#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"
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)
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 )
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 );
{
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 */
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 )
{
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 )
{
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 );
exit:
md_free( &sha1_ctx );
- return( 0 );
+ return( ret );
}
#endif /* POLARSSL_SHA1_C */
#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,
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;
{
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 );
TLS_PSK_WITH_NULL_SHA256,
TLS_PSK_WITH_NULL_SHA,
-#endif
+#endif /* SSL_CIPHERSUITES */
0
};
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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
#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
#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
#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
#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
#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 */
#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
#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
{
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;
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 );
}
* 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] ) );
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];
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 ) );
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;
{
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;
{
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 );
}
(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) );
return( ret );
}
- ssl->renegotiation = SSL_RENEGOTIATION_PENDING;
-
SSL_DEBUG_MSG( 2, ( "<= write hello request" ) );
return( 0 );
/*
* 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.
*/
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 */
*/
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 );
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 &&
}
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 )
{
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 );
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 )
{
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 )
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 );
}
#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
{
(void) get_timer( &hires, 1 );
- m_sleep( 500 * secs );
+ m_sleep( (int)( 500 * secs ) );
millisecs = get_timer( &hires, 0 );
{
(void) get_timer( &hires, 1 );
- set_alarm( secs );
+ set_alarm( (int) secs );
while( !alarmed )
;
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): " );
* 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 ) );
}
/*
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 ) );
((void) sig_opts);
#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
- return( (int) size - n );
+ return( (int)( size - n ) );
}
/*
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 );
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 );
}
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++;
}
if( first_error == 0 )
first_error = ret;
+ total_failed++;
continue;
}
else
}
#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;
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;
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 );
}
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.
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;
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 &&
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 &&