⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ossl_tls_funcs.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 4 页
字号:
      return NULL;
    }

  debug_printf(DEBUG_TLS_CORE, "Using session key const of : %s\n",
               sesskey);

  retblock = (uint8_t *)Malloc(TLS_SESSION_KEY_SIZE);
  if (!retblock)
  {
	  ipc_events_malloc_failed(NULL);
    return NULL;
  }

  if (first == TLS_FUNCS_CLIENT_FIRST)
    {
      memcpy(p, mytls_vars->ssl->s3->client_random, SSL3_RANDOM_SIZE);
      p+= SSL3_RANDOM_SIZE;
      memcpy(p, mytls_vars->ssl->s3->server_random, SSL3_RANDOM_SIZE);
    }
  else
    {
      memcpy(p, mytls_vars->ssl->s3->server_random, SSL3_RANDOM_SIZE);
      p+= SSL3_RANDOM_SIZE;
      memcpy(p, mytls_vars->ssl->s3->client_random, SSL3_RANDOM_SIZE);
    }

  ossl_tls_funcs_PRF(SSL_get_session(mytls_vars->ssl)->master_key,
		     SSL_get_session(mytls_vars->ssl)->master_key_length,
		     (uint8_t *) sesskey, sesskeylen, seed,
		     SSL3_RANDOM_SIZE * 2, retblock,
		     TLS_SESSION_KEY_SIZE);

  debug_printf(DEBUG_TLS_CORE, "Keyblock (%d) :\n ", TLS_SESSION_KEY_SIZE);
  debug_hex_dump(DEBUG_TLS_CORE, retblock, TLS_SESSION_KEY_SIZE);
  return retblock;
}


/************************************************************************
 *
 *  Buffer any data that will eventually need to be sent to OpenSSL.
 *
 ************************************************************************/
int tls_funcs_buffer(struct tls_vars *mytls_vars, uint8_t *newfrag,
		     uint16_t fragsize)
{
  uint32_t value32 = 0;
  uint8_t *p = NULL;

  TRACE

  if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
    return XEGENERROR;

  if (!xsup_assert((newfrag != NULL), "newfrag != NULL", FALSE))
    return XEGENERROR;

  p = newfrag;
  if ((newfrag[0] & EAPTLS_LENGTH_INCL) == EAPTLS_LENGTH_INCL)
    {
      // We have length data, which means this should be the first piece
      // of a fragment.  So, verify that there isn't anything already
      // buffered.
      if (mytls_vars->tlsinqueue != NULL)
        {
		if (config_get_friendly_warnings() == TRUE)
		    {
		      debug_printf(DEBUG_NORMAL, "This appears to be the first piece "
				   "of a data fragment.  However, there is already "
				   "data in the fragment buffer.  It "
				   "is likely that your authentication will fail!\n");
		    }
        }
	  else
  	    {
		  // This is the first packet, possibly in a sequence.  So create our queue.
		  if (queue_create(&mytls_vars->tlsinqueue) != 0)
		  {
			  debug_printf(DEBUG_NORMAL, "Couldn't create queue to store incoming fragments!\n");
			  return XEGENERROR;
		  }
	   }

      p++;    // Skip to the bytes that contain the value.

      memcpy(&value32, p, 4);
      value32 = ntohl(value32);
      p+=3;

      mytls_vars->expected_in = value32;
      fragsize -= 4;                  // Skip the length value.
    }
    else
	  {
		  if (queue_create(&mytls_vars->tlsinqueue) != 0)
		 {
			  debug_printf(DEBUG_NORMAL, "Couldn't create queue to store incoming message.\n");
			  return XEGENERROR;
		}
	}


  p++;  // Skip the ID byte.
  fragsize--;

  if (queue_get_size(&mytls_vars->tlsinqueue, &value32) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't determine the queue size!  We won't be able to "
		  "continue!\n");
	  return XEGENERROR;
  }

  debug_printf(DEBUG_TLS_CORE, "Total expected data size should be %d.  (0 means we don't know what to expect!) We currently"
               " have %d byte(s) of data, and will be adding %d more.\n",
               mytls_vars->expected_in, value32, fragsize);

  if (queue_enqueue(&mytls_vars->tlsinqueue, p, fragsize) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't enqueue the data fragment!\n");
	  return XEGENERROR;
  }

  if (queue_get_size(&mytls_vars->tlsinqueue, &value32) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't determine new queue size!\n");
  }
  else
  {
	if (((newfrag[0] & EAPTLS_MORE_FRAGS) != EAPTLS_MORE_FRAGS) &&
		(value32 < mytls_vars->expected_in))
    {
		debug_printf(DEBUG_NORMAL, "The server indicated that there are no "
			  "fragments remaining.  However, we only have %d of %d "
 			  "byte(s).  It is likely your authentication will fail."
			  "\n", value32, mytls_vars->expected_in);
	}
  }

  return XENONE;
}

/************************************************************************
 *
 *  Do we have something that is ready to be decrypted?
 *
 ************************************************************************/
int tls_funcs_decrypt_ready(struct tls_vars *mytls_vars)
{
	uint32_t value32 = 0;

  TRACE

  if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
    return -1;

  // The buffer is full.
  if (queue_get_size(&mytls_vars->tlsinqueue, &value32) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't determine the queue depth!\n");
	  return -1;
  }

  debug_printf(DEBUG_TLS_CORE, "Expected size : %d  Current size : %d\n",
	  mytls_vars->expected_in, value32);

  if (mytls_vars->expected_in == value32)
      return value32;

  if (value32 > mytls_vars->expected_in)
	  return value32;

  // Otherwise, we aren't ready yet.
  return 0;
}

/************************************************************************
 *
 *  Decrypt data in our buffer.
 *
 * This function derived from the original Xsupplicant code written by 
 * Danielle Brevi.
 *
 ************************************************************************/
int tls_funcs_decrypt(struct tls_vars *mytls_vars, uint8_t *indata,
		      uint16_t *insize)
{
  int rc = 0;
  uint8_t *toencrypt = NULL;
  uint32_t value32 = 0;
  uint32_t expected = 0;

  TRACE

  if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
    return -1;

  if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
    return -1;

  if (!xsup_assert((insize != NULL), "insize != NULL", FALSE))
    return -1;

  // Determine how much data we have to push in.
  if (queue_get_size(&mytls_vars->tlsinqueue, &value32) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't determine queue depth!\n");
	  return -1;
  }

  // Remember how much data we expect to get back.
  expected = value32;

  // Then, dequeue it all.
  if (queue_dequeue(&mytls_vars->tlsinqueue, &toencrypt, &value32) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't dequeue data!\n");
	  return -1;
  }

  // We are done with this queue.  Destroy it.
  if (queue_destroy(&mytls_vars->tlsinqueue) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Couldn't destroy queue!  We will leak memory!\n");
	  FREE(toencrypt);
	  return -1;
  }

  if (expected != value32)  // ACK!  What happened!? -- This is probably a show-stopper.
  {
	  debug_printf(DEBUG_NORMAL, "We didn't dequeue the amount of data we were expecting.  Something "
			"is *SERIOUSLY* wrong!\n");
	  FREE(toencrypt);
	  return -1;
  }

  rc = BIO_write(mytls_vars->ssl_in, toencrypt, value32);
  if (rc < 0)
    {
      debug_printf(DEBUG_NORMAL, "Failed to send data to OpenSSL for "
		   "decryption.\n");
	  FREE(toencrypt);
      return -1;
    }

  FREE(toencrypt);

  memset(indata, 0x00, (*insize));

  rc = SSL_read(mytls_vars->ssl, indata, (*insize));
  if (rc < 0)
    {
      debug_printf(DEBUG_NORMAL, "Failed to get decyrpted data from OpenSSL."
		   "\n");
      tls_funcs_process_error();
      return XEMALLOC;
    }

  (*insize) = rc;

  return XENONE;
}

/************************************************************************
 *
 *  Encrypt data in our buffer.
 *
 ************************************************************************/
int tls_funcs_encrypt(struct tls_vars *mytls_vars, uint8_t *inbuf,
		      uint16_t insize)
{
  uint8_t *encrdata = NULL;
  int rc = 0;

  TRACE

  if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
    return -1;

  if (!xsup_assert((inbuf != NULL), "inbuf != NULL", FALSE))
    return -1;

  encrdata = Malloc(1500);
  if (encrdata == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store encrypted"
		   " data!\n");
	  ipc_events_malloc_failed(NULL);
      return XEMALLOC;
    }

  BIO_reset(mytls_vars->ssl_in);
  BIO_reset(mytls_vars->ssl_out);

  debug_printf(DEBUG_TLS_CORE, "inbuf (%d) :\n", insize);
  debug_hex_dump(DEBUG_TLS_CORE, inbuf, insize);

  rc = SSL_write(mytls_vars->ssl, inbuf, insize);
  if (rc <= 0)
    {
      debug_printf(DEBUG_NORMAL, "Error sending data to OpenSSL to be "
		   "encrypted.\n");
      rc = SSL_get_error(mytls_vars->ssl, rc);
      debug_printf(DEBUG_NORMAL, "Error was : ");
      switch (rc)
	{
	case SSL_ERROR_ZERO_RETURN:
	  debug_printf_nl(DEBUG_NORMAL, "zero return\n");
	  break;

	case SSL_ERROR_WANT_READ:
	  debug_printf_nl(DEBUG_NORMAL, "want read\n");
	  break;

	case SSL_ERROR_WANT_WRITE:
	  debug_printf_nl(DEBUG_NORMAL, "want write\n");
	  break;

	case SSL_ERROR_WANT_CONNECT:
	case SSL_ERROR_WANT_ACCEPT:
	  debug_printf_nl(DEBUG_NORMAL, "want connect/accept.\n");
	  break;

	case SSL_ERROR_WANT_X509_LOOKUP:
	  debug_printf_nl(DEBUG_NORMAL, "want x509 lookup.\n");
	  break;

	case SSL_ERROR_SYSCALL:
	  debug_printf_nl(DEBUG_NORMAL, "error syscall.\n");
	  break;
	}

      tls_funcs_process_error();
      FREE(encrdata);
      return -1;
    }

  if (mytls_vars->tlsoutqueue == NULL)
  {
	  // Need to build a queue.
	  debug_printf(DEBUG_TLS_CORE, "First packet in a possible chain.  Building queue.\n");
	  if (queue_create(&mytls_vars->tlsoutqueue) != 0)
	  {
		  debug_printf(DEBUG_NORMAL, "Couldn't create queue for outgoing data!!\n");
		  return -1;
	  }
  }

  rc = BIO_read(mytls_vars->ssl_out, encrdata, 1500);
  if (rc <= 0)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't read encrypted data from OpenSSL!"
		   "\n");
      tls_funcs_process_error();
      FREE(encrdata);
      return -1;
    }

  if (queue_enqueue(&mytls_vars->tlsoutqueue, encrdata, rc) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Failed to enqueue %d byte(s)!\n", rc);
	  FREE(encrdata);
	  return -1;
  }

  FREE(encrdata);

  return XENONE;
}

/************************************************************************
 *
 *  Clean up any memory that we used during our TLS session.
 *
 ************************************************************************/
void tls_funcs_deinit(struct tls_vars *mytls_vars)
{
  if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
    return;

  queue_destroy(&mytls_vars->tlsinqueue);
  queue_destroy(&mytls_vars->tlsoutqueue);

  //  BIOs are freed by the SSL_free call below.  Do not try to free them any other
  //  way, or you will segfault!
  if (mytls_vars->ssl != NULL)
    {
      SSL_free(mytls_vars->ssl);
      mytls_vars->ssl = NULL;
    }

  if (mytls_vars->ctx != NULL)
    {
      SSL_CTX_free(mytls_vars->ctx);
      mytls_vars->ctx = NULL;
    }
}

int tls_funcs_get_keyblock_len(struct tls_vars *mytls_vars)
{
  EVP_CIPHER *key_material;
  EVP_MD *hash;
  int len;

  key_material = (EVP_CIPHER *)mytls_vars->ssl->enc_read_ctx->cipher;
  hash = (EVP_MD *)mytls_vars->ssl->read_hash;

  len = 0;

  len = (EVP_CIPHER_key_length(key_material) * 2);
  len += (EVP_MD_size(hash) * 2);
  len += (EVP_CIPHER_iv_length(key_material) * 2);

  debug_printf(DEBUG_TLS_CORE, "Key block length used is %d byte(s).\n",
	       len);

  return len;
}

int tls_funcs_set_hello_extension(struct tls_vars *myvars, int type,
				  void *data, int len)
{
#ifdef EAP_FAST
  return SSL_set_hello_extension(myvars->ssl, type, data, len);
#else
  return -1;
#endif
}

uint8_t *tls_funcs_get_client_random(struct tls_vars *myvars)
{
  uint8_t *temp;

  temp = Malloc(SSL3_RANDOM_SIZE);
  if (temp == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store a "
		   "temporary copy of the TLS client random!\n");
	  ipc_events_malloc_failed(NULL);
      return NULL;
    }

  memcpy(temp, myvars->ssl->s3->client_random, SSL3_RANDOM_SIZE);

  return temp;
}

#ifdef EAP_FAST
static int tls_funcs_set_secret_cb(SSL *s, void *secret, int *secret_len,
				   STACK_OF(SSL_CIPHER) *peer_ciphers, 
				   SSL_CIPHER **cipher, void *arg)
{
  struct tls_vars *mytls_vars;

  mytls_vars = (struct tls_vars *)arg;

  debug_printf(DEBUG_NORMAL, "Secret CB called!\n");
  memcpy(secret, mytls_vars->derived_shared_secret, 
	 mytls_vars->derived_shared_secret_len);

  (*secret_len) = mytls_vars->derived_shared_secret_len;

  debug_printf(DEBUG_TLS_CORE, "Shared secret : \n");
  debug_hex_dump(DEBUG_TLS_CORE, secret, (*secret_len));

  return 1;
}

int tls_funcs_set_master_secret(struct tls_vars *myvars, uint8_t *new_secret,
				uint16_t length)
{
  if (!xsup_assert((myvars != NULL), "myvars != NULL", FALSE))
    return -1;

  if (!xsup_assert((new_secret != NULL), "new_secret != NULL", FALSE))
    return -1;

  myvars->derived_shared_secret = Malloc(length);
  if (myvars->derived_shared_secret == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store derived "
		   "shared secret!\n");
	  ipc_events_malloc_failed(NULL);
      return -1;
    }

  debug_printf(DEBUG_TLS_CORE, "Shared secret : \n");
  debug_hex_dump(DEBUG_TLS_CORE, new_secret, length);

  memcpy(myvars->derived_shared_secret, new_secret, length);
  myvars->derived_shared_secret_len = length;

  if (SSL_set_session_secret_cb(myvars->ssl, tls_funcs_set_secret_cb, myvars) != 1)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't set the derived secret callback "
		   "function!\n");
      return -1;
    }

  return 0;
}
#endif // EAP_FAST

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -