void BundleAuthenticationBlock::auth(dtn::data::Bundle &bundle, const dtn::security::SecurityKey &key)
		{
			BundleAuthenticationBlock& bab_begin = bundle.push_front<BundleAuthenticationBlock>();
			bab_begin.set(dtn::data::Block::DISCARD_IF_NOT_PROCESSED, true);

			// set security source
			if (!key.reference.sameHost(bundle.source)) bab_begin.setSecuritySource( key.reference );

			dtn::data::Number correlator = createCorrelatorValue(bundle);
			bab_begin.setCorrelator(correlator);
			bab_begin.setCiphersuiteId(BAB_HMAC);

			BundleAuthenticationBlock& bab_end = bundle.push_back<BundleAuthenticationBlock>();
			bab_end.set(dtn::data::Block::DISCARD_IF_NOT_PROCESSED, true);

			bab_end.setCorrelator(correlator);
			bab_end._ciphersuite_flags |= CONTAINS_SECURITY_RESULT;

			std::string sizehash_hash = calcMAC(bundle, key);
			bab_end._security_result.set(SecurityBlock::integrity_signature, sizehash_hash);
		}
Пример #2
0
		void PayloadConfidentialBlock::encrypt(dtn::data::Bundle& bundle, const dtn::security::SecurityKey &long_key, const dtn::data::EID& source)
		{
			// contains the random salt
			uint32_t salt;

			// contains the random key
			unsigned char ephemeral_key[ibrcommon::AES128Stream::key_size_in_bytes];

			unsigned char iv[ibrcommon::AES128Stream::iv_len];
			unsigned char tag[ibrcommon::AES128Stream::tag_len];

			// create a new correlator value
			dtn::data::Number correlator = createCorrelatorValue(bundle);

			// create a random salt and key
			createSaltAndKey(salt, ephemeral_key, ibrcommon::AES128Stream::key_size_in_bytes);

			// count all PCBs
			dtn::data::Size pcbs_size = std::count(bundle.begin(), bundle.end(), PayloadConfidentialBlock::BLOCK_TYPE);

			// count all PIBs
			dtn::data::Size pibs_size = std::count(bundle.begin(), bundle.end(), PayloadIntegrityBlock::BLOCK_TYPE);

			// encrypt PCBs and PIBs
			dtn::data::Bundle::find_iterator find_pcb(bundle.begin(), PayloadConfidentialBlock::BLOCK_TYPE);
			while (find_pcb.next(bundle.end()))
			{
				SecurityBlock::encryptBlock<PayloadConfidentialBlock>(bundle, find_pcb, salt, ephemeral_key).setCorrelator(correlator);
			}

			dtn::data::Bundle::find_iterator find_pib(bundle.begin(), PayloadIntegrityBlock::BLOCK_TYPE);
			while (find_pib.next(bundle.end()))
			{
				SecurityBlock::encryptBlock<PayloadConfidentialBlock>(bundle, find_pib, salt, ephemeral_key).setCorrelator(correlator);
			}

			// create a new payload confidential block
			PayloadConfidentialBlock& pcb = bundle.push_front<PayloadConfidentialBlock>();

			// set the correlator
			if (pcbs_size > 0 || pibs_size > 0)
				pcb.setCorrelator(correlator);

			// get reference to the payload block
			dtn::data::PayloadBlock& plb = bundle.find<dtn::data::PayloadBlock>();
			ibrcommon::BLOB::Reference blobref = plb.getBLOB();

			// encrypt payload - BEGIN
			{
				ibrcommon::BLOB::iostream stream = blobref.iostream();
				ibrcommon::AES128Stream aes_stream(ibrcommon::CipherStream::CIPHER_ENCRYPT, *stream, ephemeral_key, salt);

				// encrypt in place
				((ibrcommon::CipherStream&)aes_stream).encrypt(*stream);

				// check if this is a fragment
				if (bundle.get(dtn::data::PrimaryBlock::FRAGMENT))
				{
					// ... and set the corresponding cipher suit params
					addFragmentRange(pcb._ciphersuite_params, bundle.fragmentoffset, stream.size());
				}

				// get the IV
				aes_stream.getIV(iv);

				// get the tag
				aes_stream.getTag(tag);
			}
			// encrypt payload - END

			// set the source and destination address of the new block
			if (source != bundle.source.getNode()) pcb.setSecuritySource( source );
			if (long_key.reference != bundle.destination.getNode()) pcb.setSecurityDestination( long_key.reference );

			// set replicate in every fragment to true
			pcb.set(REPLICATE_IN_EVERY_FRAGMENT, true);

			// store encypted key, tag, iv and salt
			addSalt(pcb._ciphersuite_params, salt);

			// get the RSA key
			RSA *rsa_key = long_key.getRSA();

			// encrypt the random key and add it to the ciphersuite params
			addKey(pcb._ciphersuite_params, ephemeral_key, ibrcommon::AES128Stream::key_size_in_bytes, rsa_key);

			// free the RSA key
			long_key.free(rsa_key);

			pcb._ciphersuite_params.set(SecurityBlock::initialization_vector, iv, ibrcommon::AES128Stream::iv_len);
			pcb._ciphersuite_flags |= SecurityBlock::CONTAINS_CIPHERSUITE_PARAMS;

			pcb._security_result.set(SecurityBlock::PCB_integrity_check_value, tag, ibrcommon::AES128Stream::tag_len);
			pcb._ciphersuite_flags |= SecurityBlock::CONTAINS_SECURITY_RESULT;
		}