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

📄 ossl_tls_funcs.c

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

/***********************************************************************
 *
 *  Return the password for our user certificate.
 *
 ***********************************************************************/
static int return_password(char *buf, int size, int rwflag, void *userdata)
{
  TRACE

  if (!xsup_assert((buf != NULL), "buf != NULL", FALSE))
    return XEMALLOC;

  if (!xsup_assert((userdata != NULL), "userdata != NULL", FALSE))
    return XEMALLOC;

  if (Strncpy(buf, size, (char *)(userdata), size) != 0)
  {
	  debug_printf(DEBUG_NORMAL, "Attempt to overflow a buffer in %s() at %d!\n",
		  __FUNCTION__, __LINE__);
	  return -1;
  }

  buf[size-1] = '\0';
  return(strlen(buf));
}

/**************************************************************************
 *
 * Load any root certificates that the user would want to use.
 *
 **************************************************************************/
int tls_funcs_load_root_certs(struct tls_vars *mytls_vars, char *root_cert, 
			      char *root_dir, char *crl_dir)
{
  TRACE

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

  if (!xsup_assert((mytls_vars->ctx != NULL), "mytls_vars->ctx != NULL", 
		   FALSE))
    return XEMALLOC;

  if ((!root_cert) && (!root_dir))
    {
      debug_printf(DEBUG_NORMAL, "Error loading cert!  Path to cert is NULL!\n");
      return XETLSCERTLOAD;
    } 

  if (mytls_vars->ctx == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Invalid context in tls_funcs_load_root_certs()!\n");
      return XEMALLOC;
    }

  debug_printf(DEBUG_TLS_CORE, "Trying to load root certificate %s or "
	       "certificate directory %s\n", root_cert, root_dir);

  SSL_CTX_set_info_callback(mytls_vars->ctx, (void (*) (const SSL *, int, int)) ssl_info_callback);
  
  if (SSL_CTX_load_verify_locations(mytls_vars->ctx, root_cert, root_dir) == 0)
    {
      debug_printf(DEBUG_NORMAL, "Failed to initialize path to root certificate!\n");
      tls_funcs_process_error();

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

  debug_printf(DEBUG_TLS_CORE, "Loaded root certificate %s and directory %s\n",
		root_cert, root_dir);

  if (crl_dir) {
    if (SSL_CTX_load_verify_locations(mytls_vars->ctx, NULL, crl_dir) == 0)
      {
	debug_printf(DEBUG_NORMAL, "Failed to initalize path to CRLs!\n");
	tls_funcs_process_error();
	//debug_printf(DEBUG_NORMAL, "Error : %s\n", ERR_error_string(ERR_get_error(), NULL));
	if(mytls_vars->ctx)
	  {
	    SSL_CTX_free(mytls_vars->ctx);
	    mytls_vars->ctx = NULL;
	  }
	return XETLSCERTLOAD;
      }
  }
  

  /* Do we really want to pick up the default paths? */
  if (SSL_CTX_set_default_verify_paths(mytls_vars->ctx) == 0)
    {
      debug_printf(DEBUG_NORMAL, "Failed to initalize default paths for root certificates!\n");
      tls_funcs_process_error();

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

  return XENONE;
}

/*************************************************************************
 *
 *  Use a file to load some random data.
 *
 *************************************************************************/
int tls_funcs_load_random(struct tls_vars *mytls_vars, char *random_file)
{
  char *default_random = "/dev/urandom", *file;

  TRACE

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

  file = random_file == NULL ? default_random : random_file;

  if (RAND_load_file(file, 1024) < 0)
    {
      tls_funcs_process_error();
      if(mytls_vars->ctx)
	{
	  SSL_CTX_free(mytls_vars->ctx);
	  mytls_vars->ctx = NULL;
	}
	  
      debug_printf(DEBUG_NORMAL, "Couldn't load random data from %s\n", file);

      return -1;
    } 

  return XENONE;
}


/***************************************************************************
 *
 * Load a user certificate in to OpenSSL so that it can be used for
 * authentication.
 *
 ***************************************************************************/
int tls_funcs_load_user_cert(struct tls_vars *mytls_vars, 
			     char *client_cert, char *key_file, char *password)
{
  TRACE

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

  if (!xsup_assert((client_cert != NULL), "client_cert != NULL", FALSE))
    return XEMALLOC;

  if (!xsup_assert((key_file != NULL), "key_file != NULL", FALSE))
    return XEMALLOC;

  if (!xsup_assert((password != NULL), "password != NULL", FALSE))
    return XEMALLOC;

  SSL_CTX_set_default_passwd_cb_userdata(mytls_vars->ctx, password);
  SSL_CTX_set_default_passwd_cb(mytls_vars->ctx, return_password);

  if (SSL_CTX_use_certificate_file(mytls_vars->ctx, client_cert, 
				   SSL_FILETYPE_ASN1) != 1 &&
      SSL_CTX_use_certificate_file(mytls_vars->ctx, client_cert, 
				   SSL_FILETYPE_PEM) != 1 )
    {
      debug_printf(DEBUG_NORMAL, "Couldn't load client certificate data!\n");
      tls_funcs_process_error();
      if(mytls_vars->ctx)
	{
	  SSL_CTX_free(mytls_vars->ctx);
	  mytls_vars->ctx = NULL;
	}
      return XETLSCERTLOAD;
    }

  debug_printf(DEBUG_TLS_CORE, "Loading user Private Key from %s...\n", key_file);
  
  // XXX Add back support for smart card based TLS.
  /*
  if (userdata->sc.engine_id)
    {
      EVP_PKEY *pkey;
      debug_printf(DEBUG_CONFIG, "Loading user Private Key with id %s from %s...\n", userdata->sc.key_id, userdata->sc.engine_id);
      set_smartcard_pin(password);
      pkey = ENGINE_load_private_key(mytls_vars->engine, userdata->sc.key_id,
		      UI_noninteractive(), NULL);
      SSL_CTX_use_PrivateKey(mytls_vars->ctx, pkey);
      //EVP_PKEY_free(pkey);
    }
    else  */
  if (SSL_CTX_use_PrivateKey_file(mytls_vars->ctx, key_file, 
				  SSL_FILETYPE_PEM) != 1 &&
      SSL_CTX_use_PrivateKey_file(mytls_vars->ctx, key_file, 
				  SSL_FILETYPE_ASN1) != 1) 
    {
      tls_funcs_process_error();
      if(mytls_vars->ctx)
	{
	  SSL_CTX_free(mytls_vars->ctx);
	  mytls_vars->ctx = NULL;
	}
      debug_printf(DEBUG_NORMAL, "Couldn't load client private key!\n");
      return XETLSCERTLOAD;
    }

  if (!SSL_CTX_check_private_key(mytls_vars->ctx))
    {
      debug_printf(DEBUG_NORMAL, "Private key isn't valid!\n");
      tls_funcs_process_error();
      return XETLSCERTLOAD;
    }

  SSL_CTX_set_options(mytls_vars->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
		      SSL_OP_SINGLE_DH_USE);

  if (mytls_vars->verify_cert == TRUE)
    {
      SSL_CTX_set_verify(mytls_vars->ctx, SSL_VERIFY_PEER | 
			 SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
    }
  else
    {
      SSL_CTX_set_verify(mytls_vars->ctx, SSL_VERIFY_NONE |
			 SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
    }

  return XENONE;
}

/* TLS PRF from rfc2246 pages 11-12 */
int
ossl_tls_funcs_PRF(uint8_t *secret, int secret_len, uint8_t *label, 
		   int label_len, uint8_t *seed, int seed_len, uint8_t *output,
		   int outlen)
{
  int retVal = 0;
  int L_S1, L_S2;
  uint8_t *S1, *S2;
  uint8_t *P_MD5_buf, *P_SHA1_buf;
  uint8_t *P_seed;
  int P_seed_len;
  uint8_t A_MD5[MD5_DIGEST_LENGTH];
  uint8_t A_SHA1[SHA_DIGEST_LENGTH];
  int MD5_iterations, SHA1_iterations;
  int i, hashed_len;
  const EVP_MD *hash;
  HMAC_CTX ctx;

  TRACE

  if (!xsup_assert((secret != NULL), "secret != NULL", FALSE))
    return XEMALLOC;

  if (!xsup_assert((label != NULL), "label != NULL", FALSE))
    return XEMALLOC;

  if (!xsup_assert((seed != NULL), "seed != NULL", FALSE))
    return XEMALLOC;

  if (!xsup_assert((output != NULL), "output != NULL", FALSE))
    return XEMALLOC;

  /* determine the length of "half" the secret */
  if (secret_len % 2 == 0) {
    L_S1 = secret_len / 2;
  }
  else {
    L_S1 = secret_len / 2 + 1;
  }
  L_S2 = L_S1;
  S1 = secret; /* first L_S1 bytes of secret */
  S2 = secret + secret_len - L_S2;  /* last L_S2 bytes of secret */
  MD5_iterations = outlen / MD5_DIGEST_LENGTH;
  /* if there is anything left over, iterate 1 more time */
  MD5_iterations = outlen % MD5_DIGEST_LENGTH == 0 ? 
    MD5_iterations : MD5_iterations + 1;
  SHA1_iterations = outlen / SHA_DIGEST_LENGTH;
  SHA1_iterations = outlen % SHA_DIGEST_LENGTH == 0 ?
    SHA1_iterations : SHA1_iterations + 1;
  P_seed_len = label_len + seed_len;
  P_seed = (uint8_t *)Malloc(sizeof(uint8_t) * P_seed_len);
  if (P_seed == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Error with malloc of P_seed in tls_funcs_PRF().\n");
	  ipc_events_malloc_failed(NULL);
      return XEMALLOC;
    }

  memcpy(P_seed, label, label_len);
  memcpy(P_seed+label_len, seed, seed_len);
  P_MD5_buf = (uint8_t *)Malloc(sizeof(uint8_t) * 
			       MD5_iterations  * MD5_DIGEST_LENGTH);
  if (P_MD5_buf == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Error with malloc of P_MD5_buf in tls_funcs_PRF().\n");
	  ipc_events_malloc_failed(NULL);
      FREE(P_seed);
      return XEMALLOC;
    }

  P_SHA1_buf = (uint8_t *)Malloc(sizeof(uint8_t) *
				SHA1_iterations * SHA_DIGEST_LENGTH);
  if (P_SHA1_buf == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Error with malloc of P_SHA1_buf in tls_funcs_PRF().\n");
	  ipc_events_malloc_failed(NULL);
      FREE(P_seed);
      FREE(P_MD5_buf);
      return XEMALLOC;
    }

  /* P_MD5 */
  hash = EVP_md5();
  /* Initialize A_MD5 */
  HMAC(hash, S1, L_S1, P_seed, P_seed_len, A_MD5, (u_int *) &hashed_len);

  for (i = 0; i < MD5_iterations; i++) {
    HMAC_Init(&ctx, S1, L_S1, hash);
    HMAC_Update(&ctx, A_MD5, MD5_DIGEST_LENGTH);
    HMAC_Update(&ctx, P_seed, P_seed_len);
    HMAC_Final(&ctx, P_MD5_buf + i*(MD5_DIGEST_LENGTH), (u_int *) &hashed_len);
    HMAC_cleanup(&ctx);
    HMAC(hash, S1, L_S1, A_MD5, MD5_DIGEST_LENGTH,
	 A_MD5, (u_int *) &hashed_len);
  }
    

  /* do P_SHA1 */
  hash = EVP_sha1();
  /* Initialize A_SHA1 */
  HMAC(hash, S2, L_S2, P_seed, P_seed_len, A_SHA1, (u_int *) &hashed_len);

  for (i = 0; i < SHA1_iterations; i++) {
    HMAC_Init(&ctx, S2, L_S2, hash);
    HMAC_Update(&ctx, A_SHA1, SHA_DIGEST_LENGTH);
    HMAC_Update(&ctx, P_seed, P_seed_len);
    HMAC_Final(&ctx, P_SHA1_buf + i*(SHA_DIGEST_LENGTH), (u_int *) &hashed_len);
    HMAC_cleanup(&ctx);
    HMAC(hash, S2, L_S2, A_SHA1, SHA_DIGEST_LENGTH,
	 A_SHA1, (u_int *) &hashed_len);
  }
  /* XOR Them for the answer */
  for (i = 0; i < outlen; i++) {
    *(output + i) = P_MD5_buf[i] ^ P_SHA1_buf[i];
  }

  FREE(P_seed);
  FREE(P_MD5_buf);
  FREE(P_SHA1_buf);

  return retVal;
}

/* smartcard support */

#define OPENSC_ENGINE_SO_PATH "/usr/lib/opensc/engine_opensc.so"
#define OPENSC_ENGINE_ID      "opensc"

/* This function 
 * - loads OpenSSL's "dynamic" engine
 * - executes all the commands given in the pre array of strings
 *   These commands will usually load the shared object, do some 
 *   initialization and add the engine to OpenSSL's internal list of 
 *   Engines
 */
#ifndef WINDOWS
int engine_load_dynamic(char *pre[])
{
  char *engine_id = "dynamic";
  int rc;
  ENGINE *e;
  ENGINE_load_dynamic();
  e = ENGINE_by_id(engine_id);
  if(!e)
    {
      printf("can't find engine %s\n", engine_id);
      goto err;
    }
  while(pre && pre[0])
    {
      /*printf("\"%s\" \"%s\"\n", pre[0], pre[1]);*/
      rc = ENGINE_ctrl_cmd_string(e, pre[0], pre[1], 0);
      if(rc == 0)
        {
          printf("ctrl cmd_string failed: %s %s\n", 
					pre[0], pre[1]);
  	  goto err_pre;
        }
      pre += 2;
    }
  /* Free the reference to the "dynamic" engine
   * The OpenSC engine can still be looked up using 
   * ENGINE_by_id() */

  ENGINE_free(e);
  return 1;
err_pre:
  ENGINE_free(e);
err:
  ENGINE_cleanup();
  return 0;
}
#endif  // WINDOWS

/* This function
 *  - makes the opensc engine available to OpenSSL
 */
#ifndef WINDOWS
int engine_load_dynamic_opensc(struct smartcard *sc)
{
  char *pre_cmd[] = 
    {
      "SO_PATH", sc->opensc_so_path,
      "ID", OPENSC_ENGINE_ID,
      "LIST_ADD", "1",
      "LOAD", NULL,
      NULL, NULL
    };

  if (xsup_assert((sc != NULL), "sc != NULL", FALSE))
    return XEMALLOC;

  debug_printf(DEBUG_NORMAL, "Loading opensc engine.\n");
  if(!sc->opensc_so_path)
    {
      /* use the default value */
      sc->opensc_so_path = OPENSC_ENGINE_SO_PATH;
    }

  return engine_load_dynamic(pre_cmd);
}
#endif  // WINDOWS

/* provide a UI_METHOD that makes it possible to use a string as the
 * smartcard PIN */
char *smartcard_pin = NULL;

void set_smartcard_pin(char *pin)
{
  smartcard_pin = pin;
}

void unset_smartcard_pin()
{
  set_smartcard_pin(NULL);
}

int read_string(UI *ui, UI_STRING *uis)
{
  if(smartcard_pin)
    {
      UI_set_result(ui, uis, smartcard_pin);
      return 1;
    }
  return 0;
}

UI_METHOD *UI_noninteractive(void)
{
  UI_METHOD *ui_method;
  ui_method = UI_create_method("ui_noninteractive");
  UI_method_set_reader(ui_method, read_string);
  return ui_method;
}

/**********************************************************************
 *
 *  Generate a key block to be used to derive keys.
 *
 **********************************************************************/
uint8_t *tls_funcs_gen_keyblock(struct tls_vars *mytls_vars, uint8_t first,
				uint8_t *sesskey, uint16_t sesskeylen)
{
  uint8_t seed[SSL3_RANDOM_SIZE*2];
  uint8_t *p = seed;
  uint8_t *retblock;

  TRACE

  debug_printf(DEBUG_TLS_CORE, "Generating key block!\n");

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

  if (sesskey == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No keying material is available!  It is "
                   "unlikely that your session will work properly.\n");
      return NULL;
    }

  if (!mytls_vars->ssl)
    {
      debug_printf(DEBUG_NORMAL, "No valid SSL context found!\n");

⌨️ 快捷键说明

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