Libraries
network_bp_source_encrypt_decrypt/main.c
// ////////////////////////////////////////////////////////////////////
//
// The network_bp_source_encrypt_decrypt program sends twelve
// encrypted packets to the network_bp_destination_encrypt_decrypt
// program using ION's bundle protocol. The
// network_bp_destination_encrypt_decrypt program decrypts the
// bundles and displays the decrypted messages. The
// network_bp_destination_encrypt_decrypt program then
// encrypts the messages prior to using ION's bundle potocol to send
// them back to the network_bp_source_encrypt_decrypt program for
// decryption and display on the source platform. The program uses
// the source public, source private key and destination public key
// created by the network_bp_destination_encrypt_decrypt program
// to encrypt and decrypt packets. The source public key and
// source private keys along with the destination
// public key must be moved to the home directory of the source
// platform prior to running the network_bp_source_encrypt_decrypt
// program. Program uses RegisterPrintMessage,
// CreateBPDevice, AddCipherToDevice,
// RegisterReceivePacket and SendPacket API functions. Note, TReK
// encryption library support is provided on 32 bit and 64 bit Linux
// operating systems and 64 bit Windows operating systems. TReK
// encryption library support is not available on 32 bit Window
// operating systems.
//
// The "network_bp_destination" example must be running on the destination
// platform prior to starting the network_bp_source_encrypt_decrypt example.
//
// ION must be configured with BP service numbers 3, 4
// and 5. Destination eid/node = 2. Source eid/node = 1.
//
// ////////////////////////////////////////////////////////////////////
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include "ds_shared.h"
#include "bp_shared.h"
#include "trek_error.h"
#ifdef __linux__
#include <unistd.h>
#else
#include <windows.h>
#endif
// ////////////////////////////////////////////////////////////////////////////
//
// PrintTheMessage controls how messages are processed and displayed to
// the user.
//
// ////////////////////////////////////////////////////////////////////////////
void PrintTheMessage(message_struct_type *mess_struct_ptr)
{
if (mess_struct_ptr->category == MSG_CAT_INFO ||
mess_struct_ptr->category == MSG_CAT_INFO_ALERT ||
mess_struct_ptr->category == MSG_CAT_ERROR ||
mess_struct_ptr->category == MSG_CAT_ERROR_ALERT)
{
printf("%s\t%s\n",GetMessageCategoryAsString(mess_struct_ptr->category),
mess_struct_ptr->message);
}
}
// ////////////////////////////////////////////////////////////////////////////
//
// ReceivePacket's key parameter is set to the packet's origin or source
// endpoint id string (ipn:<source node number>.<source service number>).
// The packet_buffer_ptr parameter points to the newly received packet.
//
// ////////////////////////////////////////////////////////////////////////////
void ReceivePacket(const char *key,
int packet_length,
unsigned char *packet_buffer_ptr)
{
// Print the data zone packets.
printf("Data\t%s\n",(char *)packet_buffer_ptr + 5);
}
// ////////////////////////////////////////////////////////////////////////////
//
// CreateDataPackets creates the data packets with a three byte header.
// The first three header bytes contains a sync hex pattern = fafbfc.
// The fourth and fifth header bytes contain the overall packet length in big
// endian byte order.
//
// ////////////////////////////////////////////////////////////////////////////
void CreateDataPackets(unsigned char *packet1_ptr,
unsigned char *packet2_ptr,
unsigned char *packet3_ptr,
unsigned char *packet4_ptr,
unsigned short *length1_ptr,
unsigned short *length2_ptr,
unsigned short *length3_ptr,
unsigned short *length4_ptr)
{
// Determine if this is a little endian or big endian platform .
unsigned short tester= 1;
unsigned char tester_byte[1];
unsigned char sync_pattern[3];
unsigned short big_endian_order = 1;
memcpy(tester_byte,&tester,1);
if (tester_byte[0] == 0x01)
{
big_endian_order = 0;
}
// Zero fill the packets prior to populating.
memset(packet1_ptr,0x00,50);
memset(packet2_ptr,0x00,50);
memset(packet3_ptr,0x00,50);
memset(packet4_ptr,0x00,50);
// Create a five byte header for all the packets. The header is populated
// with the sync bytes and a big endian two byte overall packet length.
// Populate packet data zone
strcpy((char *)packet1_ptr+5,"Mary had a little lamb");
strcpy((char *)packet2_ptr+5,"Its feet were black as soot");
strcpy((char *)packet3_ptr+5,"And into Mary's bread and jam ");
strcpy((char *)packet4_ptr+5,"Its sooty foot it put");
// Get packet length including 5 byte header and null terminator.
*length1_ptr = strlen((char *)packet1_ptr+5) + 6;
*length2_ptr = strlen((char *)packet2_ptr+5) + 6;
*length3_ptr = strlen((char *)packet3_ptr+5) + 6;
*length4_ptr = strlen((char *)packet4_ptr+5) + 6;
// Populate headers.
// Populate packet length field.
if (big_endian_order == 1)
{
memmove(packet1_ptr+3,length1_ptr,2);
memmove(packet2_ptr+3,length2_ptr,2);
memmove(packet3_ptr+3,length3_ptr,2);
memmove(packet4_ptr+3,length4_ptr,2);
}
else
{
memmove(packet1_ptr+4,length1_ptr,1);
memmove(packet2_ptr+4,length2_ptr,1);
memmove(packet3_ptr+4,length3_ptr,1);
memmove(packet4_ptr+4,length4_ptr,1);
}
// Populate sync field.
sync_pattern[0] = 0xfa;
sync_pattern[1] = 0xfb;
sync_pattern[2] = 0xfc;
memcpy(packet1_ptr,sync_pattern,3);
memcpy(packet2_ptr,sync_pattern,3);
memcpy(packet3_ptr,sync_pattern,3);
memcpy(packet4_ptr,sync_pattern,3);
}
// ////////////////////////////////////////////////////////////////////
//
// The network_bp_source_encrypt_decrypt program sends twelve
// encrypted packets to the network_bp_destination_encrypt_decrypt
// program using ION's bundle protocol. The
// network_bp_destination_encrypt_decrypt program decrypts the
// bundles and displays the decrypted messages. The
// network_bp_destination_encrypt_decrypt program then
// encrypts the messages prior to using ION's bundle potocol to send
// them back to the network_bp_source_encrypt_decrypt program for
// decryption and display on the source platform. The program uses
// the source public, source private key and destination public key
// created by the network_bp_destination_encrypt_decrypt program
// to encrypt and decrypt packets. The source public key and
// source private keys along with the destination
// public key must be moved to the home directory of the source
// platform prior to running the network_bp_source_encrypt_decrypt
// program. Program uses RegisterPrintMessage,
// CreateBPDevice, AddCipherToDevice,
// RegisterReceivePacket and SendPacket API functions. Note, TReK
// encryption library support is provided on 32 bit and 64 bit Linux
// operating systems and 64 bit Windows operating systems. TReK
// encryption library support is not available on 32 bit Window
// operating systems.
//
// The "network_bp_destination" example must be running on the destination
// platform prior to starting the network_bp_source_encrypt_decrypt example.
//
// ION must be configured with BP service numbers 3, 4
// and 5. Destination eid/node = 2. Source eid/node = 1.
//
// ////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
unsigned int source_service_number;
unsigned int lifespan;
bp_class_of_service_type cos; // BPD_BULK_PRIORITY, BPD_STD_PRIORITY or BPD_EXPEDITED_PRIORITY
unsigned int ordinal; // Values from 0-254. Only associated with EXPEDITED_PRIORITY class_of_service.
bp_transmission_mode_type mode; // BPD_BEST_EFFORT, BPD_ASSURED or BPD_ASSURED_WITH_CUSTODY_TRANSFER
bp_criticality_type criticality; // BPD_NOT_CRITICAL or BPD_CRITICAL
char source_device_key3[50];
char source_device_key4[50];
char source_device_key5[50];
unsigned char packet1[50];
unsigned char packet2[50];
unsigned char packet3[50];
unsigned char packet4[50];
unsigned short length1;
unsigned short length2;
unsigned short length3;
unsigned short length4;
unsigned int key_buffer_size;
long long destination_node_number;
unsigned int destination_service_number;
char home_path[256];
char source_public_key_pathname[256];
char source_private_key_pathname[256];
char destination_public_key_pathname[256];
char user_passphrase[64];
cipher_class_type cipher_class;
int pkt_key_encrypt_time_interval_sec;
// Create data packets.
CreateDataPackets(packet1,
packet2,
packet3,
packet4,
&length1,
&length2,
&length3,
&length4);
// Register the PrintMessage callback function prior to InitToolkitCfdp
// to process error messages that may be generated during initialization.
RegisterMessage(&PrintTheMessage);
printf("\nNetwork BP Source\n\n");
if (TCAACGetHomeDirectory(home_path, sizeof(home_path)) != SUCCESS)
{
printf("\nFailed to get the home directory\n");
return(FAIL);
}
// Set the ECC source public/private key pair pathnames
sprintf(source_public_key_pathname, "%s/source_bp_public.key", home_path);
sprintf(source_private_key_pathname, "%s/source_bp_private.key", home_path);
// Set the ECC destination public key pathname
sprintf(destination_public_key_pathname, "%s/destination_bp_public.key", home_path);
// Create a BP source device
source_service_number = 3;
lifespan = 86400;
ordinal = 0;
mode = BPD_ASSURED;
criticality = BPD_NOT_CRITICAL;
key_buffer_size = sizeof(source_device_key3);
if (CreateBPDevice(source_service_number,lifespan,cos,ordinal,mode,criticality,&key_buffer_size,source_device_key3) != SUCCESS)
{
return 0;
}
// Attach a cipher to the BP device. Since no peer node
// is associated with the cipher, it will encyrpt
// the bundles of data that are sent by the device to all
// peer nodes and decrypt the bundles of data that are
// received by the device from all peer nodes.
// The same cipher must be used for both the send and recieve devices
cipher_class = AES_256_GCM;
// Set the time interval defining how often the encryption key
// is changed (A zero value will change the encryption key
// with every bundle though this could impact performance for
// high bundle rate streams). The default value is 10 seconds.
pkt_key_encrypt_time_interval_sec = 0;
// No passphrase was used to encrypt the private key so pass
// and empty string
strcpy(user_passphrase, "");
if (AddCipherToDevice(source_device_key3,
cipher_class,
source_public_key_pathname,
source_private_key_pathname,
destination_public_key_pathname,
pkt_key_encrypt_time_interval_sec,
user_passphrase) != SUCCESS)
{
return 0;
}
// Associate the ReceivePacket callback function with the BP
// device so all packets received by the device will
// be processed by ReceivePacket callback function.
if (RegisterReceivePacket(source_device_key3,
&ReceivePacket) != SUCCESS)
{
return 0;
}
// Create and register a second BP source device
source_service_number = 4;
if (CreateBPDevice(source_service_number,lifespan,cos,ordinal,mode,criticality,&key_buffer_size,source_device_key4) != SUCCESS)
{
return 0;
}
// Attach a cipher to the BP device. Since no peer node
// is associated with the cipher, it will encyrpt
// the bundles of data that are sent by the device to all
// peer nodes and decrypt the bundles of data that are
// received by the device from all peer nodes.
if (AddCipherToDevice(source_device_key4,
cipher_class,
source_public_key_pathname,
source_private_key_pathname,
destination_public_key_pathname,
pkt_key_encrypt_time_interval_sec,
user_passphrase) != SUCCESS)
{
return 0;
}
if (RegisterReceivePacket(source_device_key4,
&ReceivePacket) != SUCCESS)
{
return 0;
}
// Create and register a third BP source device
source_service_number = 5;
if (CreateBPDevice(source_service_number,lifespan,cos,ordinal,mode,criticality,&key_buffer_size,source_device_key5) != SUCCESS)
{
return 0;
}
// Attach a cipher to the BP device. Since no peer node
// is associated with the cipher, it will encyrpt
// the bundles of data that are sent by the device to all
// peer nodes and decrypt the bundles of data that are
// received by the device from all peer nodes.
if (AddCipherToDevice(source_device_key5,
cipher_class,
source_public_key_pathname,
source_private_key_pathname,
destination_public_key_pathname,
pkt_key_encrypt_time_interval_sec,
user_passphrase) != SUCCESS)
{
return 0;
}
if (RegisterReceivePacket(source_device_key5,
&ReceivePacket) != SUCCESS)
{
return 0;
}
// BP service 3 device.
destination_node_number = 2;
destination_service_number = 3;
if (SendPacketFromBPDevice (source_device_key3,
length1,packet1,
destination_node_number,
destination_service_number) == SUCCESS)
{
if (SendPacketFromBPDevice (source_device_key3,
length2,
packet2,
destination_node_number,
destination_service_number) == SUCCESS)
{
if (SendPacketFromBPDevice (source_device_key3,
length3,
packet3,
destination_node_number,
destination_service_number) == SUCCESS)
{
SendPacketFromBPDevice (source_device_key3,
length4,
packet4,
destination_node_number,
destination_service_number);
}
}
}
// Send and receive the four data packets to the destination via the
// BP service 4 device.
destination_node_number = 2;
destination_service_number = 4;
if (SendPacketFromBPDevice (source_device_key4,
length1,packet1,
destination_node_number,
destination_service_number) == SUCCESS)
{
if (SendPacketFromBPDevice (source_device_key4,
length2,
packet2,
destination_node_number,
destination_service_number) == SUCCESS)
{
if (SendPacketFromBPDevice (source_device_key4,
length3,
packet3,
destination_node_number,
destination_service_number) == SUCCESS)
{
SendPacketFromBPDevice (source_device_key4,
length4,
packet4,
destination_node_number,
destination_service_number);
}
}
}
// Send and receive the four data packets to the destination via the
// BP service 5 device.
destination_node_number = 2;
destination_service_number = 5;
if (SendPacketFromBPDevice (source_device_key5,
length1,packet1,
destination_node_number,
destination_service_number) == SUCCESS)
{
if (SendPacketFromBPDevice (source_device_key5,
length2,
packet2,
destination_node_number,
destination_service_number) == SUCCESS)
{
if (SendPacketFromBPDevice (source_device_key5,
length3,
packet3,
destination_node_number,
destination_service_number) == SUCCESS)
{
SendPacketFromBPDevice (source_device_key5,
length4,
packet4,
destination_node_number,
destination_service_number);
}
}
}
// Allow time to print messages.
#ifdef __linux__
sleep(4);
#else
Sleep(4000);
#endif
return 0;
}