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