// // DSA Parameter Generation // void BSafe::BSafeKeyPairGenContext::generate( const Context &context, uint32 bitSize, CssmData ¶ms, 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; } }
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))); }
static int desEncrypt( TestParams *testParams, B_KEY_OBJ desKey, uint8 *initVector, CSSM_DATA *ptext, CSSM_DATA *ctext) { ITEM iv; B_BLK_CIPHER_W_FEEDBACK_PARAMS spec; B_ALGORITHM_OBJ alg = NULL; int brtn; unsigned actLen; unsigned remCtext = ctext->Length; iv.data = initVector; iv.len = DES_BLOCK_SIZE; brtn = desEncDecSetup(&iv, &spec, &alg); if(brtn) { return brtn; } brtn = B_EncryptInit(alg, desKey, BSAFE_ALGORITHM_CHOOSER, (A_SURRENDER_CTX *)NULL_PTR); if(brtn) { printf("***B_EncryptInit error (%d)\n", brtn); return brtn; } brtn = B_EncryptUpdate(alg, ctext->Data, &actLen, remCtext, ptext->Data, ptext->Length, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR); if(brtn) { printf("***B_EncryptUpdate error (%d)\n", brtn); return brtn; } remCtext -= actLen; ctext->Length = actLen; brtn = B_EncryptFinal(alg, ctext->Data + actLen, &actLen, remCtext, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR); if(brtn) { printf("***B_EncryptFinal error (%d)\n", brtn); return brtn; } ctext->Length += actLen; B_DestroyAlgorithmObject (&alg); return 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; }
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; }
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; }
/* 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); }
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); }
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); }
void BSafe::BSafeContext::reset() { B_DestroyAlgorithmObject(&bsAlgorithm); B_DestroyAlgorithmObject(&bsRandom); destroyBsKey(); }
/* * 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; }
/* * 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; }