/* common code to set up encrypt/decrypt */
static int desEncDecSetup(
	ITEM	 						*iv,
    B_BLK_CIPHER_W_FEEDBACK_PARAMS 	*spec,
	B_ALGORITHM_OBJ					*alg)
{
	int brtn;
	
	spec->encryptionMethodName = POINTER("des");
	spec->feedbackMethodName = POINTER("cbc");
	spec->feedbackParams = POINTER(iv);
	spec->paddingParams = NULL_PTR;
	spec->encryptionParams = NULL_PTR;
	spec->paddingMethodName = POINTER("pad");
	
	brtn = B_CreateAlgorithmObject(alg);
	if(brtn) {
		printf("***B_CreateAlgorithmObject error (%d)\n", brtn);
		return 1;
	}
	brtn = B_SetAlgorithmInfo(*alg, AI_FeedbackCipher, (POINTER)spec);
	if(brtn) {
		printf("***B_SetAlgorithmInfo error (%d)\n", brtn);
		return 1;
	}
	return 0;
}
void BSafe::BSafeContext::setAlgorithm(
	B_INFO_TYPE bAlgType, 
	const void *info)
{
    B_DestroyAlgorithmObject(&bsAlgorithm);	// clear any old BSafe algorithm
    check(B_CreateAlgorithmObject(&bsAlgorithm));
    check(B_SetAlgorithmInfo(bsAlgorithm, bAlgType, POINTER(info)));
}
void BSafe::BSafeContext::setRandom()
{
    if (bsRandom == NULL) {
        check(B_CreateAlgorithmObject(&bsRandom));
        check(B_SetAlgorithmInfo(bsRandom, AI_X962Random_V0, NULL_PTR));
        check(B_RandomInit(bsRandom, chooser(), bsSurrender));
        uint8 seed[BSAFE_RANDSIZE];
		session().getRandomBytes(BSAFE_RANDSIZE, seed);
        check(B_RandomUpdate(bsRandom, seed, sizeof(seed), bsSurrender));
    }
}
//
// DSA Parameter Generation
//
void BSafe::BSafeKeyPairGenContext::generate(
	const Context &context, 
	uint32 bitSize,
    CssmData &params,
    uint32 &attrCount, 
	Context::Attr * &attrs)
{
	assert(context.algorithm() == CSSM_ALGID_DSA);
	
    B_ALGORITHM_OBJ genAlg = NULL;
    B_ALGORITHM_OBJ result = NULL;

    try {
        check(B_CreateAlgorithmObject(&genAlg));

        B_DSA_PARAM_GEN_PARAMS genParams;
        genParams.primeBits = bitSize;
        check(B_SetAlgorithmInfo(genAlg, AI_DSAParamGen, POINTER(&genParams)));
        setRandom();
        check(B_GenerateInit(genAlg, chooser(), bsSurrender), true);
        check(B_CreateAlgorithmObject(&result));
        check(B_GenerateParameters(genAlg, result, bsRandom, bsSurrender));

        // get parameters out of algorithm object
        A_DSA_PARAMS *kParams = NULL;
        check(B_GetAlgorithmInfo((POINTER *)&kParams, result, AI_DSAKeyGen), true);

        // shred them into context attribute form
        attrs = normAllocator->alloc<Context::Attr>(3);
        attrs[0] = Context::Attr(CSSM_ATTRIBUTE_PRIME,
                   *BSafeItem(kParams->prime).copyp<CssmData>(*normAllocator));
        attrs[1] = Context::Attr(CSSM_ATTRIBUTE_SUBPRIME,
                   *BSafeItem(kParams->subPrime).copyp<CssmData>(*normAllocator));
        attrs[2] = Context::Attr(CSSM_ATTRIBUTE_BASE,
                   *BSafeItem(kParams->base).copyp<CssmData>(*normAllocator));
        attrCount = 3;

        // clean up
        B_DestroyAlgorithmObject(&result);
        B_DestroyAlgorithmObject(&genAlg);
    } catch (...) {
        // clean up
        B_DestroyAlgorithmObject(&result);
        B_DestroyAlgorithmObject(&genAlg);
        throw;
    }
}
Beispiel #5
0
int
read_priv_key (FILE * privring, PRIVATE_KEY * privkey,
	       unsigned char *newID)
{
  unsigned char line[1024];
  int i, err, len, length;
  unsigned char iv[20];
  unsigned char *temp, *temp2;
  byte digest[16], *byteptr;
  byte des3key[24];
  BUFFER *buff;
#ifdef USE_RSAREF
  R_DIGEST_CTX digest_context;
  DES3_CBC_CTX context;
#else
  B_ALGORITHM_OBJ digest_obj;
  B_ALGORITHM_OBJ des_obj;
  B_KEY_OBJ key_obj;
  A_PKCS_RSA_PRIVATE_KEY keyinfo;
#endif

  buff = new_buffer ();
  /* read in the length */
  if ((temp = getline (line, sizeof (line), privring)) == NULL)
    return -1;
  sscanf (line, "%d", &length);

  /* Read in iv */
  if (((temp = getline (line, sizeof (line), privring)) == NULL)
      || (decode_block (iv, &len, line, strlen (line))))
    return -1;

  if ((temp = getline (line, sizeof (line), privring)) == NULL)
    return -1;
  while (temp != NULL && !streq (line, end_key))
    {
      add_to_buffer (buff, line, strlen (line));
      temp = getline (line, sizeof (line), privring);
    }
  temp = malloc (buff->length);
  temp2 = malloc (buff->length);
  if (decode_block (temp, &len, buff->message, buff->length) != 0)
    return -1;

  if (len < length)
    {
      fprintf (errlog, "Error: recovered key is too small!\n");
      return (-2);
    }
  /* decrypt key */
#ifdef USE_RSAREF
  R_DigestInit (&digest_context, DA_MD5);
  R_DigestUpdate (&digest_context, PASSPHRASE, strlen (PASSPHRASE));
  R_DigestFinal (&digest_context, digest, &i);
  memcpy (des3key, digest, 16);	/* set first 2 keys */
  memcpy (des3key + 16, digest, 8);	/* third key = first key */
  DES3_CBCInit (&context, des3key, iv, 0);
  while (len % 8 != 0)
    len++;			/* align on block boundry */
  err = DES3_CBCUpdate (&context, temp2, temp, len);
#else
  B_CreateAlgorithmObject (&digest_obj);
  B_SetAlgorithmInfo (digest_obj, AI_MD5, NULL);

  B_DigestInit (digest_obj, NULL, CHOOSER, NULL);
  B_DigestUpdate (digest_obj, PASSPHRASE, strlen (PASSPHRASE), NULL);
  B_DigestFinal (digest_obj, digest, &i, 16, NULL);
  B_DestroyAlgorithmObject (&digest_obj);

  memcpy (des3key, digest, 16);	/* set first 2 keys */
  memcpy (des3key + 16, digest, 8);	/* third key = first key */
  B_CreateAlgorithmObject (&des_obj);
  B_SetAlgorithmInfo (des_obj, AI_DES_EDE3_CBC_IV8, iv);
  B_CreateKeyObject (&key_obj);
  err = B_SetKeyInfo (key_obj, KI_DES24Strong, des3key);
  B_DecryptInit (des_obj, key_obj, CHOOSER, NULL);
  err = B_DecryptUpdate (des_obj, temp2, &i, len, temp, len, random_obj,
			 NULL);
  B_DecryptFinal (des_obj, temp2 + i, &i, len - i, random_obj, NULL);
  B_DestroyKeyObject (&key_obj);
  B_DestroyAlgorithmObject (&des_obj);
#endif

  if (err)
    {
      printf ("Error: Problem decrypting key %x\n", err);
      return (-1);
    }
  memset ((void *) digest, 0, 16);	/* zero password */
  free (temp);

  /* Rebuild privkey */
  byteptr = temp2;
  i = *byteptr++;
  i += (*byteptr++ * 256);

#ifdef USE_RSAREF
  (*privkey).bits = i;

  for (i = 0; i < MAX_RSA_MODULUS_LEN; i++)
    (*privkey).modulus[i] = *byteptr++;
  for (i = 0; i < MAX_RSA_MODULUS_LEN; i++)
    (*privkey).publicExponent[i] = *byteptr++;
  for (i = 0; i < MAX_RSA_MODULUS_LEN; i++)
    (*privkey).exponent[i] = *byteptr++;
  for (i = 0; i < MAX_RSA_PRIME_LEN; i++)
    (*privkey).prime[0][i] = *byteptr++;
  for (i = 0; i < MAX_RSA_PRIME_LEN; i++)
    (*privkey).prime[1][i] = *byteptr++;
  for (i = 0; i < MAX_RSA_PRIME_LEN; i++)
    (*privkey).primeExponent[0][i] = *byteptr++;
  for (i = 0; i < MAX_RSA_PRIME_LEN; i++)
    (*privkey).primeExponent[1][i] = *byteptr++;
  for (i = 0; i < MAX_RSA_PRIME_LEN; i++)
    (*privkey).coefficient[i] = *byteptr++;
  free (temp2);

  /* Make Key ID */
  R_DigestInit (&digest_context, DA_MD5);
  R_DigestUpdate (&digest_context, privkey->modulus, MAX_RSA_MODULUS_LEN);
  R_DigestUpdate (&digest_context, privkey->publicExponent, MAX_RSA_MODULUS_LEN);
  R_DigestFinal (&digest_context, newID, &i);
#else
  i = (i + 7) / 8;
  if (i < MAX_RSA_MODULUS_LEN)
    i = MAX_RSA_MODULUS_LEN;

  keyinfo.modulus.len = i;
  keyinfo.publicExponent.len = i;
  keyinfo.privateExponent.len = i;
  keyinfo.prime[0].len = (i + 1) / 2;
  keyinfo.prime[1].len = (i + 1) / 2;
  keyinfo.primeExponent[0].len = (i + 1) / 2;
  keyinfo.primeExponent[1].len = (i + 1) / 2;
  keyinfo.coefficient.len = (i + 1) / 2;

  keyinfo.modulus.data = malloc (keyinfo.modulus.len);
  memcpy (keyinfo.modulus.data, byteptr, keyinfo.modulus.len);
  byteptr += keyinfo.modulus.len;

  keyinfo.publicExponent.data = malloc (keyinfo.publicExponent.len);
  memcpy (keyinfo.publicExponent.data, byteptr, keyinfo.publicExponent.len);
  byteptr += keyinfo.publicExponent.len;

  keyinfo.privateExponent.data = malloc (keyinfo.privateExponent.len);
  memcpy (keyinfo.privateExponent.data, byteptr, keyinfo.privateExponent.len);
  byteptr += keyinfo.privateExponent.len;

  keyinfo.prime[0].data = malloc (keyinfo.prime[0].len);
  memcpy (keyinfo.prime[0].data, byteptr, keyinfo.prime[0].len);
  byteptr += keyinfo.prime[0].len;

  keyinfo.prime[1].data = malloc (keyinfo.prime[1].len);
  memcpy (keyinfo.prime[1].data, byteptr, keyinfo.prime[1].len);
  byteptr += keyinfo.prime[1].len;

  keyinfo.primeExponent[0].data = malloc (keyinfo.primeExponent[0].len);
  memcpy (keyinfo.primeExponent[0].data, byteptr,
	  keyinfo.primeExponent[0].len);
  byteptr += keyinfo.primeExponent[0].len;

  keyinfo.primeExponent[1].data = malloc (keyinfo.primeExponent[1].len);
  memcpy (keyinfo.primeExponent[1].data, byteptr,
	  keyinfo.primeExponent[1].len);
  byteptr += keyinfo.primeExponent[1].len;

  keyinfo.coefficient.data = malloc (keyinfo.coefficient.len);
  memcpy (keyinfo.coefficient.data, byteptr, keyinfo.coefficient.len);

  B_CreateKeyObject (privkey);
  B_SetKeyInfo (*privkey, KI_PKCS_RSAPrivate, (POINTER) & keyinfo);

  /* Make Key ID */
  B_CreateAlgorithmObject (&digest_obj);
  B_SetAlgorithmInfo (digest_obj, AI_MD5, NULL);

  B_DigestInit (digest_obj, NULL, CHOOSER, NULL);
  B_DigestUpdate (digest_obj, keyinfo.modulus.data, keyinfo.modulus.len, NULL);
  B_DigestUpdate (digest_obj, keyinfo.publicExponent.data,
		  keyinfo.publicExponent.len, NULL);
  B_DigestFinal (digest_obj, newID, &i, 16, NULL);
  B_DestroyAlgorithmObject (&digest_obj);
  free (keyinfo.modulus.data);
  free (keyinfo.publicExponent.data);
  free (keyinfo.privateExponent.data);
  free (keyinfo.prime[0].data);
  free (keyinfo.prime[1].data);
  free (keyinfo.primeExponent[0].data);
  free (keyinfo.primeExponent[1].data);
  free (keyinfo.coefficient.data);
  free (temp2);
#endif
  return 0;
}
Beispiel #6
0
int
generate_key (const char *header)
{
  PUBLIC_KEY pubkey;
  PRIVATE_KEY privkey;
  unsigned char line[1024];
  int i, err, len;
  unsigned char iv[8];
  byte digest[16], ID[16], tmpbyte;
  byte des3key[24];
  BUFFER *b1, *encrypted_key;
  FILE *privring, *privlock;
#ifdef USE_RSAREF
  R_DIGEST_CTX digest_context;
  DES3_CBC_CTX context;
  R_RSA_PROTO_KEY protokey;
#else
  B_ALGORITHM_OBJ digest_obj;
  B_ALGORITHM_OBJ des_obj;
  B_ALGORITHM_OBJ gen_obj;
  B_KEY_OBJ key_obj;
  A_RSA_KEY_GEN_PARAMS keypar;
  A_PKCS_RSA_PRIVATE_KEY *keyinfo;
  unsigned char pubexpt[] =
  {1, 0, 1};
#endif

#ifdef DEBUG
  printf ("Generating key:\n%s", header);
#endif
  /* Generate a 1024 bit key with pub exponent = 65537 */
#ifdef USE_RSAREF
  protokey.bits = MIX_RSA_MOD;
  protokey.useFermat4 = 1;
  err = R_GeneratePEMKeys (&pubkey, &privkey, &protokey, &random_obj);
#else
  B_CreateAlgorithmObject (&gen_obj);
  /* Generate a 1024 bit key with pub exponent = 65537 */
  keypar.modulusBits = 1024;
  keypar.publicExponent.data = pubexpt;
  keypar.publicExponent.len = sizeof (pubexpt);
  B_SetAlgorithmInfo (gen_obj, AI_RSAKeyGen, (POINTER) & keypar);
  B_GenerateInit (gen_obj, CHOOSER, NULL);
  B_CreateKeyObject (&pubkey);
  B_CreateKeyObject (&privkey);
  err = (B_GenerateKeypair (gen_obj, pubkey, privkey, random_obj, NULL));
#endif
  if (err != 0)
    {
      fprintf (errlog, "Key generation error.\n");
      return (-1);
    }

#ifdef DEBUG
  printf ("Done.\n");
#endif
  /* put private key in a buffer */
  b1 = new_buffer ();
#ifdef USE_RSAREF
  /* Convert privkey.bits to two bytes */
  i = privkey.bits;
#else
  B_GetKeyInfo ((POINTER *) & keyinfo, privkey, KI_PKCS_RSAPrivate);
  i = keyinfo->modulus.len * 8;
#endif
  tmpbyte = i & 0xFF;
  add_to_buffer (b1, &tmpbyte, 1);	/* low byte of bits */
  tmpbyte = (i / 256) & 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);

  /* Make Key ID */
  R_DigestInit (&digest_context, DA_MD5);
  R_DigestUpdate (&digest_context, pubkey.modulus, MAX_RSA_MODULUS_LEN);
  R_DigestUpdate (&digest_context, pubkey.exponent, MAX_RSA_MODULUS_LEN);
  R_DigestFinal (&digest_context, ID, &i);

  add_to_buffer (b1, privkey.exponent, MAX_RSA_MODULUS_LEN);
  add_to_buffer (b1, privkey.prime[0], MAX_RSA_PRIME_LEN);
  add_to_buffer (b1, privkey.prime[1], MAX_RSA_PRIME_LEN);
  add_to_buffer (b1, privkey.primeExponent[0], MAX_RSA_PRIME_LEN);
  add_to_buffer (b1, privkey.primeExponent[1], MAX_RSA_PRIME_LEN);
  add_to_buffer (b1, privkey.coefficient, MAX_RSA_PRIME_LEN);
#else
  i = (i + 7) / 8;

  /* Make Key ID */
  B_CreateAlgorithmObject (&digest_obj);
  B_SetAlgorithmInfo (digest_obj, AI_MD5, NULL);
  B_DigestInit (digest_obj, NULL, CHOOSER, NULL);

  add_to_buffer (b1, keyinfo->modulus.data, i);

  if (keyinfo->publicExponent.len < i)
    add_to_buffer (b1, NULL,
		   i - keyinfo->publicExponent.len);
  add_to_buffer (b1, keyinfo->publicExponent.data,
		 keyinfo->publicExponent.len);

  B_DigestUpdate (digest_obj, b1->message + 2,
		  2 * i,
		  NULL);
  B_DigestFinal (digest_obj, ID, &i, 16, NULL);
  B_DestroyAlgorithmObject (&digest_obj);

  if (keyinfo->privateExponent.len < i)
    add_to_buffer (b1, NULL,
		   i - keyinfo->privateExponent.len);
  add_to_buffer (b1, keyinfo->privateExponent.data,
		 keyinfo->privateExponent.len);

  i = (i + 1) / 2;

  if (keyinfo->prime[0].len < i)
    add_to_buffer (b1, NULL,
		   i - keyinfo->prime[0].len);
  add_to_buffer (b1, keyinfo->prime[0].data, keyinfo->prime[0].len);

  if (keyinfo->prime[1].len < i)
    add_to_buffer (b1, NULL,
		   i - keyinfo->prime[1].len);
  add_to_buffer (b1, keyinfo->prime[1].data, keyinfo->prime[1].len);

  if (keyinfo->primeExponent[0].len < i)
    add_to_buffer (b1, NULL,
		   i - keyinfo->primeExponent[0].len);
  add_to_buffer (b1, keyinfo->primeExponent[0].data,
		 keyinfo->primeExponent[0].len);

  if (keyinfo->primeExponent[1].len < i)
    add_to_buffer (b1, NULL,
		   i - keyinfo->primeExponent[1].len);
  add_to_buffer (b1, keyinfo->primeExponent[1].data,
		 keyinfo->primeExponent[1].len);

  if (keyinfo->coefficient.len < i)
    add_to_buffer (b1, NULL,
		   i - keyinfo->coefficient.len);
  add_to_buffer (b1, keyinfo->coefficient.data, keyinfo->coefficient.len);
#endif

  /* Encrypt the secret key */
  encrypted_key = new_buffer ();
  len = b1->length;
  if (len % 8 != 0)		/* ensure length is mult of 8 */
    len += 8 - len % 8;
  add_to_buffer (encrypted_key, malloc (len), len);
  our_randombytes (iv, 8);
#ifdef USE_RSAREF
  R_DigestInit (&digest_context, DA_MD5);
  R_DigestUpdate (&digest_context, PASSPHRASE, strlen (PASSPHRASE));
  R_DigestFinal (&digest_context, digest, &i);
  memcpy (des3key, digest, 16);	/* set first 2 keys */
  memcpy (des3key + 16, digest, 8);	/* third key = first key */
  DES3_CBCInit (&context, des3key, iv, 1);
  if (DES3_CBCUpdate (&context, encrypted_key->message, b1->message,
		      encrypted_key->length))
    {
      printf ("Error: Problem encrypting key\n");
      return (-1);
    }
#else
  B_CreateAlgorithmObject (&digest_obj);
  B_SetAlgorithmInfo (digest_obj, AI_MD5, NULL);

  B_DigestInit (digest_obj, NULL, CHOOSER, NULL);
  B_DigestUpdate (digest_obj, PASSPHRASE, strlen (PASSPHRASE), NULL);
  B_DigestFinal (digest_obj, digest, &i, 16, NULL);
  B_DestroyAlgorithmObject (&digest_obj);

  memcpy (des3key, digest, 16);	/* set first 2 keys */
  memcpy (des3key + 16, digest, 8);	/* third key = first key */
  B_CreateAlgorithmObject (&des_obj);
  B_SetAlgorithmInfo (des_obj, AI_DES_EDE3_CBC_IV8, iv);
  B_CreateKeyObject (&key_obj);
  B_SetKeyInfo (key_obj, KI_DES24Strong, des3key);
  B_EncryptInit (des_obj, key_obj, CHOOSER, NULL);
  B_EncryptUpdate (des_obj, encrypted_key->message, &len,
		   encrypted_key->length,
		   b1->message, b1->length, random_obj, NULL);
  B_EncryptFinal (des_obj, encrypted_key->message + len,
		  &len, encrypted_key->length - len, random_obj, NULL);
  /* err? XXX */
#endif
  memset ((void *) digest, 0, 16);	/* zero password */

  mix_lock ("secring", &privlock);
  if ((privring = open_mix_file (SECRING, "a+")) == NULL)
    {
      mix_unlock ("secring", privlock);
      return (-1);
    }
  fprintf (privring, "%s\n", begin_key);
  if (strlen (header) > 0)
    {
      fprintf (privring, KEY_VERSION "%s\n", VERSION);
      fprintf (privring, "%s", header);
    }
  print_ID (privring, ID);
  fprintf (privring, "%d\n", len);
  encode_block (line, &i, iv, 8);
  fwrite (line, 1, i, privring);
  fprintf (privring, "\n");

  /* Armor privkey */
  armor (encrypted_key);
  write_buffer (encrypted_key, privring);
  free_buffer (encrypted_key);
  fprintf (privring, "%s\n", end_key);
  fclose (privring);
  mix_unlock ("secring", privlock);
  return 0;
}
Beispiel #7
0
int
read_pub_key (FILE * pubring, PUBLIC_KEY * pubkey,
	      unsigned char *newID)
{
  unsigned char line[1024];
  int i, len, length;
  unsigned char *temp;
  byte *byteptr;
  BUFFER *buff;
#ifdef USE_RSAREF
  R_DIGEST_CTX digest_context;
#else
  B_ALGORITHM_OBJ digest_obj;
  A_RSA_KEY keyinfo;
#endif

  buff = new_buffer ();
  /* read in the length */
  if ((temp = getline (line, sizeof (line), pubring)) == NULL)
    return -1;
  sscanf (line, "%d", &length);

  if ((temp = getline (line, sizeof (line), pubring)) == NULL)
    return -1;
  while (temp != NULL && !streq (line, end_key))
    {
      add_to_buffer (buff, line, strlen (line));
      temp = getline (line, sizeof (line), pubring);
    }
  temp = malloc (buff->length);	/* Longer than we need */
  if (decode_block (temp, &len, buff->message, buff->length) != 0)
    {
      fprintf (errlog, "Error: Malformatted key!\n");
      return (-2);
    }
  free_buffer (buff);
  if (len < length)
    {
      fprintf (errlog, "Error: recovered key is too small!\n");
      return (-2);
    }
  byteptr = temp;
  i = *byteptr++;
  i += (*byteptr++ * 256);
#ifdef USE_RSAREF
  if ((i + 7) / 8 > MAX_RSA_MODULUS_LEN)
    {
      fprintf (errlog, "Keysize not supported by RSAREF.\n");
      return (-1);
    }
  (*pubkey).bits = i;
  for (i = 0; i < MAX_RSA_MODULUS_LEN; i++)
    (*pubkey).modulus[i] = *byteptr++;
  for (i = 0; i < MAX_RSA_MODULUS_LEN; i++)
    (*pubkey).exponent[i] = *byteptr++;
#else
  keyinfo.modulus.len = (i + 7) / 8;
  if (keyinfo.modulus.len < MAX_RSA_MODULUS_LEN)
    keyinfo.modulus.len = MAX_RSA_MODULUS_LEN;
  keyinfo.exponent.len = keyinfo.modulus.len;

  keyinfo.modulus.data = malloc (keyinfo.modulus.len);
  memcpy (keyinfo.modulus.data, byteptr, keyinfo.modulus.len);
  byteptr += keyinfo.modulus.len;

  keyinfo.exponent.data = malloc (keyinfo.exponent.len);
  memcpy (keyinfo.exponent.data, byteptr, keyinfo.exponent.len);

  B_CreateKeyObject (pubkey);
  B_SetKeyInfo (*pubkey, KI_RSAPublic, (POINTER) & keyinfo);
#endif
  free (temp);

  /* Make Key ID */
#ifdef USE_RSAREF
  R_DigestInit (&digest_context, DA_MD5);
  R_DigestUpdate (&digest_context, (*pubkey).modulus,
		  MAX_RSA_MODULUS_LEN);
  R_DigestUpdate (&digest_context, (*pubkey).exponent,
		  MAX_RSA_MODULUS_LEN);
  R_DigestFinal (&digest_context, newID, &i);
#else
  B_CreateAlgorithmObject (&digest_obj);
  B_SetAlgorithmInfo (digest_obj, AI_MD5, NULL);

  B_DigestInit (digest_obj, NULL, CHOOSER, NULL);
  B_DigestUpdate (digest_obj, keyinfo.modulus.data, keyinfo.modulus.len, NULL);
  B_DigestUpdate (digest_obj, keyinfo.exponent.data, keyinfo.exponent.len,
		  NULL);
  B_DigestFinal (digest_obj, newID, &i, 16, NULL);
  B_DestroyAlgorithmObject (&digest_obj);
  free (keyinfo.modulus.data);
  free (keyinfo.exponent.data);
#endif
  return 0;
}
Beispiel #8
0
int main(int argc, char *argv[])
{
    int status;

    int keySize = argv[1] ? atoi(argv[1]) : 512;
    printf("Key size = %d bits\n", keySize);

    B_ALGORITHM_OBJ pGen = NULL;
    check(B_CreateAlgorithmObject(&pGen));
    B_DSA_PARAM_GEN_PARAMS gParams;
    gParams.primeBits = keySize;
    check(B_SetAlgorithmInfo(pGen, AI_DSAParamGen, POINTER(&gParams)));

    B_ALGORITHM_OBJ random = NULL;
    check(B_CreateAlgorithmObject(&random));
    check(B_SetAlgorithmInfo(random, AI_X962Random_V0, NULL));
    check(B_RandomInit(random, chooser, NULL));
    check(B_RandomUpdate(random, seed, sizeof(seed), NULL));

    check(B_GenerateInit(pGen, chooser, NULL));
    B_ALGORITHM_OBJ result = NULL;
    check(B_CreateAlgorithmObject(&result));
    printf("Generating DSA parameters\n");
    check(B_GenerateParameters(pGen, result, random, NULL));
    printf("DSA generate complete, writing...\n");

    A_DSA_PARAMS *dParams;
    memset(&dParams, 0, sizeof(dParams));
    check(B_GetAlgorithmInfo((POINTER *)&dParams, result, AI_DSAKeyGen));
    dumpItem(dParams->prime, "prime");
    dumpItem(dParams->subPrime, "subprime");
    dumpItem(dParams->base, "base");

#if 0
    B_KEY_OBJ pubKey = NULL;
    check(B_CreateKeyObject(&pubKey));
    B_KEY_OBJ privKey = NULL;
    check(B_CreateKeyObject(&privKey));

    B_ALGORITHM_OBJ gen = NULL;
    check(B_CreateAlgorithmObject(&gen));
    A_RSA_KEY_GEN_PARAMS args;
    args.modulusBits = keySize;
    args.publicExponent.data = exponent;
    args.publicExponent.len = sizeof(exponent);
    check(B_SetAlgorithmInfo(gen, AI_RSAStrongKeyGen, POINTER(&args)));
    check(B_GenerateInit(gen, chooser, NULL));
    check(B_GenerateKeypair(gen, pubKey, privKey, random, NULL));

    B_ALGORITHM_OBJ enc = NULL;
    check(B_CreateAlgorithmObject(&enc));
    check(B_SetAlgorithmInfo(enc, AI_PKCS_RSAPublic, NULL));
    check(B_EncryptInit(enc, pubKey, chooser, NULL));
    unsigned int inLen;
    check(B_EncryptUpdate(enc, crypt, &inLen, sizeof(crypt),
                          POINTER(in), sizeof(in), random, NULL));
    printf("EncryptUpdate output = %u\n", inLen);
    check(B_EncryptFinal(enc, crypt, &inLen, sizeof(crypt), random, NULL));
    printf("EncryptFinal output=%u\n", inLen);

    B_ALGORITHM_OBJ dec = NULL;
    check(B_CreateAlgorithmObject(&dec));
    check(B_SetAlgorithmInfo(dec, AI_PKCS_RSAPrivate, NULL));
    check(B_DecryptInit(dec, privKey, chooser, NULL));
    unsigned int outLen, outLen2;
    check(B_DecryptUpdate(dec, out, &outLen, sizeof(out),
                          crypt, inLen, random, NULL));
    printf("DecryptUpdate output = %u\n", outLen);
    check(B_DecryptFinal(dec, out2, &outLen2, sizeof(out2), random, NULL));
    printf("DecryptFinal output=%u %s\n", outLen2, (char*)out2);
    B_DestroyKeyObject(&pubKey);
    B_DestroyKeyObject(&privKey);
#endif

    exit(0);
}
Beispiel #9
0
/* this actually makes the message block and sends it */
int
build_message (FILE * in_ptr, byte numdest,
	       char **destination, int *chain, byte numsub,
	       char **subject, char *outfile, int outfileflag,
	       REMAILER * remailer_list, int num_remailers,
	       int client)
{
  int hop, i, j, k, numpackets, packet, copy;
  long int chunk, tmpchunk;
  byte iv[8];
  byte ivarray[NUM_IV][8], innerkey[24], digest[16];
  BUFFER *sendbuff, *bodybuff, *headbuff[21], *message, *tempbuff;
  long offset;
  char line[1024];
  byte *key[5], packetID[16], commonpacketID[16], messageID[16];
  byte tmpbyte;
  byte packet_type;
#ifdef USE_RSAREF
  PUBLIC_KEY pubKey, *keyPtr[5];
  unsigned int numPubKeys, keylen;
  R_ENVELOPE_CTX rsa_context;
#else
  PUBLIC_KEY pubKey;
  unsigned int keylen;
  B_ALGORITHM_OBJ rsa_context;
  B_ALGORITHM_OBJ des_context;
  B_KEY_OBJ des_key;
#endif
  unsigned long timestamp;

  message = new_buffer ();
  /* prepend destinations to body */
  add_to_buffer (message, &numdest, 1);
  for (i = 0; i < numdest; i++)
    add_to_buffer (message, destination[i], DESTSIZE);
  /* add message header lines to body */
  add_to_buffer (message, &numsub, 1);
  for (i = 0; i < numsub; i++)
    add_to_buffer (message, subject[i], SUBSIZE);

  offset = message->length;

  /* add the file to body */
  if (in_ptr)
    {
      while ((i = fread (line, 1, sizeof (line), in_ptr)) > 0)
	{
	  if (i < 0)
	    return (-1);	/* file error */
	  add_to_buffer (message, line, i);
	}
      fclose (in_ptr);
    }

  /* message is complete. */
  add_to_random (message->message, message->length);

  /* Choose the final hop now. */
  if (chain[chain[0]] == 0)
    if (rnd_select (chain[0], chain, remailer_list, num_remailers) < 0)
      return (-1);

#ifdef USE_ZLIB
  /* should we compress this message? */
  if (message->length > PACKETSIZE &&
      check_abilities (remailer_list[chain[chain[0]]].abilities, "C", ""))
    {
      tempbuff = new_buffer ();
      if (compress_buf2buf (message, tempbuff, offset))
	{
	  free_buffer (message);
	  message = tempbuff;
	}
      else
	free_buffer (tempbuff);
    }

  /* in case it already is compressed, but should not be */
  if (!check_abilities (remailer_list[chain[chain[0]]].abilities, "C", ""))
    {
      tempbuff = new_buffer ();
      if (uncompress_buf2buf (message, tempbuff, offset))
	{
	  free_buffer (message);
	  message = tempbuff;
	}
      else
	free_buffer (tempbuff);
    }
#endif

  numpackets = message->length / PACKETSIZE;
  if (message->length % PACKETSIZE != 0)
    numpackets++;

  bodybuff = new_buffer ();
  sendbuff = new_buffer ();
  for (i = 1; i <= HOPMAX; i++)
    headbuff[i] = new_buffer ();

  our_randombytes (messageID, 16);

  /* Loop to make one packet at a time */
  for (packet = 1; packet <= numpackets; packet++)
    {
      /* put the packet in bodybuff, and put the rest back in message */
      chunk = message->length;
      if (chunk > PACKETSIZE)
	chunk = PACKETSIZE;
      clear_buffer (bodybuff);

      tmpchunk = chunk;
      tmpbyte = tmpchunk & 0xFF;
      add_to_buffer (bodybuff, &tmpbyte, 1);	/* prepend length of data low byte */
      tmpchunk = tmpchunk / 256;
      tmpbyte = tmpchunk & 0xFF;
      add_to_buffer (bodybuff, &tmpbyte, 1);	/* prepend length of data 2nd byte */
      tmpchunk = tmpchunk / 256;
      tmpbyte = tmpchunk & 0xFF;
      add_to_buffer (bodybuff, &tmpbyte, 1);	/* prepend length of data 3rd byte */
      tmpchunk = tmpchunk / 256;
      tmpbyte = tmpchunk & 0xFF;
      add_to_buffer (bodybuff, &tmpbyte, 1);	/* prepend length of data high byte */

      add_to_buffer (bodybuff, message->message, chunk);
      tempbuff = new_buffer ();
      add_to_buffer (tempbuff, (message->message) + chunk, message->length - chunk);
      free_buffer (message);
      message = tempbuff;

      if (NUMCOPIES < 1 || NUMCOPIES > 10)
	{
	  fprintf (errlog, "Error: Invalid number of copies.\n");
	  return (-1);
	}
      for (copy = 1; copy <= NUMCOPIES; copy++)
	{
	  clear_buffer (sendbuff);
	  add_to_buffer (sendbuff, bodybuff->message, bodybuff->length);
	  pad_buffer (sendbuff, PACKETSIZE + 4);

	  /* Create fake header cards */
	  for (i = chain[0] + 1; i <= HOPMAX; i++)
	    {
	      reset_buffer (headbuff[i]);
	      pad_buffer (headbuff[i], HEADERSIZE);
	    }
	  if (rnd_selectchain (chain, remailer_list, num_remailers) < 0)
	    return (-1);
	  for (hop = chain[0]; hop >= 1; hop--)
	    {
	      /* Get public key for remailer */
	      if (get_pub_key (remailer_list[abs (chain[hop])].key_ID,
			       &pubKey) != 0)
		{
		  fprintf (errlog, "Can't get public key!\n");
		  return (-1);
		}
	      key[0] = malloc (MAX_ENCRYPTED_KEY_LEN);
#ifdef USE_RSAREF
	      numPubKeys = 1;
	      keyPtr[0] = &pubKey;
	      if (R_SealInit (&rsa_context, key, &keylen, iv, numPubKeys,
			      keyPtr, EA_DES_EDE3_CBC, &random_obj) != 0)
		{
		  fprintf (errlog, "R_SealInit error %x!!!\n", i);
		  exit (-1);
		}
#else
	      B_CreateAlgorithmObject (&rsa_context);
	      B_CreateAlgorithmObject (&des_context);
	      B_SetAlgorithmInfo (rsa_context, AI_PKCS_RSAPublic, 0);
	      B_SetAlgorithmInfo (des_context, AI_DES_EDE3_CBC_IV8, iv);
	      our_randombytes (line, 24);
	      B_CreateKeyObject (&des_key);
	      B_SetKeyInfo (des_key, KI_DES24Strong, line);

	      B_EncryptInit (rsa_context, pubKey, CHOOSER, NULL);
	      B_EncryptUpdate (rsa_context, key[0], &keylen,
			       MAX_ENCRYPTED_KEY_LEN, line, 24,
			       random_obj, NULL);
	      B_EncryptFinal (rsa_context, key[0] + keylen, &k,
			      MAX_ENCRYPTED_KEY_LEN - keylen, random_obj,
			      NULL);
	      B_DestroyAlgorithmObject (&rsa_context);
	      B_DestroyKeyObject (&pubKey);
	      keylen += k;

	      B_EncryptInit (des_context, des_key, CHOOSER, NULL);
	      /* XXX Error handling! */
#endif
	      /* make packet ID and innerkey */
	      /* packet ID is unique except for duplicates in the last hop */
	      if (hop != chain[0])
		  our_randombytes (packetID, 16);
	      else
	      {
		  if (copy == 1)
		      our_randombytes (commonpacketID, 16);
	      memcpy (packetID, commonpacketID, 16);
	      }

	      our_randombytes (innerkey, 24);
	      /* make the iv array */
	      for (i = 0; i < NUM_IV; i++)
		our_randombytes (ivarray[i], 8);

	      /* Now build the current header */
	      reset_buffer (headbuff[hop]);
	      add_to_buffer (headbuff[hop], packetID, 16);	/* also like another IV */
	      add_to_buffer (headbuff[hop], innerkey, 24);	/* Key used to encrypt headers and body */
	      if (hop == chain[0])
		{		/* if this is the last hop */
		  if (numpackets == 1)
		    /* final hop */
		    packet_type = P_FINAL;
		  else
		    /* partial message */
		    packet_type = P_PARTIAL;
		  add_to_buffer (headbuff[hop], &packet_type, 1);
		  if (packet_type & P_PARTIAL)
		    {
		      tmpbyte = packet;	/* which packet is this */
		      add_to_buffer (headbuff[hop], &tmpbyte, 1);
		      tmpbyte = numpackets;	/* out of how many */
		      add_to_buffer (headbuff[hop], &tmpbyte, 1);
		    }
		  add_to_buffer (headbuff[hop], messageID, 16);
		  add_to_buffer (headbuff[hop], ivarray[BODY_IV], 8);
		}
	      else
		{		/* this is not the last hop */
		  packet_type = 0;	/* packet type = intermediate packet */
		  add_to_buffer (headbuff[hop], &packet_type, 1);
		  /* insert the array of IVs */
		  for (i = 0; i < NUM_IV; i++)
		    {
		      add_to_buffer (headbuff[hop], ivarray[i], 8);
		    }
		  add_to_buffer (headbuff[hop], remailer_list[abs (chain[hop + 1])].name, 80);
		}

	      /* Extension to original mixmaster format:
		 Use timestamp to prevent replay of old messages. */
	      add_to_buffer (headbuff[hop], TSMAGIC, sizeof(TSMAGIC));
	      /* Fuzzy timestamp: don't leak more information than necessary */
	      timestamp = time(NULL) / SECONDSPERDAY - random_number(4);
	      tmpbyte = timestamp & 0xFF;
	      add_to_buffer (headbuff[hop], &tmpbyte, 1);
	      tmpbyte = (timestamp / 256) & 0xFF;
	      add_to_buffer (headbuff[hop], &tmpbyte, 1);

	      /* Make and append an MD5 checksum of the packet */
	      make_digest (headbuff[hop], digest);
	      add_to_buffer (headbuff[hop], digest, 16);

	      /* Now pad pre-encrypted header to standard size */
	      pad_buffer (headbuff[hop], INNERHEAD);

	      /* Done building headbuff[hop] so now RSA it */
	      tempbuff = new_buffer ();
	      assert (headbuff[hop]->length <= INNERHEAD);

#ifdef USE_RSAREF
	      R_SealUpdate (&rsa_context, line, &k, headbuff[hop]->message,
			    headbuff[hop]->length);
#else
	      B_EncryptUpdate (des_context, line, &k, sizeof (line),
			       headbuff[hop]->message, headbuff[hop]->length,
			       random_obj, NULL);
#endif
	      add_to_buffer (tempbuff, line, k);
#ifdef USE_RSAREF
	      R_SealFinal (&rsa_context, line, &k);
#else
	      B_EncryptFinal (des_context, line, &k,
			      INNERHEAD - k,
			      random_obj, NULL);
	      B_DestroyAlgorithmObject (&des_context);
	      B_DestroyKeyObject (&des_key);
#endif
	      add_to_buffer (tempbuff, line, k);
	      clear_buffer (headbuff[hop]);

	      /* Prepend RSA key ID */
	      add_to_buffer (headbuff[hop], remailer_list[abs (chain[hop])].key_ID, 16);
	      /* prepend keys and IV to header */
	      tmpbyte = keylen;
	      add_to_buffer (headbuff[hop], &tmpbyte, 1);
	      add_to_buffer (headbuff[hop], key[0], tmpbyte);
	      add_to_buffer (headbuff[hop], iv, 8);
	      /* add encryped header */
	      add_to_buffer (headbuff[hop], tempbuff->message, tempbuff->length);
	      free_buffer (tempbuff);

	      /* pad out encrypted header to standard size */
	      pad_buffer (headbuff[hop], HEADERSIZE);

	      /* encrypt body */
	      crypt_in_buffer (innerkey, ivarray[BODY_IV], sendbuff, 1);

	      /* encrypt all later headers */
	      /* i is the index for ivarray */
	      for (i = 0, j = hop + 1; j <= HOPMAX; j++)
		crypt_in_buffer (innerkey, ivarray[i++], headbuff[j], 1);
	    }			/* hop loop for a given packet */
	  if (VERBOSE)
	    {
	      fprintf (errlog, "Packet chain: ");
	      for (i = 1; i <= chain[0]; i++)
		fprintf (errlog, "%s;", remailer_list[abs (chain[i])].shortname);
	      fprintf (errlog, "\n");
	    }
	  if (strlen (outfile) > 0 && (!streq (outfile, "-")) && (numpackets > 1 || NUMCOPIES > 1))
	    {
	      sprintf (line, "%s.%d", outfile, (packet - 1) * NUMCOPIES + copy);
	      send_new_packet (headbuff, sendbuff, remailer_list[abs (chain[1])].name, line, outfileflag, client);
	    }
	  else
	    {
	      send_new_packet (headbuff, sendbuff, remailer_list[abs (chain[1])].name, outfile, outfileflag, client);
	    }
	}			/* copies of one packet */
    }				/* end loop processing packets */
  free_buffer (bodybuff);
  free_buffer (sendbuff);
  free_buffer (message);
  for (i = 1; i <= HOPMAX; i++)
    free_buffer (headbuff[i]);

  return (0);
}
Beispiel #10
0
static int
dst_bsafe_verify(const int mode, DST_KEY *dkey, void **context,
		 const u_char *data, const int len,
		 const u_char *signature, const int sig_len)
{
	B_ALGORITHM_OBJ *md5_ctx = NULL;
	u_char digest[DST_HASH_SIZE];
	u_char work_area[DST_HASH_SIZE + sizeof(pkcs1)];
	int status = 0, w_bytes = 0;
	u_int u_bytes = 0;

	if (mode & SIG_MODE_INIT) { 
		md5_ctx = (B_ALGORITHM_OBJ *) malloc(sizeof(B_ALGORITHM_OBJ));
		if ((status = B_CreateAlgorithmObject(md5_ctx)))
			return (-1);
		if ((status = B_SetAlgorithmInfo(*md5_ctx, AI_MD5, NULL)))
			return (-1);
	}
	else if (context) 
		md5_ctx = (B_ALGORITHM_OBJ *) *context;
	if (md5_ctx == NULL) 
		return (-1);

	w_bytes = dst_bsafe_md5digest(mode, md5_ctx, data, len, 
				      digest, sizeof(digest));

	if (w_bytes < 0 || (mode & SIG_MODE_FINAL)) {
		B_DestroyAlgorithmObject(md5_ctx);
		SAFE_FREE(md5_ctx);
		if (w_bytes < 0)
			return (-1);
	}

	if (mode & SIG_MODE_FINAL) {
		RSA_Key *key;
		int ret = 0;
		B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ) NULL_PTR;

		if (dkey == NULL || dkey->dk_KEY_struct == NULL)
			return (-1);
		key = (RSA_Key *) dkey->dk_KEY_struct;
		if (key->rk_Public_Key == NULL)
			return (-2);
		if (rsaEncryptor == NULL_PTR) {
			if ((status = B_CreateAlgorithmObject(&rsaEncryptor)))
				ret = SIGN_FINAL_FAILURE;
			if (ret == 0 &&
			    (status = B_SetAlgorithmInfo(rsaEncryptor,
							 AI_PKCS_RSAPublic,
							 NULL_PTR)))
				ret = VERIFY_FINAL_FAILURE;
		}
		if (ret == 0 &&
		    (status = B_DecryptInit(rsaEncryptor, key->rk_Public_Key,
					    CHOOSER, NULL_SURRENDER)))
			ret = VERIFY_FINAL_FAILURE;

		if (ret == 0 && 
		    (status = B_DecryptUpdate(rsaEncryptor, work_area,
					      &u_bytes, 0,
					      (const u_char *) signature,
					      sig_len,
					      NULL_PTR, NULL_SURRENDER)))
			ret = VERIFY_FINAL_FAILURE;

		if (ret == 0 && 
		    (status = B_DecryptFinal(rsaEncryptor, work_area + u_bytes,
					     &u_bytes,
					     sizeof(work_area) - u_bytes,
					     NULL_PTR, NULL_SURRENDER)))
			ret = VERIFY_FINAL_FAILURE;
		B_DestroyAlgorithmObject(&rsaEncryptor);
		/* skip PKCS#1 header in output from Decrypt function */
		if (ret)
			return (ret);
		ret = memcmp(digest, &work_area[sizeof(pkcs1)], w_bytes);
		if (ret == 0)
			return(0);
		else
			return(VERIFY_FINAL_FAILURE);
	}
	else {
		if (context == NULL) 
			return (-1);
		*context = (void *) md5_ctx;
	}
	return (0);
}
Beispiel #11
0
static int
dst_bsafe_sign(const int mode, DST_KEY *dkey, void **context,
	       const u_char *data, const int len, 
	       u_char *signature, const int sig_len)
{
	u_int sign_len = 0;
	int status = 0;
	B_ALGORITHM_OBJ *md5_ctx = NULL;
	int w_bytes = 0;
	u_int u_bytes = 0;
	u_char work_area[NS_MD5RSA_MAX_SIZE];

	if (mode & SIG_MODE_INIT) { 
		md5_ctx = (B_ALGORITHM_OBJ *) malloc(sizeof(B_ALGORITHM_OBJ));
		if ((status = B_CreateAlgorithmObject(md5_ctx)))
			return (-1);
		if ((status = B_SetAlgorithmInfo(*md5_ctx, AI_MD5, NULL)))
			return (-1);
	}
	else if (context) 
		md5_ctx = (B_ALGORITHM_OBJ *) *context;
	if (md5_ctx == NULL) 
		return (-1);

	w_bytes = dst_bsafe_md5digest(mode, md5_ctx, 
				      data, len,work_area, sizeof(work_area));
        if (w_bytes < 0 || (mode & SIG_MODE_FINAL)) {
		B_DestroyAlgorithmObject(md5_ctx);
		SAFE_FREE(md5_ctx);
		if (w_bytes < 0)
			return (w_bytes);
	}

	if (mode & SIG_MODE_FINAL) {
		RSA_Key *key;
		int ret = 0;
		B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ) NULL_PTR;
		
		if (dkey == NULL || dkey->dk_KEY_struct == NULL)
			return (-1);
		key = (RSA_Key *) dkey->dk_KEY_struct;
		if (key == NULL || key->rk_Private_Key == NULL)
			return (-1);

		if ((status = B_CreateAlgorithmObject(&rsaEncryptor)))
			return (SIGN_FINAL_FAILURE);
		if ((status = B_SetAlgorithmInfo(rsaEncryptor,
						 AI_PKCS_RSAPrivate,
						 NULL_PTR)))

			ret = SIGN_FINAL_FAILURE;
		if (ret == 0 && 
		    (status = B_EncryptInit(rsaEncryptor,
					    key->rk_Private_Key,
					    CHOOSER, NULL_SURRENDER)))
			ret = SIGN_FINAL_FAILURE;
		if (ret == 0 &&
		    (status = B_EncryptUpdate(rsaEncryptor, signature,
					      &u_bytes, sig_len, pkcs1,
					      sizeof(pkcs1), NULL_PTR,
					      NULL_SURRENDER)))
			ret = SIGN_FINAL_FAILURE;
		if (ret == 0 &&
		    (status = B_EncryptUpdate(rsaEncryptor, signature,
					      &u_bytes, sig_len, work_area,
					      w_bytes, NULL_PTR,
					      NULL_SURRENDER)))
			ret = SIGN_FINAL_FAILURE;

		if (ret == 0 &&
		    (status = B_EncryptFinal(rsaEncryptor, signature + u_bytes,
					     &sign_len, sig_len - u_bytes,
					     NULL_PTR, NULL_SURRENDER)))
			ret = SIGN_FINAL_FAILURE;
		B_DestroyAlgorithmObject(&rsaEncryptor);
		if (ret != 0) 
			return (ret);

	}
	else {
		if (context == NULL) 
			return (-1);
		*context = (void *) md5_ctx;
	}
	return (sign_len);
}
Beispiel #12
0
/*
 * Performs an RSA decryption.  Returns a prefix of the unwrapped
 * data in the given buf.  Returns the length of the untruncated
 * data, which may exceed "len". Returns <0 on error.
 */
int
rsaPrivateDecrypt(PGPByte *outbuf, unsigned len, BigNum *bn,
	RSAsec const *sec)
{
	unsigned bytes = bnBytes(&sec->n);
	PGPByte *buf = NULL;
	B_ALGORITHM_OBJ bobj = NULL;
	B_KEY_OBJ rprivk = NULL;
	unsigned int bufoutlen;
	PGPMemoryMgrRef	mgr	= bn->mgr;
	int err;

	buf = PGPNewSecureData (mgr, bytes, 0);
	if (buf == NULL) {
		err = kPGPError_OutOfMemory;
		goto error;
	}
	bnExtractBigBytes (bn, buf, 0, bytes);

	/* Initialize BSafe private key structure */
	err = B_CreateAlgorithmObject (&bobj);
	CHKERR(err);
	err = B_SetAlgorithmInfo (bobj, AI_RSAPrivate, NULL);
	CHKERR(err);
	err = B_CreateKeyObject (&rprivk);
	CHKERR(err);
	err = rprivk_init(rprivk, sec, mgr);
	CHKERR(err);
	err = B_DecryptInit (bobj, rprivk, RSA_CHOOSER, (A_SURRENDER_CTX *)0);
	CHKERR(err);

	/* Do an RSA decryption to recover PKCS-1 padded key */
	err = B_DecryptUpdate (bobj, buf, &bufoutlen, bytes, buf, bytes,
						(B_ALGORITHM_OBJ)NULL, (A_SURRENDER_CTX *)NULL);
	CHKERR(err);
	err = B_DecryptFinal (bobj, buf+bufoutlen, &bufoutlen, bytes-bufoutlen,
						(B_ALGORITHM_OBJ)NULL, (A_SURRENDER_CTX *)NULL);
	CHKERR(err);

	B_DestroyKeyObject (&rprivk);
	rprivk = NULL;
	B_DestroyAlgorithmObject (&bobj);
	bobj = NULL;

	/* Return to bn format */
	bnSetQ (bn, 0);
	bnInsertBigBytes (bn, buf, 0, bytes);
	pgpClearMemory (buf, bytes);
	PGPFreeData (buf);
	buf = NULL;
	
	err = pgpPKCSUnpack(outbuf, len, bn, PKCS_PAD_ENCRYPTED, bytes);

error:
	if (buf) {
		pgpClearMemory (buf, bytes);
		PGPFreeData (buf);
	}
	if (rprivk)
		B_DestroyKeyObject (&rprivk);
	if (bobj)
		B_DestroyAlgorithmObject (&bobj);
	
	return err;
}
Beispiel #13
0
/*
 * Encrypt a buffer holding a session key with an RSA public key
 */
int
rsaPublicEncrypt(BigNum *bn, PGPByte const *in, unsigned len,
	RSApub const *pub, PGPRandomContext const *rc)
{
	unsigned bytes = bnBytes(&pub->n);
	PGPByte *buf = NULL;
	B_ALGORITHM_OBJ bobj = NULL;
	B_KEY_OBJ rpubk = NULL;
	unsigned int bufoutlen;
	PGPMemoryMgrRef	mgr	= bn->mgr;
	int err = 0;

	pgpPKCSPack(bn, in, len, PKCS_PAD_ENCRYPTED, bytes, rc);
	buf = PGPNewSecureData (mgr, bytes, 0);
	if (buf == NULL) {
		err = kPGPError_OutOfMemory;
		goto error;
	}
	bnExtractBigBytes (bn, buf, 0, bytes);
	bnSetQ (bn, 0);

	/* Initialize BSafe public key structure */
	err = B_CreateAlgorithmObject (&bobj);
	CHKERR(err);
	err = B_SetAlgorithmInfo (bobj, AI_RSAPublic, NULL);
	CHKERR(err);
	err = B_CreateKeyObject (&rpubk);
	CHKERR(err);
	err = rpubk_init(rpubk, pub, mgr);
	CHKERR(err);
	err = B_EncryptInit (bobj, rpubk, RSA_CHOOSER, (A_SURRENDER_CTX *)0);
	CHKERR(err);

	/* Encrypt data */
	err = B_EncryptUpdate (bobj, buf, &bufoutlen, bytes, buf, bytes,
						(B_ALGORITHM_OBJ)NULL, (A_SURRENDER_CTX *)NULL);
	CHKERR(err);
	err = B_EncryptFinal (bobj, buf+bufoutlen, &bufoutlen, bytes-bufoutlen,
						(B_ALGORITHM_OBJ)NULL, (A_SURRENDER_CTX *)NULL);
	CHKERR(err);

	B_DestroyKeyObject (&rpubk);
	rpubk = NULL;
	B_DestroyAlgorithmObject (&bobj);
	bobj = NULL;

	/* Return to bn format */
	bnInsertBigBytes (bn, buf, 0, bytes);
	pgpClearMemory (buf, bytes);
	PGPFreeData (buf);
	buf = NULL;

error:
	if (buf) {
		pgpClearMemory (buf, bytes);
		PGPFreeData (buf);
	}
	if (rpubk)
		B_DestroyKeyObject (&rpubk);
	if (bobj)
		B_DestroyAlgorithmObject (&bobj);
	
	return err;
}