diff options
author | Android Chromium Automerger <chromium-automerger@android> | 2014-09-06 09:55:31 +0000 |
---|---|---|
committer | Android Chromium Automerger <chromium-automerger@android> | 2014-09-06 09:55:31 +0000 |
commit | 256a6006d9a42678b415f4b5faf284b600f10c00 (patch) | |
tree | 7272ab8a18944675363a24d0092d9ef92b513651 | |
parent | 0363311333c5613cfe1f7ca7eb88db4b85f92246 (diff) | |
parent | 7bdec13c03744049ba5f776b6418cbcfe61356cd (diff) | |
download | src-256a6006d9a42678b415f4b5faf284b600f10c00.tar.gz |
Merge third_party/boringssl/src from https://boringssl.googlesource.com/boringssl.git at 7bdec13c03744049ba5f776b6418cbcfe61356cd
This commit was generated by merge_from_chromium.py.
Change-Id: I0ecba22aadd52001a91d760eb63d9f68dbf52ebf
43 files changed, 554 insertions, 288 deletions
diff --git a/crypto/bio/bio_mem.c b/crypto/bio/bio_mem.c index 457c2e0..6e90db5 100644 --- a/crypto/bio/bio_mem.c +++ b/crypto/bio/bio_mem.c @@ -132,13 +132,12 @@ static int mem_free(BIO *bio) { } static int mem_read(BIO *bio, char *out, int outl) { - int ret = -1; - BUF_MEM *b; + int ret; + BUF_MEM *b = (BUF_MEM*) bio->ptr; - b = (BUF_MEM *)bio->ptr; BIO_clear_retry_flags(bio); ret = outl; - if (ret > (int)b->length) { + if (b->length < INT_MAX && ret > (int)b->length) { ret = b->length; } diff --git a/crypto/chacha/chacha_generic.c b/crypto/chacha/chacha_generic.c index 40a6f20..c497980 100644 --- a/crypto/chacha/chacha_generic.c +++ b/crypto/chacha/chacha_generic.c @@ -47,7 +47,7 @@ static const char sigma[16] = "expand 32-byte k"; x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \ x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7); -#if defined(OPENSSL_ARM) +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) /* Defined in chacha_vec.c */ void CRYPTO_chacha_20_neon(uint8_t *out, const uint8_t *in, size_t in_len, const uint8_t key[32], const uint8_t nonce[8], @@ -87,7 +87,7 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, uint8_t buf[64]; size_t todo, i; -#if defined(OPENSSL_ARM) +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) if (CRYPTO_is_NEON_capable() && ((intptr_t)in & 15) == 0 && ((intptr_t)out & 15) == 0) { CRYPTO_chacha_20_neon(out, in, in_len, key, nonce, counter); diff --git a/crypto/chacha/chacha_vec_arm.S b/crypto/chacha/chacha_vec_arm.S index be87ab3..535e20a 100644 --- a/crypto/chacha/chacha_vec_arm.S +++ b/crypto/chacha/chacha_vec_arm.S @@ -21,6 +21,8 @@ # # /opt/gcc-linaro-arm-linux-gnueabihf-4.7-2012.10-20121022_linux/bin/arm-linux-gnueabihf-gcc -O3 -mcpu=cortex-a8 -mfpu=neon -S chacha_vec.c -I ../../include -fpic -o chacha_vec_arm.S +#if !defined(OPENSSL_NO_ASM) + .syntax unified .cpu cortex-a8 .eabi_attribute 27, 3 @@ -884,3 +886,5 @@ CRYPTO_chacha_20_neon: .word 1797285236 .ident "GCC: (crosstool-NG linaro-1.13.1-4.7-2012.10-20121022 - Linaro GCC 2012.10) 4.7.3 20121001 (prerelease)" .section .note.GNU-stack,"",%progbits + +#endif /* !OPENSSL_NO_ASM */ diff --git a/crypto/ec/wnaf.c b/crypto/ec/wnaf.c index b86107d..2fed4a5 100644 --- a/crypto/ec/wnaf.c +++ b/crypto/ec/wnaf.c @@ -448,8 +448,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, wNAF[num] = tmp_wNAF; wNAF[num + 1] = NULL; wNAF_len[num] = tmp_len; - if (tmp_len > max_len) - max_len = tmp_len; /* pre_comp->points starts with the points that we need here: */ val_sub[num] = pre_comp->points; } else { diff --git a/crypto/ecdsa/ecdsa.c b/crypto/ecdsa/ecdsa.c index 067fd6c..ddc3e61 100644 --- a/crypto/ecdsa/ecdsa.c +++ b/crypto/ecdsa/ecdsa.c @@ -140,8 +140,9 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, } /* check input values */ - if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || - (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { + if ((group = EC_KEY_get0_group(eckey)) == NULL || + (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || + sig == NULL) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_MISSING_PARAMETERS); return 0; } diff --git a/crypto/evp/example_sign.c b/crypto/evp/example_sign.c index 847330d..9d2a296 100644 --- a/crypto/evp/example_sign.c +++ b/crypto/evp/example_sign.c @@ -127,9 +127,13 @@ int example_EVP_DigestSignInit(void) { fprintf(stderr, "sig_len mismatch\n"); goto out; } + sig = malloc(sig_len); - if (sig == NULL || - EVP_DigestSignFinal(&md_ctx, sig, &sig_len) != 1) { + if (sig == NULL) { + goto out; + } + if (EVP_DigestSignFinal(&md_ctx, sig, &sig_len) != 1) { + free(sig); goto out; } diff --git a/crypto/internal.h b/crypto/internal.h index 39d35ad..65a52ed 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -111,6 +111,10 @@ #include <openssl/ex_data.h> +#if defined(__cplusplus) +extern "C" { +#endif + /* st_CRYPTO_EX_DATA_IMPL contains an ex_data implementation. See the comments * in ex_data.h for details of the behaviour of each of the functions. */ diff --git a/crypto/obj/obj.c b/crypto/obj/obj.c index 8a7a584..bfcc08b 100644 --- a/crypto/obj/obj.c +++ b/crypto/obj/obj.c @@ -66,7 +66,7 @@ #include <openssl/mem.h> #include <openssl/thread.h> -#include <openssl/obj_dat.h> +#include "obj_dat.h" /* These globals are protected by CRYPTO_LOCK_OBJ. */ static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL; diff --git a/include/openssl/obj_dat.h b/crypto/obj/obj_dat.h index 18bcec1..18bcec1 100644 --- a/include/openssl/obj_dat.h +++ b/crypto/obj/obj_dat.h diff --git a/crypto/poly1305/poly1305.c b/crypto/poly1305/poly1305.c index 9b9c734..bf5cd5e 100644 --- a/crypto/poly1305/poly1305.c +++ b/crypto/poly1305/poly1305.c @@ -48,7 +48,7 @@ static void U32TO8_LE(uint8_t *m, uint32_t v) { } #endif -#if defined(OPENSSL_ARM) +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]); void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in, @@ -165,7 +165,7 @@ void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) { struct poly1305_state_st *state = (struct poly1305_state_st *)statep; uint32_t t0, t1, t2, t3; -#if defined(OPENSSL_ARM) +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) if (CRYPTO_is_NEON_functional()) { CRYPTO_poly1305_init_neon(statep, key); return; @@ -212,7 +212,7 @@ void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in, unsigned int i; struct poly1305_state_st *state = (struct poly1305_state_st *)statep; -#if defined(OPENSSL_ARM) +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) if (CRYPTO_is_NEON_functional()) { CRYPTO_poly1305_update_neon(statep, in, in_len); return; @@ -255,7 +255,7 @@ void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) { uint32_t g0, g1, g2, g3, g4; uint32_t b, nb; -#if defined(OPENSSL_ARM) +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) if (CRYPTO_is_NEON_functional()) { CRYPTO_poly1305_finish_neon(statep, mac); return; diff --git a/crypto/poly1305/poly1305_arm.c b/crypto/poly1305/poly1305_arm.c index 9d5e276..002a4c4 100644 --- a/crypto/poly1305/poly1305_arm.c +++ b/crypto/poly1305/poly1305_arm.c @@ -17,8 +17,7 @@ #include <openssl/poly1305.h> - -#if defined(OPENSSL_ARM) +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) typedef struct { uint32_t v[12]; /* for alignment; only using 10 */ @@ -285,4 +284,4 @@ void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]) { fe1305x2_tobytearray(mac, h); } -#endif /* OPENSSL_ARM */ +#endif /* OPENSSL_ARM && !OPENSSL_NO_ASM */ diff --git a/crypto/poly1305/poly1305_arm_asm.S b/crypto/poly1305/poly1305_arm_asm.S index 9cf7656..9d87413 100644 --- a/crypto/poly1305/poly1305_arm_asm.S +++ b/crypto/poly1305/poly1305_arm_asm.S @@ -1,4 +1,4 @@ -#if defined(__arm__) +#if defined(__arm__) && !defined(OPENSSL_NO_ASM) # This implementation was taken from the public domain, neon2 version in # SUPERCOP by D. J. Bernstein and Peter Schwabe. @@ -2012,4 +2012,4 @@ vst1.8 d4,[r0,: 64] add sp,sp,#0 bx lr -#endif +#endif /* __arm__ && !OPENSSL_NO_ASM */ diff --git a/include/openssl/base.h b/include/openssl/base.h index bee4030..079b1c4 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h @@ -63,6 +63,11 @@ #include <openssl/opensslfeatures.h> +#if defined(__cplusplus) +extern "C" { +#endif + + #if defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) #define OPENSSL_64_BIT #define OPENSSL_X86_64 @@ -205,4 +210,8 @@ typedef struct x509_store_st X509_STORE; typedef void *OPENSSL_BLOCK; +#if defined(__cplusplus) +} /* extern C */ +#endif + #endif /* OPENSSL_HEADER_BASE_H */ diff --git a/include/openssl/pqueue.h b/include/openssl/pqueue.h index af6f7f1..ceb1fa2 100644 --- a/include/openssl/pqueue.h +++ b/include/openssl/pqueue.h @@ -84,11 +84,11 @@ typedef struct _pitem *piterator; /* pqueue_new allocates a fresh, empty priority queue object and returns it, or * NULL on error. */ -pqueue pqueue_new(void); +OPENSSL_EXPORT pqueue pqueue_new(void); /* pqueue_free frees |pq| but not any of the items it points to. Thus |pq| must * be empty or a memory leak will occur. */ -void pqueue_free(pqueue pq); +OPENSSL_EXPORT void pqueue_free(pqueue pq); /* Creating and freeing items. */ @@ -97,47 +97,46 @@ void pqueue_free(pqueue pq); * has a priority given by |prio64be|, which is a 64-bit, unsigned number * expressed in big-endian form. It returns the fresh item, or NULL on * error. */ -pitem *pitem_new(uint8_t prio64be[8], void *data); +OPENSSL_EXPORT pitem *pitem_new(uint8_t prio64be[8], void *data); /* pitem_free frees |item|, but not any data that it points to. */ -void pitem_free(pitem *item); +OPENSSL_EXPORT void pitem_free(pitem *item); /* Queue accessor functions */ /* pqueue_peek returns the item with the smallest priority from |pq|, or NULL * if empty. */ -pitem *pqueue_peek(pqueue pq); +OPENSSL_EXPORT pitem *pqueue_peek(pqueue pq); /* pqueue_find returns the item whose priority matches |prio64be| or NULL if no * such item exists. */ -pitem *pqueue_find(pqueue pq, unsigned char *prio64be); +OPENSSL_EXPORT pitem *pqueue_find(pqueue pq, uint8_t *prio64be); /* Queue mutation functions */ /* pqueue_insert inserts |item| into |pq| and returns item. */ -pitem *pqueue_insert(pqueue pq, pitem *item); +OPENSSL_EXPORT pitem *pqueue_insert(pqueue pq, pitem *item); /* pqueue_pop takes the item with the least priority from |pq| and returns it, * or NULL if |pq| is empty. */ -pitem *pqueue_pop(pqueue pq); +OPENSSL_EXPORT pitem *pqueue_pop(pqueue pq); /* pqueue_size returns the number of items in |pq|. */ -size_t pqueue_size(pqueue pq); +OPENSSL_EXPORT size_t pqueue_size(pqueue pq); /* Iterating */ /* pqueue_iterator returns an iterator that can be used to iterate over the * contents of the queue. */ -pitem *pqueue_iterator(pqueue pq); +OPENSSL_EXPORT piterator pqueue_iterator(pqueue pq); /* pqueue_next returns the current value of |iter| and advances it to the next * position. If the iterator has advanced over all the elements, it returns * NULL. */ -pitem *pqueue_next(piterator *iter); - +OPENSSL_EXPORT pitem *pqueue_next(piterator *iter); #if defined(__cplusplus) diff --git a/include/openssl/srtp.h b/include/openssl/srtp.h index 3e29e5d..c11608e 100644 --- a/include/openssl/srtp.h +++ b/include/openssl/srtp.h @@ -130,9 +130,23 @@ extern "C" { #define SRTP_NULL_SHA1_80 0x0005 #define SRTP_NULL_SHA1_32 0x0006 +/* SSL_CTX_set_tlsext_use_srtp enables SRTP for all SSL objects + * created from |ctx|. |profile| contains a colon-separated list of + * profile names. It returns zero on success and one on failure. + * + * WARNING: this function is dangerous because it breaks the usual + * return value convention. */ OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); + +/* SSL_set_tlsext_use_srtp enables SRTP for |ssl| with a profile list. + * |profile| contains a colon-separated list of profile names. It + * returns zero on success and one on failure. + * + * WARNING: this function is dangerous because it breaks the usual + * return value convention. */ OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); + OPENSSL_EXPORT SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); OPENSSL_EXPORT STACK_OF(SRTP_PROTECTION_PROFILE) * diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 70afbd4..66904fb 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -471,33 +471,21 @@ struct ssl_session_st #endif -#define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L -#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L -/* Allow initial connection to servers that don't support RI */ +/* SSL_OP_LEGACY_SERVER_CONNECT allows initial connection to servers + * that don't support RI */ #define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L -#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L -#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L -#define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040L -#define SSL_OP_TLS_D5_BUG 0x00000100L -#define SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200L -/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */ -#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +/* SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER allows for record sizes + * SSL3_RT_MAX_EXTRA bytes above the maximum record size. */ +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L -/* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS is vestigial. Previously it disabled the - * insertion of empty records in CBC mode, but the empty records were commonly - * misinterpreted as EOF by other TLS stacks and so this was disabled by - * SSL_OP_ALL. - * - * This has been replaced by 1/n-1 record splitting, which is enabled by - * SSL_MODE_CBC_RECORD_SPLITTING in SSL_set_mode. This involves sending a - * one-byte record rather than an empty record and has much better - * compatibility. */ -#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800L /* added in 0.9.6e */ +/* SSL_OP_TLS_D5_BUG accepts an RSAClientKeyExchange in TLS encoded as + * SSL3, without a length prefix. */ +#define SSL_OP_TLS_D5_BUG 0x00000100L -/* SSL_OP_ALL: various bug workarounds that should be rather harmless. - * This used to be 0x000FFFFFL before 0.9.7. */ -#define SSL_OP_ALL 0x80000BFFL +/* SSL_OP_ALL enables the above bug workarounds that should be rather + * harmless. */ +#define SSL_OP_ALL 0x00000BFFL /* DTLS options */ #define SSL_OP_NO_QUERY_MTU 0x00001000L @@ -689,6 +677,14 @@ OPENSSL_EXPORT void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int v #define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) #define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +/* SSL_CTX_set_keylog_bio sets configures all SSL objects attached to |ctx| to + * log session material to |keylog_bio|. This is intended for debugging use with + * tools like Wireshark. |ctx| takes ownership of |keylog_bio|. + * + * The format is described in + * https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. */ +void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio); + struct ssl_aead_ctx_st; typedef struct ssl_aead_ctx_st SSL_AEAD_CTX; @@ -1033,6 +1029,11 @@ struct ssl_ctx_st /* If true, a client will request a stapled OCSP response. */ char ocsp_stapling_enabled; + + /* If not NULL, session key material will be logged to this BIO for + * debugging purposes. The format matches NSS's and is readable by + * Wireshark. */ + BIO *keylog_bio; }; #endif @@ -1375,12 +1376,9 @@ struct ssl_st void *arg); void *tlsext_debug_arg; char *tlsext_hostname; - int servername_done; /* no further mod of servername - 0 : call the servername extension callback. - 1 : prepare 2, allow last ack just after in server callback. - 2 : don't call servername callback, no ack in server hello - */ - + /* should_ack_sni is true if the SNI extension should be acked. This is + * only used by a server. */ + char should_ack_sni; /* RFC4507 session ticket expected to be received or sent */ int tlsext_ticket_expected; size_t tlsext_ecpointformatlist_length; @@ -2477,6 +2475,8 @@ OPENSSL_EXPORT void ERR_load_SSL_strings(void); #define SSL_F_ssl3_expect_change_cipher_spec 282 #define SSL_F_ssl23_get_v2_client_hello 283 #define SSL_F_ssl3_cert_verify_hash 284 +#define SSL_F_ssl_ctx_log_rsa_client_key_exchange 285 +#define SSL_F_ssl_ctx_log_master_secret 286 #define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 100 #define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 101 #define SSL_R_INVALID_NULL_CMD_NAME 102 diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h index 44f9367..3aea752 100644 --- a/include/openssl/ssl3.h +++ b/include/openssl/ssl3.h @@ -340,7 +340,6 @@ typedef struct ssl3_buffer_st #define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 #define SSL3_FLAGS_POP_BUFFER 0x0004 -#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 /* TODO(davidben): This flag can probably be merged into s3->change_cipher_spec * to something tri-state. (Normal / Expect CCS / Between CCS and Finished). */ #define SSL3_FLAGS_EXPECT_CCS 0x0080 diff --git a/ssl/d1_both.c b/ssl/d1_both.c index caa18d1..2d944d8 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -1165,7 +1165,6 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, saved_state.write_hash = s->write_hash; saved_state.session = s->session; saved_state.epoch = s->d1->w_epoch; - saved_state.epoch = s->d1->w_epoch; s->d1->retransmitting = 1; diff --git a/ssl/d1_enc.c b/ssl/d1_enc.c index 70b74b8..dec0ea5 100644 --- a/ssl/d1_enc.c +++ b/ssl/d1_enc.c @@ -202,11 +202,6 @@ int dtls1_enc(SSL *s, int send) /* we need to add 'i' padding bytes of value j */ j=i-1; - if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) - { - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - j++; - } for (k=(int)l; k<(int)(l+i); k++) rec->input[k]=j; l+=i; diff --git a/ssl/d1_srtp.c b/ssl/d1_srtp.c index 2652f84..1f909de 100644 --- a/ssl/d1_srtp.c +++ b/ssl/d1_srtp.c @@ -161,13 +161,13 @@ static int find_profile_by_name(char *profile_name, len)) { *pptr=p; - return 0; + return 1; } p++; } - return 1; + return 0; } static int find_profile_by_num(unsigned profile_num, @@ -181,12 +181,12 @@ static int find_profile_by_num(unsigned profile_num, if(p->id == profile_num) { *pptr=p; - return 0; + return 1; } p++; } - return 1; + return 0; } static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out) @@ -201,14 +201,14 @@ static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTE if(!(profiles=sk_SRTP_PROTECTION_PROFILE_new_null())) { OPENSSL_PUT_ERROR(SSL, ssl_ctx_make_profiles, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); - return 1; + return 0; } do { col=strchr(ptr,':'); - if(!find_profile_by_name(ptr,&p, + if(find_profile_by_name(ptr,&p, col ? col-ptr : (int)strlen(ptr))) { sk_SRTP_PROTECTION_PROFILE_push(profiles,p); @@ -216,7 +216,7 @@ static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTE else { OPENSSL_PUT_ERROR(SSL, ssl_ctx_make_profiles, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); - return 1; + return 0; } if(col) ptr=col+1; @@ -224,17 +224,19 @@ static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTE *out=profiles; - return 0; + return 1; } int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,const char *profiles) { - return ssl_ctx_make_profiles(profiles,&ctx->srtp_profiles); + /* This API inverts its return value. */ + return !ssl_ctx_make_profiles(profiles,&ctx->srtp_profiles); } int SSL_set_tlsext_use_srtp(SSL *s,const char *profiles) { - return ssl_ctx_make_profiles(profiles,&s->srtp_profiles); + /* This API inverts its return value. */ + return !ssl_ctx_make_profiles(profiles,&s->srtp_profiles); } @@ -278,13 +280,13 @@ int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int max if(ct==0) { OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_use_srtp_ext, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); - return 1; + return 0; } if((2 + ct*2 + 1) > maxlen) { OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_use_srtp_ext, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); - return 1; + return 0; } /* Add the length */ @@ -301,7 +303,7 @@ int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int max *len=2 + ct*2 + 1; - return 0; + return 1; } @@ -335,7 +337,7 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert) goto done; } - if (!find_profile_by_num(profile_id, &cprof)) + if (find_profile_by_num(profile_id, &cprof)) { sk_SRTP_PROTECTION_PROFILE_push(clnt, cprof); } @@ -381,13 +383,13 @@ int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int max if(maxlen < 5) { OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_use_srtp_ext, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); - return 1; + return 0; } if(s->srtp_profile==0) { OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_use_srtp_ext, SSL_R_USE_SRTP_NOT_NEGOTIATED); - return 1; + return 0; } s2n(2, p); s2n(s->srtp_profile->id,p); @@ -395,7 +397,7 @@ int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int max } *len=5; - return 0; + return 1; } diff --git a/ssl/pqueue/CMakeLists.txt b/ssl/pqueue/CMakeLists.txt index 58963ff..6049350 100644 --- a/ssl/pqueue/CMakeLists.txt +++ b/ssl/pqueue/CMakeLists.txt @@ -7,3 +7,11 @@ add_library( pqueue.c ) + +add_executable( + pqueue_test + + pqueue_test.c +) + +target_link_libraries(pqueue_test ssl) diff --git a/ssl/pqueue/pqueue.c b/ssl/pqueue/pqueue.c index 4c68cb1..4c94355 100644 --- a/ssl/pqueue/pqueue.c +++ b/ssl/pqueue/pqueue.c @@ -111,7 +111,7 @@ pitem *pqueue_find(pqueue_s *pq, uint8_t *prio64be) { pitem *curr; for (curr = pq->items; curr; curr = curr->next) { - if (memcmp(curr->priority, prio64be, 8) == 0) { + if (memcmp(curr->priority, prio64be, sizeof(curr->priority)) == 0) { return curr; } } @@ -130,9 +130,9 @@ size_t pqueue_size(pqueue_s *pq) { return count; } -pitem *pqueue_iterator(pqueue_s *pq) { return pq->items; } +piterator pqueue_iterator(pqueue_s *pq) { return pq->items; } -pitem *pqueue_next(pitem **item) { +pitem *pqueue_next(piterator *item) { pitem *ret; if (item == NULL || *item == NULL) { @@ -156,9 +156,9 @@ pitem *pqueue_insert(pqueue_s *pq, pitem *item) { for (curr = NULL, next = pq->items; next != NULL; curr = next, next = next->next) { /* we can compare 64-bit value in big-endian encoding with memcmp. */ - int cmp = memcmp(next->priority, item->priority, 8); - if (cmp > 0) /* next > item */ - { + int cmp = memcmp(next->priority, item->priority, sizeof(item->priority)); + if (cmp > 0) { + /* next > item */ item->next = next; if (curr == NULL) { @@ -168,8 +168,10 @@ pitem *pqueue_insert(pqueue_s *pq, pitem *item) { } return item; - } else if (cmp == 0) /* duplicates not allowed */ + } else if (cmp == 0) { + /* duplicates not allowed */ return NULL; + } } item->next = NULL; diff --git a/ssl/pqueue/pqueue_test.c b/ssl/pqueue/pqueue_test.c new file mode 100644 index 0000000..112afed --- /dev/null +++ b/ssl/pqueue/pqueue_test.c @@ -0,0 +1,88 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <stdio.h> +#include <string.h> + +#include <openssl/pqueue.h> + + +static int trivial() { + pqueue q = pqueue_new(); + if (q == NULL) { + return 0; + } + int32_t data = 0xdeadbeef; + uint8_t priority[8] = {0}; + pitem *item = pitem_new(priority, &data); + if (item == NULL || + pqueue_insert(q, item) != item || + pqueue_size(q) != 1 || + pqueue_peek(q) != item || + pqueue_pop(q) != item || + pqueue_size(q) != 0 || + pqueue_pop(q) != NULL) { + return 0; + } + pitem_free(item); + pqueue_free(q); + return 1; +} + +#define NUM_ITEMS 10 + +static int fixed_random() { + /* Random order of 10 elements, chosen by + random.choice(list(itertools.permutations(range(10)))) */ + int ordering[NUM_ITEMS] = {9, 6, 3, 4, 0, 2, 7, 1, 8, 5}; + int i; + pqueue q = pqueue_new(); + if (q == NULL) { + return 0; + } + uint8_t priority[8] = {0}; + /* Insert the elements */ + for (i = 0; i < NUM_ITEMS; i++) { + priority[7] = ordering[i]; + pitem *item = pitem_new(priority, &ordering[i]); + pqueue_insert(q, item); + } + piterator iter = pqueue_iterator(q); + pitem *curr = pqueue_next(&iter); + if (curr == NULL) { + return 0; + } + while (1) { + pitem *next = pqueue_next(&iter); + if (next == NULL) { + break; + } + int *curr_data = (int*)curr->data; + int *next_data = (int*)next->data; + if (*curr_data >= *next_data) { + return 0; + } + curr = next; + } + return 1; +} + +int main(void) { + if (!trivial() || !fixed_random()) { + return 1; + } + + printf("PASS\n"); + return 0; +} diff --git a/ssl/s3_both.c b/ssl/s3_both.c index f5bd284..6604fc7 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -168,6 +168,14 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) memcpy(p, s->s3->tmp.finish_md, i); l=i; + /* Log the master secret, if logging is enabled. */ + if (!ssl_ctx_log_master_secret(s->ctx, + s->s3->client_random, SSL3_RANDOM_SIZE, + s->session->master_key, s->session->master_key_length)) + { + return 0; + } + /* Copy the finished so we can use it for renegotiation checks */ if(s->type == SSL_ST_CONNECT) @@ -688,8 +696,9 @@ int ssl3_setup_write_buffer(SSL *s) len = s->max_send_fragment + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) - len += headerlen + align + /* Account for 1/n-1 record splitting. */ + if (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) + len += headerlen + align + 1 + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; if ((p=OPENSSL_malloc(len)) == NULL) diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c index e80734e..6a0de9c 100644 --- a/ssl/s3_cbc.c +++ b/ssl/s3_cbc.c @@ -52,7 +52,6 @@ #include <assert.h> -#include <openssl/md5.h> #include <openssl/obj.h> #include <openssl/sha.h> @@ -166,28 +165,6 @@ int tls1_cbc_remove_padding(const SSL* s, padding_length = rec->data[rec->length-1]; - if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) - { - /* First packet is even in size, so check */ - if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) && - !(padding_length & 1)) - { - s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; - } - if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && - padding_length > 0) - { - padding_length--; - } - } - - if (EVP_CIPHER_flags(s->enc_read_ctx->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER) - { - /* padding is already verified */ - rec->length -= padding_length + 1; - return 1; - } - good = constant_time_ge(rec->length, overhead+padding_length); /* The padding consists of a length byte at the end of the record and * then that many bytes of padding, all with the same value as the @@ -334,15 +311,6 @@ void ssl3_cbc_copy_mac(unsigned char* out, /* These functions serialize the state of a hash and thus perform the standard * "final" operation without adding the padding and length that such a function * typically does. */ -static void tls1_md5_final_raw(void* ctx, unsigned char *md_out) - { - MD5_CTX *md5 = ctx; - u32toLE(md5->A, md_out); - u32toLE(md5->B, md_out); - u32toLE(md5->C, md_out); - u32toLE(md5->D, md_out); - } - static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out) { SHA_CTX *sha1 = ctx; @@ -386,12 +354,9 @@ char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) { switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: case NID_sha1: - case NID_sha224: case NID_sha256: case NID_sha384: - case NID_sha512: return 1; default: return 0; @@ -448,7 +413,6 @@ void ssl3_cbc_digest_record( /* mdLengthSize is the number of bytes in the length field that terminates * the hash. */ unsigned md_length_size = 8; - char length_is_big_endian = 1; /* This is a, hopefully redundant, check that allows us to forget about * many possible overflows later in this function. */ @@ -456,26 +420,12 @@ void ssl3_cbc_digest_record( switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: - MD5_Init((MD5_CTX*)md_state.c); - md_final_raw = tls1_md5_final_raw; - md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform; - md_size = 16; - sslv3_pad_length = 48; - length_is_big_endian = 0; - break; case NID_sha1: SHA1_Init((SHA_CTX*)md_state.c); md_final_raw = tls1_sha1_final_raw; md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform; md_size = 20; break; - case NID_sha224: - SHA224_Init((SHA256_CTX*)md_state.c); - md_final_raw = tls1_sha256_final_raw; - md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; - md_size = 224/8; - break; case NID_sha256: SHA256_Init((SHA256_CTX*)md_state.c); md_final_raw = tls1_sha256_final_raw; @@ -490,14 +440,6 @@ void ssl3_cbc_digest_record( md_block_size = 128; md_length_size = 16; break; - case NID_sha512: - SHA512_Init((SHA512_CTX*)md_state.c); - md_final_raw = tls1_sha512_final_raw; - md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; - md_size = 64; - md_block_size = 128; - md_length_size = 16; - break; default: /* ssl3_cbc_record_digest_supported should have been * called first to check that the hash function is @@ -599,22 +541,11 @@ void ssl3_cbc_digest_record( md_transform(md_state.c, hmac_pad); } - if (length_is_big_endian) - { - memset(length_bytes,0,md_length_size-4); - length_bytes[md_length_size-4] = (unsigned char)(bits>>24); - length_bytes[md_length_size-3] = (unsigned char)(bits>>16); - length_bytes[md_length_size-2] = (unsigned char)(bits>>8); - length_bytes[md_length_size-1] = (unsigned char)bits; - } - else - { - memset(length_bytes,0,md_length_size); - length_bytes[md_length_size-5] = (unsigned char)(bits>>24); - length_bytes[md_length_size-6] = (unsigned char)(bits>>16); - length_bytes[md_length_size-7] = (unsigned char)(bits>>8); - length_bytes[md_length_size-8] = (unsigned char)bits; - } + memset(length_bytes,0,md_length_size-4); + length_bytes[md_length_size-4] = (unsigned char)(bits>>24); + length_bytes[md_length_size-3] = (unsigned char)(bits>>16); + length_bytes[md_length_size-2] = (unsigned char)(bits>>8); + length_bytes[md_length_size-1] = (unsigned char)bits; if (k > 0) { @@ -622,8 +553,7 @@ void ssl3_cbc_digest_record( { /* The SSLv3 header is larger than a single block. * overhang is the number of bytes beyond a single - * block that the header consumes: either 7 bytes - * (SHA1) or 11 bytes (MD5). */ + * block that the header consumes: 7 bytes (SHA1). */ unsigned overhang = header_length-md_block_size; md_transform(md_state.c, header); memcpy(first_block, header + md_block_size, overhang); diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 44d26a7..cb9f95f 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -798,6 +798,7 @@ int ssl3_get_server_hello(SSL *s) CBS server_hello, server_random, session_id; uint16_t server_version, cipher_suite; uint8_t compression_method; + unsigned long mask_ssl; n=s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A, @@ -913,10 +914,16 @@ int ssl3_get_server_hello(SSL *s) OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNKNOWN_CIPHER_RETURNED); goto f_err; } + /* ct->mask_ssl was computed from client capabilities. Now + * that the final version is known, compute a new mask_ssl. */ + if (!SSL_USE_TLS1_2_CIPHERS(s)) + mask_ssl = SSL_TLSV1_2; + else + mask_ssl = 0; /* If it is a disabled cipher we didn't send it in client hello, * so return an error. */ - if (c->algorithm_ssl & ct->mask_ssl || + if (c->algorithm_ssl & mask_ssl || c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a) { @@ -2008,6 +2015,13 @@ int ssl3_send_client_key_exchange(SSL *s) goto err; } + /* Log the premaster secret, if logging is enabled. */ + if (!ssl_ctx_log_rsa_client_key_exchange(s->ctx, + p, n, tmp_buf, sizeof(tmp_buf))) + { + goto err; + } + /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION) { @@ -2229,9 +2243,8 @@ int ssl3_send_client_key_exchange(SSL *s) /* Free allocated memory */ BN_CTX_free(bn_ctx); - if (encodedPoint != NULL) OPENSSL_free(encodedPoint); - if (clnt_ecdh != NULL) - EC_KEY_free(clnt_ecdh); + OPENSSL_free(encodedPoint); + EC_KEY_free(clnt_ecdh); EVP_PKEY_free(srvr_pub_pkey); } else if (!(alg_k & SSL_kPSK) || ((alg_k & SSL_kPSK) && !(alg_a & SSL_aPSK))) diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index 12c5467..f5079a1 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -311,7 +311,7 @@ static int ssl3_get_record(SSL *s) extra=0; if (extra && !s->s3->init_extra) { - /* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER + /* An application error: SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER * set after ssl3_setup_buffers() was done */ OPENSSL_PUT_ERROR(SSL, ssl3_get_record, ERR_R_INTERNAL_ERROR); return -1; @@ -760,9 +760,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (eivlen <= 1) eivlen = 0; } - /* Need explicit part of IV for GCM mode */ - else if (mode == EVP_CIPH_GCM_MODE) - eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; else eivlen = 0; } diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 691b5fd..8361007 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -354,8 +354,7 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, if (!ssl_cipher_get_mac(s, md, mac_pkey_type, mac_secret_size)) return 0; - if ((*enc != NULL) && - (*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) && + if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef)) { if (s->ssl_version>>8 != TLS1_VERSION_MAJOR || diff --git a/ssl/ssl_error.c b/ssl/ssl_error.c index 20737a5..f6120dc 100644 --- a/ssl/ssl_error.c +++ b/ssl/ssl_error.c @@ -163,6 +163,8 @@ const ERR_STRING_DATA SSL_error_string_data[] = { {ERR_PACK(ERR_LIB_SSL, SSL_F_ssl_cipher_process_rulestr, 0), "ssl_cipher_process_rulestr"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_ssl_cipher_strength_sort, 0), "ssl_cipher_strength_sort"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_ssl_create_cipher_list, 0), "ssl_create_cipher_list"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_ssl_ctx_log_master_secret, 0), "ssl_ctx_log_master_secret"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_ssl_ctx_log_rsa_client_key_exchange, 0), "ssl_ctx_log_rsa_client_key_exchange"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_ssl_ctx_make_profiles, 0), "ssl_ctx_make_profiles"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_ssl_get_new_session, 0), "ssl_get_new_session"}, {ERR_PACK(ERR_LIB_SSL, SSL_F_ssl_get_prev_session, 0), "ssl_get_prev_session"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 58684b0..1ad825a 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1079,7 +1079,7 @@ int SSL_shutdown(SSL *s) return -1; } - if ((s != NULL) && !SSL_in_init(s)) + if (!SSL_in_init(s)) return(s->method->ssl_shutdown(s)); else return(1); @@ -2130,6 +2130,9 @@ void SSL_CTX_free(SSL_CTX *a) if (a->tlsext_channel_id_private) EVP_PKEY_free(a->tlsext_channel_id_private); + if (a->keylog_bio) + BIO_free(a->keylog_bio); + OPENSSL_free(a); } @@ -3088,6 +3091,122 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); } +void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio) + { + if (ctx->keylog_bio != NULL) + BIO_free(ctx->keylog_bio); + ctx->keylog_bio = keylog_bio; + } + +static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) + { + static const char hextable[] = "0123456789abcdef"; + uint8_t *out; + size_t i; + + if (!CBB_add_space(cbb, &out, in_len * 2)) + { + return 0; + } + + for (i = 0; i < in_len; i++) + { + *(out++) = (uint8_t)hextable[in[i] >> 4]; + *(out++) = (uint8_t)hextable[in[i] & 0xf]; + } + return 1; + } + +int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx, + const uint8_t *encrypted_premaster, size_t encrypted_premaster_len, + const uint8_t *premaster, size_t premaster_len) + { + BIO *bio = ctx->keylog_bio; + CBB cbb; + uint8_t *out; + size_t out_len; + int ret; + + if (bio == NULL) + { + return 1; + } + + if (encrypted_premaster_len < 8) + { + OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_rsa_client_key_exchange, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len*2 + 1)) + { + return 0; + } + if (!CBB_add_bytes(&cbb, (const uint8_t*)"RSA ", 4) || + /* Only the first 8 bytes of the encrypted premaster secret are + * logged. */ + !cbb_add_hex(&cbb, encrypted_premaster, 8) || + !CBB_add_bytes(&cbb, (const uint8_t*)" ", 1) || + !cbb_add_hex(&cbb, premaster, premaster_len) || + !CBB_add_bytes(&cbb, (const uint8_t*)"\n", 1) || + !CBB_finish(&cbb, &out, &out_len)) + { + CBB_cleanup(&cbb); + return 0; + } + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio); + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + + OPENSSL_free(out); + return ret; + } + +int ssl_ctx_log_master_secret(SSL_CTX *ctx, + const uint8_t *client_random, size_t client_random_len, + const uint8_t *master, size_t master_len) + { + BIO *bio = ctx->keylog_bio; + CBB cbb; + uint8_t *out; + size_t out_len; + int ret; + + if (bio == NULL) + { + return 1; + } + + if (client_random_len != 32) + { + OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_master_secret, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!CBB_init(&cbb, 14 + 64 + 1 + master_len*2 + 1)) + { + return 0; + } + if (!CBB_add_bytes(&cbb, (const uint8_t*)"CLIENT_RANDOM ", 14) || + !cbb_add_hex(&cbb, client_random, 32) || + !CBB_add_bytes(&cbb, (const uint8_t*)" ", 1) || + !cbb_add_hex(&cbb, master, master_len) || + !CBB_add_bytes(&cbb, (const uint8_t*)"\n", 1) || + !CBB_finish(&cbb, &out, &out_len)) + { + CBB_cleanup(&cbb); + return 0; + } + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio); + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + + OPENSSL_free(out); + return ret; + } + int SSL_cutthrough_complete(const SSL *s) { return (!s->server && /* cutthrough only applies to clients */ diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index ad2d843..2d10650 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1091,6 +1091,19 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, int idx); void tls1_set_cert_validity(SSL *s); +/* ssl_ctx_log_rsa_client_key_exchange logs |premaster| to |ctx|, if logging is + * enabled. It returns one on success and zero on failure. The entry is + * identified by the first 8 bytes of |encrypted_premaster|. */ +int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx, + const uint8_t *encrypted_premaster, size_t encrypted_premaster_len, + const uint8_t *premaster, size_t premaster_len); + +/* ssl_ctx_log_master_secret logs |master| to |ctx|, if logging is enabled. It + * returns one on success and zero on failure. The entry is identified by + * |client_random|. */ +int ssl_ctx_log_master_secret(SSL_CTX *ctx, + const uint8_t *client_random, size_t client_random_len, + const uint8_t *master, size_t master_len); int ssl3_can_cutthrough(const SSL *s); int ssl_get_max_version(const SSL *s); diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index a2d96d6..2f92524 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -521,11 +521,7 @@ int tls1_change_cipher_state(SSL *s, int which) else { key_len = EVP_CIPHER_key_length(cipher); - - if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) - iv_len = EVP_GCM_TLS_FIXED_IV_LEN; - else - iv_len = EVP_CIPHER_iv_length(cipher); + iv_len = EVP_CIPHER_iv_length(cipher); } key_data = s->s3->tmp.key_block; @@ -617,11 +613,7 @@ int tls1_setup_key_block(SSL *s) if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size)) goto cipher_unavailable_err; key_len = EVP_CIPHER_key_length(c); - - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) - iv_len = EVP_GCM_TLS_FIXED_IV_LEN; - else - iv_len = EVP_CIPHER_iv_length(c); + iv_len = EVP_CIPHER_iv_length(c); } s->s3->tmp.new_aead=aead; @@ -911,11 +903,6 @@ int tls1_enc(SSL *s, int send) /* we need to add 'i' padding bytes of value j */ j=i-1; - if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) - { - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - j++; - } for (k=(int)l; k<(int)(l+i); k++) rec->input[k]=j; l+=i; @@ -951,12 +938,6 @@ int tls1_enc(SSL *s, int send) ?(i<0) :(i==0)) return -1; /* AEAD can fail to verify MAC */ - if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send) - { - rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; - } #ifdef KSSL_DEBUG { diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 8fdd813..b9553a5 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1099,7 +1099,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c s2n(TLSEXT_TYPE_use_srtp,ret); s2n(el,ret); - if(ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) + if(!ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) { OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR); return NULL; @@ -1212,7 +1212,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c ret+=2; if (ret>=limit) return NULL; /* this really never occurs, but ... */ - if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL) + if (!s->hit && s->should_ack_sni && s->session->tlsext_hostname != NULL) { if ((long)(limit - ret - 4) < 0) return NULL; @@ -1296,7 +1296,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c s2n(TLSEXT_TYPE_use_srtp,ret); s2n(el,ret); - if(ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) + if(!ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) { OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR); return NULL; @@ -1418,7 +1418,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) CBS extensions; size_t i; - s->servername_done = 0; + s->should_ack_sni = 0; s->s3->next_proto_neg_seen = 0; s->s3->tmp.certificate_status_expected = 0; @@ -1506,6 +1506,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) if (type == TLSEXT_TYPE_server_name) { CBS server_name_list; + char have_seen_host_name = 0; if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) || CBS_len(&server_name_list) < 1 || @@ -1532,45 +1533,49 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) if (name_type != TLSEXT_NAMETYPE_host_name) continue; + if (have_seen_host_name) + { + /* The ServerNameList MUST NOT contain + * more than one name of the same + * name_type. */ + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + have_seen_host_name = 1; + + if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name) || + CBS_len(&host_name) < 1) + { + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + if (CBS_len(&host_name) > TLSEXT_MAXLEN_host_name || + CBS_contains_zero_byte(&host_name)) + { + *out_alert = SSL_AD_UNRECOGNIZED_NAME; + return 0; + } + if (!s->hit) { + assert(s->session->tlsext_hostname == NULL); if (s->session->tlsext_hostname) { - /* The ServerNameList MUST NOT - contain more than one name of - the same name_type. */ + /* This should be impossible. */ *out_alert = SSL_AD_DECODE_ERROR; return 0; } - if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name) || - CBS_len(&host_name) < 1) - { - *out_alert = SSL_AD_DECODE_ERROR; - return 0; - } - - if (CBS_len(&host_name) > TLSEXT_MAXLEN_host_name || - CBS_contains_zero_byte(&host_name)) - { - *out_alert = SSL_AD_UNRECOGNIZED_NAME; - return 0; - } - /* Copy the hostname as a string. */ if (!CBS_strdup(&host_name, &s->session->tlsext_hostname)) { *out_alert = SSL_AD_INTERNAL_ERROR; return 0; } - s->servername_done = 1; - } - else - { - s->servername_done = s->session->tlsext_hostname - && strlen(s->session->tlsext_hostname) == CBS_len(&host_name) - && strncmp(s->session->tlsext_hostname, - (char *)CBS_data(&host_name), CBS_len(&host_name)) == 0; + + s->should_ack_sni = 1; } } } @@ -2147,12 +2152,14 @@ static int ssl_check_clienthello_tlsext(SSL *s) case SSL_TLSEXT_ERR_ALERT_WARNING: ssl3_send_alert(s,SSL3_AL_WARNING,al); - return 1; - + return 1; + case SSL_TLSEXT_ERR_NOACK: - s->servername_done=0; - default: - return 1; + s->should_ack_sni = 0; + return 1; + + default: + return 1; } } @@ -2200,17 +2207,15 @@ static int ssl_check_serverhello_tlsext(SSL *s) switch (ret) { case SSL_TLSEXT_ERR_ALERT_FATAL: - ssl3_send_alert(s,SSL3_AL_FATAL,al); + ssl3_send_alert(s,SSL3_AL_FATAL,al); return -1; case SSL_TLSEXT_ERR_ALERT_WARNING: ssl3_send_alert(s,SSL3_AL_WARNING,al); - return 1; - - case SSL_TLSEXT_ERR_NOACK: - s->servername_done=0; - default: - return 1; + return 1; + + default: + return 1; } } diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index 8955324..0459afc 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc @@ -316,6 +316,9 @@ static int do_exchange(SSL_SESSION **out_session, if (config->cookie_exchange) { SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE); } + if (config->tls_d5_bug) { + SSL_set_options(ssl, SSL_OP_TLS_D5_BUG); + } if (!config->expected_channel_id.empty()) { SSL_enable_tls_channel_id(ssl); } diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go index 78e484f..f22f95a 100644 --- a/ssl/test/runner/common.go +++ b/ssl/test/runner/common.go @@ -440,6 +440,15 @@ type ProtocolBugs struct { // isn't sent until we receive an application data record // from the peer. ExpectFalseStart bool + + // SSL3RSAKeyExchange causes the client to always send an RSA + // ClientKeyExchange message without the two-byte length + // prefix, as if it were SSL3. + SSL3RSAKeyExchange bool + + // SkipCipherVersionCheck causes the server to negotiate + // TLS 1.2 ciphers in earlier versions of TLS. + SkipCipherVersionCheck bool } func (c *Config) serverInit() { diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index 855f992..6d61fd5 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go @@ -832,7 +832,7 @@ func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version if (candidate.flags&suiteECDSA != 0) != ecdsaOk { continue } - if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { + if !c.config.Bugs.SkipCipherVersionCheck && version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { continue } if c.isDTLS && candidate.flags&suiteNoDTLS != 0 { diff --git a/ssl/test/runner/key_agreement.go b/ssl/test/runner/key_agreement.go index 2e2eff4..f8ba1f8 100644 --- a/ssl/test/runner/key_agreement.go +++ b/ssl/test/runner/key_agreement.go @@ -87,7 +87,7 @@ func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello return nil, nil, err } ckx := new(clientKeyExchangeMsg) - if clientHello.vers != VersionSSL30 { + if clientHello.vers != VersionSSL30 && !config.Bugs.SSL3RSAKeyExchange { ckx.ciphertext = make([]byte, len(encrypted)+2) ckx.ciphertext[0] = byte(len(encrypted) >> 8) ckx.ciphertext[1] = byte(len(encrypted)) diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 79bf99c..9322592 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -483,6 +483,18 @@ var testCases = []testCase{ shouldFail: true, expectedError: ":HTTPS_PROXY_REQUEST:", }, + { + name: "SkipCipherVersionCheck", + config: Config{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + MaxVersion: VersionTLS11, + Bugs: ProtocolBugs{ + SkipCipherVersionCheck: true, + }, + }, + shouldFail: true, + expectedError: ":WRONG_CIPHER_RETURNED:", + }, } func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int) error { @@ -1311,6 +1323,40 @@ func addVersionNegotiationTests() { } } +func addD5BugTests() { + testCases = append(testCases, testCase{ + testType: serverTest, + name: "D5Bug-NoQuirk-Reject", + config: Config{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + Bugs: ProtocolBugs{ + SSL3RSAKeyExchange: true, + }, + }, + shouldFail: true, + expectedError: ":TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG:", + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "D5Bug-Quirk-Normal", + config: Config{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + }, + flags: []string{"-tls-d5-bug"}, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "D5Bug-Quirk-Bug", + config: Config{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + Bugs: ProtocolBugs{ + SSL3RSAKeyExchange: true, + }, + }, + flags: []string{"-tls-d5-bug"}, + }) +} + func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sync.WaitGroup) { defer wg.Done() @@ -1363,6 +1409,7 @@ func main() { addCBCSplittingTests() addClientAuthTests() addVersionNegotiationTests() + addD5BugTests() for _, async := range []bool{false, true} { for _, splitHandshake := range []bool{false, true} { for _, protocol := range []protocol{tls, dtls} { diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc index 9d1ffc9..41188af 100644 --- a/ssl/test/test_config.cc +++ b/ssl/test/test_config.cc @@ -54,6 +54,7 @@ const BoolFlag kBoolFlags[] = { { "-no-ssl3", &TestConfig::no_ssl3 }, { "-cookie-exchange", &TestConfig::cookie_exchange }, { "-shim-writes-first", &TestConfig::shim_writes_first }, + { "-tls-d5-bug", &TestConfig::tls_d5_bug }, }; const size_t kNumBoolFlags = sizeof(kBoolFlags) / sizeof(kBoolFlags[0]); @@ -95,7 +96,8 @@ TestConfig::TestConfig() no_tls1(false), no_ssl3(false), cookie_exchange(false), - shim_writes_first(false) { + shim_writes_first(false), + tls_d5_bug(false) { } bool ParseConfig(int argc, char **argv, TestConfig *out_config) { diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h index d79b7f4..208f19b 100644 --- a/ssl/test/test_config.h +++ b/ssl/test/test_config.h @@ -46,6 +46,7 @@ struct TestConfig { std::string expected_channel_id; std::string send_channel_id; bool shim_writes_first; + bool tls_d5_bug; }; bool ParseConfig(int argc, char **argv, TestConfig *out_config); diff --git a/tool/client.cc b/tool/client.cc index 5acc8b1..8aef559 100644 --- a/tool/client.cc +++ b/tool/client.cc @@ -18,6 +18,7 @@ #include <vector> #include <errno.h> +#include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> @@ -253,6 +254,16 @@ bool Client(const std::vector<std::string> &args) { SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); + const char *keylog_file = getenv("SSLKEYLOGFILE"); + if (keylog_file) { + BIO *keylog_bio = BIO_new_file(keylog_file, "a"); + if (!keylog_bio) { + ERR_print_errors_cb(PrintErrorCallback, stderr); + return false; + } + SSL_CTX_set_keylog_bio(ctx, keylog_bio); + } + int sock = -1; if (!Connect(&sock, args_map["-connect"])) { return false; diff --git a/util/all_tests.sh b/util/all_tests.sh index 43dd880..e4f3126 100644 --- a/util/all_tests.sh +++ b/util/all_tests.sh @@ -20,33 +20,34 @@ if [ "$#" -ge 1 ]; then fi TESTS=" +./crypto/base64/base64_test +./crypto/bio/bio_test +./crypto/bn/bn_test +./crypto/bytestring/bytestring_test ./crypto/cipher/aead_test aes-128-gcm $SRC/crypto/cipher/aes_128_gcm_tests.txt +./crypto/cipher/aead_test aes-128-key-wrap $SRC/crypto/cipher/aes_128_key_wrap_tests.txt ./crypto/cipher/aead_test aes-256-gcm $SRC/crypto/cipher/aes_256_gcm_tests.txt +./crypto/cipher/aead_test aes-256-key-wrap $SRC/crypto/cipher/aes_256_key_wrap_tests.txt ./crypto/cipher/aead_test chacha20-poly1305 $SRC/crypto/cipher/chacha20_poly1305_tests.txt ./crypto/cipher/aead_test rc4-md5 $SRC/crypto/cipher/rc4_md5_tests.txt -./crypto/cipher/aead_test aes-128-key-wrap $SRC/crypto/cipher/aes_128_key_wrap_tests.txt -./crypto/cipher/aead_test aes-256-key-wrap $SRC/crypto/cipher/aes_256_key_wrap_tests.txt -./crypto/base64/base64_test -./crypto/bio/bio_test -./crypto/bn/bn_test ./crypto/cipher/cipher_test $SRC/crypto/cipher/cipher_test.txt ./crypto/dh/dh_test ./crypto/dsa/dsa_test -./crypto/err/err_test ./crypto/ec/example_mul ./crypto/ecdsa/ecdsa_test +./crypto/err/err_test ./crypto/evp/example_sign ./crypto/hmac/hmac_test ./crypto/lhash/lhash_test ./crypto/md5/md5_test ./crypto/modes/gcm_test +./crypto/pkcs8/pkcs12_test ./crypto/rsa/rsa_test ./crypto/sha/sha1_test +./crypto/x509/pkcs7_test ./crypto/x509v3/tab_test ./crypto/x509v3/v3name_test -./crypto/bytestring/bytestring_test -./crypto/x509/pkcs7_test -./crypto/pkcs8/pkcs12_test +./ssl/pqueue/pqueue_test ./ssl/ssl_test " diff --git a/util/doc.config b/util/doc.config index 7c0835d..4b5f3b1 100644 --- a/util/doc.config +++ b/util/doc.config @@ -3,45 +3,45 @@ "Sections": [{ "Name": "Low-level infrastructure", "Headers": [ - "crypto/base64/base64.h", - "crypto/bio/bio.h", - "crypto/buf/buf.h", - "crypto/err/err.h", - "crypto/cpu.h", - "crypto/ex_data.h", - "crypto/lhash/lhash.h", - "crypto/mem.h", - "crypto/obj/obj.h", - "crypto/stack/stack.h", - "crypto/thread.h", - "crypto/time_support.h" + "include/openssl/base64.h", + "include/openssl/bio.h", + "include/openssl/buf.h", + "include/openssl/err.h", + "include/openssl/cpu.h", + "include/openssl/ex_data.h", + "include/openssl/lhash.h", + "include/openssl/mem.h", + "include/openssl/obj.h", + "include/openssl/stack.h", + "include/openssl/thread.h", + "include/openssl/time_support.h" ] },{ "Name": "Low-level crypto primitives", "Headers": [ - "crypto/aes/aes.h", - "crypto/bn/bn.h", - "crypto/des/des.h", - "crypto/dh/dh.h", - "crypto/dsa/dsa.h", - "crypto/ec/ec.h", - "crypto/ec/ec_key.h", - "crypto/ecdh/ecdh.h", - "crypto/ecdsa/ecdsa.h", - "crypto/engine/engine.h", - "crypto/hmac/hmac.h", - "crypto/md5/md5.h", - "crypto/modes/modes.h", - "crypto/rc4/rc4.h", - "crypto/rsa/rsa.h", - "crypto/sha/sha.h" + "include/openssl/aes.h", + "include/openssl/bn.h", + "include/openssl/des.h", + "include/openssl/dh.h", + "include/openssl/dsa.h", + "include/openssl/ec.h", + "include/openssl/ec_key.h", + "include/openssl/ecdh.h", + "include/openssl/ecdsa.h", + "include/openssl/engine.h", + "include/openssl/hmac.h", + "include/openssl/md5.h", + "include/openssl/modes.h", + "include/openssl/rc4.h", + "include/openssl/rsa.h", + "include/openssl/sha.h" ] },{ "Name": "Crypto interfaces", "Headers": [ - "crypto/digest/digest.h", - "crypto/cipher/cipher.h", - "crypto/evp/evp.h" + "include/openssl/digest.h", + "include/openssl/cipher.h", + "include/openssl/evp.h" ] }] } |