--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/security/Ciphersuite.h Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2006 SPARTA Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CIPHERSUITE_H_
+#define _CIPHERSUITE_H_
+
+#ifdef BSP_ENABLED
+
+#include "bundling/BlockProcessor.h"
+
+namespace dtn {
+
+class BP_Local_CS;
+
+/**
+ * Block processor superclass for ciphersutes
+ * This level handles suite registration and
+ * similar activities but no specific work
+ */
+ class Ciphersuite {
+public:
+ /// For local binary (non-string) stuff we use
+ /// a scratch buffer but with minimal initial allocation
+ typedef oasys::ScratchBuffer<u_char*, 16> LocalBuffer;
+
+ /// @{ Import some typedefs from other classes
+ typedef BlockInfo::list_owner_t list_owner_t;
+ typedef BundleProtocol::status_report_reason_t status_report_reason_t;
+ /// @}
+
+ /**
+ * Values for security flags that appear in the
+ * ciphersuite field.
+ */
+ typedef enum {
+ CS_BLOCK_HAS_SOURCE = 0x10,
+ CS_BLOCK_HAS_DEST = 0x08,
+ CS_BLOCK_HAS_PARAMS = 0x04,
+ CS_BLOCK_HAS_CORRELATOR = 0x02,
+ CS_BLOCK_HAS_RESULT = 0x01
+ } ciphersuite_flags_t;
+
+ /**
+ * Values for flags that appear in the
+ * proc_flags_ field.
+ */
+ typedef enum {
+ CS_BLOCK_RESERVED0 = 0x01,
+ CS_BLOCK_PROCESSED = 0x02,
+ CS_BLOCK_DID_NOT_FAIL = 0x04,
+ CS_BLOCK_FAILED_VALIDATION = 0x08,
+ CS_BLOCK_PASSED_VALIDATION = 0x10,
+ CS_BLOCK_COMPLETED_DO_NOT_FORWARD = 0x20,
+ CS_BLOCK_PROCESSING_FAILED_DO_NOT_SEND = 0x40
+ } proc_flags_t;
+
+ /**
+ * Values for security types that appear in the
+ * ciphersuite parameters and results fields.
+ */
+ typedef enum {
+ CS_reserved0 = 0,
+ CS_IV_field = 1,
+ CS_reserved2_field = 2,
+ CS_key_info_field = 3,
+ CS_fragment_offset_and_length_field = 4,
+ CS_signature_field = 5,
+ CS_reserved6 = 6,
+ CS_PC_block_salt = 7,
+ CS_PC_block_ICV_field = 8,
+ CS_reserved9 = 9,
+ CS_encap_block_field = 10,
+ CS_reserved11 = 11
+ } ciphersuite_fields_t;
+
+ /// Constructor
+ Ciphersuite();
+
+ /**
+ * Virtual destructor.
+ */
+ virtual ~Ciphersuite();
+
+ static void register_ciphersuite(Ciphersuite* cs);
+
+ static Ciphersuite* find_suite(u_int16_t num);
+
+ static void init_default_ciphersuites(void);
+
+ virtual u_int16_t cs_num();
+
+ virtual size_t result_len() { return 0; }
+
+ static void parse(BlockInfo* block);
+
+ /**
+ * First callback for parsing blocks that is expected to append a
+ * chunk of the given data to the given block. When the block is
+ * completely received, this should also parse the block into any
+ * fields in the bundle class.
+ *
+ * The base class implementation parses the block preamble fields
+ * to find the length of the block and copies the preamble and the
+ * data in the block's contents buffer.
+ *
+ * This and all derived implementations must be able to handle a
+ * block that is received in chunks, including cases where the
+ * preamble is split into multiple chunks.
+ *
+ * @return the amount of data consumed or -1 on error
+ */
+ virtual int consume(Bundle* bundle, BlockInfo* block,
+ u_char* buf, size_t len) = 0;
+
+ virtual int reload_post_process(Bundle* bundle,
+ BlockInfoVec* block_list,
+ BlockInfo* block);
+
+ /**
+ * Validate the block. This is called after all blocks in the
+ * bundle have been fully received.
+ *
+ * @return true if the block passes validation
+ */
+ virtual bool validate(const Bundle* bundle,
+ BlockInfoVec* block_list,
+ BlockInfo* block,
+ status_report_reason_t* reception_reason,
+ status_report_reason_t* deletion_reason) = 0;
+
+ /**
+ * First callback to generate blocks for the output pass. The
+ * function is expected to initialize an appropriate BlockInfo
+ * structure in the given BlockInfoVec.
+ *
+ * The base class simply initializes an empty BlockInfo with the
+ * appropriate owner_ pointer.
+ */
+ virtual int prepare(const Bundle* bundle,
+ BlockInfoVec* xmit_blocks,
+ const BlockInfo* source,
+ const LinkRef& link,
+ list_owner_t list) = 0;
+
+ /**
+ * Second callback for transmitting a bundle. This pass should
+ * generate any data for the block that does not depend on other
+ * blocks' contents. It MUST add any EID references it needs by
+ * calling block->add_eid(), then call generate_preamble(), which
+ * will add the EIDs to the primary block's dictionary and write
+ * their offsets to this block's preamble.
+ */
+ virtual int generate(const Bundle* bundle,
+ BlockInfoVec* xmit_blocks,
+ BlockInfo* block,
+ const LinkRef& link,
+ bool last) = 0;
+
+ /**
+ * Third callback for transmitting a bundle. This pass should
+ * generate any data (such as security signatures) for the block
+ * that may depend on other blocks' contents.
+ *
+ * The base class implementation does nothing.
+ *
+ * We pass xmit_blocks explicitly to indicate that ALL blocks
+ * might be changed by finalize, typically by being encrypted.
+ * Parameters such as length might also change due to padding
+ * and encapsulation.
+ */
+ virtual int finalize(const Bundle* bundle,
+ BlockInfoVec* xmit_blocks,
+ BlockInfo* block,
+ const LinkRef& link) = 0;
+
+ /**
+ * Check the block list for validation flags for the
+ * specified ciphersuite
+ */
+ static bool check_validation(const Bundle* bundle,
+ const BlockInfoVec* block_list,
+ u_int16_t num);
+
+ /**
+ * Ccreate a correlator for this block-list. Include part
+ * of the fragment-offset is this bundle is a fragment.
+ */
+ static u_int64_t create_correlator(const Bundle* bundle,
+ const BlockInfoVec* block_list);
+
+ /**
+ * Convenience methods to test if the security source/destination
+ * is an endpoint registered at the local node.
+ */
+ static bool source_is_local_node(const Bundle* bundle,
+ const BlockInfo* block);
+
+ static bool destination_is_local_node(const Bundle* bundle,
+ const BlockInfo* block);
+
+
+ virtual void init_locals(BlockInfo* block);
+
+protected:
+
+ /**
+ * Generate the standard preamble for the given block type, flags,
+ * EID-list and content length.
+ */
+ void generate_preamble(BlockInfoVec* xmit_blocks,
+ BlockInfo* block,
+ u_int8_t type,
+ u_int64_t flags,
+ u_int64_t data_length);
+
+
+private:
+
+ /**
+ * Array of registered BlockProcessor-derived handlers for
+ * various ciphersuites -- fixed size for now [maybe make adjustable later]
+ */
+ static Ciphersuite* ciphersuites_[1024];
+
+ static bool inited;
+};
+
+class BP_Local_CS : public BP_Local {
+public:
+ /// Use the same LocalBuffer type as Ciphersuite
+ typedef Ciphersuite::LocalBuffer LocalBuffer;
+
+ /**
+ * Constructor.
+ */
+ BP_Local_CS();
+
+ /**
+ * Copy constructor.
+ */
+ BP_Local_CS(const BP_Local_CS&);
+
+ /**
+ * Virtual destructor.
+ */
+ virtual ~BP_Local_CS();
+
+ /// @{ Accessors
+ // need to think about which ones map to the locals and which
+ // are derived
+
+ u_int16_t cs_flags() const { return cs_flags_; }
+ u_int16_t owner_cs_num() const { return owner_cs_num_; }
+ u_int32_t security_result_offset() const { return security_result_offset_; }
+ u_int64_t correlator() const { return correlator_; }
+ u_int16_t correlator_sequence() const { return correlator_sequence_; }
+ const LocalBuffer& key() const { return key_; }
+ const LocalBuffer& salt() const { return salt_; }
+ const LocalBuffer& iv() const { return iv_; }
+ const LocalBuffer& security_params() const { return security_params_; }
+ std::string security_src() const { return security_src_; }
+ std::string security_dest() const { return security_dest_; }
+ const LocalBuffer& security_result() const { return security_result_; }
+ BlockInfo::list_owner_t list_owner() const { return list_owner_; }
+ u_int16_t proc_flags() const { return proc_flags_; }
+ bool proc_flag(u_int16_t f) const { return (proc_flags_ & f) != 0; }
+ /// @}
+
+
+ /// @{ Mutating accessors
+ void set_cs_flags(u_int16_t f) { cs_flags_ = f; }
+ void set_owner_cs_num(u_int16_t n) { owner_cs_num_ = n; }
+ void set_security_result_offset(u_int64_t o){ security_result_offset_ = o; }
+ void set_key(u_char* k, size_t len);
+ void set_salt(u_char* s, size_t len);
+ void set_iv(u_char* iv, size_t len);
+ void set_correlator(u_int64_t c) { correlator_ = c; }
+ void set_correlator_sequence(u_int16_t c) { correlator_sequence_ = c; }
+ LocalBuffer* writable_security_params() { return &security_params_; }
+ void set_security_src(std::string s) { security_src_ = s; }
+ void set_security_dest(std::string d) { security_dest_ = d; }
+ LocalBuffer* writable_security_result() { return &security_result_; }
+ void set_list_owner(BlockInfo::list_owner_t o) { list_owner_ = o; }
+ void set_proc_flags(u_int16_t f) { proc_flags_ = f; }
+ void set_proc_flag(u_int16_t f) { proc_flags_ |= f; }
+ /// @}
+
+
+protected:
+
+ u_int16_t cs_flags_;
+ u_int16_t correlator_sequence_;
+ u_int32_t security_result_offset_;
+ u_int64_t correlator_;
+ LocalBuffer key_;
+ LocalBuffer iv_;
+ LocalBuffer salt_;
+ LocalBuffer security_params_;
+ std::string security_src_;
+ std::string security_dest_;
+ LocalBuffer security_result_;
+ BlockInfo::list_owner_t list_owner_;
+ u_int16_t owner_cs_num_;
+ u_int16_t proc_flags_; ///< Flags tracking processing status etc
+
+}; /* BP_Local_CS */
+
+} // namespace dtn
+
+#define CS_FAIL_IF(x) \
+ do { if ( (x) ) { \
+ log_err_p(log, "TEST FAILED (%s) at %s:%d\n", \
+ (#x), __FILE__, __LINE__); \
+ goto fail; \
+ } } while(0);
+
+#define CS_FAIL_IF_NULL(x) \
+ do { if ( (x) == NULL) { \
+ log_err_p(log, "TEST FAILED (%s == NULL) at %s:%d\n", \
+ (#x), __FILE__, __LINE__); \
+ goto fail; \
+ } } while(0);
+
+#endif /* BSP_ENABLED */
+
+#endif /* _CIPHERSUITE_H_ */