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

📄 crypto.c

📁 一个开源的VPN原码
💻 C
📖 第 1 页 / 共 3 页
字号:
      /* make sure IV changed */      if (!memcmp (iv_save, co->iv, EVP_MAX_IV_LENGTH))	  msg (M_FATAL, "IV Collision: before:%s after:%s",	       format_hex (iv_save, EVP_MAX_IV_LENGTH, 0),	       format_hex (co->iv, EVP_MAX_IV_LENGTH, 0));      /* decrypt */      openvpn_decrypt (&buf, decrypt_workspace, co, frame, current);      /* compare */      if (buf.len != src.len)	msg (M_FATAL, "SELF TEST FAILED, src.len=%d buf.len=%d", src.len, buf.len);      for (j = 0; j < i; ++j)	{	  const uint8_t in = *(BPTR (&src) + j);	  const uint8_t out = *(BPTR (&buf) + j);	  if (in != out)	    msg (M_FATAL, "SELF TEST FAILED, pos=%d in=%d out=%d", j, in, out);	}    }  msg (M_INFO, "OpenVPN crypto self-test mode SUCCEEDED.");}#ifdef USE_SSLvoidget_tls_handshake_key (const struct key_type *key_type,		       struct key_ctx_bi *ctx, const char *passphrase_file){  if (passphrase_file && key_type->hmac_length)    {      struct key key;      struct key_type kt = *key_type;      /* for control channel we are only authenticating, not encrypting */      kt.cipher_length = 0;      kt.cipher = NULL;      /* get key material for hmac */      {	int digest_len;	uint8_t digest[MAX_HMAC_KEY_LENGTH];	EVP_MD_CTX md;	CLEAR (key);	EVP_DigestInit (&md, kt.digest);	/* read passphrase file */	{	  const int min_passphrase_size = 8;	  uint8_t buf[512];	  int total_size = 0;	  int fd = open (passphrase_file, O_RDONLY);	  if (fd == -1)	    msg (M_ERR, "Cannot open passphrase file: %s", passphrase_file);	  for (;;)	    {	      int size = read (fd, buf, sizeof (buf));	      if (size == 0)		break;	      if (size == -1)		msg (M_ERR, "Read error on passphrase file: %s",		     passphrase_file);	      EVP_DigestUpdate (&md, buf, size);	      total_size += size;	    }	  close (fd);	  warn_if_group_others_accessible (passphrase_file);	  if (total_size < min_passphrase_size)	    msg (M_FATAL,		 "Passphrase file %s is too small (must have at least %d characters)",		 passphrase_file, min_passphrase_size);	}	EVP_DigestFinal (&md, digest, &digest_len);	ASSERT (digest_len == kt.hmac_length);	memcpy (key.hmac, digest, digest_len);	CLEAR (digest);	EVP_MD_CTX_cleanup (&md);      }      /* use same hmac key in both directions */      init_key_ctx (&ctx->encrypt, &key, &kt, DO_ENCRYPT,		    "Outgoing Control Channel Authentication");      init_key_ctx (&ctx->decrypt, &key, &kt, DO_DECRYPT,		    "Incoming Control Channel Authentication");      CLEAR (key);    }  else    {      CLEAR (*ctx);    }}#endif/* header and footer for static key file */static const char static_key_head[] = "-----BEGIN OpenVPN Static key V1-----";static const char static_key_foot[] = "-----END OpenVPN Static key V1-----";static const char printable_char_fmt[] =  "Non-Hex character ('%c') found at line %d in key file %s (%d/%d bytes found/required)";static const char unprintable_char_fmt[] =  "Non-Hex, unprintable character (0x%02x) found at line %d in key file %s (%d/%d bytes found/required)";/* read key from file */voidread_key_file (struct key *key, const char *filename){  const int gc_level = gc_new_level ();  struct buffer in = alloc_buf_gc (512);  int state = 0;  uint8_t* out = (uint8_t*) key;  int count = 0;  uint8_t hex_byte[3] = {0, 0, 0};  int hb_index = 0;  int line_num = 1;  int line_index = 0;  int matchlen = 0;  const int headlen = strlen(static_key_head);  const int keylen = sizeof (*key);  int fd, size;  fd = open (filename, O_RDONLY);  if (fd == -1)    msg (M_ERR, "Cannot open shared secret file %s", filename);  while (size = read (fd, in.data, in.capacity))    {      const char *cp = in.data;      while (size)	{	  const char c = *cp;	  /* msg (M_INFO, "char='%c' state=%d line_num=%d line_index=%d matchlen=%d",	     c, state, line_num, line_index, matchlen); */	  if (c == '\n')	    {	      line_index = 0;	      ++line_num;	    }	  else	    {	      /* found header line? */	      if (state == 0 && !line_index)		{		  if (matchlen == headlen)		    state = 1;		  matchlen = 0;		}	      /* compare read chars with header line */	      if (state == 0) {		if (line_index < headlen && c == static_key_head[line_index])		  ++matchlen;	      }	      /* reading key */	      if (state == 1) {		if (isxdigit(c))		  {		    ASSERT(hb_index < 2);		    hex_byte[hb_index++] = c;		    if (hb_index == 2)		      {			unsigned int u;			ASSERT(sscanf(hex_byte, "%x", &u) == 1);			*out++ = u;			hb_index = 0;			if (++count == keylen)			  state = 2;		      }		  }		else if (isspace(c))		  ;		else		  {		    msg (M_FATAL,			 (isprint (c) ? printable_char_fmt : unprintable_char_fmt),			 c, line_num, filename, count, keylen);		  }	      }	      ++line_index;	    }	  ++cp;	  --size;	}    }  close (fd);  if (state != 2)    msg (M_ERR, "Key not found in file %s (%d/%d bytes found/required)",	 filename, count, keylen);  /* zero file read buffer */  memset(in.data, 0, in.capacity);  warn_if_group_others_accessible (filename);  /* pop our garbage collection level */  gc_free_level (gc_level);}/* write key to file */voidwrite_key_file (const struct key *key, const char *filename){  int fd, size, len;  char* fmt;  const int gc_level = gc_new_level ();  struct buffer out = alloc_buf_gc (512);  /* open key file */  fd = open (filename, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU);  if (fd == -1)    msg (M_ERR, "Cannot open shared secret file %s for write", filename);  /* format key as ascii */  fmt = format_hex_ex ((const uint8_t*)key, sizeof (*key), 0, 8, "\n");  buf_printf (&out, "%s\n", static_key_head);  buf_printf (&out, "%s\n", fmt);  buf_printf (&out, "%s\n", static_key_foot);  /* write data to file */  len = strlen (BPTR(&out));  size = write (fd, BPTR(&out), len);  if (size != len)    msg (M_ERR, "Write error on shared secret file %s", filename);  if (close (fd))    msg (M_ERR, "Close error on shared secret file %s", filename);  /* zero memory that held keys (memory will be freed by garbage collector) */  memset (BPTR(&out), 0, len);  memset (fmt, 0, strlen(fmt));  /* pop our garbage collection level */  gc_free_level (gc_level);}/* given a key and key_type, write key to buffer */voidwrite_key (const struct key *key, const struct key_type *kt,	   struct buffer *buf){  ASSERT (kt->cipher_length <= MAX_CIPHER_KEY_LENGTH	  && kt->hmac_length <= MAX_HMAC_KEY_LENGTH);  ASSERT (buf_write (buf, &kt->cipher_length, 1));  ASSERT (buf_write (buf, &kt->hmac_length, 1));  ASSERT (buf_write (buf, key->cipher, kt->cipher_length));  ASSERT (buf_write (buf, key->hmac, kt->hmac_length));}/* * Given a key_type and buffer, read key from buffer. * Return: 1 on success *        -1 read failure *         0 on key length mismatch  */intread_key (struct key *key, const struct key_type *kt, struct buffer *buf){  uint8_t cipher_length;  uint8_t hmac_length;  CLEAR (*key);  if (!buf_read (buf, &cipher_length, 1))    goto read_err;  if (!buf_read (buf, &hmac_length, 1))    goto read_err;  if (!buf_read (buf, key->cipher, cipher_length))    goto read_err;  if (!buf_read (buf, key->hmac, hmac_length))    goto read_err;  if (cipher_length != kt->cipher_length || hmac_length != kt->hmac_length)    goto key_len_err;  return 1;read_err:  msg (D_TLS_ERRORS, "TLS Error: error reading key from remote");  return -1;key_len_err:  msg (D_TLS_ERRORS,       "TLS Error: key length mismatch, local cipher/hmac %d/%d, remote cipher/hmac %d/%d",       kt->cipher_length, kt->hmac_length, cipher_length, hmac_length);  return 0;}voidshow_available_ciphers (){  int nid;  printf ("The following ciphers and cipher modes are available\n"	  "for use with OpenVPN.  Each cipher shown below may be\n"	  "used as a parameter to the --cipher option.  The default\n"	  "key size is shown as well as whether or not it can be\n"          "changed with the --keysize directive.  Using a CBC mode\n"	  "is recommended.\n\n");  for (nid = 0; nid < 10000; ++nid)	/* is there a better way to get the size of the nid list? */    {      const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid);      if (cipher && cipher_ok (OBJ_nid2sn (nid)))	{	  const unsigned int mode = EVP_CIPHER_mode (cipher);	  if (mode == EVP_CIPH_CBC_MODE || mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE)	    printf ("%s %d bit default key (%s)\n",		    OBJ_nid2sn (nid),		    EVP_CIPHER_key_length (cipher) * 8,		    ((EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ?		     "variable" : "fixed"));	}    }  printf ("\n");}voidshow_available_digests (){  int nid;  printf ("The following message digests are available for use with\n"	  "OpenVPN.  A message digest is used in conjunction with\n"	  "the HMAC function, to authenticate received packets.\n"	  "You can specify a message digest as parameter to\n"	  "the --auth option.\n\n");  for (nid = 0; nid < 10000; ++nid)    {      const EVP_MD *digest = EVP_get_digestbynid (nid);      if (digest)	{	  printf ("%s %d bit digest size\n",		  OBJ_nid2sn (nid), EVP_MD_size (digest) * 8);	}    }  printf ("\n");}/* * This routine should have additional OpenSSL crypto library initialisations * used by both crypto and ssl components of OpenVPN. */void init_crypto_lib (){}#ifndef USE_SSLvoidinit_ssl_lib (){  ERR_load_crypto_strings ();  OpenSSL_add_all_algorithms ();  init_crypto_lib();}voidfree_ssl_lib (){  EVP_cleanup ();  ERR_free_strings ();}#endif /* USE_SSL */#endif /* USE_CRYPTO */

⌨️ 快捷键说明

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