encryption_tentacle.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "encryption_tentacle.h"
00016 #include "encryption_wrapper.h"
00017 #include "key_repository.h"
00018
00019 #include <crypto/blowfish_crypto.h>
00020 #include <crypto/rsa_crypto.h>
00021 #include <loggers/program_wide_logger.h>
00022 #include <structures/symbol_table.h>
00023 #include <textual/byte_formatter.h>
00024
00025 using namespace basis;
00026 using namespace crypto;
00027 using namespace loggers;
00028 using namespace structures;
00029 using namespace textual;
00030
00031 namespace octopi {
00032
00033 #undef LOG
00034 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
00035
00036 #define DEBUG_ENCRYPTION_TENTACLE
00037
00038
00040
00041 encryption_tentacle::encryption_tentacle()
00042 : tentacle_helper<encryption_infoton>
00043 (encryption_infoton::encryption_classifier(), false),
00044 _server_side(true),
00045 _keys(new key_repository),
00046 _rsa_private(NIL)
00047 {
00048 }
00049
00050 encryption_tentacle::encryption_tentacle(const byte_array &private_key)
00051 : tentacle_helper<encryption_infoton>
00052 (encryption_infoton::encryption_classifier(), false),
00053 _server_side(false),
00054 _keys(new key_repository),
00055 _rsa_private(new rsa_crypto(private_key))
00056 {
00057 }
00058
00059 encryption_tentacle::encryption_tentacle(int key_size)
00060 : tentacle_helper<encryption_infoton>
00061 (encryption_infoton::encryption_classifier(), false),
00062 _server_side(false),
00063 _keys(new key_repository),
00064 _rsa_private(new rsa_crypto(key_size))
00065 {
00066 }
00067
00068 encryption_tentacle::~encryption_tentacle()
00069 {
00070 WHACK(_rsa_private);
00071 WHACK(_keys);
00072 }
00073
00074 key_repository &encryption_tentacle::keys() const { return *_keys; }
00075
00076 const rsa_crypto &encryption_tentacle::private_key() const
00077 { return *_rsa_private; }
00078
00079 outcome encryption_tentacle::reconstitute(const string_array &classifier,
00080 byte_array &packed_form, infoton * &reformed)
00081 {
00082 if (classifier != encryption_infoton::encryption_classifier())
00083 return NO_HANDLER;
00084
00085 return reconstituter(classifier, packed_form, reformed,
00086 (encryption_infoton *)NIL);
00087 }
00088
00089 void encryption_tentacle::expunge(const octopus_entity &formal(to_remove))
00090 {
00092
00093
00094 }
00095
00096 outcome encryption_tentacle::consume(infoton &to_chow,
00097 const octopus_request_id &item_id, byte_array &transformed)
00098 {
00099 FUNCDEF("consume");
00100 transformed.reset();
00101 encryption_infoton *inf = dynamic_cast<encryption_infoton *>(&to_chow);
00102 if (!inf) {
00103
00104
00105
00106 encryption_wrapper *wrap = dynamic_cast<encryption_wrapper *>(&to_chow);
00107 if (!wrap) {
00108 #ifdef DEBUG_ENCRYPTION_TENTACLE
00109
00110
00111 #endif
00112
00113 return ENCRYPTION_MISMATCH;
00114 }
00115
00116 octenc_key_record record;
00117 octenc_key_record *rec = _keys->lock(item_id._entity);
00118 if (!rec) {
00119 #ifdef DEBUG_ENCRYPTION_TENTACLE
00120 LOG(astring("no key stored for entity ")
00121 + item_id._entity.mangled_form()
00122 + "; rejecting packet.");
00123 #endif
00124 return DISALLOWED;
00125 }
00126 record = *rec;
00127 _keys->unlock(rec);
00128
00129 byte_array decro;
00130 bool decrypts_properly = record._key.decrypt(wrap->_wrapped, decro);
00131 if (decrypts_properly) {
00132
00133
00134 transformed = decro;
00135 return PARTIAL;
00136 }
00137
00138 #ifdef DEBUG_ENCRYPTION_TENTACLE
00139 LOG(astring("denying client ") + item_id._entity.mangled_form()
00140 + " due to erroneous decryption");
00141 #endif
00142
00143
00144 return DISALLOWED;
00145 }
00146
00147
00148
00149 if (!_server_side) {
00150
00151
00152 blowfish_crypto new_key(blowfish_crypto::minimum_key_size());
00153 outcome ret = inf->extract_response(*_rsa_private, new_key);
00154 if (ret != OKAY) {
00155 #ifdef DEBUG_ENCRYPTION_TENTACLE
00156 LOG(astring("client failed to process encrypted blowfish key for ")
00157 + item_id._entity.mangled_form());
00158 #endif
00159 } else {
00160 _keys->add(item_id._entity, new_key);
00161 }
00162
00163 return ret;
00164 } else {
00165
00166
00167 blowfish_crypto agreed_key(blowfish_crypto::minimum_key_size());
00168
00169 outcome worked = inf->prepare_blowfish_key(agreed_key);
00170 if (worked != OKAY) {
00171 #ifdef DEBUG_ENCRYPTION_TENTACLE
00172 LOG(astring("server failed to encrypt blowfish key for ")
00173 + item_id._entity.mangled_form());
00174 #endif
00175 } else {
00176 _keys->add(item_id._entity, agreed_key);
00177 }
00178 }
00179
00180 if (!store_product(dynamic_cast<infoton *>(inf->clone()), item_id))
00181 return NO_SPACE;
00182 return OKAY;
00183 }
00184
00185 }
00186