Пример #1
0
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();
   }
Пример #2
0
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 "";
   }
Пример #3
0
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");
   }
Пример #4
0
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");
   }
Пример #5
0
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);
	}