X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fthird_party%2Fboringssl%2Fsrc%2Fssl%2Fssl_lib.c;h=720ab54d6b3902e3db069d234b04f55e3771adcf;hb=3545e9f2671f595d2a2f3ee75ca0393b01e35ef6;hp=182b9ebb7e56d30c3757a5d0030bebc81850000b;hpb=7d210d4c7e9ba36e635eabc5b5780495f8a63292;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/third_party/boringssl/src/ssl/ssl_lib.c b/src/third_party/boringssl/src/ssl/ssl_lib.c index 182b9eb..720ab54 100644 --- a/src/third_party/boringssl/src/ssl/ssl_lib.c +++ b/src/third_party/boringssl/src/ssl/ssl_lib.c @@ -172,6 +172,13 @@ SSL3_ENC_METHOD ssl3_undef_enc_method={ int use_context)) ssl_undefined_function, }; +/* Some error codes are special. Ensure the make_errors.go script + * never regresses this. */ +OPENSSL_COMPILE_ASSERT( + SSL_R_TLSV1_ALERT_NO_RENEGOTIATION == + SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET, + ssl_alert_reason_code_mismatch); + int SSL_clear(SSL *s) { @@ -187,7 +194,6 @@ int SSL_clear(SSL *s) s->session=NULL; } - s->error=0; s->hit=0; s->shutdown=0; @@ -337,15 +343,8 @@ SSL *SSL_new(SSL_CTX *ctx) s->tlsext_debug_cb = 0; s->tlsext_debug_arg = NULL; s->tlsext_ticket_expected = 0; - s->tlsext_status_type = -1; - s->tlsext_status_expected = 0; - s->tlsext_ocsp_ids = NULL; - s->tlsext_ocsp_exts = NULL; - s->tlsext_ocsp_resp = NULL; - s->tlsext_ocsp_resplen = -1; CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); s->initial_ctx=ctx; -#ifndef OPENSSL_NO_EC if (ctx->tlsext_ecpointformatlist) { s->tlsext_ecpointformatlist = @@ -366,10 +365,7 @@ SSL *SSL_new(SSL_CTX *ctx) s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length; } -#endif -# ifndef OPENSSL_NO_NEXTPROTONEG s->next_proto_negotiated = NULL; -# endif if (s->ctx->alpn_client_proto_list) { @@ -405,6 +401,12 @@ SSL *SSL_new(SSL_CTX *ctx) s->psk_client_callback=ctx->psk_client_callback; s->psk_server_callback=ctx->psk_server_callback; + if (!s->server) + { + s->signed_cert_timestamps_enabled = s->ctx->signed_cert_timestamps_enabled; + s->ocsp_stapling_enabled = s->ctx->ocsp_stapling_enabled; + } + return(s); err: if (s != NULL) @@ -670,20 +672,8 @@ void SSL_free(SSL *s) if (s->tlsext_hostname) OPENSSL_free(s->tlsext_hostname); if (s->initial_ctx) SSL_CTX_free(s->initial_ctx); -#ifndef OPENSSL_NO_EC if (s->tlsext_ecpointformatlist) OPENSSL_free(s->tlsext_ecpointformatlist); if (s->tlsext_ellipticcurvelist) OPENSSL_free(s->tlsext_ellipticcurvelist); -#endif /* OPENSSL_NO_EC */ - if (s->tlsext_ocsp_exts) - sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, - X509_EXTENSION_free); - /* TODO(fork): OCSP support */ -#if 0 - if (s->tlsext_ocsp_ids) - sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); -#endif - if (s->tlsext_ocsp_resp) - OPENSSL_free(s->tlsext_ocsp_resp); if (s->alpn_client_proto_list) OPENSSL_free(s->alpn_client_proto_list); if (s->tlsext_channel_id_private) @@ -699,14 +689,17 @@ void SSL_free(SSL *s) if (s->ctx) SSL_CTX_free(s->ctx); -#if !defined(OPENSSL_NO_NEXTPROTONEG) if (s->next_proto_negotiated) OPENSSL_free(s->next_proto_negotiated); -#endif if (s->srtp_profiles) sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); + if (s->tlsext_session_ticket) + { + OPENSSL_free(s->tlsext_session_ticket); + } + OPENSSL_free(s); } @@ -1028,7 +1021,7 @@ int SSL_connect(SSL *s) long SSL_get_default_timeout(const SSL *s) { - return(s->method->get_timeout()); + return SSL_DEFAULT_SESSION_TIMEOUT; } int SSL_read(SSL *s,void *buf,int num) @@ -1093,7 +1086,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); @@ -1158,11 +1151,8 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg) s->max_cert_list=larg; return(l); case SSL_CTRL_SET_MTU: -#ifndef OPENSSL_NO_DTLS1 if (larg < (long)dtls1_min_mtu()) return 0; -#endif - if (SSL_IS_DTLS(s)) { s->d1->mtu = larg; @@ -1393,7 +1383,7 @@ STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) /** The old interface to get the same thing as SSL_get_ciphers() */ const char *SSL_get_cipher_list(const SSL *s,int n) { - SSL_CIPHER *c; + const SSL_CIPHER *c; STACK_OF(SSL_CIPHER) *sk; if (s == NULL) return(NULL); @@ -1467,7 +1457,7 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) { char *p; STACK_OF(SSL_CIPHER) *sk; - SSL_CIPHER *c; + const SSL_CIPHER *c; int i; if ((s->session == NULL) || (s->session->ciphers == NULL) || @@ -1505,7 +1495,7 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p) { int i; - SSL_CIPHER *c; + const SSL_CIPHER *c; CERT *ct = s->cert; unsigned char *q; int no_scsv = s->renegotiate; @@ -1541,7 +1531,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p) { if (!no_scsv) { - static SSL_CIPHER scsv = + static const SSL_CIPHER scsv = { 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -1552,7 +1542,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p) } if (s->fallback_scsv) { - static SSL_CIPHER fallback_scsv = + static const SSL_CIPHER fallback_scsv = { 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -1671,6 +1661,63 @@ int SSL_get_servername_type(const SSL *s) return -1; } +void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) + { + ctx->signed_cert_timestamps_enabled = 1; + } + +int SSL_enable_signed_cert_timestamps(SSL *ssl) + { + /* Currently not implemented server-side. */ + if (ssl->server) + return 0; + + ssl->signed_cert_timestamps_enabled = 1; + return 1; + } + +void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) + { + ctx->ocsp_stapling_enabled = 1; + } + +int SSL_enable_ocsp_stapling(SSL *ssl) + { + /* Currently not implemented server-side. */ + if (ssl->server) + return 0; + ssl->ocsp_stapling_enabled = 1; + return 1; + } + +void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, uint8_t **out, size_t *out_len) + { + SSL_SESSION *session = ssl->session; + + *out_len = 0; + *out = NULL; + if (ssl->server) + return; + if (!session || !session->tlsext_signed_cert_timestamp_list) + return; + *out = session->tlsext_signed_cert_timestamp_list; + *out_len = session->tlsext_signed_cert_timestamp_list_length; + } + +void SSL_get0_ocsp_response(const SSL *ssl, uint8_t **out, size_t *out_len) + { + SSL_SESSION *session = ssl->session; + + *out_len = 0; + *out = NULL; + if (ssl->server) + return; + if (!session || !session->ocsp_response) + return; + *out = session->ocsp_response; + *out_len = session->ocsp_response_length; + } + /* SSL_select_next_proto implements the standard protocol selection. It is * expected that this function is called from the callback set by * SSL_CTX_set_next_proto_select_cb. @@ -1737,7 +1784,6 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const unsi return status; } -# ifndef OPENSSL_NO_NEXTPROTONEG /* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's * requested protocol for this connection and returns 0. If the client didn't * request any protocol, then *data is set to NULL. @@ -1786,7 +1832,6 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned ctx->next_proto_select_cb = cb; ctx->next_proto_select_cb_arg = arg; } -# endif /* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|. * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit @@ -1924,7 +1969,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->session_cache_tail=NULL; /* We take the system default */ - ret->session_timeout=meth->get_timeout(); + ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT; ret->new_session_cb=0; ret->remove_session_cb=0; @@ -1979,10 +2024,6 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) if (!ret->param) goto err; - ret->rsa_md5 = EVP_md5(); - ret->md5 = EVP_md5(); - ret->sha1 = EVP_sha1(); - if ((ret->client_CA=sk_X509_NAME_new_null()) == NULL) goto err; @@ -2003,33 +2044,12 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->tlsext_status_cb = 0; ret->tlsext_status_arg = NULL; -# ifndef OPENSSL_NO_NEXTPROTONEG ret->next_protos_advertised_cb = 0; ret->next_proto_select_cb = 0; -# endif ret->psk_identity_hint=NULL; ret->psk_client_callback=NULL; ret->psk_server_callback=NULL; -#ifndef OPENSSL_NO_ENGINE - ret->client_cert_engine = NULL; -#ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO -#define eng_strx(x) #x -#define eng_str(x) eng_strx(x) - /* Use specific client engine automatically... ignore errors */ - { - ENGINE *eng; - eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); - if (!eng) - { - ERR_clear_error(); - ENGINE_load_builtin_engines(); - eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); - } - if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) - ERR_clear_error(); - } -#endif -#endif + /* Default is to connect to non-RI servers. When RI is more widely * deployed might change this. */ @@ -2104,26 +2124,19 @@ void SSL_CTX_free(SSL_CTX *a) if (a->psk_identity_hint) OPENSSL_free(a->psk_identity_hint); - /* TODO(fork): remove. */ -#if 0 -#ifndef OPENSSL_NO_ENGINE - if (a->client_cert_engine) - ENGINE_finish(a->client_cert_engine); -#endif -#endif - -# ifndef OPENSSL_NO_EC if (a->tlsext_ecpointformatlist) OPENSSL_free(a->tlsext_ecpointformatlist); if (a->tlsext_ellipticcurvelist) OPENSSL_free(a->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ if (a->alpn_client_proto_list != NULL) OPENSSL_free(a->alpn_client_proto_list); 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); } @@ -2167,45 +2180,22 @@ void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg) void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) { CERT_PKEY *cpk; - int rsa_enc,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign; + int rsa_enc,rsa_sign,dh_tmp; unsigned long mask_k,mask_a; -#ifndef OPENSSL_NO_ECDSA int have_ecc_cert, ecdsa_ok; -#endif -#ifndef OPENSSL_NO_ECDH - int have_ecdh_tmp, ecdh_ok; -#endif -#ifndef OPENSSL_NO_EC + int have_ecdh_tmp; X509 *x = NULL; - EVP_PKEY *ecc_pkey = NULL; - int signature_nid = 0, pk_nid = 0, md_nid = 0; -#endif if (c == NULL) return; -#ifndef OPENSSL_NO_DH dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL); -#else - dh_tmp=0; -#endif -#ifndef OPENSSL_NO_ECDH have_ecdh_tmp=(c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto); -#endif cpk= &(c->pkeys[SSL_PKEY_RSA_ENC]); rsa_enc= cpk->valid_flags & CERT_PKEY_VALID; cpk= &(c->pkeys[SSL_PKEY_RSA_SIGN]); rsa_sign= cpk->valid_flags & CERT_PKEY_SIGN; - cpk= &(c->pkeys[SSL_PKEY_DSA_SIGN]); - dsa_sign= cpk->valid_flags & CERT_PKEY_SIGN; - cpk= &(c->pkeys[SSL_PKEY_DH_RSA]); - dh_rsa= cpk->valid_flags & CERT_PKEY_VALID; - cpk= &(c->pkeys[SSL_PKEY_DH_DSA]); -/* FIX THIS EAY EAY EAY */ - dh_dsa= cpk->valid_flags & CERT_PKEY_VALID; cpk= &(c->pkeys[SSL_PKEY_ECC]); -#ifndef OPENSSL_NO_EC have_ecc_cert= cpk->valid_flags & CERT_PKEY_VALID; -#endif mask_k=0; mask_a=0; @@ -2218,90 +2208,38 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) if (rsa_enc) mask_k|=SSL_kRSA; -#if 0 - /* The match needs to be both kEDH and aRSA or aDSA, so don't worry */ - if ( (dh_tmp || dh_rsa || dh_dsa) && - (rsa_enc || rsa_sign || dsa_sign)) - mask_k|=SSL_kEDH; -#endif - if (dh_tmp) mask_k|=SSL_kEDH; - if (dh_rsa) mask_k|=SSL_kDHr; - - if (dh_dsa) mask_k|=SSL_kDHd; - - if (mask_k & (SSL_kDHr|SSL_kDHd)) - mask_a |= SSL_aDH; - if (rsa_enc || rsa_sign) { mask_a|=SSL_aRSA; } - if (dsa_sign) - { - mask_a|=SSL_aDSS; - } - mask_a|=SSL_aNULL; - /* An ECC certificate may be usable for ECDH and/or - * ECDSA cipher suites depending on the key usage extension. - */ -#ifndef OPENSSL_NO_EC + /* An ECC certificate may be usable for ECDSA cipher suites depending on + * the key usage extension. */ if (have_ecc_cert) { cpk = &c->pkeys[SSL_PKEY_ECC]; x = cpk->x509; /* This call populates extension flags (ex_flags) */ X509_check_purpose(x, -1, 0); - ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? - (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1; ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; if (!(cpk->valid_flags & CERT_PKEY_SIGN)) ecdsa_ok = 0; - ecc_pkey = X509_get_pubkey(x); - EVP_PKEY_free(ecc_pkey); - if ((x->sig_alg) && (x->sig_alg->algorithm)) - { - signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); - } -#ifndef OPENSSL_NO_ECDH - if (ecdh_ok) - { - - if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) - { - mask_k|=SSL_kECDHr; - mask_a|=SSL_aECDH; - } - - if (pk_nid == NID_X9_62_id_ecPublicKey) - { - mask_k|=SSL_kECDHe; - mask_a|=SSL_aECDH; - } - } -#endif -#ifndef OPENSSL_NO_ECDSA if (ecdsa_ok) { mask_a|=SSL_aECDSA; } -#endif } -#endif -#ifndef OPENSSL_NO_ECDH if (have_ecdh_tmp) { mask_k|=SSL_kEECDH; } -#endif mask_k |= SSL_kPSK; mask_a |= SSL_aPSK; @@ -2315,15 +2253,13 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) #define ku_reject(x, usage) \ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) -#ifndef OPENSSL_NO_EC int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) { - unsigned long alg_k, alg_a; + unsigned long alg_a; int signature_nid = 0, md_nid = 0, pk_nid = 0; const SSL_CIPHER *cs = s->s3->tmp.new_cipher; - alg_k = cs->algorithm_mkey; alg_a = cs->algorithm_auth; /* This call populates the ex_flags field correctly */ @@ -2333,34 +2269,6 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); } - if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) - { - /* key usage, if present, must allow key agreement */ - if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) - { - OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); - return 0; - } - if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION) - { - /* signature alg must be ECDSA */ - if (pk_nid != NID_X9_62_id_ecPublicKey) - { - OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE); - return 0; - } - } - if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION) - { - /* signature alg must be RSA */ - - if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa) - { - OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE); - return 0; - } - } - } if (alg_a & SSL_aECDSA) { /* key usage, if present, must allow signing */ @@ -2374,7 +2282,6 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) return 1; /* all checks are ok */ } -#endif static int ssl_get_server_cert_index(const SSL *s) { @@ -2431,10 +2338,7 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd) else #endif - if ((alg_a & SSL_aDSS) && - (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) - idx = SSL_PKEY_DSA_SIGN; - else if (alg_a & SSL_aRSA) + if (alg_a & SSL_aRSA) { if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) idx = SSL_PKEY_RSA_SIGN; @@ -2462,14 +2366,14 @@ void ssl_update_cache(SSL *s,int mode) * and it would be rather hard to do anyway :-) */ if (s->session->session_id_length == 0) return; - i=s->session_ctx->session_cache_mode; + i=s->initial_ctx->session_cache_mode; if ((i & mode) && (!s->hit) && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) - || SSL_CTX_add_session(s->session_ctx,s->session)) - && (s->session_ctx->new_session_cb != NULL)) + || SSL_CTX_add_session(s->initial_ctx,s->session)) + && (s->initial_ctx->new_session_cb != NULL)) { CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION); - if (!s->session_ctx->new_session_cb(s,s->session)) + if (!s->initial_ctx->new_session_cb(s,s->session)) SSL_SESSION_free(s->session); } @@ -2478,10 +2382,10 @@ void ssl_update_cache(SSL *s,int mode) ((i & mode) == mode)) { if ( (((mode & SSL_SESS_CACHE_CLIENT) - ?s->session_ctx->stats.sess_connect_good - :s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff) + ?s->initial_ctx->stats.sess_connect_good + :s->initial_ctx->stats.sess_accept_good) & 0xff) == 0xff) { - SSL_CTX_flush_sessions(s->session_ctx,(unsigned long)time(NULL)); + SSL_CTX_flush_sessions(s->initial_ctx,(unsigned long)time(NULL)); } } } @@ -2689,22 +2593,32 @@ SSL_METHOD *ssl_bad_method(int ver) return(NULL); } -const char *SSL_get_version(const SSL *s) +static const char *ssl_get_version(int version) { - if (s->version == TLS1_2_VERSION) + if (version == TLS1_2_VERSION) return("TLSv1.2"); - else if (s->version == TLS1_1_VERSION) + else if (version == TLS1_1_VERSION) return("TLSv1.1"); - else if (s->version == TLS1_VERSION) + else if (version == TLS1_VERSION) return("TLSv1"); - else if (s->version == SSL3_VERSION) + else if (version == SSL3_VERSION) return("SSLv3"); - else if (s->version == SSL2_VERSION) + else if (version == SSL2_VERSION) return("SSLv2"); else return("unknown"); } +const char *SSL_get_version(const SSL *s) + { + return ssl_get_version(s->version); + } + +const char *SSL_SESSION_get_version(const SSL_SESSION *sess) + { + return ssl_get_version(sess->ssl_version); + } + void ssl_clear_cipher_ctx(SSL *s) { if (s->enc_read_ctx != NULL) @@ -3036,7 +2950,6 @@ RSA *cb(SSL *ssl,int is_export,int keylength) * \param dh the callback */ -#ifndef OPENSSL_NO_DH void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export, int keylength)) { @@ -3048,9 +2961,7 @@ void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export, { SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh); } -#endif -#ifndef OPENSSL_NO_ECDH void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,EC_KEY *(*ecdh)(SSL *ssl,int is_export, int keylength)) { @@ -3062,7 +2973,6 @@ void SSL_set_tmp_ecdh_callback(SSL *ssl,EC_KEY *(*ecdh)(SSL *ssl,int is_export, { SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh); } -#endif int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) { @@ -3185,6 +3095,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 */ @@ -3216,11 +3242,7 @@ int ssl3_can_cutthrough(const SSL *s) return 0; /* require ALPN or NPN extension */ - if (!s->s3->alpn_selected -#ifndef OPENSSL_NO_NEXTPROTONEG - && !s->s3->next_proto_neg_seen -#endif - ) + if (!s->s3->alpn_selected && !s->s3->next_proto_neg_seen) { return 0; }