Пример #1
0
int
shishi_apreq_decrypt (Shishi * handle,
		      Shishi_asn1 apreq,
		      Shishi_key * key,
		      int keyusage, Shishi_asn1 * authenticator)
{
  int res;
  int i;
  char *buf;
  size_t buflen;
  char *cipher;
  size_t cipherlen;
  int etype;

  res = shishi_apreq_get_authenticator_etype (handle, apreq, &etype);
  if (res != SHISHI_OK)
    return res;

  if (etype != shishi_key_type (key))
    return SHISHI_APREQ_BAD_KEYTYPE;

  res = shishi_asn1_read (handle, apreq, "authenticator.cipher",
			  &cipher, &cipherlen);
  if (res != SHISHI_OK)
    return res;

  res = shishi_decrypt (handle, key, keyusage,
			cipher, cipherlen, &buf, &buflen);
  free (cipher);
  if (res != SHISHI_OK)
    {
      shishi_error_printf (handle,
			   "decrypt fail, most likely wrong password\n");
      return SHISHI_APREQ_DECRYPT_FAILED;
    }

  /* The crypto is so 1980; no length indicator. Trim off pad bytes
     until we can parse it. */
  for (i = 0; i < 8; i++)
    {
      if (VERBOSEASN1 (handle))
	printf ("Trying with %d pad in enckdcrep...\n", i);

      *authenticator = shishi_der2asn1_authenticator (handle, &buf[0],
						      buflen - i);
      if (*authenticator != NULL)
	break;
    }

  if (*authenticator == NULL)
    {
      shishi_error_printf (handle, "Could not DER decode Authenticator. "
			   "Password probably correct (decrypt ok) though\n");
      return SHISHI_ASN1_ERROR;
    }

  return SHISHI_OK;
}
Пример #2
0
/* read encrypted data on socket */
int
readenc (Shishi * h, int sock, char *buf, int *len, shishi_ivector * iv,
	 Shishi_key * enckey, int proto)
{
  char *out;
  char *outbis;

  int rc;
  int val;
  int outlen;
  int dlen = 0, blocksize, enctype, hashsize;

  /* read size of message */
  read (sock, &dlen, sizeof (int));

  dlen = ntohl (dlen);
  /* if 0 put read size to 0 */
  if (!dlen)
    {
      *len = dlen;
      return SHISHI_OK;
    }

  if (proto == 1)
    *len = dlen;

  /* convert size to encryption size */
  enctype = shishi_key_type (enckey);

  blocksize = shishi_cipher_blocksize (enctype);
  hashsize =
    shishi_checksum_cksumlen (shishi_cipher_defaultcksumtype (enctype));

  switch (enctype)
    {
    case SHISHI_AES128_CTS_HMAC_SHA1_96:
    case SHISHI_AES256_CTS_HMAC_SHA1_96:
      dlen += 4 + hashsize + blocksize;
      break;
    case SHISHI_ARCFOUR_HMAC:
    case SHISHI_ARCFOUR_HMAC_EXP:
      dlen += 4 + 8 + blocksize - 1;
      dlen /= blocksize;
      dlen *= blocksize;
      dlen += hashsize;
      break;
    case SHISHI_DES3_CBC_HMAC_SHA1_KD:
      dlen += 4 + 2 * blocksize - 1;
      dlen /= blocksize;
      dlen *= blocksize;
      dlen += hashsize;
      break;
    case SHISHI_DES_CBC_CRC:
      dlen += 2 * blocksize - 1;
      if (proto == 2)
	dlen += 4;
      dlen += hashsize;
      dlen /= blocksize;
      dlen *= blocksize;
      break;
    default:
      dlen += blocksize - 1;
      if (proto == 2)
	dlen += 4;
      dlen += hashsize;
      dlen /= blocksize;
      dlen *= blocksize;
      break;
    }

  /* read encrypted data */
  outbis = malloc (dlen);
  if (outbis == NULL)
    {
      perror ("readenc()");
      return 1;
    }

  rc = read (sock, outbis, dlen);
  if (rc != dlen)
    {
      fprintf (stderr, "Error during read socket\n");
      free (outbis);
      return 1;
    }

  if (proto == 1)
    {
      rc =
	shishi_decrypt (h, enckey, iv->keyusage, outbis, dlen, &out, &outlen);
      if (rc != SHISHI_OK)
	{
	  fprintf (stderr, "decryption error\n");
	  free (outbis);
	  return 1;
	}

      val = 0;
    }
  else
    {
      rc = shishi_crypto_decrypt (iv->ctx, outbis, dlen, &out, &outlen);
      if (rc != SHISHI_OK)
	{
	  fprintf (stderr, "decryption error\n");
	  free (outbis);
	  return 1;
	}

      /* in KCMDV0.2 first 4 bytes of decrypted data = len of data */
      *len = ntohl (*((int *) out));
      val = sizeof (int);
    }

  memset (buf, 0, BUFLEN);

  /* copy decrypted data to output */
  memcpy (buf, out + val, outlen - val);

  free (out);
  free (outbis);

  return SHISHI_OK;
}