00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 # include <dtn-config.h>
00022 #endif
00023
00024 #ifdef BSP_ENABLED
00025
00026 #include "SPD.h"
00027 #include "Ciphersuite.h"
00028 #include "Ciphersuite_BA1.h"
00029 #include "Ciphersuite_PS2.h"
00030 #include "Ciphersuite_C3.h"
00031
00032 namespace dtn {
00033
00034 template <>
00035 SPD* oasys::Singleton<SPD, false>::instance_ = NULL;
00036
00037 static const char * log = "/dtn/bundle/security";
00038
00039 SPD::SPD()
00040 : global_policy_inbound_(SPD_USE_NONE),
00041 global_policy_outbound_(SPD_USE_NONE)
00042 {
00043 }
00044
00045 SPD::~SPD()
00046 {
00047 }
00048
00049 void
00050 SPD::init()
00051 {
00052 if (instance_ != NULL)
00053 {
00054 PANIC("SPD already initialized");
00055 }
00056
00057 instance_ = new SPD();
00058 log_debug_p(log, "SPD::init() done");
00059 }
00060
00061 void
00062 SPD::set_global_policy(spd_direction_t direction, spd_policy_t policy)
00063 {
00064 ASSERT(direction == SPD_DIR_IN || direction == SPD_DIR_OUT);
00065 ASSERT((policy & ~(SPD_USE_BAB | SPD_USE_CB | SPD_USE_PSB)) == 0);
00066 if (direction == SPD_DIR_IN)
00067 instance()->global_policy_inbound_ = policy;
00068 else
00069 instance()->global_policy_outbound_ = policy;
00070 log_debug_p(log, "SPD::set_global_policy() done");
00071 }
00072
00073 void
00074 SPD::prepare_out_blocks(const Bundle* bundle, const LinkRef& link,
00075 BlockInfoVec* xmit_blocks)
00076 {
00077 spd_policy_t policy = find_policy(SPD_DIR_OUT, bundle);
00078
00079 if (policy & SPD_USE_PSB) {
00080 Ciphersuite* bp =
00081 Ciphersuite::find_suite(Ciphersuite_PS2::CSNUM_PS2);
00082 ASSERT(bp != NULL);
00083 bp->prepare(bundle, xmit_blocks, NULL, link,
00084 BlockInfo::LIST_NONE);
00085 }
00086
00087 if (policy & SPD_USE_CB) {
00088 Ciphersuite* bp =
00089 Ciphersuite::find_suite(Ciphersuite_C3::CSNUM_C3);
00090 ASSERT(bp != NULL);
00091 bp->prepare(bundle, xmit_blocks, NULL, link,
00092 BlockInfo::LIST_NONE);
00093 }
00094
00095 if (policy & SPD_USE_BAB) {
00096 Ciphersuite* bp =
00097 Ciphersuite::find_suite(Ciphersuite_BA1::CSNUM_BA1);
00098 ASSERT(bp != NULL);
00099 bp->prepare(bundle, xmit_blocks, NULL, link,
00100 BlockInfo::LIST_NONE);
00101 }
00102 log_debug_p(log, "SPD::prepare_out_blocks() done");
00103 }
00104
00105 bool
00106 SPD::verify_in_policy(const Bundle* bundle)
00107 {
00108 spd_policy_t policy = find_policy(SPD_DIR_IN, bundle);
00109 const BlockInfoVec* recv_blocks = &bundle->recv_blocks();
00110
00111 log_debug_p(log, "SPD::verify_in_policy() 0x%x", policy);
00112
00113 if (policy & SPD_USE_BAB) {
00114 if ( !Ciphersuite::check_validation(bundle, recv_blocks, Ciphersuite_BA1::CSNUM_BA1 )) {
00115 log_debug_p(log, "SPD::verify_in_policy() no BP_TAG_BAB_IN_DONE");
00116 return false;
00117 }
00118 }
00119
00120 if (policy & SPD_USE_CB) {
00121 if ( !Ciphersuite::check_validation(bundle, recv_blocks, Ciphersuite_C3::CSNUM_C3 )) {
00122 log_debug_p(log, "SPD::verify_in_policy() no BP_TAG_CB_IN_DONE");
00123 return false;
00124 }
00125 }
00126
00127 if (policy & SPD_USE_PSB) {
00128 if ( !Ciphersuite::check_validation(bundle, recv_blocks, Ciphersuite_PS2::CSNUM_PS2 )) {
00129 log_debug_p(log, "SPD::verify_in_policy() no BP_TAG_PSB_IN_DONE");
00130 return false;
00131 }
00132 }
00133
00134 return true;
00135 }
00136
00137 SPD::spd_policy_t
00138 SPD::find_policy(spd_direction_t direction, const Bundle* bundle)
00139 {
00140 ASSERT(direction == SPD_DIR_IN || direction == SPD_DIR_OUT);
00141
00142 (void)bundle;
00143 log_debug_p(log, "SPD::find_policy()");
00144
00145 return (direction == SPD_DIR_IN ? instance()->global_policy_inbound_
00146 : instance()->global_policy_outbound_);
00147 }
00148
00149 }
00150
00151 #endif