示例#1
0
文件: keymgt.c 项目: crooks/mixmaster
int
get_priv_key (unsigned char *ID, PRIVATE_KEY * privkey)
{
  /* return key ID, or signature key if ID == NULL */
  unsigned char line[1024], IDstr[80];
  unsigned char newID[16];
  int found = 0;
  FILE *privring;
  FILE *privlock;
  unsigned long t;

  if (ID != NULL)
    encode_ID (IDstr, ID);
  mix_lock ("secring", &privlock);
  if ((privring = open_mix_file (SECRING, "r")) == NULL)
    {
      mix_unlock ("secring", privlock);
      return (-1);
    }
  while (!found)
    {
      getline (line, sizeof (line), privring);
      while (!streq (line, begin_key))
	{
	  if (getline (line, sizeof (line), privring) == NULL)
	    {
	      fclose (privring);
	      mix_unlock ("secring", privlock);
	      goto notfound;
	    }
	}
      getline (line, sizeof (line), privring);
      /* THIS SHOULD NOT RELY ON THE ORDER OF THE LINES ** */
      if (strstr (line, KEY_VERSION))
	getline (line, sizeof (line), privring);
      if (strstr (line, KEY_VALID))
	{
	  sscanf (line, KEY_VALID "%lu", &t);
	  if ((unsigned long) time (NULL) < t)
	    continue;		/* don't use keys that aren't currently valid */
	}
      if (strstr (line, KEY_EXPIRES))
	{
	  sscanf (line, KEY_EXPIRES "%lu", &t);
	  if (t < (unsigned long) time (NULL))
	    continue;
	}
      if ((ID != NULL) && strstr (line, KEY_TYPE) && strstr (line, "sig"))
	continue;		/* use sig key only if asked */

      if ((ID != NULL && strstr (line, IDstr)) ||
	  ((ID == NULL) && strstr (line, KEY_TYPE) && strstr (line, "sig")))
	{
	  /* we use this key if the ID matches or it is the sig key we need */

	  if (strstr (line, "sig"))
	    getline (line, sizeof (line), privring);	/* read and drop ID */

	  if (read_priv_key (privring, privkey, newID) != 0)
	    break;
	  /* compare new ID with passed ID */
	  if ((ID != NULL) && (memcmp (ID, newID, 16) != 0))
	    {
	      fprintf (errlog, "Error: Private Key IDs do not match!  Bad passphrase?\n");
	      break;
	    }
	  found = 1;		/* this will end the loop */
	}
    }
  fclose (privring);
  mix_unlock ("secring", privlock);
  if (found)
    return (0);
notfound:
  if (ID == NULL)
    fprintf (errlog, "Unable to get signature key!\n");
  else
    fprintf (errlog, "Unable to get private key %s!\n", IDstr);
  return (1);
}
示例#2
0
文件: keymgt.c 项目: crooks/mixmaster
void
write_keyfile (void)
{
  /* read the public keys from secring.mix... */
  FILE *privring, *privlock;
  FILE *keyfile, *keylock, *keyinfo;
  BUFFER *b1, *buff, *header;
#ifdef NEW
  BUFFER *signature;
#endif
  char line[1024], IDstr[80];
  long pos;
  int i, len;
  byte tmpbyte;
  PRIVATE_KEY privkey;
  unsigned char ID[16];
  char abilities[256] = "";
#ifndef USE_RSAREF
  A_PKCS_RSA_PRIVATE_KEY *pkinfo;
#endif

  our_abilities (abilities);

  mix_lock ("secring", &privlock);
  if ((privring = open_mix_file (SECRING, "r+")) == NULL)
    {
      mix_unlock ("secring", privlock);
      return;
    }

  buff = new_buffer ();
#ifdef NEW
  str_to_buffer (buff, begin_signed);
  str_to_buffer (buff, "\n");
#endif
  while ((pos = next_key (privring)) != -1)
    {
      header = new_buffer ();

      for (;;)			/* copy the header and to a buffer */
	{
	  getline (line, sizeof (line), privring);
	  if (!strstr (line, ": "))
	    break;
	  str_to_buffer (header, line);
	}
      if (read_priv_key (privring, &privkey, ID) != 0)
	break;
      encode_ID (IDstr, ID);
      if (memcmp (line, IDstr, 32) != 0)
	{
	  fprintf (errlog, "Error: Private Key IDs do not match!  Bad passphrase?\n");
	  fclose (privring);
	  mix_unlock ("secring", privlock);
	  exit (-1);
	}

      /* write key to buff */
      if (header->length == 0)
	{			/* old format */
	  sprintf (line, "%s %s ", SHORTNAME, REMAILERADDR);
	  str_to_buffer (buff, line);
	  str_to_buffer (buff, IDstr);
	  str_to_buffer (buff, " ");
	  str_to_buffer (buff, mixmaster_protocol);
	  str_to_buffer (buff, VERSION);
	  str_to_buffer (buff, " ");
	  str_to_buffer (buff, abilities);
	  str_to_buffer (buff, "\n\n");
	  str_to_buffer (buff, begin_key);
	  str_to_buffer (buff, "\n");
	}
      else
	{
	  str_to_buffer (buff, begin_key);
	  str_to_buffer (buff, "\n");
	  add_to_buffer (buff, header->message, header->length);
	}
      str_to_buffer (buff, IDstr);
      str_to_buffer (buff, "\n");
      free_buffer (header);

      /* Armor pubkey */
      b1 = new_buffer ();
#ifdef USE_RSAREF
      /* Convert pubkey.bits to two bytes */
      i = privkey.bits;
#else
      B_GetKeyInfo ((POINTER *) & pkinfo, privkey, KI_PKCS_RSAPrivate);
      i = pkinfo->modulus.len * 8;
#endif
      tmpbyte = i & 0xFF;
      add_to_buffer (b1, &tmpbyte, 1);	/* low byte of bits */
      i = i / 256;
      tmpbyte = i & 0xFF;
      add_to_buffer (b1, &tmpbyte, 1);	/* high byte of bits */

#ifdef USE_RSAREF
      add_to_buffer (b1, privkey.modulus, MAX_RSA_MODULUS_LEN);
      add_to_buffer (b1, privkey.publicExponent, MAX_RSA_MODULUS_LEN);
#else
      add_to_buffer (b1, pkinfo->modulus.data, pkinfo->modulus.len);
      if (pkinfo->publicExponent.len < pkinfo->modulus.len)
	add_to_buffer (b1, NULL,
		       pkinfo->modulus.len - pkinfo->publicExponent.len);
      add_to_buffer (b1, pkinfo->publicExponent.data,
		     pkinfo->publicExponent.len);
#endif
      len = b1->length;
      while ((b1->length % 3) != 0)
	str_to_buffer (b1, "X");

      sprintf (line, "%d\n", len);
      str_to_buffer (buff, line);
      armor (b1);
      add_to_buffer (buff, b1->message, b1->length);
      free_buffer (b1);
      str_to_buffer (buff, end_key);
      str_to_buffer (buff, "\n");
    }
  fclose (privring);
  mix_unlock ("secring", privlock);

#ifdef NEW
  str_to_buffer (buff, begin_cfg);
  sprintf (line, "\n%s%s\n", KEY_VERSION, VERSION);
  str_to_buffer (buff, line);
  sprintf (line, "%s%s\n", CFG_REMAILER, SHORTNAME);
  str_to_buffer (buff, line);
  sprintf (line, "%s%s\n", CFG_ADDRESS, REMAILERADDR);
  str_to_buffer (buff, line);
  sprintf (line, "%s%s\n", CFG_ABILITIES, abilities);
  str_to_buffer (buff, line);
  sprintf (line, "%s%lu\n", CFG_DATE, (unsigned long) time (NULL));
  str_to_buffer (buff, line);
  str_to_buffer (buff, end_cfg);

  signature = new_buffer ();
  create_sig (buff, signature);
  armor (signature);
  str_to_buffer (buff, "\n");
  str_to_buffer (buff, begin_signature);
  str_to_buffer (buff, "\n");
  add_to_buffer (buff, signature->message, signature->length);
  str_to_buffer (buff, end_signature);
#endif

  mix_lock ("key", &keylock);
  if ((keyinfo = open_mix_file (KEYINFO, "r")) == NULL ||
      (keyfile = open_mix_file (KEYFILE, "w")) == NULL)
    {
      mix_unlock ("key", keylock);
      return;
    }
  while (getline (line, sizeof (line), keyinfo) != NULL)
    fprintf (keyfile, "%s\n", line);
  fclose (keyinfo);
  write_buffer (buff, keyfile);
  fclose (keyfile);
  mix_unlock ("key", keylock);
  free_buffer (buff);
}
示例#3
0
/*
* RSA public decryption function.
* Dencrypt 'in_len' bytes from 'envelope' buffer with the private key contained in 'priv_key_file' 
* Parameter 'outlen' is the size of output buffer 
* It returns the received plaintext or NULL if an error occurs.
*/
unsigned char* asym_decrypt(unsigned char* envelope, int in_len, int* out_len, char* priv_key_file){
	EVP_PKEY* priv_key;
	int ret;	
	EVP_CIPHER_CTX* ctx;
	unsigned char* encrypted_key;
	int encrypted_key_len;
	unsigned char* iv;
	int iv_len;
	unsigned char* ciphertext;
	int ciphertext_len;
	unsigned char* output;
	int output_len;
	int app;
	
		
	if(ciphertext == NULL || in_len < 0 || out_len == NULL || priv_key_file == NULL)
		return NULL;
	
	//Reads the receiver's public key for its file
	priv_key = read_priv_key(priv_key_file);
	
	//Note: envelope format -> <IV><Dim_Key><Ecrypt_KEY><Ciphertext>
	
	//Set to the head the iv pointer
	iv = envelope;
	iv_len = EVP_CIPHER_iv_length(SYM_CIPHER);
	
	//Read from the envelop the encrypted_key_len
	memcpy(&encrypted_key_len, envelope + iv_len, sizeof(int));
	
	//Set the encrypted_key pointer
	encrypted_key = envelope + iv_len + sizeof(int);
	
	//Set the ciphertext pointer
	ciphertext = envelope + iv_len + sizeof(int) + encrypted_key_len;
	ciphertext_len = in_len - iv_len - sizeof(int) - encrypted_key_len;
	
	//Instantiate and initialize the context
	ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
	EVP_CIPHER_CTX_init(ctx);
	ret = EVP_OpenInit(ctx, SYM_CIPHER, encrypted_key, encrypted_key_len, iv, priv_key);
	if(ret == 0)
		goto error;
	
	//Decrypt the ciphertext
	output_len = ciphertext_len;
	output = malloc(output_len);
	output_len = 0;
	ret = EVP_OpenUpdate(ctx, output, &app, ciphertext, ciphertext_len);
	if(ret == 0)
		goto error;
		
	output_len += app;
	ret = EVP_OpenFinal(ctx, output + app, &app);
	if(ret == 0)
		goto error;
	output_len += app;
	
	*out_len = output_len;
	
	//Cleanup	
	EVP_CIPHER_CTX_cleanup(ctx);
   	free(ctx);
	free(priv_key);
	
	return output;
error:
	if(ctx != NULL){
		EVP_CIPHER_CTX_cleanup(ctx);
   		free(ctx);
	}
	if(encrypted_key != NULL)
		free(ciphertext);	
	if(priv_key != NULL)
		free(priv_key);
	if(iv != NULL)		
		free(iv);
	if(ciphertext != NULL)
		free(ciphertext);		
	if(output != NULL)
		free(output);
	return NULL;
	
}