X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=3fbb48953944d7f610aae5eadb032ab2e61fc8fe;hp=ff710045dc2f09172a73c0d652a48711aa99e42f;hb=ddd13d677b0fc62c34d246b3d060c9cb5de04d82;hpb=44959ee456effed8c9b7e2d7a49c27b46a5a4454 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index ff710045dc..3fbb489539 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -176,7 +176,10 @@ SSL3_ENC_METHOD ssl3_undef_enc_method={ 0, /* client_finished_label_len */ NULL, /* server_finished_label */ 0, /* server_finished_label_len */ - (int (*)(int))ssl_undefined_function + (int (*)(int))ssl_undefined_function, + (int (*)(SSL *, unsigned char *, size_t, const char *, + size_t, const unsigned char *, size_t, + int use_context)) ssl_undefined_function, }; int SSL_clear(SSL *s) @@ -260,7 +263,7 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx,const SSL_METHOD *meth) sk=ssl_create_cipher_list(ctx->method,&(ctx->cipher_list), &(ctx->cipher_list_by_id), - meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST); + meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST, ctx->cert); if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); @@ -319,6 +322,7 @@ SSL *SSL_new(SSL_CTX *ctx) s->msg_callback=ctx->msg_callback; s->msg_callback_arg=ctx->msg_callback_arg; s->verify_mode=ctx->verify_mode; + s->not_resumable_session_cb=ctx->not_resumable_session_cb; #if 0 s->verify_depth=ctx->verify_depth; #endif @@ -353,7 +357,29 @@ SSL *SSL_new(SSL_CTX *ctx) s->tlsext_ocsp_resplen = -1; CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); s->initial_ctx=ctx; -# ifndef OPENSSL_NO_NPN +#ifndef OPENSSL_NO_EC + if (ctx->tlsext_ecpointformatlist) + { + s->tlsext_ecpointformatlist = + BUF_memdup(ctx->tlsext_ecpointformatlist, + ctx->tlsext_ecpointformatlist_length); + if (!s->tlsext_ecpointformatlist) + goto err; + s->tlsext_ecpointformatlist_length = + ctx->tlsext_ecpointformatlist_length; + } + if (ctx->tlsext_ellipticcurvelist) + { + s->tlsext_ellipticcurvelist = + BUF_memdup(ctx->tlsext_ellipticcurvelist, + ctx->tlsext_ellipticcurvelist_length); + if (!s->tlsext_ellipticcurvelist) + goto err; + s->tlsext_ellipticcurvelist_length = + ctx->tlsext_ellipticcurvelist_length; + } +#endif +# ifndef OPENSSL_NO_NEXTPROTONEG s->next_proto_negotiated = NULL; # endif #endif @@ -499,6 +525,11 @@ int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) return X509_VERIFY_PARAM_set1(ssl->param, vpm); } +void SSL_certs_clear(SSL *s) + { + ssl_cert_clear_certs(s->cert); + } + void SSL_free(SSL *s) { int i; @@ -589,11 +620,14 @@ void SSL_free(SSL *s) kssl_ctx_free(s->kssl_ctx); #endif /* OPENSSL_NO_KRB5 */ -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NPN) +#if !defined(OPENSSL_NO_TLSEXT) && !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); + OPENSSL_free(s); } @@ -1025,14 +1059,14 @@ int SSL_renegotiate(SSL *s) } int SSL_renegotiate_abbreviated(SSL *s) -{ + { if (s->renegotiate == 0) s->renegotiate=1; - + s->new_session=0; - + return(s->method->ssl_renegotiate(s)); -} + } int SSL_renegotiate_pending(SSL *s) { @@ -1073,6 +1107,11 @@ 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_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) { @@ -1089,6 +1128,21 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg) if (s->s3) return s->s3->send_connection_binding; else return 0; + case SSL_CTRL_CERT_FLAGS: + return(s->cert->cert_flags|=larg); + case SSL_CTRL_CLEAR_CERT_FLAGS: + return(s->cert->cert_flags &=~larg); + + case SSL_CTRL_GET_RAW_CIPHERLIST: + if (parg) + { + if (s->cert->ciphers_raw == NULL) + return 0; + *(unsigned char **)parg = s->cert->ciphers_raw; + return (int)s->cert->ciphers_rawlen; + } + else + return ssl_put_cipher_by_char(s,NULL,NULL); default: return(s->method->ssl_ctrl(s,cmd,larg,parg)); } @@ -1115,6 +1169,20 @@ LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg) { long l; + /* For some cases with ctx == NULL perform syntax checks */ + if (ctx == NULL) + { + switch (cmd) + { + case SSL_CTRL_SET_CURVES_LIST: + return tls1_set_curves_list(NULL, NULL, parg); + case SSL_CTRL_SET_SIGALGS_LIST: + case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: + return tls1_set_sigalgs_list(NULL, parg, 0); + default: + return 0; + } + } switch (cmd) { @@ -1186,6 +1254,10 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg) return 0; ctx->max_send_fragment = larg; return 1; + case SSL_CTRL_CERT_FLAGS: + return(ctx->cert->cert_flags|=larg); + case SSL_CTRL_CLEAR_CERT_FLAGS: + return(ctx->cert->cert_flags &=~larg); default: return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg)); } @@ -1286,7 +1358,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) STACK_OF(SSL_CIPHER) *sk; sk=ssl_create_cipher_list(ctx->method,&ctx->cipher_list, - &ctx->cipher_list_by_id,str); + &ctx->cipher_list_by_id,str, ctx->cert); /* ssl_create_cipher_list may return an empty stack if it * was unable to find a cipher matching the given rule string * (for example if the rule string specifies a cipher which @@ -1310,7 +1382,7 @@ int SSL_set_cipher_list(SSL *s,const char *str) STACK_OF(SSL_CIPHER) *sk; sk=ssl_create_cipher_list(s->ctx->method,&s->cipher_list, - &s->cipher_list_by_id,str); + &s->cipher_list_by_id,str, s->cert); /* see comment in SSL_CTX_set_cipher_list */ if (sk == NULL) return 0; @@ -1363,10 +1435,11 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, { int i,j=0; SSL_CIPHER *c; + CERT *ct = s->cert; unsigned char *q; -#ifndef OPENSSL_NO_KRB5 - int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx); -#endif /* OPENSSL_NO_KRB5 */ + int no_scsv = s->renegotiate; + /* Set disabled masks for this session */ + ssl_set_client_disabled(s); if (sk == NULL) return(0); q=p; @@ -1374,24 +1447,27 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, for (i=0; ialgorithm_mkey & SSL_kKRB5) || (c->algorithm_auth & SSL_aKRB5)) && - nokrb5) - continue; -#endif /* OPENSSL_NO_KRB5 */ -#ifndef OPENSSL_NO_PSK - /* with PSK there must be client callback set */ - if (((c->algorithm_mkey & SSL_kPSK) || (c->algorithm_auth & SSL_aPSK)) && - s->psk_client_callback == NULL) + /* Skip disabled ciphers */ + if (c->algorithm_ssl & ct->mask_ssl || + c->algorithm_mkey & ct->mask_k || + c->algorithm_auth & ct->mask_a) continue; -#endif /* OPENSSL_NO_PSK */ +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + if (c->id == SSL3_CK_SCSV) + { + if (no_scsv) + continue; + else + no_scsv = 1; + } +#endif j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p); p+=j; } /* If p == q, no ciphers and caller indicates an error. Otherwise * add SCSV if not renegotiating. */ - if (p != q && !s->new_session) + if (p != q && !no_scsv) { static SSL_CIPHER scsv = { @@ -1430,6 +1506,16 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, sk_SSL_CIPHER_zero(sk); } + if (s->cert->ciphers_raw) + OPENSSL_free(s->cert->ciphers_raw); + s->cert->ciphers_raw = BUF_memdup(p, num); + if (s->cert->ciphers_raw == NULL) + { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,ERR_R_MALLOC_FAILURE); + goto err; + } + s->cert->ciphers_rawlen = (size_t)num; + for (i=0; inew_session) + if (s->renegotiate) { SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); @@ -1496,7 +1582,7 @@ int SSL_get_servername_type(const SSL *s) return -1; } -# ifndef OPENSSL_NO_NPN +# ifndef OPENSSL_NO_NEXTPROTONEG /* 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. @@ -1611,10 +1697,21 @@ 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 #endif +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, const unsigned char *p, size_t plen, + int use_context) + { + if (s->version < TLS1_VERSION) + return -1; + + return s->method->ssl3_enc->export_keying_material(s, out, olen, label, + llen, p, plen, + use_context); + } + static unsigned long ssl_session_hash(const SSL_SESSION *a) { unsigned long l; @@ -1658,6 +1755,14 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) return(NULL); } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (meth->version < TLS1_VERSION)) + { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return NULL; + } +#endif + if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); @@ -1727,7 +1832,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ssl_create_cipher_list(ret->method, &ret->cipher_list,&ret->cipher_list_by_id, - meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST); + meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST, ret->cert); if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { @@ -1777,7 +1882,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->tlsext_status_cb = 0; ret->tlsext_status_arg = NULL; -# ifndef OPENSSL_NO_NPN +# ifndef OPENSSL_NO_NEXTPROTONEG ret->next_protos_advertised_cb = 0; ret->next_proto_select_cb = 0; # endif @@ -1787,6 +1892,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->psk_client_callback=NULL; ret->psk_server_callback=NULL; #endif +#ifndef OPENSSL_NO_SRP + SSL_CTX_SRP_CTX_init(ret); +#endif #ifndef OPENSSL_NO_BUF_FREELISTS ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); @@ -1915,10 +2023,16 @@ void SSL_CTX_free(SSL_CTX *a) a->comp_methods = NULL; #endif + if (a->srtp_profiles) + sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); + #ifndef OPENSSL_NO_PSK if (a->psk_identity_hint) OPENSSL_free(a->psk_identity_hint); #endif +#ifndef OPENSSL_NO_SRP + SSL_CTX_SRP_CTX_free(a); +#endif #ifndef OPENSSL_NO_ENGINE if (a->client_cert_engine) ENGINE_finish(a->client_cert_engine); @@ -1929,6 +2043,14 @@ void SSL_CTX_free(SSL_CTX *a) ssl_buf_freelist_free(a->wbuf_freelist); if (a->rbuf_freelist) ssl_buf_freelist_free(a->rbuf_freelist); +#endif +#ifndef OPENSSL_NO_TLSEXT +# 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 */ #endif OPENSSL_free(a); @@ -1961,6 +2083,16 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth) X509_VERIFY_PARAM_set_depth(ctx->param, depth); } +void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg), void *arg) + { + ssl_cert_set_cert_cb(c->cert, cb, arg); + } + +void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg) + { + ssl_cert_set_cert_cb(s->cert, cb, arg); + } + void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) { CERT_PKEY *cpk; @@ -1974,7 +2106,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) #endif X509 *x = NULL; EVP_PKEY *ecc_pkey = NULL; - int signature_nid = 0; + int signature_nid = 0, pk_nid = 0, md_nid = 0; if (c == NULL) return; @@ -1996,24 +2128,24 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) #endif #ifndef OPENSSL_NO_ECDH - have_ecdh_tmp=(c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL); + 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->x509 != NULL && cpk->privatekey != NULL); + rsa_enc= cpk->valid_flags & CERT_PKEY_VALID; rsa_enc_export=(rsa_enc && EVP_PKEY_size(cpk->privatekey)*8 <= kl); cpk= &(c->pkeys[SSL_PKEY_RSA_SIGN]); - rsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL); + rsa_sign= cpk->valid_flags & CERT_PKEY_SIGN; cpk= &(c->pkeys[SSL_PKEY_DSA_SIGN]); - dsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL); + dsa_sign= cpk->valid_flags & CERT_PKEY_SIGN; cpk= &(c->pkeys[SSL_PKEY_DH_RSA]); - dh_rsa= (cpk->x509 != NULL && cpk->privatekey != NULL); + dh_rsa= cpk->valid_flags & CERT_PKEY_VALID; dh_rsa_export=(dh_rsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl); cpk= &(c->pkeys[SSL_PKEY_DH_DSA]); /* FIX THIS EAY EAY EAY */ - dh_dsa= (cpk->x509 != NULL && cpk->privatekey != NULL); + dh_dsa= cpk->valid_flags & CERT_PKEY_VALID; dh_dsa_export=(dh_dsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl); cpk= &(c->pkeys[SSL_PKEY_ECC]); - have_ecc_cert= (cpk->x509 != NULL && cpk->privatekey != NULL); + have_ecc_cert= cpk->valid_flags & CERT_PKEY_VALID; mask_k=0; mask_a=0; emask_k=0; @@ -2065,6 +2197,9 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) if (dh_dsa) mask_k|=SSL_kDHd; if (dh_dsa_export) emask_k|=SSL_kDHd; + if (emask_k & (SSL_kDHr|SSL_kDHd)) + mask_a |= SSL_aDH; + if (rsa_enc || rsa_sign) { mask_a|=SSL_aRSA; @@ -2092,30 +2227,30 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) */ if (have_ecc_cert) { + cpk = &c->pkeys[SSL_PKEY_ECC]; + x = cpk->x509; /* This call populates extension flags (ex_flags) */ - x = (c->pkeys[SSL_PKEY_ECC]).x509; 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); ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0; 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) { - const char *sig = OBJ_nid2ln(signature_nid); - if (sig == NULL) - { - ERR_clear_error(); - sig = "unknown"; - } - - if (strstr(sig, "WithRSA")) + + if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) { mask_k|=SSL_kECDHr; mask_a|=SSL_aECDH; @@ -2126,7 +2261,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) } } - if (signature_nid == NID_ecdsa_with_SHA1) + if (pk_nid == NID_X9_62_id_ecPublicKey) { mask_k|=SSL_kECDHe; mask_a|=SSL_aECDH; @@ -2175,12 +2310,13 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) #ifndef OPENSSL_NO_EC -int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs) +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) { unsigned long alg_k, alg_a; EVP_PKEY *pkey = NULL; int keysize = 0; - int signature_nid = 0; + 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; @@ -2198,7 +2334,10 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs) /* This call populates the ex_flags field correctly */ X509_check_purpose(x, -1, 0); 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); + } if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) { /* key usage, if present, must allow key agreement */ @@ -2207,26 +2346,20 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs) SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); return 0; } - if (alg_k & SSL_kECDHe) + if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION) { /* signature alg must be ECDSA */ - if (signature_nid != NID_ecdsa_with_SHA1) + if (pk_nid != NID_X9_62_id_ecPublicKey) { SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE); return 0; } } - if (alg_k & SSL_kECDHr) + if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION) { /* signature alg must be RSA */ - const char *sig = OBJ_nid2ln(signature_nid); - if (sig == NULL) - { - ERR_clear_error(); - sig = "unknown"; - } - if (strstr(sig, "WithRSA") == NULL) + if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa) { SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE); return 0; @@ -2248,100 +2381,105 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs) #endif -/* THIS NEEDS CLEANING UP */ -X509 *ssl_get_server_send_cert(SSL *s) +static int ssl_get_server_cert_index(const SSL *s) + { + int idx; + idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); + if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) + idx = SSL_PKEY_RSA_SIGN; + if (idx == -1) + SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX,ERR_R_INTERNAL_ERROR); + return idx; + } + +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) { - unsigned long alg_k,alg_a; CERT *c; int i; - c=s->cert; + c = s->cert; ssl_set_cert_masks(c, s->s3->tmp.new_cipher); - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - - if (alg_k & (SSL_kECDHr|SSL_kECDHe)) - { - /* we don't need to look at SSL_kEECDH - * since no certificate is needed for - * anon ECDH and for authenticated - * EECDH, the check for the auth - * algorithm will set i correctly - * NOTE: For ECDH-RSA, we need an ECC - * not an RSA cert but for EECDH-RSA - * we need an RSA cert. Placing the - * checks for SSL_kECDH before RSA - * checks ensures the correct cert is chosen. - */ - i=SSL_PKEY_ECC; - } - else if (alg_a & SSL_aECDSA) - { - i=SSL_PKEY_ECC; - } - else if (alg_k & SSL_kDHr) - i=SSL_PKEY_DH_RSA; - else if (alg_k & SSL_kDHd) - i=SSL_PKEY_DH_DSA; - else if (alg_a & SSL_aDSS) - i=SSL_PKEY_DSA_SIGN; - else if (alg_a & SSL_aRSA) - { - if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL) - i=SSL_PKEY_RSA_SIGN; - else - i=SSL_PKEY_RSA_ENC; - } - else if (alg_a & SSL_aKRB5) - { - /* VRS something else here? */ - return(NULL); - } - else if (alg_a & SSL_aGOST94) - i=SSL_PKEY_GOST94; - else if (alg_a & SSL_aGOST01) - i=SSL_PKEY_GOST01; - else /* if (alg_a & SSL_aNULL) */ - { - SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR); - return(NULL); - } - if (c->pkeys[i].x509 == NULL) return(NULL); - return(c->pkeys[i].x509); +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + /* Broken protocol test: return last used certificate: which may + * mismatch the one expected. + */ + if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) + return c->key; +#endif + + i = ssl_get_server_cert_index(s); + + /* This may or may not be an error. */ + if (i < 0) + return NULL; + + /* May be NULL. */ + return &c->pkeys[i]; } -EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher) +EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd) { unsigned long alg_a; CERT *c; + int idx = -1; alg_a = cipher->algorithm_auth; c=s->cert; +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + /* Broken protocol test: use last key: which may + * mismatch the one expected. + */ + if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) + idx = c->key - c->pkeys; + else +#endif + if ((alg_a & SSL_aDSS) && (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) - return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey); + idx = SSL_PKEY_DSA_SIGN; else if (alg_a & SSL_aRSA) { if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) - return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey); + idx = SSL_PKEY_RSA_SIGN; else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) - return(c->pkeys[SSL_PKEY_RSA_ENC].privatekey); - else - return(NULL); + idx = SSL_PKEY_RSA_ENC; } else if ((alg_a & SSL_aECDSA) && (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) - return(c->pkeys[SSL_PKEY_ECC].privatekey); - else /* if (alg_a & SSL_aNULL) */ + idx = SSL_PKEY_ECC; + if (idx == -1) { SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR); return(NULL); } + if (pmd) + *pmd = c->pkeys[idx].digest; + return c->pkeys[idx].privatekey; } +#ifndef OPENSSL_NO_TLSEXT +unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length) + { + CERT *c; + int i; + + c = s->cert; + i = ssl_get_server_cert_index(s); + + if (i == -1) + return NULL; + + *authz_length = 0; + if (c->pkeys[i].authz == NULL) + return(NULL); + *authz_length = c->pkeys[i].authz_length; + + return c->pkeys[i].authz; + } +#endif + void ssl_update_cache(SSL *s,int mode) { int i; @@ -2564,10 +2702,12 @@ SSL_METHOD *ssl_bad_method(int ver) const char *SSL_get_version(const SSL *s) { - if (s->version == TLS1_1_VERSION) + if (s->version == TLS1_2_VERSION) + return("TLSv1.2"); + else if (s->version == TLS1_1_VERSION) return("TLSv1.1"); - else if (s->version == SSL3_VERSION) - return("SSLv3"); + else if (s->version == TLS1_VERSION) + return("TLSv1"); else if (s->version == SSL3_VERSION) return("SSLv3"); else if (s->version == SSL2_VERSION) @@ -2926,6 +3066,11 @@ int SSL_state(const SSL *ssl) return(ssl->state); } +void SSL_set_state(SSL *ssl, int state) + { + ssl->state = state; + } + void SSL_set_verify_result(SSL *ssl,long arg) { ssl->verify_result=arg; @@ -3164,6 +3309,19 @@ 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_not_resumable_session_callback(SSL_CTX *ctx, + int (*cb)(SSL *ssl, int is_forward_secure)) + { + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB, + (void (*)(void))cb); + } +void SSL_set_not_resumable_session_callback(SSL *ssl, + int (*cb)(SSL *ssl, int is_forward_secure)) + { + SSL_callback_ctrl(ssl, SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB, + (void (*)(void))cb); + } + /* Allocates new EVP_MD_CTX and sets pointer to it into given pointer * vairable, freeing EVP_MD_CTX previously stored in that variable, if * any. If EVP_MD pointer is passed, initializes ctx with this md @@ -3184,6 +3342,21 @@ void ssl_clear_hash_ctx(EVP_MD_CTX **hash) *hash=NULL; } +void SSL_set_debug(SSL *s, int debug) + { + s->debug = debug; + } + +int SSL_cache_hit(SSL *s) + { + return s->hit; + } + +int SSL_is_server(SSL *s) + { + return s->server; + } + #if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16) #include "../crypto/bio/bss_file.c" #endif @@ -3192,4 +3365,3 @@ IMPLEMENT_STACK_OF(SSL_CIPHER) IMPLEMENT_STACK_OF(SSL_COMP) IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); -