std::vector<uint8_t> Handshake_State::session_ticket() const { if(new_session_ticket() && !new_session_ticket()->ticket().empty()) return new_session_ticket()->ticket(); return client_hello()->session_ticket(); }
std::string Handshake_State::srp_identifier() const { #if defined(BOTAN_HAS_SRP6) // Authenticated via the successful key exchange if(ciphersuite().valid() && ciphersuite().kex_algo() == "SRP_SHA") return client_hello()->srp_identifier(); #endif return ""; }
std::pair<std::string, Signature_Format> Handshake_State::choose_sig_format(const Private_Key& key, std::string& hash_algo_out, std::string& sig_algo_out, bool for_client_auth, const Policy& policy) const { const std::string sig_algo = key.algo_name(); const std::string hash_algo = choose_hash(sig_algo, this->version(), policy, for_client_auth, client_hello(), cert_req()); if(this->version().supports_negotiable_signature_algorithms()) { hash_algo_out = hash_algo; sig_algo_out = sig_algo; } if(sig_algo == "RSA") { const std::string padding = "EMSA3(" + hash_algo + ")"; return std::make_pair(padding, IEEE_1363); } else if(sig_algo == "DSA" || sig_algo == "ECDSA") { const std::string padding = "EMSA1(" + hash_algo + ")"; return std::make_pair(padding, DER_SEQUENCE); } throw Invalid_Argument(sig_algo + " is invalid/unknown for TLS signatures"); }
std::pair<std::string, Signature_Format> Handshake_State::parse_sig_format(const Public_Key& key, const std::string& input_hash_algo, const std::string& input_sig_algo, bool for_client_auth, const Policy& policy) const { const std::string key_type = key.algo_name(); if(!policy.allowed_signature_method(key_type)) { throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Rejecting " + key_type + " signature"); } std::string hash_algo; if(this->version().supports_negotiable_signature_algorithms()) { if(input_sig_algo != key_type) throw Decoding_Error("Counterparty sent inconsistent key and sig types"); if(input_hash_algo == "") throw Decoding_Error("Counterparty did not send hash/sig IDS"); hash_algo = input_hash_algo; if(for_client_auth && !cert_req()) { throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "No certificate verify set"); } /* Confirm the signature type we just received against the supported_algos list that we sent; it better be there. */ const auto supported_algos = for_client_auth ? cert_req()->supported_algos() : client_hello()->supported_algos(); if(!supported_algos_include(supported_algos, key_type, hash_algo)) { throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "TLS signature extension did not allow for " + key_type + "/" + hash_algo + " signature"); } } else { if(input_hash_algo != "" || input_sig_algo != "") throw Decoding_Error("Counterparty sent hash/sig IDs with old version"); if(key_type == "RSA") { hash_algo = "Parallel(MD5,SHA-160)"; } else if(key_type == "DSA" || key_type == "ECDSA") { hash_algo = "SHA-1"; } else { throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures"); } /* There is no check on the acceptability of a v1.0/v1.1 hash type, since it's implicit with use of the protocol */ } if(key_type == "RSA") { const std::string padding = "EMSA3(" + hash_algo + ")"; return std::make_pair(padding, IEEE_1363); } else if(key_type == "DSA" || key_type == "ECDSA") { const std::string padding = "EMSA1(" + hash_algo + ")"; return std::make_pair(padding, DER_SEQUENCE); } throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures"); }
int ssl2_connect(SSL *s) { unsigned long l=(unsigned long)time(NULL); BUF_MEM *buf=NULL; int ret= -1; void (*cb)(const SSL *ssl,int type,int val)=NULL; int new_state,state; RAND_add(&l,sizeof(l),0); ERR_clear_error(); clear_sys_error(); if (s->info_callback != NULL) cb=s->info_callback; else if (s->ctx->info_callback != NULL) cb=s->ctx->info_callback; /* init things to blank */ s->in_handshake++; if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); for (;;) { state=s->state; switch (s->state) { case SSL_ST_BEFORE: case SSL_ST_CONNECT: case SSL_ST_BEFORE|SSL_ST_CONNECT: case SSL_ST_OK|SSL_ST_CONNECT: s->server=0; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); s->version=SSL2_VERSION; s->type=SSL_ST_CONNECT; buf=s->init_buf; if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL)) { ret= -1; goto end; } if (!BUF_MEM_grow(buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { if (buf == s->init_buf) buf=NULL; ret= -1; goto end; } s->init_buf=buf; buf=NULL; s->init_num=0; s->state=SSL2_ST_SEND_CLIENT_HELLO_A; s->ctx->stats.sess_connect++; s->handshake_func=ssl2_connect; BREAK; case SSL2_ST_SEND_CLIENT_HELLO_A: case SSL2_ST_SEND_CLIENT_HELLO_B: s->shutdown=0; ret=client_hello(s); if (ret <= 0) goto end; s->init_num=0; s->state=SSL2_ST_GET_SERVER_HELLO_A; BREAK; case SSL2_ST_GET_SERVER_HELLO_A: case SSL2_ST_GET_SERVER_HELLO_B: ret=get_server_hello(s); if (ret <= 0) goto end; s->init_num=0; if (!s->hit) /* new session */ { s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_A; BREAK; } else { s->state=SSL2_ST_CLIENT_START_ENCRYPTION; break; } case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: ret=client_master_key(s); if (ret <= 0) goto end; s->init_num=0; s->state=SSL2_ST_CLIENT_START_ENCRYPTION; break; case SSL2_ST_CLIENT_START_ENCRYPTION: /* Ok, we now have all the stuff needed to * start encrypting, so lets fire it up :-) */ if (!ssl2_enc_init(s,1)) { ret= -1; goto end; } s->s2->clear_text=0; s->state=SSL2_ST_SEND_CLIENT_FINISHED_A; break; case SSL2_ST_SEND_CLIENT_FINISHED_A: case SSL2_ST_SEND_CLIENT_FINISHED_B: ret=client_finished(s); if (ret <= 0) goto end; s->init_num=0; s->state=SSL2_ST_GET_SERVER_VERIFY_A; break; case SSL2_ST_GET_SERVER_VERIFY_A: case SSL2_ST_GET_SERVER_VERIFY_B: ret=get_server_verify(s); if (ret <= 0) goto end; s->init_num=0; s->state=SSL2_ST_GET_SERVER_FINISHED_A; break; case SSL2_ST_GET_SERVER_FINISHED_A: case SSL2_ST_GET_SERVER_FINISHED_B: ret=get_server_finished(s); if (ret <= 0) goto end; break; case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: ret=client_certificate(s); if (ret <= 0) goto end; s->init_num=0; s->state=SSL2_ST_GET_SERVER_FINISHED_A; break; case SSL_ST_OK: if (s->init_buf != NULL) { BUF_MEM_free(s->init_buf); s->init_buf=NULL; } s->init_num=0; /* ERR_clear_error();*/ /* If we want to cache session-ids in the client * and we successfully add the session-id to the * cache, and there is a callback, then pass it out. * 26/11/96 - eay - only add if not a re-used session. */ ssl_update_cache(s,SSL_SESS_CACHE_CLIENT); if (s->hit) s->ctx->stats.sess_hit++; ret=1; /* s->server=0; */ s->ctx->stats.sess_connect_good++; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); goto end; /* break; */ default: SSLerr(SSL_F_SSL2_CONNECT,SSL_R_UNKNOWN_STATE); return(-1); /* break; */ } if ((cb != NULL) && (s->state != state)) { new_state=s->state; s->state=state; cb(s,SSL_CB_CONNECT_LOOP,1); s->state=new_state; } } end: s->in_handshake--; if (buf != NULL) BUF_MEM_free(buf); if (cb != NULL) cb(s,SSL_CB_CONNECT_EXIT,ret); return(ret); }