A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qkd-app-014.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 DOTFEESA www.tk.etf.unsa.ba
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Emir Dervisevic <emir.dervisevic@etf.unsa.ba>
19  * Miralem Mehic <miralem.mehic@ieee.org>
20  */
21 
22 #include "ns3/address.h"
23 #include "ns3/address-utils.h"
24 #include "ns3/log.h"
25 #include "ns3/inet-socket-address.h"
26 #include "ns3/inet6-socket-address.h"
27 #include "ns3/node.h"
28 #include "ns3/socket.h"
29 #include "ns3/udp-socket-factory.h"
30 #include "ns3/tcp-socket-factory.h"
31 #include "ns3/simulator.h"
32 #include "ns3/socket-factory.h"
33 #include "ns3/packet.h"
34 #include "ns3/trace-source-accessor.h"
35 #include "qkd-app-014.h"
36 
37 namespace ns3 {
38 
39 NS_LOG_COMPONENT_DEFINE ("QKDApp014");
40 
41 NS_OBJECT_ENSURE_REGISTERED (QKDApp014);
42 
43 TypeId
45 {
46  static TypeId tid = TypeId ("ns3::QKDApp014")
48  .SetGroupName("Applications")
49  .AddConstructor<QKDApp014> ()
50  .AddAttribute ("Protocol", "The type of protocol to use.",
54  .AddAttribute ("NumberOfKeyToFetchFromKMS",
55  "The total number of keys per request to LKMS (ESTI QKD 014)",
56  UintegerValue (3),
58  MakeUintegerChecker<uint32_t> ())
59  .AddAttribute ("LengthOfAuthenticationTag",
60  "The default length of the authentication tag",
61  UintegerValue (256), //32 bytes
63  MakeUintegerChecker<uint32_t> ())
64  .AddAttribute ("EncryptionType",
65  "The type of encryption to be used (0-unencrypted, 1-OTP, 2-AES)",
66  UintegerValue (1),
68  MakeUintegerChecker<uint32_t> ())
69  .AddAttribute ("AuthenticationType",
70  "The type of authentication to be used (0-unauthenticated, 1-VMAC, 2-MD5, 3-SHA1)",
71  UintegerValue (2),
73  MakeUintegerChecker<uint32_t> ())
74  .AddAttribute ("AESLifetime",
75  "Lifetime of AES key expressed in bytes",
76  UintegerValue (1),
78  MakeUintegerChecker<uint64_t> ())
79  .AddAttribute ("UseCrypto",
80  "Should crypto functions be performed (0-No, 1-Yes)",
81  UintegerValue (0),
83  MakeUintegerChecker<uint32_t> ())
84  .AddAttribute ("WaitInsufficient","Penalty time (in seconds) when there is insufficient amount of key",
85  TimeValue (Seconds (0.3)),
87  MakeTimeChecker ())
88  .AddAttribute ("WaitTransform","Penalty time (in seconds) when keys are being transformed",
89  TimeValue (Seconds (0.05)),
91  MakeTimeChecker ())
92 
93  .AddTraceSource ("Tx", "A new packet is created and is sent",
95  "ns3::Packet::TracedCallback")
96  .AddTraceSource ("TxSig", "A new signaling packet is created and is sent",
98  "ns3::Packet::TracedCallback")
99  .AddTraceSource ("TxKMS", "A new packet is created and is sent to local KMS",
101  "ns3::Packet::TracedCallback")
102  .AddTraceSource ("Rx", "A new packet is received",
104  "ns3::Packet::TracedCallback")
105  .AddTraceSource ("RxSig", "A new signaling packet is received",
107  "ns3::Packet::TracedCallback")
108  .AddTraceSource ("RxKMS", "A new packet is received from local KMS",
110  "ns3::Packet::TracedCallback")
111  .AddTraceSource ("StateTransition",
112  "Trace fired upon every QKDApp014 state transition.",
114  "ns3::Application::StateTransitionCallback")
115  .AddTraceSource ("PacketEncrypted",
116  "The change trance for currenly ecrypted packet",
118  "ns3::QKDCrypto::PacketEncrypted")
119  .AddTraceSource ("PacketDecrypted",
120  "The change trance for currenly decrypted packet",
122  "ns3::QKDCrypto::PacketDecrypted")
123  .AddTraceSource ("PacketAuthenticated",
124  "The change trance for currenly authenticated packet",
126  "ns3::QKDCrypto::PacketAuthenticated")
127  .AddTraceSource ("PacketDeAuthenticated",
128  "The change trance for currenly deauthenticated packet",
130  "ns3::QKDCrypto::PacketDeAuthenticated")
131  .AddTraceSource ("Mx", "Missed send packet call",
133  "ns3::Packet::TracedCallback")
134  .AddTraceSource ("KeyObtained", "Trace amount of obtained key material",
136  "ns3::QKDApp014::KeyObtained")
137  ;
138 
139  return tid;
140 }
141 //@toDo: add use fallback to AES when OTP is used (Y/N)
142 
143 uint32_t QKDApp014::m_applicationCounts = 0;
144 
154  : m_sendSignalingSocketApp (0),
155  m_sinkSignalingSocketApp (0),
156  m_sendDataSocketApp (0),
157  m_sinkDataSocketApp (0),
158  m_sendSocketToKMS (0),
159  m_sinkSocketFromKMS (0),
160  m_packetSize (0),
161  m_dataRate (0),
162  m_sendEvent (),
163  m_packetsSent (0),
164  m_dataSent (0),
165  m_master (0),
166  m_encryptor (0),
167  m_appState (NOT_STARTED)
168 {
170  m_id = UUID::Random();
171  m_random = CreateObject<UniformRandomVariable> ();
172 
174  {"NOT_STARTED", "INITIALIZED"},
175  {"INITIALIZED", "WAIT"},
176  {"INITIALIZED", "READY"},
177  {"WAIT", "READY"},
178  {"READY", "WAIT"},
179  {"READY", "SEND_DATA"},
180  {"SEND_DATA", "READY"},
181  {"READY", "DECRYPT_DATA"},
182  {"DECRYPT_DATA", "READY"},
183  {"DECRYPT_DATA", "STOPPED"},
184  {"SEND_DATA", "STOPPED"},
185  {"READY", "STOPPED"},
186  {"WAIT", "STOPPED"},
187  };
188 }
189 
191 {
192  //Data sockets
195  //Signaling sockets
198  //KMS sockets
199  m_sendSocketToKMS = 0;
201 }
202 
203 void
205  std::string socketType,
206  Address src,
207  Address dst,
208  Address kms,
209  UUID dstSaeId,
210  std::string type
211 ){
212  Setup(
213  socketType,
214  src,
215  dst,
216  kms,
217  dstSaeId,
218  0,
219  0,
220  DataRate ("0bps"),
221  type
222  );
223 }
224 
225 void
227  std::string socketType,
228  Address src,
229  Address dst,
230  Address kms,
231  UUID dstSaeId,
232  uint32_t packetSize,
233  uint32_t nPacketsSize,
234  DataRate dataRate,
235  std::string type
236 ){
237 
238  NS_LOG_FUNCTION (this << m_appState);
239 
240  if(type == "alice"){
241  m_master = 1;
242  }else{
243  m_master = 0;
244  }
245 
246  m_local = src;
247  m_peer = dst;
248  m_kms = kms;
249 
253  );
257  );
258 
259  m_dstSaeId = dstSaeId;
261  m_dataRate = dataRate;
262  m_socketType = socketType;
263 
264  m_internalAppWait = false; //No longer wait schedule required!
265  InitializeAppKeyBuffer (); //Setup application key buffer!
267 }
268 
269 
270 
278 void
280 {
281  NS_LOG_FUNCTION (this << m_appState);
282 
284  {
285  NS_LOG_FUNCTION (this << "QKDApp014 is running!");
286  double delay = m_packetSize * 8 / static_cast<double> (m_dataRate.GetBitRate ());
287  NS_LOG_FUNCTION( this << "delay" << Seconds (delay) );
288  Time tNext (Seconds (delay));
290 
291  } else
292  NS_LOG_FUNCTION (this << "QKDApp014 is" << GetAppStateString(m_appState));
293 }
294 
295 uint32_t
297 {
298  NS_LOG_FUNCTION( this << action << t );
299  uint32_t scheduleID {0};
300  EventId event;
301  if(action == "CheckAppBufferState"){
302  if(m_internalAppWait == false){
303  m_internalAppWait = true;
305  scheduleID = event.GetUid();
306  m_scheduledEvents.insert( std::make_pair( scheduleID , event) );
307  NS_LOG_FUNCTION(this << "Event successfully scheduled!");
308  }else{
309  NS_LOG_FUNCTION(this << "Scheduled event already exists!");
310  }
311  }else
312  NS_FATAL_ERROR( this << "Invalid action" << action );
313 
314  return scheduleID;
315 }
316 
317 void
319 {
320  NS_LOG_FUNCTION(this << eventId);
321 
322  std::map<uint32_t, EventId >::iterator eventEntry = m_scheduledEvents.find ( eventId );
323  if(eventEntry != m_scheduledEvents.end ()){
324  Simulator::Cancel (eventEntry->second);
325  }else{
326  NS_FATAL_ERROR ("Invalid entryId " << eventId );
327  }
328 
329 }
330 
331 
339 void
341 {
342 
343  NS_LOG_FUNCTION(this);
344 
345  if(!m_sinkSocketFromKMS){
346  Address localAddress = InetSocketAddress(
347  //InetSocketAddress::ConvertFrom(m_kms).GetIpv4 (),
349  82//InetSocketAddress::ConvertFrom(m_kms).GetPort ()
350  );
352 
353  if (m_sinkSocketFromKMS->Bind (localAddress) == -1)
354  NS_FATAL_ERROR ("Failed to bind socket");
355 
362  );
366  );
367  NS_LOG_FUNCTION (this << "Create new APP socket " << m_sinkSocketFromKMS
368  << " to listen packets from KMS on " << InetSocketAddress::ConvertFrom(localAddress).GetIpv4 ()
369  << " and port " << 82//InetSocketAddress::ConvertFrom(localAddress).GetPort ()
370  );
371  }else{
372  NS_LOG_FUNCTION (this << "Socket to listen from local KMS exists!" << m_sinkSocketFromKMS);
373  }
374 
375 }
376 
377 void
379 {
380  NS_LOG_FUNCTION(this);
381 
382  if(!m_sendSocketToKMS){
383  Address lkmsAddress = InetSocketAddress(
386  );
395  m_sendSocketToKMS->Connect ( lkmsAddress );
396  NS_LOG_FUNCTION (this << "Create new APP socket " << m_sendSocketToKMS << " to reach local KMS!");
397  }else{
398  NS_LOG_FUNCTION (this << "Socket to reach local KMS exists!" << m_sendSocketToKMS);
399  }
400 
401 }
402 
403 void
405 {
407 
409  {
410 
412 
413  if(m_socketType == "tcp"){
415  }else{
417  }
418 
424  }
425 
427  {
428 
429  if(m_socketType == "tcp"){
431  }else{
433  }
434 
440  }
441 
442  }else{
443  NS_LOG_FUNCTION (this << "Socket to reach peer app exists!" << m_sendSignalingSocketApp);
444  }
445 }
446 
447 void
449 {
450  NS_LOG_FUNCTION(this << GetNode()->GetId() << m_socketType );
451 
453  {
454 
455  if(m_socketType == "tcp") {
457  } else {
459  }
460 
462  NS_FATAL_ERROR ("Failed to bind socket");
463 
468  MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
470  );
474  );
475 
476  }else{
477  NS_LOG_FUNCTION (this << "Socket to listen signaling from peer app exists!" << m_sinkSignalingSocketApp);
478  }
479 
480 
482  {
483 
484  if(m_socketType == "tcp")
486  else
488 
489  if (m_sinkDataSocketApp->Bind (m_local) == -1)
490  NS_FATAL_ERROR ("Failed to bind socket");
491 
496  MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
498  );
502  );
503  }else{
504  NS_LOG_FUNCTION (this << "Socket to listen data from peer app exists!" << m_sinkSignalingSocketApp);
505  }
506 
507 }
508 
509 bool
511 {
512  NS_LOG_FUNCTION (this << socket << from
513  << InetSocketAddress::ConvertFrom(from).GetIpv4 ()
514  << InetSocketAddress::ConvertFrom(from).GetPort ()
515  );
516  NS_LOG_FUNCTION (this << "QKDApp014 Connection from KMS requested on socket " << socket);
517  return true; // Unconditionally accept the connection request.
518 
519 }
520 
521 void
523 {
524  Address peer;
525  NS_LOG_FUNCTION (this << socket << from
526  << InetSocketAddress::ConvertFrom(from).GetIpv4 ()
527  << InetSocketAddress::ConvertFrom(from).GetPort ()
528  );
529  NS_LOG_FUNCTION (this << "QKDApp014 Connection from KMS accepted on socket " << socket);
531 }
532 
533 void
535 {
536  NS_LOG_FUNCTION (this << s << from
537  << InetSocketAddress::ConvertFrom(from).GetIpv4 ()
538  << InetSocketAddress::ConvertFrom(from).GetPort ()
539  );
540 
541  NS_LOG_FUNCTION (this << "QKDApp014 Connection from APP accepted on socket " << s);
543 }
544 
545 void
547 {
548  NS_LOG_FUNCTION (this << s << from
549  << InetSocketAddress::ConvertFrom(from).GetIpv4 ()
550  << InetSocketAddress::ConvertFrom(from).GetPort ()
551  );
552 
553  NS_LOG_FUNCTION (this << "QKDApp014 Signaling Connection from APP accepted on socket " << s);
555 }
556 
557 void
559 {
560  NS_LOG_FUNCTION (this << socket << "QKDApp014 Connection to KMS succeeded via socket " << socket);
561 }
562 
563 void
565 {
566  NS_LOG_FUNCTION (this << socket << "QKDApp014, Connection to KMS Failed via socket " << socket);
567 }
568 
569 void
571 {
572  NS_LOG_FUNCTION (this << socket << "QKDApp014 Connection to APP succeeded via socket " << socket);
573 }
574 
575 void
577 {
578  NS_LOG_FUNCTION (this << socket << "QKDApp014, Connection to APP Failed via socket " << socket);
579 }
580 
581 void
583 {
584  NS_LOG_FUNCTION (this << socket << "QKDApp014 Signaling Connection to APP succeeded via socket " << socket);
585 }
586 
587 void
589 {
590  NS_LOG_FUNCTION (this << socket << "QKDApp014, Connection to APP Failed via socket " << socket);
591 }
592 
593 void
595 {
596  NS_LOG_FUNCTION (this << socket);
597 }
598 
599 void
601 {
602  NS_LOG_FUNCTION (this << socket);
603 }
604 
605 void
607 {
608  NS_LOG_FUNCTION (this << socket);
609 }
610 void
612 {
613  NS_LOG_FUNCTION (this << socket);
614 }
615 
616 void
618 {
619  NS_LOG_FUNCTION (this << socket);
620 }
621 
622 void
624 {
625  NS_LOG_FUNCTION (this << socket);
626 }
627 
628 void
630 {
631  NS_LOG_FUNCTION (this << socket);
632 
633  Ptr<Packet> packet;
634  Address from;
635  while ((packet = socket->RecvFrom (from)))
636  {
637  if (packet->GetSize () == 0)
638  { //EOF
639  break;
640  }
641 
642  NS_LOG_FUNCTION (this
643  << packet << "PACKETID: " << packet->GetUid()
644  << " of size: " << packet->GetSize()
645  );
646 
648  {
649  NS_LOG_FUNCTION("At time " << Simulator::Now ().GetSeconds ()
650  << "s packet from KMS received "
651  << packet->GetSize () << " bytes from "
653  << " port " << InetSocketAddress::ConvertFrom (from).GetPort ()
654  );
655  }
656 
657  PacketReceivedFromKMS (packet, from, socket);
658  }
659 }
660 
661 void
663 {
664  NS_LOG_FUNCTION (this << socket);
665 
666  Ptr<Packet> packet;
667  Address from;
668  while ((packet = socket->RecvFrom (from)))
669  {
670  if (packet->GetSize () == 0)
671  { //EOF
672  break;
673  }
674 
675  NS_LOG_FUNCTION (this << packet
676  << "PACKETID: " << packet->GetUid()
677  << " of size: " << packet->GetSize()
678  );
679 
681  {
682  NS_LOG_FUNCTION( this << "At time " << Simulator::Now ().GetSeconds ()
683  << "s packet from APP pair received "
684  << packet->GetSize () << " bytes from "
686  << " port " << InetSocketAddress::ConvertFrom (from).GetPort () << "\n");
687  }
688 
689  DataPacketReceivedFromApp (packet, from, socket);
690  }
691 }
692 
693 void
695 {
696  NS_LOG_FUNCTION (this << socket);
697 
698  Ptr<Packet> packet;
699  Address from;
700  while ((packet = socket->RecvFrom (from)))
701  {
702  if (packet->GetSize () == 0)
703  { //EOF
704  break;
705  }
706 
707  NS_LOG_FUNCTION (this << packet
708  << "PACKETID: " << packet->GetUid()
709  << " of size: " << packet->GetSize()
710  );
711 
713  {
714  NS_LOG_FUNCTION( this << "At time " << Simulator::Now ().GetSeconds ()
715  << "s signaling packet from APP pair received "
716  << packet->GetSize () << " bytes from "
718  << " port " << InetSocketAddress::ConvertFrom (from).GetPort () << "\n");
719  }
720 
721  SignalingPacketReceivedFromApp (packet, from, socket);
722  }
723 }
724 
725 void
727 {
728  NS_LOG_FUNCTION (this << "QKDApp014 Data to KMS Sent via socket " << socket);
729 }
730 
731 
739 void
741 {
742 
743  NS_LOG_FUNCTION( this << "Application key buffer is initialized!");
744  //Initialize storages of keys!
749 }
750 
751 void
752 QKDApp014::RemoveKeysFromTemporaryKeyStore (std::vector<std::string> keyIds)
753 {
754  NS_LOG_FUNCTION( this << "Keys removed from temporary key store" << keyIds );
755  std::map<std::string, QKDApp014::QKDApp014Key>::iterator it;
756  for (uint i = 0; i < keyIds.size(); i++) {
757  it = (m_appKeyBuffer.temporaryKeyStoreMaster).find(keyIds[i]);
758  if (it == m_appKeyBuffer.temporaryKeyStoreMaster.end())
759  //NS_FATAL_ERROR( this << "Key with ID" << keyIds[i] << "does not exist in temporary key store!" );
760  NS_LOG_DEBUG( this << "Key with ID" << keyIds[i] << "does not exist in temporary key store!" );
761  else
763  }
764 }
765 
766 void
768 {
769  NS_LOG_FUNCTION( this << "Key with ID" << key.keyId << "is added to inbound key store!" );
770  (m_appKeyBuffer.inboundKeyStore).insert(std::make_pair(key.keyId, key));
771 }
772 
773 void
775 {
776  NS_LOG_FUNCTION( this << "Key with ID" << key.keyId << "is added to encription key store!" );
777  (m_appKeyBuffer.outboundEncKeyStore).insert(std::make_pair(key.keyId, key));
778 }
779 
780 void
782 {
783  NS_LOG_FUNCTION( this << "Key with ID" << key.keyId << "is added to authentication key store!" );
784  (m_appKeyBuffer.outboundAuthKeyStore).insert(std::make_pair(key.keyId, key));
785 }
786 
787 void
789 {
790  std::map<std::string, QKDApp014::QKDApp014Key>::iterator it = (m_appKeyBuffer.temporaryKeyStoreMaster).begin();
791  while (it != (m_appKeyBuffer.temporaryKeyStoreMaster).end()) {
792  NS_LOG_FUNCTION( this << "KeyId" << it->first << it->second.keyId << "\n" );
793  it++;
794  }
795 }
796 
797 void
799 {
800  NS_LOG_FUNCTION( this << "Outbound encrption key count" << m_appKeyBuffer.outboundEncKeyStore.size()
801  << "Outbound authentication key count" << m_appKeyBuffer.outboundAuthKeyStore.size()
802  << "Inbound key count" << m_appKeyBuffer.inboundKeyStore.size() );
803 }
804 
805 void
807 {
808  NS_LOG_FUNCTION(this << "Primary QKDApp checks internal enc/auth buffer states ...");
810  //Note: CheckAppBufferState must not be triggered from anywhere while m_internalAppWait is true! It is called on scheduled event!
811  if(m_master){ //Only at Primary application!
812  if(GetEncryptionKeySize() != 0 && m_appKeyBuffer.outboundEncKeyStore.empty()) //Check the state of encryption key store
813  GetKeysFromKMS(0); // 0 - Encryption key
814  if(GetAuthenticationKeySize() != 0 && m_appKeyBuffer.outboundAuthKeyStore.empty()) //Check the state of authentication key store
815  GetKeysFromKMS(1); // 1 - Authentication key
816  CheckAppState();
817  }
818 }
819 
820 void
822 {
823  NS_LOG_FUNCTION(this << "Checking the conditions to change the application state ...");
824  bool encryptionReady {true}, authenticationReady {true};
826  encryptionReady = false;
828  authenticationReady = false;
829 
830  if(m_appState == WAIT && encryptionReady && authenticationReady)
832  else if(m_appState == READY && !(encryptionReady && authenticationReady))
834 }
835 
838 {
840  if(keyType == 0){ //Get encryption key
841  NS_LOG_FUNCTION( this << "Obtaining encryption key from application key buffer!" );
842  if(!m_appKeyBuffer.outboundEncKeyStore.empty()){
843  std::map<std::string, QKDApp014::QKDApp014Key>::iterator it = m_appKeyBuffer.outboundEncKeyStore.begin();
844  key = it->second;
845  NS_LOG_FUNCTION( this << "Key" << key.keyId << key.lifetime << m_packetSize );
846  if(int64_t (key.lifetime - m_packetSize) < int64_t (m_packetSize)){
847  NS_LOG_FUNCTION( this << "Key " << key.keyId << " removed from application key buffer!" );
849  } else {
850  it->second.lifetime = key.lifetime - m_packetSize;
851  }
852  } else
853  NS_FATAL_ERROR ( this << "Encryption key buffer is empty!" );
854 
855  }else if(keyType == 1){ //Get authentication key
856  NS_LOG_FUNCTION( this << "Obtaining authentication key from application key buffer!" );
858  std::map<std::string, QKDApp014::QKDApp014Key>::iterator it = m_appKeyBuffer.outboundAuthKeyStore.begin();
859  key = it->second;
860  NS_LOG_FUNCTION( this << "Key " << key.keyId << " removed from applicaiton key buffer!" );
862  } else
863  NS_FATAL_ERROR ( this << "Authentication key buffer is empty!" );
864 
865  }else
866  NS_FATAL_ERROR( this << "Invalid key type" << keyType
867  << "Allowed values are 0-Encryption key type, and 1-Authentication key type" );
868 
869  return key;
870 
871 }
872 
874 QKDApp014::GetKeyFromAppKeyBuffer (std::string keyId, std::string keyType)
875 {
876  NS_LOG_FUNCTION( this << keyId );
878  std::map<std::string, QKDApp014::QKDApp014Key>::iterator it;
879  it = m_appKeyBuffer.inboundKeyStore.find(keyId);
880  if(it != m_appKeyBuffer.inboundKeyStore.end()){
881  key = it->second;
882  if (keyType == "enc"){
883  if(
884  (m_encryptionTypeInt == 2 &&
885  int64_t (key.lifetime - m_packetSize) < int64_t (m_packetSize)) ||
887  ){ //AES expired key or OTP
888  NS_LOG_FUNCTION( this << "Key " << key.keyId << " removed from inbound key buffer!" );
890  }else if(m_encryptionTypeInt == 2){ //AES update lifetime
891  it->second.lifetime = key.lifetime - m_packetSize;
892  }
893  }else if(keyType == "auth"){
894  NS_LOG_FUNCTION( this << "Key " << key.keyId << " removed from inbound key buffer!" );
896  }else
897  NS_FATAL_ERROR( this << "Inalid key type as input " << keyType );
898  }else
899  NS_FATAL_ERROR( this << "Key" << keyId << " is missing from inbound key store" );
900 
901  return key;
902 }
903 
904 
912 void
913 QKDApp014::MemoriesRequestKMS (uint32_t methodType, uint32_t keyType)
914 {
915  m_httpRequestsKMS.push_back (std::make_pair (methodType, keyType));
916 }
917 
918 void
919 QKDApp014::MemoriesRequestApp (std::vector<std::string> keyIds)
920 {
921  m_httpRequestsApp.push_back (keyIds);
922 }
923 
924 void
926 {
927  m_httpRequestsKMS.erase (m_httpRequestsKMS.begin());
928 }
929 
930 void
932 {
933  m_httpRequestsApp.erase (m_httpRequestsApp.begin());
934 }
935 
936 uint32_t
938 {
939  return (m_httpRequestsKMS[0]).first;
940 }
941 
942 uint32_t
944 {
945  return (m_httpRequestsKMS[0]).second;
946 }
947 
948 
956 void
958 {
959  NS_LOG_FUNCTION ( this << m_local << m_peer << m_master );
960 
961  m_packetsSent = 0;
962 
963  if(m_encryptionTypeInt < 0 || m_encryptionTypeInt > 2){
964  NS_FATAL_ERROR ("Invalid encryption type " << m_encryptionTypeInt << ". Allowed values are (0-unencrypted, 1-OTP, 2-AES)" );
965  }
966 
967  if(m_authenticationTypeInt < 0 || m_authenticationTypeInt > 3){
968  NS_FATAL_ERROR ("Invalid authentication type " << m_authenticationTypeInt << ". Allowed values are (0-unauthenticated, 1-VMAC, 2-MD5, 3-SHA1)" );
969  }
970 
971  if(m_aesLifetime < 0)
972  NS_FATAL_ERROR ("Invalid AES lifetime " << m_aesLifetime << ". The value must be larger than zero." );
973 
974  else if (m_aesLifetime < m_packetSize && m_aesLifetime != 0)
975  NS_FATAL_ERROR ("Invalid AES lifetime " << m_aesLifetime << ". The value must be larger than one packet size " << m_packetSize );
976 
977  if (m_appState == INITIALIZED)
978  {
979 
984  );
985  AppTransitionTree(); //Transition states
986  PrepareSinkSocketFromApp(); //Create sink sockets for peer QKD applications
987 
988  } else {
989  NS_FATAL_ERROR ("Invalid state " << GetAppStateString ()
990  << " for StartApplication().");
991  }
992 
993 }
994 
995 void
997 {
998  NS_LOG_FUNCTION( this );
999 
1000  if (m_sendEvent.IsRunning ())
1001  {
1003  }
1004 
1005  if (m_sendDataSocketApp)
1007  if (m_sinkDataSocketApp)
1013 
1014  InitializeAppKeyBuffer(); //Clear app key buffer!
1015  if (m_sendSocketToKMS)
1017  if (m_sinkSocketFromKMS)
1019 
1020  NS_LOG_FUNCTION( this << "Open sockets are closed and application is stopped" );
1022 }
1023 
1024 void
1026 {
1027  NS_LOG_FUNCTION( this );
1028 
1029  if (m_appState == READY) //Direct call from SceduleTx()
1031 
1032  if (m_appState == SEND_DATA) { //QKDApp014 can send packets only when in SEND_DATA state!
1033 
1034  if(!m_sendDataSocketApp) {
1036  }
1037 
1038  bool encrypted = m_encryptionType;
1039  bool authenticated = m_authenticationType;
1040  NS_LOG_FUNCTION( this << "Enc/Auth" << encrypted << authenticated );
1041 
1042  //Obtain secret keys!
1043  QKDApp014::QKDApp014Key encKey;
1044  encKey.keyId = std::string(32, '0');
1045  QKDApp014::QKDApp014Key authKey;
1046  authKey.keyId = std::string(32, '0');
1047 
1048  if (encrypted) //Obtain encryption key from application key buffer!
1049  encKey = GetKeyFromAppKeyBuffer(0); //0 - encryption key
1050  if (GetAuthenticationKeySize() != 0) //Obtain authentication key from application key buffer!
1051  authKey = GetKeyFromAppKeyBuffer(1); //1 - authentication key
1052 
1053  //Decode keys from Base64!
1054  std::string encKeyDecoded = m_encryptor->Base64Decode(encKey.key);
1055  std::string authKeyDecoded = m_encryptor->Base64Decode(authKey.key);
1056 
1057  //Define confidential message
1058  std::string confidentialMsg = GetPacketContent();
1059  NS_LOG_FUNCTION( this << "Confidential message" << confidentialMsg.size() << confidentialMsg );
1060 
1061  std::string encryptedMsg;
1062  std::string authTag;
1063 
1064  if (m_useCrypto) {
1065 
1066  encryptedMsg = m_encryptor->EncryptMsg(confidentialMsg, encKeyDecoded);
1067  NS_LOG_FUNCTION ( this << "Encryption key" << encKey.keyId << encKeyDecoded
1068  << "Encrypted message (Base64 print)" << m_encryptor->Base64Encode(encryptedMsg));
1069  authTag = m_encryptor->Authenticate (encryptedMsg, authKeyDecoded);
1070  NS_LOG_FUNCTION( this << "Authentication key" << authKey.keyId << authKeyDecoded
1071  << "Authentication tag" << authTag );
1072 
1073  } else {
1074 
1075  encryptedMsg = confidentialMsg;
1076  authTag = GetPacketContent(32); //Use random authTag
1077  NS_LOG_FUNCTION ( this << "Encryption key" << encKey.keyId << encKeyDecoded );
1078  NS_LOG_FUNCTION( this << "Authentication key" << authKey.keyId << authKeyDecoded );
1079 
1080  }
1081 
1082  //Create packet with protected/unprotected data
1083  std::string msg = encryptedMsg;
1084  Ptr<Packet> packet = Create<Packet> ( (uint8_t*) msg.c_str(), msg.length() );
1085  NS_ASSERT (packet);
1086  m_authenticationTrace (packet, authTag);
1087 
1088  //Add qkd header!
1089  QKDAppHeader qHeader;
1090  qHeader.SetEncrypted(m_encryptionType);
1091  qHeader.SetEncryptionKeyId(CreateKeyIdField(encKey.keyId));
1093  qHeader.SetAuthenticationKeyId(CreateKeyIdField(authKey.keyId));
1094  qHeader.SetAuthTag(authTag);
1095  qHeader.SetLength(packet->GetSize() + qHeader.GetSerializedSize());
1096  packet->AddHeader(qHeader);
1097 
1098  //Send packet!
1099  m_txTrace (packet, m_dstSaeId.string());
1100  m_sendDataSocketApp->Send (packet);
1101  m_packetsSent++;
1102  m_dataSent += packet->GetSize();
1103 
1104  NS_LOG_FUNCTION (this << "Sending protected packet: " << packet->GetUid() << " of size " << packet->GetSize() );
1105 
1106  SwitchAppState(READY); //Application is now ready
1108  //Schedule new time instance to send data!
1109  ScheduleTx ();
1110 
1111  } else if (m_appState == WAIT) {
1112 
1113  m_mxTrace (0, m_dstSaeId.string());
1114  ScheduleTx ();
1115  NS_LOG_FUNCTION( this << "Application is currently unable to send new data! QKDApp014 state" << GetAppStateString(m_appState) );
1116 
1117  }
1118 
1119 }
1120 
1121 void
1123 {
1124  NS_LOG_FUNCTION ( this << m_master << p->GetUid() << p->GetSize() << from );
1125 
1126  if (m_master == 0) { //Process encrypted data on Replica QKDApp014
1127 
1128  if (m_appState == READY) { //Replica QKDApp014 MUST be in ready state to receive data
1129 
1130  QKDAppHeader header;
1131  Ptr<Packet> buffer;
1132 
1133  auto itBuffer = m_buffer_QKDApp014.find (from);
1134  if (itBuffer == m_buffer_QKDApp014.end ())
1135  {
1136  itBuffer = m_buffer_QKDApp014.insert (std::make_pair (from, Create<Packet> (0))).first;
1137  }
1138 
1139  buffer = itBuffer->second;
1140  buffer->AddAtEnd (p);
1141  buffer->PeekHeader (header);
1142 
1143  NS_ABORT_IF (header.GetLength () == 0);
1144 
1145  while (buffer->GetSize () >= header.GetLength ())
1146  {
1147  NS_LOG_DEBUG ("Removing packet of size " << header.GetLength () << " from buffer of size " << buffer->GetSize ());
1148  Ptr<Packet> completePacket = buffer->CreateFragment (0, static_cast<uint32_t> (header.GetLength ()));
1149  buffer->RemoveAtStart (static_cast<uint32_t> (header.GetLength ()));
1150 
1151  m_rxTrace ( completePacket, m_dstSaeId.string() );
1152  completePacket->RemoveHeader (header);
1153  NS_LOG_FUNCTION(this << "RECEIVED QKDApp014 HEADER: " << header);
1154 
1155  ProcessDataPacketFromApp(header, completePacket, socket);
1156 
1157  if (buffer->GetSize () > header.GetSerializedSize ())
1158  {
1159  buffer->PeekHeader (header);
1160  }
1161  else
1162  {
1163  break;
1164  }
1165  }
1166 
1167  } else {
1168  NS_LOG_FUNCTION( this << "Primary/Replica:" << m_master << "Invalid state " << GetAppStateString() );
1169  }
1170  }
1171 
1172 }
1173 
1174 void
1176 {
1177  NS_LOG_FUNCTION( this );
1178 
1179  if (m_master == 0) { //Only Replica QKDApp014 receives encrypted data!
1180 
1181  uint8_t *buffer = new uint8_t[packet->GetSize ()];
1182  packet->CopyData(buffer, packet->GetSize ());
1183  std::string payload = std::string((char*)buffer, packet->GetSize ());
1184  delete[] buffer;
1185 
1186  NS_LOG_FUNCTION( this << "Replica QKDApp014 received data packet from peer QKDApp014" << m_encryptor->Base64Encode(payload) );
1187 
1190  std::string decryptedMsg;
1191  bool authSuccessful = false;
1192  m_packetSize = payload.length();
1193  //Perform authentication first
1194  if (GetAuthenticationKeySize() != 0)
1195  {
1196  //Fetch key
1199 
1200  if (m_useCrypto)
1201  {
1202  //Decode key
1203  std::string decodedKey = m_encryptor->Base64Decode(key.key);
1204  //Check authTag
1205  if (m_encryptor->CheckAuthentication(payload, header.GetAuthTag(), decodedKey)) {
1206  authSuccessful = true;
1207  NS_LOG_FUNCTION( this << "Packet successfully authenticated" );
1208  }
1209  else
1210  NS_LOG_FUNCTION( this << "FAILED authentication of received packet" );
1211 
1212  } else { //We assume packet is authenticated
1213 
1214  authSuccessful = true;
1215  NS_LOG_FUNCTION( this << "Packet authenticated" );
1216  }
1217 
1218  } else if (header.GetAuthenticated()) {
1219 
1220  if (m_useCrypto)
1221  {
1222  if (m_encryptor->CheckAuthentication(payload, header.GetAuthTag(), "")) {
1223  authSuccessful = true;
1224  NS_LOG_FUNCTION( this << "Packet successfully authenticated" );
1225  }
1226  else
1227  NS_LOG_FUNCTION( this << "FAILED authentication of received packet" );
1228  } else { //We assume packet is authenticated
1229 
1230  authSuccessful = true;
1231  NS_LOG_FUNCTION( this << "Packet authenticated" );
1232  }
1233  } else
1234  authSuccessful = true;
1235 
1236  //Perform decryption
1237  if (header.GetEncrypted()) //Perform decryption
1238  {
1239  //Fetch key
1242  if (m_useCrypto)
1243  {
1244  //Decode key
1245  std::string decodedKey = m_encryptor->Base64Decode(key.key);
1246  NS_LOG_FUNCTION( this << decodedKey );
1247  //Decrypt packet
1248  if (authSuccessful)
1249  {
1250  decryptedMsg = m_encryptor->DecryptMsg (payload, decodedKey);
1251  NS_LOG_FUNCTION( this << "Decrypted message" << decryptedMsg );
1252  }
1253  } else {
1254 
1255  if (authSuccessful)
1256  NS_LOG_FUNCTION( this << "Packet decrypted" );
1257  }
1258 
1259  } else {
1260 
1261  if (m_useCrypto)
1262  NS_LOG_FUNCTION( this << "Packet decrypted" );
1263  else
1264  NS_LOG_FUNCTION( this << "Received message" << payload );
1265  }
1266 
1268 
1269  } else
1270  NS_FATAL_ERROR( this << "Only Replica QKDApp014 should receive protected packet" );
1271 }
1272 
1273 
1274 
1283 void
1285 {
1286  NS_LOG_FUNCTION (this << "QKDApp014 Get Status " << keyType);
1287 
1288  if(!m_sendSocketToKMS)
1290 
1291  if(!m_sinkSocketFromKMS)
1293 
1294  //SEND PACKET TO KMS - GET STATUS
1295 
1297  std::ostringstream lkmsAddressTemp;
1298  lkmsAddress.Print(lkmsAddressTemp); //IPv4Address to string
1299  std::string headerUri = "http://" + lkmsAddressTemp.str ();
1300 
1301  if(keyType)
1302  headerUri += "/api/v1/keys/" + m_ksid_enc.string() + "/status";
1303  else
1304  headerUri += "/api/v1/keys/" + m_ksid_auth.string() + "/status";
1305 
1306 
1307  //Create packet
1308  HTTPMessage httpMessage;
1309  httpMessage.CreateRequest(headerUri, "GET");
1310  std::string hMessage = httpMessage.ToString();
1311  Ptr<Packet> packet = Create<Packet> (
1312  (uint8_t*) (hMessage).c_str(),
1313  hMessage.size()
1314  );
1315  NS_ASSERT (packet);
1316 
1317  NS_LOG_FUNCTION (this << "Sending PACKETID: " << packet->GetUid()
1318  << " of size: " << packet->GetSize()
1319  << " via socket " << m_sendSocketToKMS
1320  );
1321 
1322  MemoriesRequestKMS(0);
1323  m_txKmsTrace (packet);
1324  m_sendSocketToKMS->Send (packet);
1325 
1326 }
1327 
1328 void
1329 QKDApp014::GetKeysFromKMS (uint32_t keyType)
1330 {
1331  NS_LOG_FUNCTION( this << "QKDApp014 Get Key" << m_master );
1332 
1333  if(!m_sendSocketToKMS)
1335  if(!m_sinkSocketFromKMS)
1337 
1338  uint32_t numberOfKeys = m_numberOfKeysKMS; //@toDo dinamic behaviour of numberOfKeys!
1339  if (numberOfKeys <= 0) //Application basic check of user input!
1340  NS_FATAL_ERROR( this << "Invalid application parameter - m_numberOfKeysKMS" << numberOfKeys );
1341 
1342  if (keyType == 0) //Get Key request for encryption keys!
1343  {
1344 
1345  uint32_t sizeOfKeys = GetEncryptionKeySize(); //Size of a key based on defined encryption algorithm
1346  NS_LOG_FUNCTION( this << "Size of encryption keys" << sizeOfKeys );
1347 
1348  std::vector<std::string> additional_slave_SAE_IDs {}; //No additional Replica SAEs
1349  bool useGet = false; //Is application allowed to use GET method for such request?
1350  bool usedMethod; //Used method: false -> POST, true -> GET (if possible)
1351 
1352  if (additional_slave_SAE_IDs.empty() && useGet)
1353  usedMethod = true;
1354  else
1355  usedMethod = false;
1356 
1357  //Create HTTP header - ETSI014 Get Key request!
1359  std::ostringstream lkmsAddressTemp;
1360  lkmsAddress.Print(lkmsAddressTemp); //IPv4Address to string
1361  std::string headerUri = "http://" + lkmsAddressTemp.str ();
1362  headerUri += "/api/v1/keys/" + m_ksid_enc.string() + "/enc_keys";
1363 
1364 
1365  std::string requestBody;
1366  HTTPMessage httpMessage;
1367  if (usedMethod)
1368  {
1369  requestBody = {};
1370 
1371  //Update header URI
1372  headerUri += "/number/" + std::to_string(numberOfKeys);
1373  headerUri += "/size/" + std::to_string(sizeOfKeys);
1374  httpMessage.CreateRequest(headerUri, "GET");
1375  } else {
1376 
1377  nlohmann::json jkeyrequest;
1378  jkeyrequest["number"] = numberOfKeys;
1379  jkeyrequest["size"] = sizeOfKeys;
1380  if (!additional_slave_SAE_IDs.empty()){
1381  jkeyrequest["additional_slave_SAE_IDs"] = additional_slave_SAE_IDs;
1382  }
1383  requestBody = jkeyrequest.dump();
1384 
1385  httpMessage.CreateRequest(headerUri, "POST", requestBody);
1386  }
1387 
1388  std::string hMessage = httpMessage.ToString();
1389  Ptr<Packet> packet = Create<Packet> (
1390  (uint8_t*) (hMessage).c_str(),
1391  hMessage.size()
1392  );
1393  NS_ASSERT (packet);
1394 
1395 
1396  NS_LOG_FUNCTION (this << "Sending PACKETID: " << packet->GetUid()
1397  << " of size: " << packet->GetSize()
1398  << " via socket " << m_sendSocketToKMS
1399  );
1400 
1401  //Store request to HTTP requests store (to be able to map responses)
1402  MemoriesRequestKMS(1, 0); //(method type, key type)
1403  m_txKmsTrace (packet);
1404  m_sendSocketToKMS->Send (packet);
1405 
1406  } else if (keyType == 1)
1407  {
1408 
1409  uint32_t sizeOfKeys = GetAuthenticationKeySize(); //Size of a key based on defined authentication algorithm
1410  NS_LOG_FUNCTION( this << "Size of authentication keys" << sizeOfKeys );
1411 
1412  std::vector<std::string> additional_slave_SAE_IDs {}; //No additional Replica SAEs
1413  bool useGet = false; //Is application allowed to use GET method for such request?
1414  bool usedMethod; //Used method: false -> POST, true -> GET
1415 
1416  if (additional_slave_SAE_IDs.empty() && useGet)
1417  usedMethod = true;
1418  else
1419  usedMethod = false;
1420 
1421  //Create HTTP header - ETSI014 Get Key request!
1423  std::ostringstream lkmsAddressTemp;
1424  lkmsAddress.Print(lkmsAddressTemp); //IPv4Address to string
1425  std::string headerUri = "http://" + lkmsAddressTemp.str ();
1426  headerUri += "/api/v1/keys/" + m_ksid_auth.string() + "/enc_keys";
1427 
1428  HTTPMessage httpMessage;
1429  std::string requestBody;
1430  if (usedMethod)
1431  {
1432  //Update header URI
1433  headerUri += "/number/" + std::to_string(numberOfKeys);
1434  headerUri += "/size/" + std::to_string(sizeOfKeys);
1435  requestBody = {};
1436  httpMessage.CreateRequest(headerUri, "GET");
1437 
1438  } else {
1439 
1440  nlohmann::json jkeyrequest;
1441  jkeyrequest["number"] = numberOfKeys;
1442  jkeyrequest["size"] = sizeOfKeys;
1443  if (!additional_slave_SAE_IDs.empty()){
1444  jkeyrequest["additional_slave_SAE_IDs"] = additional_slave_SAE_IDs;
1445  }
1446 
1447  requestBody = jkeyrequest.dump();
1448  httpMessage.CreateRequest(headerUri, "POST", requestBody);
1449 
1450  }
1451 
1452  //SEND PACKET
1453  std::string hMessage = httpMessage.ToString();
1454  Ptr<Packet> packet = Create<Packet> (
1455  (uint8_t*) (hMessage).c_str(),
1456  hMessage.size()
1457  );
1458  NS_ASSERT (packet);
1459 
1460  NS_LOG_FUNCTION (this << "Sending PACKETID: " << packet->GetUid()
1461  << " of size: " << packet->GetSize()
1462  << " via socket " << m_sendSocketToKMS
1463  );
1464 
1465  MemoriesRequestKMS(1, 1);
1466  m_txKmsTrace (packet);
1467  m_sendSocketToKMS->Send (packet);
1468 
1469  } else {
1470  NS_FATAL_ERROR( this << "Invalid key type" << keyType << "Available values are 0-Encryption key type, and 1-Authentication key type" );
1471  }
1472 
1473 }
1474 
1475 void
1477 {
1478  NS_LOG_FUNCTION( this << "QKDApp014 Get key with key IDs" << m_master );
1479 
1480  if(!m_sendSocketToKMS)
1482 
1483  if(!m_sinkSocketFromKMS)
1485 
1486  std::string ksid;
1487  if (m_keyIDs.contains("ksid"))
1488  ksid = m_keyIDs["ksid"];
1489 
1490  //Create HTTP header
1492  std::ostringstream lkmsAddressTemp;
1493  lkmsAddress.Print(lkmsAddressTemp); //IPv4Address to string
1494  std::string headerUri = "http://" + lkmsAddressTemp.str ();
1495 
1496  std::string msg = m_keyIDs.dump(); //Json - KeyIDs is already in m_keyIDs variable!
1497  headerUri += "/api/v1/keys/"+ksid+"/dec_keys";
1498 
1499  NS_LOG_FUNCTION(this << "ccc:" << m_keyIDs);
1500 
1501  //Create packet
1502  HTTPMessage httpMessage;
1503  httpMessage.CreateRequest(headerUri, "POST", msg);
1504  std::string hMessage = httpMessage.ToString();
1505  Ptr<Packet> packet = Create<Packet> (
1506  (uint8_t*) (hMessage).c_str(),
1507  hMessage.size()
1508  );
1509  NS_ASSERT (packet);
1510 
1511  NS_LOG_FUNCTION (this << "Sending PACKETID: " << packet->GetUid()
1512  << " of size: " << packet->GetSize()
1513  << " via socket " << m_sendSocketToKMS
1514  );
1515 
1516  MemoriesRequestKMS(2);
1517  m_txKmsTrace (packet);
1518  m_sendSocketToKMS->Send (packet);
1519 
1520 }
1521 
1522 void
1524 {
1525  std::string receivedStatus = p->ToString();
1526  NS_LOG_FUNCTION ( this << "\n\n\n" << p->GetUid() << p->GetSize() << receivedStatus << from );
1527 
1528  Ptr<Packet> buffer;
1529  if (receivedStatus.find("Fragment") != std::string::npos) {
1530  auto itBuffer = m_buffer_kms.find (from);
1531  if (itBuffer == m_buffer_kms.end ()){
1532  itBuffer = m_buffer_kms.insert (
1533  std::make_pair (from, Create<Packet> (0))
1534  ).first;
1535  }
1536  buffer = itBuffer->second;
1537  buffer->AddAtEnd (p);
1538  }else{
1539  NS_LOG_FUNCTION(this << "Full packet received!");
1540  buffer = p;
1541  }
1542 
1544  HTTPMessage request;
1545 
1546  //copy buffer payload to string
1547  uint8_t *b1 = new uint8_t[buffer->GetSize ()];
1548  buffer->CopyData(b1, buffer->GetSize ());
1549  std::string requestString = std::string((char*)b1);
1550  delete[] b1;
1551 
1552  //parse HTTP message
1553  parser.Parse(&request, requestString);
1554  if(request.IsFragmented() || request.GetStatusMessage() == "Undefined")
1555  {
1556  NS_LOG_FUNCTION(this << "HTTP Content Parsed after merge with buffer: " << request.ToString() << "\n ***IsFragmented:" << request.IsFragmented() << "\n\n\n\n");
1557  }else{
1558  NS_LOG_FUNCTION(this << "Full packet received:" << request.ToString());
1559  }
1560 
1561  while (buffer->GetSize () >= request.GetSize())
1562  {
1563  NS_LOG_DEBUG ("Parsing packet pid(" << p->GetUid() << ") of size " << request.GetSize () << " from buffer of size " << buffer->GetSize ());
1564  Ptr<Packet> completePacket = buffer->CreateFragment (0, static_cast<uint32_t> (request.GetSize () ));
1565 
1566  uint8_t *b2 = new uint8_t[completePacket->GetSize ()];
1567  completePacket->CopyData(b2, completePacket->GetSize ());
1568  std::string s2 = std::string((char*)b2);
1569 
1570  HTTPMessage request2;
1571  parser.Parse(&request2, s2);
1572  delete[] b2;
1573 
1574  if(request2.IsFragmented() == false){
1575  buffer->RemoveAtStart (static_cast<uint32_t> (request2.GetSize () ));
1576  m_rxKmsTrace (completePacket);
1577  ProcessResponseFromKMS(request2, completePacket, socket);
1578  }
1579 
1580  NS_LOG_FUNCTION(this << "Croped HTTP message: " << request2.ToString());
1581  NS_LOG_FUNCTION(this << "Remains in the buffer " << buffer->GetSize () );
1582  break;
1583  }
1584 }
1585 
1586 void
1588 {
1589  NS_LOG_FUNCTION (this << packet->GetUid() << packet->GetSize());
1590 
1591  std::string payload = header.GetMessageBodyString();
1592  //Map response to request
1593  uint32_t methodType = GetETSIMethod();
1594  //Process json data structure of KMS response!
1595  nlohmann::json jresponse;
1596  try {
1597 
1598  jresponse = nlohmann::json::parse(payload);
1599 
1600  if (methodType == 0) {
1601 
1602  ProcessStatusResponse(header, jresponse);
1603 
1604  } else if (methodType == 1){
1605 
1606  ProcessGetKeyResponse(header, jresponse);
1607 
1608  } else if (methodType == 2) {
1609 
1610  ProcessGetKeyWithKeyIDsResponse(header, jresponse);
1611 
1612  } else {
1613  NS_FATAL_ERROR (this << "Invalid ETSI method used in request");
1614  }
1615 
1616  } catch (...) {
1617  NS_FATAL_ERROR (this << "JSON parse error!");
1618  }
1619 }
1620 
1621 void
1623 {
1624 
1625  HTTPMessage::HttpStatus responseStatus = header.GetStatus();
1626  if (
1627  responseStatus == HTTPMessage::HttpStatus::BadRequest ||
1628  responseStatus == HTTPMessage::HttpStatus::Unauthorized ||
1629  responseStatus == HTTPMessage::HttpStatus::ServiceUnavailable
1630  ) {
1631 
1632  NS_FATAL_ERROR( this << "QKDApp014 received ERROR status information from local KMS" << jstatusResponse.dump() );
1633 
1634  } else if (responseStatus == HTTPMessage::HttpStatus::Ok){
1635 
1636  NS_LOG_FUNCTION( this << "QKDApp014 received status information from local KMS" );
1637  //Check the AppBufferState
1639 
1640  } else {
1641  NS_FATAL_ERROR( this << "Unsupported error status code" << responseStatus << "of response.");
1642  }
1643 
1644  RequestProcessedKMS(); //Remove request from store.
1645 
1646 }
1647 
1648 void
1650 {
1651  NS_LOG_FUNCTION( this );
1652 
1653  if(jGetKeyResponse.empty())
1654  NS_FATAL_ERROR(this << "KMS response on GET_KEY is empty!");
1655 
1656  std::string ksid;
1657  if (jGetKeyResponse.contains("ksid"))
1658  ksid = jGetKeyResponse["ksid"];
1659 
1660  HTTPMessage::HttpStatus responseStatus = header.GetStatus();
1661  if (
1662  responseStatus == HTTPMessage::HttpStatus::BadRequest ||
1663  responseStatus == HTTPMessage::HttpStatus::Unauthorized ||
1664  responseStatus == HTTPMessage::HttpStatus::ServiceUnavailable
1665  ) {
1666 
1667  if (jGetKeyResponse.contains("message"))
1668  {
1669  if (jGetKeyResponse["message"] == std::string {"requested parameters do not adhere to KMS rules"})
1670  NS_FATAL_ERROR( this << jGetKeyResponse.dump());
1671  else if (jGetKeyResponse["message"] == std::string {"insufficient amount of key material"})
1672  ScheduleAction(Time (m_waitInsufficient), "CheckAppBufferState");
1673  else if (jGetKeyResponse["message"] == std::string {"keys are being transformed"})
1674  ScheduleAction(Time (m_waitTransform), "CheckAppBufferState"); //Results in two times schedule when enc and auth! Fixed in ScheduleAction
1675  else
1676  NS_FATAL_ERROR( this << "uknown error message");
1677  } else {
1678  NS_FATAL_ERROR( this << "uknown error message");
1679  }
1680 
1681  } else if (responseStatus == HTTPMessage::HttpStatus::Ok){
1682 
1683  NS_LOG_FUNCTION( this << "Primary QKDApp014 received requested number of keys" << jGetKeyResponse.dump() );
1684 
1685  uint32_t keyType = GetKeyType();
1686  //Push obtained keys to temporary key buffer, until they are negotiated with peer QKDApp014.
1688  std::vector<std::string> keysToNegotiate;
1689  for (nlohmann::json::iterator it = jGetKeyResponse["keys"].begin(); it != jGetKeyResponse["keys"].end(); ++it) {
1690  key.key = (it.value())["key"];
1691  key.keyId = (it.value())["key_ID"];
1692  key.keyType = keyType;
1693  if(keyType == 0 && m_encryptionType == 2)
1694  key.lifetime = m_aesLifetime;
1695  else
1696  key.lifetime = m_packetSize;
1697  (m_appKeyBuffer.temporaryKeyStoreMaster).insert(std::make_pair(key.keyId, key));
1698  keysToNegotiate.push_back(key.keyId);
1699 
1700  m_obtainedKeyMaterialTrace ((m_encryptor->Base64Decode(key.key)).size() * 8);
1701  }
1702 
1704  ExchangeInfoMessages(ksid, keysToNegotiate);
1705 
1706  } else {
1707  NS_FATAL_ERROR( this << "Unsupported error status code" << responseStatus << "of response.");
1708  }
1709 
1710  RequestProcessedKMS(); //Remove request from store.
1711 
1712 }
1713 
1714 void
1716 {
1717 
1718  NS_LOG_FUNCTION( this );
1719 
1720  std::string ksid;
1721  if (jGetKeyWithKeyIDsResponse.contains("ksid"))
1722  ksid = jGetKeyWithKeyIDsResponse["ksid"];
1723 
1724  HTTPMessage::HttpStatus responseStatus = header.GetStatus();
1725  if (
1726  responseStatus == HTTPMessage::HttpStatus::BadRequest ||
1727  responseStatus == HTTPMessage::HttpStatus::Unauthorized ||
1728  responseStatus == HTTPMessage::HttpStatus::ServiceUnavailable
1729  ) {
1730 
1731  NS_FATAL_ERROR( this << "Replica QKDApp014 received ERROR response on key request" << jGetKeyWithKeyIDsResponse.dump() );
1732 
1733  ExchangeInfoMessages(ksid, {}, responseStatus);
1734 
1735  } else if (responseStatus == HTTPMessage::HttpStatus::Ok) {
1736 
1737  NS_LOG_FUNCTION( this << "Replica QKDApp014 received requested keys" << jGetKeyWithKeyIDsResponse.dump() );
1738 
1739  //Replica application directly stores the keys in application key buffer!
1741  for (nlohmann::json::iterator it = jGetKeyWithKeyIDsResponse["keys"].begin(); it != jGetKeyWithKeyIDsResponse["keys"].end(); ++it) {
1742 
1743  key.key = (it.value())["key"];
1744  key.keyId = (it.value())["key_ID"];
1745  key.lifetime = m_aesLifetime; //In case AES is used!
1747 
1748  m_obtainedKeyMaterialTrace ((m_encryptor->Base64Decode(key.key)).size() * 8);
1749  }
1750 
1751  ExchangeInfoMessages(ksid, {}, responseStatus);
1752 
1753  } else {
1754  NS_FATAL_ERROR( this << "Unsupported HTTP status code" << responseStatus << "of response");
1755  }
1756 
1757  RequestProcessedKMS(); //Remove request from store.
1758 
1759 }
1760 
1761 void
1763 {
1764  std::string receivedStatus = p->ToString();
1765  NS_LOG_FUNCTION ( this << "\n\n\n" << p->GetUid() << p->GetSize() << receivedStatus << from );
1766 
1767  Ptr<Packet> buffer;
1768  if (receivedStatus.find("Fragment") != std::string::npos) {
1769  auto itBuffer = m_buffer_kms.find (from);
1770  if (itBuffer == m_buffer_kms.end ()){
1771  itBuffer = m_buffer_kms.insert (
1772  std::make_pair (from, Create<Packet> (0))
1773  ).first;
1774  }
1775  buffer = itBuffer->second;
1776  buffer->AddAtEnd (p);
1777  }else{
1778  NS_LOG_FUNCTION(this << "Full packet received!");
1779  buffer = p;
1780  }
1781 
1783  HTTPMessage request;
1784 
1785  //copy buffer payload to string
1786  uint8_t *b1 = new uint8_t[buffer->GetSize ()];
1787  buffer->CopyData(b1, buffer->GetSize ());
1788  std::string requestString = std::string((char*)b1);
1789  delete[] b1;
1790 
1791  //parse HTTP message
1792  parser.Parse(&request, requestString);
1793  if(request.IsFragmented() || request.GetStatusMessage() == "Undefined")
1794  {
1795  NS_LOG_FUNCTION(this << "HTTP Content Parsed after merge with buffer: " << request.ToString() << "\n ***IsFragmented:" << request.IsFragmented() << "\n\n\n\n");
1796  }else{
1797  NS_LOG_FUNCTION(this << "Full packet received:" << request.ToString());
1798  }
1799 
1800  NS_LOG_FUNCTION(this << "aaaaa: \t" << buffer->GetSize() << request.GetSize());
1801 
1802  while (buffer->GetSize () >= request.GetSize())
1803  {
1804  NS_LOG_DEBUG ("Parsing packet pid(" << p->GetUid() << ") of size " << request.GetSize () << " from buffer of size " << buffer->GetSize ());
1805  Ptr<Packet> completePacket = buffer->CreateFragment (0, static_cast<uint32_t> (request.GetSize () ));
1806 
1807  uint8_t *b2 = new uint8_t[completePacket->GetSize ()];
1808  completePacket->CopyData(b2, completePacket->GetSize ());
1809  std::string s2 = std::string((char*)b2);
1810 
1811  HTTPMessage request2;
1812  parser.Parse(&request2, s2);
1813  delete[] b2;
1814 
1815  if(request2.IsFragmented() == false){
1816  buffer->RemoveAtStart (static_cast<uint32_t> (request2.GetSize () ));
1817  m_rxSigTrace (completePacket);
1818  ProcessSignalingPacketFromApp(request2, completePacket, socket);
1819  }
1820  NS_LOG_FUNCTION(this << "Croped HTTP message: " << request2.ToString());
1821  NS_LOG_FUNCTION(this << "Remains in the buffer " << buffer->GetSize () );
1822  break;
1823  }
1824 }
1825 
1826 void
1828 {
1829  NS_LOG_FUNCTION( this << packet->GetSize() << packet->GetUid() );
1830 
1831  if (m_master == 1) { //Primary QKDApp014 processes received signaling packet from Replica QKDApp014.
1832 
1833  NS_LOG_FUNCTION( this << "APP-SIGNALING: Primary QKDApp014 received response from Replica QKDApp014. Packet ID" << packet->GetUid());
1834 
1835  std::vector<std::string> keyIds = m_httpRequestsApp[0]; //Take first request in store (mapping of response to request)
1836  if (header.GetStatus() == HTTPMessage::HttpStatus::Ok) { //Keys successfully negotiated! Primary QKDApp014 adds keys to enc/auth key store for use.
1837 
1839 
1840  for (uint i = 0; i < keyIds.size(); i++) {
1841  NS_LOG_FUNCTION( this << keyIds[i] << i << keyIds.size() );
1842 
1843  std::map<std::string, QKDApp014::QKDApp014Key>::iterator it;
1844  it = m_appKeyBuffer.temporaryKeyStoreMaster.find(keyIds[i]);
1845 
1846  if (it == m_appKeyBuffer.temporaryKeyStoreMaster.end()){
1847 
1848  NS_LOG_DEBUG( this << "Key " << keyIds[i] << " was not found in the temporary key store!" );
1849 
1850  }else{
1851  if ((it->second).keyType == 0)
1852  AddEncKeyInKeyStore(it->second);
1853  else
1854  AddAuthKeyInKeyStore(it->second);
1855  }
1856  }
1857 
1861  CheckAppState();
1862 
1863 
1864  } else { //Possible collision on requested key!
1865 
1866  NS_LOG_DEBUG ( this << "The attempt to negotiate keys failed.");
1867  //Only the request for this particular key type must be repeated
1868  if(!m_internalAppWait){ //Only repeat the request if the CheckAppBufferState is not scheduled!
1869  NS_LOG_FUNCTION(this << "Application is submitting a new GET_KEY request ...");
1870  //First find a key type! Take a single keyID (first one) ->
1871  std::string keyID = m_httpRequestsApp[0][0];
1872  //Find this key in the temporary key store to determine the type ->
1873  std::map<std::string, QKDApp014::QKDApp014Key>::iterator it = m_appKeyBuffer.temporaryKeyStoreMaster.find(keyID);
1875  GetKeysFromKMS(it->second.keyType); //Try to aquire and negotiate a new key material.
1876  }else
1877  NS_LOG_DEBUG(this << "Key" << keyID << "was not found in the temporary key store!");
1878  }
1879  RemoveKeysFromTemporaryKeyStore(keyIds); //Remove keys from the temporary key store!
1881  }
1882 
1884 
1885  } else { //Replica QKDApp014 processes received signaling packet from Primary QKDApp014.
1886 
1887 
1888  std::string payload = header.GetMessageBodyString();
1889  nlohmann::json jKeyIDs;
1890 
1891  try {
1892 
1893  jKeyIDs = nlohmann::json::parse(payload);
1894 
1895  NS_LOG_FUNCTION( this << "APP-SIGNALING: Replica QKDApp014 received proposal from Primary QKDApp014. Packet ID" << packet->GetUid() << jKeyIDs);
1896 
1897  m_keyIDs = jKeyIDs; //Use m_keyIDs to make GetKeyWithKeyIDs!
1898  GetKeyWithKeyIDs();
1899 
1900  } catch(...) {
1901  NS_LOG_FUNCTION( this << "JSON parse error" );
1902  }
1903 
1904  }
1905 }
1906 
1907 void
1908 QKDApp014::ExchangeInfoMessages (std::string ksid, std::vector<std::string> keyIds, HTTPMessage::HttpStatus statusCode)
1909 {
1910 
1915 
1916  if(m_master) { //Primary QKDApp014 sends proposal of keys to Replica QKDApp014.
1917 
1918  nlohmann::json key_IDs;
1919  key_IDs["ksid"] = ksid;
1920  for (uint i = 0; i < keyIds.size(); i++) {
1921  key_IDs["key_IDs"].push_back({ {"key_ID", keyIds[i] } });
1922  }
1923 
1924  std::string msg = key_IDs.dump();
1925 
1926  //Create packet
1927  HTTPMessage httpMessage;
1928  httpMessage.CreateRequest("/keys/key_ids", "POST", msg);
1929  std::string hMessage = httpMessage.ToString();
1930  Ptr<Packet> packet = Create<Packet> (
1931  (uint8_t*) (hMessage).c_str(),
1932  hMessage.size()
1933  );
1934  NS_ASSERT (packet);
1935 
1936  MemoriesRequestApp(keyIds);
1937  m_txSigTrace (packet);
1938  m_sendSignalingSocketApp->Send(packet);
1939  m_packetsSent++;
1940  m_dataSent += packet->GetSize();
1941  NS_LOG_FUNCTION(this << "APP-SIGNALING: Primary QKDApp014 sends proposal to Replica QKDApp014. Packet ID" << packet->GetUid() << packet->GetSize());
1942 
1943  } else { //Replica QKDApp014 sends response to Primary QKDApp014.
1944 
1945  //create packet
1946  HTTPMessage httpMessage;
1947  httpMessage.CreateResponse(statusCode);
1948  std::string hMessage = httpMessage.ToString();
1949  Ptr<Packet> packet = Create<Packet> (
1950  (uint8_t*) (hMessage).c_str(),
1951  hMessage.size()
1952  );
1953  NS_ASSERT (packet);
1954 
1955  m_txSigTrace (packet);
1956  m_sendSignalingSocketApp->Send(packet);
1957  m_packetsSent++;
1958  m_dataSent += packet->GetSize();
1959  NS_LOG_FUNCTION( this << "APP-SIGNALING: Replica QKDApp014 sends respond to Primary QKDApp014. Packet ID" << packet->GetUid() );
1960 
1961  }
1962 }
1963 
1964 
1965 
1974 /*
1975  * \brief QKD App state transitions (Data transmision)
1976  */
1977 void
1979 {
1980  NS_LOG_FUNCTION( this );
1981 
1982  if (m_master) //Data transmision state transition for Primary QKDApp014
1983  {
1984 
1985  if (m_appState == INITIALIZED) {
1987  if (GetEncryptionKeySize() == 0 && GetAuthenticationKeySize() == 0) //No initial key material needed!
1988  {
1991  SendPacket(); //Imidiatly send packet
1992  } else { //Obtain status information from KMS, obtain initial key material!
1995 
1996  if(GetEncryptionKeySize() > 0) GetStatusFromKMS(0); //First call Get Status
1997  if(GetAuthenticationKeySize() > 0) GetStatusFromKMS(1); //First call Get Status
1998 
1999  SendPacket(); //It will result in schedule
2000  }
2001  } else {
2002  NS_FATAL_ERROR( this << "Invalid entry state" << m_appState <<
2003  "for AppTransitionTree()!");
2004  }
2005 
2006  } else if (!m_master) { //Data transmision state transition for Replica QKDApp014
2007 
2008  if (m_appState == INITIALIZED) {
2010  } else {
2011  NS_FATAL_ERROR( this << "Invalid entry state" << m_appState <<
2012  "for AppTransitionTree()!");
2013  }
2014 
2015  }
2016 }
2017 
2018 
2021 {
2022  return m_appState;
2023 }
2024 
2025 std::string
2027 {
2028  switch (state)
2029  {
2030  case NOT_STARTED:
2031  return "NOT_STARTED";
2032  break;
2033  case INITIALIZED:
2034  return "INITIALIZED";
2035  break;
2036  case READY:
2037  return "READY";
2038  break;
2039  case WAIT:
2040  return "WAIT";
2041  break;
2042  case SEND_DATA:
2043  return "SEND_DATA";
2044  break;
2045  case DECRYPT_DATA:
2046  return "DECRYPT_DATA";
2047  break;
2048  case STOPPED:
2049  return "STOPPED";
2050  break;
2051  default:
2052  NS_FATAL_ERROR ("Unknown state");
2053  return "FATAL_ERROR";
2054  break;
2055  }
2056 }
2057 
2058 
2059 std::string
2061 {
2062  return GetAppStateString (m_appState);
2063 }
2064 
2065 void
2067 {
2068 
2069  const std::string oldState = GetAppStateString ();
2070  const std::string newState = GetAppStateString (state);
2071 
2072 
2073  bool found = false;
2074  for (std::multimap<std::string, std::string>::iterator iter =
2075  m_transitionMatrix.begin ();
2076  iter != m_transitionMatrix.end (); iter++
2077  ){
2078  if(iter->first == oldState && iter->second == newState){
2079  m_appState = state;
2080  NS_LOG_DEBUG (this << " QKDApp014 " << oldState << " --> " << newState << ".");
2081  m_stateTransitionTrace (oldState, newState);
2082  found = true;
2083  }
2084  }
2085 
2086  if(found == false) {
2087  NS_FATAL_ERROR ("Unsupported transition from " << oldState << " to " << newState);
2088  }
2089 
2090 
2091 }
2092 
2101 void
2103  uint32_t encryptionType,
2104  uint32_t authenticationType,
2105  uint32_t authenticationTagLengthInBits
2106 ){
2107 
2108  NS_LOG_FUNCTION (this << encryptionType << authenticationType << authenticationTagLengthInBits);
2109 
2110  switch (encryptionType){
2111  case 0:
2113  break;
2114  case 1:
2116  break;
2117  case 2:
2119  break;
2120  }
2121 
2122  switch (authenticationType){
2123  case 0:
2125  break;
2126  case 1:
2128  break;
2129  case 2:
2131  break;
2132  case 3:
2134  break;
2135  }
2136 
2137  if(!m_encryptor){
2138  m_encryptor = CreateObject<QKDEncryptor> (
2141  authenticationTagLengthInBits
2142  );
2143  }else{
2144  m_encryptor->ChangeSettings(
2147  authenticationTagLengthInBits
2148  );
2149  }
2150 
2151 }
2152 
2153 std::string
2154 QKDApp014::GetPacketContent(uint32_t msgLength)
2155 {
2156  NS_LOG_FUNCTION(this);
2157 
2158  if (msgLength == 0)
2159  msgLength = m_packetSize;
2160 
2161  //Generate random string with same size as merged key string
2162  std::string confidentialMessage;
2163  static const char alphanum[] =
2164  "0123456789"
2165  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2166  "abcdefghijklmnopqrstuvwxyz";
2167 
2168  uint32_t randVal = 0;
2169  for (uint32_t i = 0; i < msgLength; ++i){
2170  randVal = round(m_random->GetValue (0, sizeof(alphanum) - 1));
2171  confidentialMessage += alphanum[ randVal ];
2172  }
2173 
2174  return confidentialMessage;
2175 
2176 }
2177 
2178 std::string
2179 QKDApp014::CreateKeyIdField (std::string keyId)
2180 {
2181  keyId.erase(std::remove(keyId.begin(), keyId.end(), '-'), keyId.end());
2182  return keyId;
2183 }
2184 
2185 std::string
2186 QKDApp014::ReadKeyIdField (std::string keyId)
2187 {
2188  NS_LOG_FUNCTION(this << keyId);
2189  keyId.insert(8, "-");
2190  keyId.insert(13, "-");
2191  keyId.insert(18, "-");
2192  keyId.insert(23, "-");
2193  NS_LOG_FUNCTION(this << keyId);
2194  return keyId;
2195 }
2196 
2197 uint32_t
2199 {
2200 
2201  NS_LOG_FUNCTION(this << CryptoPP::AES::DEFAULT_KEYLENGTH);
2202 
2203  switch (m_encryptionType)
2204  {
2206  return 0;
2207  break;
2209  return m_packetSize * 8; //This will work great for Primary QKDApp014, Replica QKDApp014 needs to calculate for itself this!
2210  break;
2212  return CryptoPP::AES::MAX_KEYLENGTH * 8; //In bits 256!
2213  break;
2214  }
2215 
2216  return 0;
2217 
2218 }
2219 
2220 uint32_t
2222 {
2223  switch (m_authenticationType)
2224  {
2226  return 0;
2227  break;
2229  return CryptoPP::AES::BLOCKSIZE * 8; //In bits //Before: m_authenticationTagLengthInBits - 32B?
2230  break;
2232  return 0; //NoKey
2233  break;
2235  return 0; //NoKey
2236  break;
2237  }
2238 
2239  return 0;
2240 
2241 }
2242 
2243 
2244 
2245 } // Namespace ns3
a polymophic address class
Definition: address.h:101
The base class for all ns3 applications.
Definition: application.h:62
Ptr< Node > GetNode() const
Definition: application.cc:108
Class for representing data rates.
Definition: data-rate.h:89
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition: data-rate.cc:305
An identifier for simulation events.
Definition: event-id.h:55
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
The basic class to represent both HTTP requests and responses.
Definition: http.h:78
std::string ToString()
Takes the headers added to the message along with the body and outputs it to a std::string for use in...
Definition: http.h:633
uint32_t GetSize()
Definition: http.h:686
void CreateRequest(const std::string &url, const std::string &method)
Definition: http.h:738
bool IsFragmented()
Definition: http.h:852
std::string GetMessageBodyString()
Definition: http.h:714
void CreateResponse(const HttpStatus status)
Definition: http.h:785
HTTPMessage::HttpStatus GetStatus()
To be returned with a status code in a response is a status text describing the status code by text r...
Definition: http.h:169
std::string GetStatusMessage() const
Get the current status message for this message.
Definition: http.h:623
A basic class to parse a HTTP message, both request and response.
Definition: http.h:941
an Inet address class
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
void Print(std::ostream &os) const
Print this address to the given output stream.
static Ipv4Address GetAny()
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:384
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:238
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
std::string ToString() const
Return a string representation of the packet.
Definition: packet.cc:448
Establish secure communication on application lavel to use the key and test LKSM.
Definition: qkd-app-014.h:82
uint32_t m_master
Is a master (sender/primary) application?
Definition: qkd-app-014.h:725
void HandleAcceptFromKMS(Ptr< Socket > s, const Address &from)
Handle an incoming connection from the KMS.
Definition: qkd-app-014.cc:522
void GetKeyWithKeyIDs()
Requests keys with given identifiers from the KMS (ETSI QKD 014 - Get key with key IDs method).
void PrepareSendSocketToKMS()
Prepare the send socket to communicate with the KMS Application.
Definition: qkd-app-014.cc:378
uint32_t GetKeyType(void)
Map the HTTP response and obtain the key type.
Definition: qkd-app-014.cc:943
void SwitchAppState(QKDApp014State state)
Change the state of the application.
void HandleReadFromKMS(Ptr< Socket > socket)
Handle a packet received from the KMS application.
Definition: qkd-app-014.cc:629
Ptr< QKDEncryptor > m_encryptor
The QKD encryptor.
Definition: qkd-app-014.h:762
void ConnectionSignalingToAppSucceeded(Ptr< Socket > socket)
Callback function after the signaling connection to the APP is complete.
Definition: qkd-app-014.cc:582
TracedCallback< const uint32_t & > m_obtainedKeyMaterialTrace
A trace callback for the obtained key material.
Definition: qkd-app-014.h:764
std::string CreateKeyIdField(std::string keyId)
Adjust the encryption key identifier for the QKDApp header.
void HandlePeerCloseSignalingFromApp(Ptr< Socket > socket)
Handle a signaling connection close from the peer QKD application.
Definition: qkd-app-014.cc:617
TracedCallback< Ptr< const Packet >, std::string > m_txTrace
A trace for transmitted data packets.
Definition: qkd-app-014.h:579
void ConnectionSignalingToAppFailed(Ptr< Socket > socket)
Callback function after the signaling connection to the APP has failed.
Definition: qkd-app-014.cc:588
void AddAuthKeyInKeyStore(QKDApp014::QKDApp014Key &key)
Add a new key to the authentication key store.
Definition: qkd-app-014.cc:781
void ProcessStatusResponse(HTTPMessage &header, nlohmann::json jstatusResponse)
Process the status response from the KMS.
QKDApp014State
The application states.
Definition: qkd-app-014.h:143
std::string GetPacketContent(uint32_t msgLength=0)
Generate a random packet (message) of a given size.
void HandlePeerErrorFromKMS(Ptr< Socket > socket)
Handle a connection error from the KMS.
Definition: qkd-app-014.cc:600
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer_kms
The buffer for the received packets from the KMS (fragmentation).
Definition: qkd-app-014.h:768
QKDApp014State GetAppState() const
Get the current state of the application.
TypeId m_tid
The type identifier.
Definition: qkd-app-014.h:724
UUID m_ksid_auth
The authentication key stream identifier.
Definition: qkd-app-014.h:743
static TypeId GetTypeId(void)
Get the type ID.
Definition: qkd-app-014.cc:44
void GetKeysFromKMS(uint32_t keyType)
Request keys from the KMS (ETSI QKD 014 - Get key method).
Time m_waitInsufficient
The amount of time spent waiting before issuing a new GET_KEY request when the previous one resulted ...
Definition: qkd-app-014.h:727
void SendPacket(void)
Send the application packet (includes the generation of a random message and optional encryption or/a...
void ConnectionToKMSSucceeded(Ptr< Socket > socket)
Callback function after the connection to the KMS is complete.
Definition: qkd-app-014.cc:558
void ProcessDataPacketFromApp(QKDAppHeader header, Ptr< Packet > packet, Ptr< Socket > socket)
Process the data packets from the peer QKD application.
std::vector< std::vector< std::string > > m_httpRequestsApp
A vector of HTTP requests sent to the peer application.
Definition: qkd-app-014.h:737
std::map< uint32_t, EventId > m_scheduledEvents
The map of scheduled events.
Definition: qkd-app-014.h:773
void MemoriesRequestKMS(uint32_t methodType, uint32_t keyType=0)
Memories the HTTP request made to the local KMS.
Definition: qkd-app-014.cc:913
TracedCallback< Ptr< const Packet >, std::string > m_mxTrace
A trace for the missed time slots to send data packets.
Definition: qkd-app-014.h:586
UUID m_dstSaeId
The peer application identifier.
Definition: qkd-app-014.h:740
uint32_t ScheduleAction(Time t, std::string action)
Schedule the action.
Definition: qkd-app-014.cc:296
DataRate m_dataRate
The application data rate.
Definition: qkd-app-014.h:720
UUID m_ksid_enc
The encryption key stream identifier.
Definition: qkd-app-014.h:742
void AddEncKeyInKeyStore(QKDApp014::QKDApp014Key &key)
Add a new key to the encryption key store.
Definition: qkd-app-014.cc:774
void PacketReceivedFromKMS(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for the TCP segmentation of the packets received from the KMS.
uint32_t GetETSIMethod(void)
Map the HTTP response and obtrain the request method.
Definition: qkd-app-014.cc:937
void HandleAcceptSignalingFromApp(Ptr< Socket > s, const Address &from)
Handle a signaling incoming connection from the peer QKD application.
Definition: qkd-app-014.cc:546
uint32_t GetAuthenticationKeySize()
Get required key size for the choosen authentication algorithm.
TracedCallback< Ptr< const Packet > > m_txKmsTrace
A trace for transmitted packets to the KMS.
Definition: qkd-app-014.h:581
void HandlePeerCloseFromKMS(Ptr< Socket > socket)
Handle a connection close from the KMS.
Definition: qkd-app-014.cc:594
QKDApp014State m_appState
The application state.
Definition: qkd-app-014.h:766
uint32_t GetEncryptionKeySize()
Get required key size for the choosen encryption algorithm.
void MemoriesRequestApp(std::vector< std::string > keyIds)
Memories the HTTP request made to the peer QKD application.
Definition: qkd-app-014.cc:919
Ptr< Socket > m_sendSocketToKMS
The sending socket to the KMS.
Definition: qkd-app-014.h:706
void ProcessResponseFromKMS(HTTPMessage &header, Ptr< Packet > packet, Ptr< Socket > socket)
Process the response from the KMS application.
uint32_t m_encryptionTypeInt
The encryption algorithm.
Definition: qkd-app-014.h:752
void ProcessGetKeyResponse(HTTPMessage &header, nlohmann::json jGetKeyResponse)
Process the GET_KEY response from the KMS.
void HandleAcceptFromApp(Ptr< Socket > s, const Address &from)
Handle an incoming connection from the peer QKD application.
Definition: qkd-app-014.cc:534
void ConnectionToAppFailed(Ptr< Socket > socket)
Callback function after the connection to the APP has failed.
Definition: qkd-app-014.cc:576
std::string GetAppStateString() const
Get the current state of the application in the string format.
Address m_kms
The local KMS address.
Definition: qkd-app-014.h:715
uint32_t m_authenticationTagLengthInBits
The size of the authentication tag in bits (32 by default).
Definition: qkd-app-014.h:754
TracedCallback< Ptr< const Packet > > m_rxSigTrace
A trace for received signaling packets.
Definition: qkd-app-014.h:583
void ExchangeInfoMessages(std::string ksid, std::vector< std::string > keyIds, HTTPMessage::HttpStatus statusCode=HTTPMessage::Ok)
Exchange key identifiers between sending and receiving application.
ns3::TracedCallback< const std::string &, const std::string & > m_stateTransitionTrace
The posible application state transitions.
Definition: qkd-app-014.h:585
TracedCallback< Ptr< Packet >, std::string > m_authenticationTrace
A trace callback for the authentication event.
Definition: qkd-app-014.h:758
void SignalingPacketReceivedFromApp(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for the TCP segmentation of the signaling packets received from the peer QKD application.
QKDApp014()
Constructor.
Definition: qkd-app-014.cc:153
uint32_t m_numberOfKeysKMS
The number of keys to fetch per request.
Definition: qkd-app-014.h:748
std::string ReadKeyIdField(std::string keyId)
Rebuild the key identifier for the QKDApp header.
bool ConnectionRequestedFromKMS(Ptr< Socket > socket, const Address &address)
Callback function after the connection response from the KMS has been received.
Definition: qkd-app-014.cc:510
void RequestProcessedKMS(void)
Remove the request from the HTTP requests store (once the response from the KMS has been processed).
Definition: qkd-app-014.cc:925
virtual void StartApplication(void)
Definition: qkd-app-014.cc:957
void CheckAppBufferState()
Check the state of the application key buffer.
Definition: qkd-app-014.cc:806
std::string m_socketType
The sockets type.
Definition: qkd-app-014.h:717
QKDApp014KeyBuffer m_appKeyBuffer
The application key buffer.
Definition: qkd-app-014.h:732
UUID GetId(void)
Get the application identifier.
Definition: qkd-app-014.h:561
Address m_localSignaling
The local address for the signaling data transmission.
Definition: qkd-app-014.h:713
TracedCallback< Ptr< Packet > > m_encryptionTrace
A trace callback for the encryption event.
Definition: qkd-app-014.h:756
std::vector< std::pair< uint32_t, uint32_t > > m_httpRequestsKMS
A vector of HTTP requests set to the KMS.
Definition: qkd-app-014.h:736
EventId m_sendEvent
The data transmission event.
Definition: qkd-app-014.h:721
void PrintAppBufferStatusInformation()
Print the status information on the application key buffer.
Definition: qkd-app-014.cc:798
uint32_t m_authenticationTypeInt
The authentication algorithm.
Definition: qkd-app-014.h:753
void ProcessGetKeyWithKeyIDsResponse(HTTPMessage &header, nlohmann::json jGetKeyWithKeyIDsResponse)
Process the Get Key with Key IDs response from the KMS.
void InitializeAppKeyBuffer()
Initialize the application key buffer.
Definition: qkd-app-014.cc:740
uint32_t m_packetSize
The data packet size.
Definition: qkd-app-014.h:719
void HandleReadFromApp(Ptr< Socket > socket)
Handle a packet received from the peer QKD application.
Definition: qkd-app-014.cc:662
TracedCallback< Ptr< const Packet > > m_txSigTrace
A trace for transmitted signaling packets.
Definition: qkd-app-014.h:580
Ptr< Socket > m_sendDataSocketApp
The sending socket for the data.
Definition: qkd-app-014.h:703
TracedCallback< Ptr< const Packet > > m_rxKmsTrace
A trace for received packets from the KMS.
Definition: qkd-app-014.h:584
virtual void StopApplication(void)
Application specific shutdown code.
Definition: qkd-app-014.cc:996
void HandlePeerErrorFromApp(Ptr< Socket > socket)
Handle a connection error from the peer QKD application.
Definition: qkd-app-014.cc:611
void ConnectionToAppSucceeded(Ptr< Socket > socket)
Callback function after the connection to the APP is complete.
Definition: qkd-app-014.cc:570
void ProcessSignalingPacketFromApp(HTTPMessage &header, Ptr< Packet > packet, Ptr< Socket > socket)
Process the signaling packets received from the peer QKD application.
uint32_t m_packetsSent
The number of sent data packets.
Definition: qkd-app-014.h:722
uint64_t m_aesLifetime
The AES key lifetime.
Definition: qkd-app-014.h:755
void DataPacketReceivedFromApp(const Ptr< Packet > &p, const Address &from, Ptr< Socket > socket)
Check for the TCP segmentation of the data packets received from the peer QKD application.
void DataToKMSSend(Ptr< Socket >, uint32_t)
Callback function to notify that data to KMS has been sent.
Definition: qkd-app-014.cc:726
void ConnectionToKMSFailed(Ptr< Socket > socket)
Callback function after the connection to the KMS has failed.
Definition: qkd-app-014.cc:564
Ptr< Socket > m_sinkDataSocketApp
The receiving socket for the data.
Definition: qkd-app-014.h:704
TracedCallback< Ptr< const Packet >, std::string > m_rxTrace
A trace for received data packets.
Definition: qkd-app-014.h:582
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer_QKDApp014
The buffer for received data packets (fragmentation).
Definition: qkd-app-014.h:770
void SetEncryptionAndAuthenticationSettings(uint32_t encryptionType, uint32_t authenticationType, uint32_t authenticationTagLengthInBits)
Set the encryption and the authentication algorithms.
void CancelScheduledAction(uint32_t eventId)
Cancel the scheduled event/action.
Definition: qkd-app-014.cc:318
Ptr< Socket > m_sinkSocketFromKMS
The receiving socket from the KMS.
Definition: qkd-app-014.h:707
QKDApp014::QKDApp014Key GetKeyFromAppKeyBuffer(uint32_t keyType)
Get the key from the application key buffer.
Definition: qkd-app-014.cc:837
void RemoveKeysFromTemporaryKeyStore(std::vector< std::string > keyIds)
Remove keys from the temporary key store.
Definition: qkd-app-014.cc:752
Address m_local
The local address for the data transmission.
Definition: qkd-app-014.h:712
void HandlePeerErrorSignalingFromApp(Ptr< Socket > socket)
Handle a signaling connection error from the peer QKD application.
Definition: qkd-app-014.cc:623
static uint32_t m_applicationCounts
The number of running applications.
Definition: qkd-app-014.h:745
nlohmann::json m_keyIDs
The latest received key identifiers from the sender application.
Definition: qkd-app-014.h:733
bool m_internalAppWait
The indicator for the longer wait (used after the GetKey error!).
Definition: qkd-app-014.h:772
void AppTransitionTree(void)
Transition through a tree of the application states and trigger actions.
void CheckAppState()
Check the conditions to change the application state.
Definition: qkd-app-014.cc:821
uint32_t m_useCrypto
Execute actual cryptographic algorithms?
Definition: qkd-app-014.h:751
std::multimap< std::string, std::string > m_transitionMatrix
The map of the possible state transitions.
Definition: qkd-app-014.h:774
void RequestProcessedApp(void)
Remove request from the HTTP requests store (once the response from the peer application has been pro...
Definition: qkd-app-014.cc:931
virtual ~QKDApp014()
Destructor.
Definition: qkd-app-014.cc:190
Ptr< UniformRandomVariable > m_random
The uniform random variable.
Definition: qkd-app-014.h:730
TracedCallback< Ptr< Packet >, std::string > m_deauthenticationTrace
A trace callback for the authentication check event.
Definition: qkd-app-014.h:759
void PrintTemporaryKeyStoreContent()
Print the content of the temporary key store.
Definition: qkd-app-014.cc:788
void PrepareSendSocketToApp()
Prepare the send socket to communicate with the peer QKD Application.
Definition: qkd-app-014.cc:404
void Setup(std::string socketType, Address src, Address dst, Address kms, UUID dstSaeId, std::string type)
Configure the application.
Definition: qkd-app-014.cc:204
UUID m_id
The application identifier.
Definition: qkd-app-014.h:739
void HandleReadSignalingFromApp(Ptr< Socket > socket)
Handle a signaling packet received from the peer QKD application.
Definition: qkd-app-014.cc:694
void GetStatusFromKMS(uint32_t keyType)
Request status information from the KMS (ETSI QKD 014 - Get status method).
Time m_waitTransform
The amount of time spent waiting before issuing a new GET_KEY request when the previous one resulted ...
Definition: qkd-app-014.h:728
TracedCallback< Ptr< Packet > > m_decryptionTrace
A trace callback for the decryption event.
Definition: qkd-app-014.h:757
Ptr< Socket > m_sendSignalingSocketApp
The sending socket for the signaling messages.
Definition: qkd-app-014.h:701
void ScheduleTx(void)
Schedule the time slot to send the data packets.
Definition: qkd-app-014.cc:279
Address m_peer
The address of the peer for the data transmission.
Definition: qkd-app-014.h:709
QKDEncryptor::AuthenticationType m_authenticationType
The authentication algorithm.
Definition: qkd-app-014.h:761
Address m_peerSignaling
The address of the peer for the signaling data transmission.
Definition: qkd-app-014.h:710
void HandlePeerCloseFromApp(Ptr< Socket > socket)
Handle a connection close from the peer QKD application.
Definition: qkd-app-014.cc:606
uint32_t m_dataSent
The amount of the sent data.
Definition: qkd-app-014.h:723
void AddKeyInInboundKeyStore(QKDApp014::QKDApp014Key &key)
Add a new key to the inbound key store.
Definition: qkd-app-014.cc:767
Ptr< Socket > m_sinkSignalingSocketApp
The receiving socket for the signaling messages.
Definition: qkd-app-014.h:702
void PrepareSinkSocketFromApp()
Prepare the sink socket to listen from the peer QKD Application.
Definition: qkd-app-014.cc:448
QKDEncryptor::EncryptionType m_encryptionType
The encryption algorithm.
Definition: qkd-app-014.h:760
void PrepareSinkSocketFromKMS()
Prepare the sink socket to listen from the KMS Application.
Definition: qkd-app-014.cc:340
QKD app packet header that carries info about used encryption, auth tag and other.
std::string GetEncryptionKeyId(void) const
Read the encryption key identifier.
std::string GetAuthTag(void) const
Read the authentication tag.
uint32_t GetSerializedSize() const
Get the serialized size of a packet.
void SetEncryptionKeyId(std::string value)
Set the encryption key identifier.
void SetEncrypted(uint32_t value)
Set the encrypted field.
uint32_t GetLength(void) const
Get message length.
void SetLength(uint32_t value)
Set the message length.
void SetAuthenticated(uint32_t value)
Set the authentication field.
uint32_t GetAuthenticated(void) const
Read the authentication field.
void SetAuthTag(std::string value)
Set the authentication tag.
std::string GetAuthenticationKeyId(void) const
Read the authentication key identifier.
void SetAuthenticationKeyId(std::string keyID)
Set the authentication key identifier.
uint32_t GetEncrypted(void) const
Read the encrypted field.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:285
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
void SetCloseCallbacks(Callback< void, Ptr< Socket >> normalClose, Callback< void, Ptr< Socket >> errorClose)
Detect socket recv() events such as graceful shutdown or error.
Definition: socket.cc:96
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
Definition: socket.cc:105
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
virtual int ShutdownRecv()=0
void SetDataSentCallback(Callback< void, Ptr< Socket >, uint32_t > dataSent)
Notify application when a packet has been sent from transport protocol (non-standard socket call)
Definition: socket.cc:114
virtual int ShutdownSend()=0
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
virtual int Close()=0
Close a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int Listen()=0
Listen for incoming connections.
void SetConnectCallback(Callback< void, Ptr< Socket >> connectionSucceeded, Callback< void, Ptr< Socket >> connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
Definition: socket.cc:87
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
static TypeId GetTypeId()
Get the type ID.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Universally unique identifier (UUID)
Definition: uuid.h:35
static UUID Random()
Generate random UUID4 (randomly or pseudo-randomly generated version)
Definition: uuid.cc:148
std::string string() const
Get string from the current UUID in format "00000000-0000-0000-0000-000000000000".
Definition: uuid.cc:74
static TypeId GetTypeId()
Get the type ID.
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:747
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:25255
basic_json<> json
default JSON class
Definition: json.h:3000
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Ptr< const AttributeChecker > MakeTypeIdChecker()
Definition: type-id.cc:1250
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Definition: type-id.h:598
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
std::map< std::string, QKDApp014Key > outboundEncKeyStore
Definition: qkd-app-014.h:133
std::map< std::string, QKDApp014Key > outboundAuthKeyStore
Definition: qkd-app-014.h:134
std::map< std::string, QKDApp014Key > inboundKeyStore
Definition: qkd-app-014.h:135
std::map< std::string, QKDApp014Key > temporaryKeyStoreMaster
Definition: qkd-app-014.h:136
The cryptographic key at the application layer.
Definition: qkd-app-014.h:120
static const uint32_t packetSize
Packet size generated at the AP.