00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #ifdef BSP_ENABLED
00022
00023 #include "C_BlockProcessor.h"
00024 #include "bundling/Bundle.h"
00025 #include "bundling/BundleDaemon.h"
00026 #include "bundling/BundleProtocol.h"
00027 #include "contacts/Link.h"
00028 #include "openssl/evp.h"
00029
00030 namespace dtn {
00031
00032 static const char * log = "/dtn/bundle/ciphersuite";
00033
00034
00035 C_BlockProcessor::C_BlockProcessor()
00036 : BlockProcessor(BundleProtocol::CONFIDENTIALITY_BLOCK)
00037 {
00038 }
00039
00040
00041 int
00042 C_BlockProcessor::consume(Bundle* bundle, BlockInfo* block,
00043 u_char* buf, size_t len)
00044 {
00045 int cc = BlockProcessor::consume(bundle, block, buf, len);
00046
00047 if (cc == -1) {
00048 return -1;
00049 }
00050
00051
00052
00053
00054 if (! block->complete()) {
00055 ASSERT(cc == (int)len);
00056 return cc;
00057 }
00058
00059 if ( block->locals() == NULL ) {
00060 Ciphersuite::parse(block);
00061 }
00062
00063 return cc;
00064 }
00065
00066
00067 int
00068 C_BlockProcessor::reload_post_process(Bundle* bundle,
00069 BlockInfoVec* block_list,
00070 BlockInfo* block)
00071 {
00072
00073
00074
00075
00076
00077
00078 Ciphersuite* p = NULL;
00079 int err = 0;
00080 int type = 0;
00081 BP_Local_CS* locals;
00082
00083 if ( ! block->reloaded() )
00084 return 0;
00085
00086 type = block->type();
00087 log_debug_p(log, "C_BlockProcessor::reload block type %d", type);
00088
00089 Ciphersuite::parse(block);
00090 locals = dynamic_cast<BP_Local_CS*>(block->locals());
00091 CS_FAIL_IF_NULL(locals);
00092
00093 p = Ciphersuite::find_suite( locals->owner_cs_num() );
00094 if ( p != NULL )
00095 err = p->reload_post_process(bundle, block_list, block);
00096
00097 block->set_reloaded(false);
00098 return err;
00099
00100 fail:
00101 if ( locals != NULL )
00102 locals->set_proc_flag(Ciphersuite::CS_BLOCK_PROCESSING_FAILED_DO_NOT_SEND);
00103 return BP_FAIL;
00104 }
00105
00106
00107 bool
00108 C_BlockProcessor::validate(const Bundle* bundle,
00109 BlockInfoVec* block_list,
00110 BlockInfo* block,
00111 status_report_reason_t* reception_reason,
00112 status_report_reason_t* deletion_reason)
00113 {
00114 (void)bundle;
00115 (void)block_list;
00116 (void)block;
00117 (void)reception_reason;
00118 (void)deletion_reason;
00119
00120 Ciphersuite* p = NULL;
00121 u_int16_t cs_flags = 0;
00122 EndpointID local_eid = BundleDaemon::instance()->local_eid();
00123 BP_Local_CS* locals = dynamic_cast<BP_Local_CS*>(block->locals());
00124 bool result = false;
00125
00126 CS_FAIL_IF_NULL(locals);
00127
00128
00129 log_debug_p(log, "C_BlockProcessor::validate() %p ciphersuite %d",
00130 block, locals->owner_cs_num());
00131 cs_flags = locals->cs_flags();
00132
00133 if ( Ciphersuite::destination_is_local_node(bundle, block) )
00134 {
00135
00136 p = Ciphersuite::find_suite( locals->owner_cs_num() );
00137 if ( p != NULL ) {
00138 result = p->validate(bundle, block_list, block,
00139 reception_reason, deletion_reason);
00140 return result;
00141 } else {
00142 log_err_p(log, "block failed security validation C_BlockProcessor");
00143 *deletion_reason = BundleProtocol::REASON_SECURITY_FAILED;
00144 return false;
00145 }
00146 } else {
00147
00148 locals->set_proc_flag(Ciphersuite::CS_BLOCK_DID_NOT_FAIL);
00149 }
00150
00151 return true;
00152
00153 fail:
00154 if ( locals != NULL )
00155 locals->set_proc_flag(Ciphersuite::CS_BLOCK_FAILED_VALIDATION |
00156 Ciphersuite::CS_BLOCK_COMPLETED_DO_NOT_FORWARD);
00157 *deletion_reason = BundleProtocol::REASON_SECURITY_FAILED;
00158 return false;
00159 }
00160
00161
00162 int
00163 C_BlockProcessor::prepare(const Bundle* bundle,
00164 BlockInfoVec* xmit_blocks,
00165 const BlockInfo* source,
00166 const LinkRef& link,
00167 list_owner_t list)
00168 {
00169 (void)bundle;
00170 (void)link;
00171 (void)list;
00172
00173 Ciphersuite* p = NULL;
00174 int result = BP_FAIL;
00175 BP_Local_CS* locals = NULL;
00176 BP_Local_CS* source_locals = NULL;
00177
00178 if ( list == BlockInfo::LIST_RECEIVED ) {
00179
00180
00181
00182
00183
00184 ASSERT(source != NULL);
00185 u_int16_t cs_flags = 0;
00186
00187 if ( Ciphersuite::destination_is_local_node(bundle, source) )
00188 return BP_SUCCESS;
00189
00190 xmit_blocks->push_back(BlockInfo(this, source));
00191 BlockInfo* bp = &(xmit_blocks->back());
00192 bp->set_eid_list(source->eid_list());
00193 log_debug_p(log, "C_BlockProcessor::prepare() - forward received block len %u",
00194 source->full_length());
00195
00196
00197 CS_FAIL_IF_NULL( source->locals() );
00198
00199 source_locals = dynamic_cast<BP_Local_CS*>(source->locals());
00200 CS_FAIL_IF_NULL(source_locals);
00201 bp->set_locals(new BP_Local_CS);
00202 locals = dynamic_cast<BP_Local_CS*>(bp->locals());
00203 CS_FAIL_IF_NULL(locals);
00204 locals->set_owner_cs_num(source_locals->owner_cs_num());
00205 cs_flags = source_locals->cs_flags();
00206 locals->set_correlator(source_locals->correlator());
00207 locals->set_list_owner(BlockInfo::LIST_RECEIVED);
00208
00209
00210 if ( source_locals->cs_flags() & Ciphersuite::CS_BLOCK_HAS_SOURCE ) {
00211 ASSERT(source_locals->security_src().length() > 0 );
00212 cs_flags |= Ciphersuite::CS_BLOCK_HAS_SOURCE;
00213 locals->set_security_src(source_locals->security_src());
00214 log_debug_p(log, "C_BlockProcessor::prepare() add security_src EID %s",
00215 source_locals->security_src().c_str());
00216 }
00217
00218 if ( source_locals->cs_flags() & Ciphersuite::CS_BLOCK_HAS_DEST ) {
00219 ASSERT(source_locals->security_dest().length() > 0 );
00220 cs_flags |= Ciphersuite::CS_BLOCK_HAS_DEST;
00221 locals->set_security_dest(source_locals->security_dest());
00222 log_debug_p(log, "C_BlockProcessor::prepare() add security_dest EID %s",
00223 source_locals->security_dest().c_str());
00224 }
00225 locals->set_cs_flags(cs_flags);
00226 log_debug_p(log, "C_BlockProcessor::prepare() - inserted block eid_list_count %zu",
00227 bp->eid_list().size());
00228 result = BP_SUCCESS;
00229 } else {
00230 if ( source != NULL ) {
00231 source_locals = dynamic_cast<BP_Local_CS*>(source->locals());
00232 CS_FAIL_IF_NULL(source_locals);
00233 p = Ciphersuite::find_suite( source_locals->owner_cs_num() );
00234 if ( p != NULL ) {
00235 result = p->prepare(bundle, xmit_blocks, source, link, list);
00236 } else {
00237 log_err_p(log, "C_BlockProcessor::prepare() - ciphersuite %d is missing",
00238 source_locals->owner_cs_num());
00239 }
00240 }
00241 }
00242 return result;
00243
00244 fail:
00245 if ( locals != NULL )
00246 locals->set_proc_flag(Ciphersuite::CS_BLOCK_PROCESSING_FAILED_DO_NOT_SEND);
00247 return BP_FAIL;
00248 }
00249
00250
00251 int
00252 C_BlockProcessor::generate(const Bundle* bundle,
00253 BlockInfoVec* xmit_blocks,
00254 BlockInfo* block,
00255 const LinkRef& link,
00256 bool last)
00257 {
00258 (void)bundle;
00259 (void)link;
00260 (void)xmit_blocks;
00261
00262 Ciphersuite* p = NULL;
00263 int result = BP_FAIL;
00264 log_debug_p(log, "C_BlockProcessor::generate()");
00265
00266 BP_Local_CS* locals = dynamic_cast<BP_Local_CS*>(block->locals());
00267 CS_FAIL_IF_NULL(locals);
00268
00269 p = Ciphersuite::find_suite( locals->owner_cs_num() );
00270 if ( p != NULL ) {
00271 result = p->generate(bundle, xmit_blocks, block, link, last);
00272 } else {
00273
00274 size_t length = block->source()->data_length();
00275
00276 generate_preamble(xmit_blocks,
00277 block,
00278 BundleProtocol::CONFIDENTIALITY_BLOCK,
00279 BundleProtocol::BLOCK_FLAG_DISCARD_BUNDLE_ONERROR |
00280 (last ? BundleProtocol::BLOCK_FLAG_LAST_BLOCK : 0),
00281 length);
00282
00283 BlockInfo::DataBuffer* contents = block->writable_contents();
00284 contents->reserve(block->data_offset() + length);
00285 contents->set_len(block->data_offset() + length);
00286 memcpy(contents->buf() + block->data_offset(),
00287 block->source()->data(), length);
00288 result = BP_SUCCESS;
00289 }
00290 return result;
00291
00292 fail:
00293 if ( locals != NULL )
00294 locals->set_proc_flag(Ciphersuite::CS_BLOCK_PROCESSING_FAILED_DO_NOT_SEND);
00295 return BP_FAIL;
00296 }
00297
00298
00299 int
00300 C_BlockProcessor::finalize(const Bundle* bundle,
00301 BlockInfoVec* xmit_blocks,
00302 BlockInfo* block,
00303 const LinkRef& link)
00304 {
00305 (void)bundle;
00306 (void)link;
00307 (void)xmit_blocks;
00308 (void)block;
00309
00310 Ciphersuite* p = NULL;
00311 int result = BP_FAIL;
00312 log_debug_p(log, "C_BlockProcessor::finalize()");
00313
00314 BP_Local_CS* locals = dynamic_cast<BP_Local_CS*>(block->locals());
00315 CS_FAIL_IF_NULL(locals);
00316
00317 p = Ciphersuite::find_suite( locals->owner_cs_num() );
00318 if ( p != NULL ) {
00319 result = p->finalize(bundle, xmit_blocks, block, link);
00320 }
00321
00322
00323 return result;
00324
00325 fail:
00326 if ( locals != NULL )
00327 locals->set_proc_flag(Ciphersuite::CS_BLOCK_PROCESSING_FAILED_DO_NOT_SEND);
00328 return BP_FAIL;
00329 }
00330
00331 }
00332
00333 #endif