1 /*****************************************************************************\
3 * Name : encryption_tentacle *
4 * Author : Chris Koeritz *
6 *******************************************************************************
7 * Copyright (c) 2004-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
13 \*****************************************************************************/
15 #include "encryption_tentacle.h"
16 #include "encryption_wrapper.h"
17 #include "key_repository.h"
19 #include <crypto/blowfish_crypto.h>
20 #include <crypto/rsa_crypto.h>
21 #include <loggers/program_wide_logger.h>
22 #include <structures/symbol_table.h>
23 #include <textual/byte_formatter.h>
25 using namespace basis;
26 using namespace crypto;
27 using namespace loggers;
28 using namespace structures;
29 using namespace textual;
34 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
36 #define DEBUG_ENCRYPTION_TENTACLE
37 // uncomment for noisier code.
41 encryption_tentacle::encryption_tentacle()
42 : tentacle_helper<encryption_infoton>
43 (encryption_infoton::encryption_classifier(), false),
45 _keys(new key_repository),
46 _rsa_private(NULL_POINTER)
50 encryption_tentacle::encryption_tentacle(const byte_array &private_key)
51 : tentacle_helper<encryption_infoton>
52 (encryption_infoton::encryption_classifier(), false),
54 _keys(new key_repository),
55 _rsa_private(new rsa_crypto(private_key))
59 encryption_tentacle::encryption_tentacle(int key_size)
60 : tentacle_helper<encryption_infoton>
61 (encryption_infoton::encryption_classifier(), false),
63 _keys(new key_repository),
64 _rsa_private(new rsa_crypto(key_size))
68 encryption_tentacle::~encryption_tentacle()
74 key_repository &encryption_tentacle::keys() const { return *_keys; }
76 const rsa_crypto &encryption_tentacle::private_key() const
77 { return *_rsa_private; }
79 outcome encryption_tentacle::reconstitute(const string_array &classifier,
80 byte_array &packed_form, infoton * &reformed)
82 if (classifier != encryption_infoton::encryption_classifier())
85 return reconstituter(classifier, packed_form, reformed,
86 (encryption_infoton *)NULL_POINTER);
89 void encryption_tentacle::expunge(const octopus_entity &formal(to_remove))
91 //// _keys->whack(to_remove);
92 //we need a better approach. it seems there are places where an entity
93 //can get reused and it still expects its key to be present.
96 outcome encryption_tentacle::consume(infoton &to_chow,
97 const octopus_request_id &item_id, byte_array &transformed)
101 encryption_infoton *inf = dynamic_cast<encryption_infoton *>(&to_chow);
103 // this package is not explicitly an encryption infoton. we need to
104 // decrypt it using what we already know.
106 encryption_wrapper *wrap = dynamic_cast<encryption_wrapper *>(&to_chow);
108 #ifdef DEBUG_ENCRYPTION_TENTACLE
109 // LOG(astring("got a stray infoton that was not encrypted: ")
110 // + to_chow.text_form());
112 // this signals that we were expecting an encrypted package.
113 return ENCRYPTION_MISMATCH;
116 octenc_key_record record;
117 octenc_key_record *rec = _keys->lock(item_id._entity);
119 #ifdef DEBUG_ENCRYPTION_TENTACLE
120 LOG(astring("no key stored for entity ")
121 + item_id._entity.mangled_form()
122 + "; rejecting packet.");
130 bool decrypts_properly = record._key.decrypt(wrap->_wrapped, decro);
131 if (decrypts_properly) {
132 // this package seems to be intact. we need to reconstitute the
134 transformed = decro; // set the decrypted blob.
138 #ifdef DEBUG_ENCRYPTION_TENTACLE
139 LOG(astring("denying client ") + item_id._entity.mangled_form()
140 + " due to erroneous decryption");
143 // the infoton's client is not authorized; it needs to be dropped.
147 // reaching here means this is explicitly an encryption startup request.
150 // client's side must track the key we were given for decryption. we'll
151 // use that from now on.
152 blowfish_crypto new_key(blowfish_crypto::minimum_key_size()); // bogus.
153 outcome ret = inf->extract_response(*_rsa_private, new_key);
155 #ifdef DEBUG_ENCRYPTION_TENTACLE
156 LOG(astring("client failed to process encrypted blowfish key for ")
157 + item_id._entity.mangled_form());
160 _keys->add(item_id._entity, new_key); // add our key for this guy.
162 // we do not store a copy of the infoton; it's just done now.
165 // server's side need to process a key request and send it back using
166 // the public key the requester provided.
167 blowfish_crypto agreed_key(blowfish_crypto::minimum_key_size());
168 // initialized with junk.
169 outcome worked = inf->prepare_blowfish_key(agreed_key);
170 if (worked != OKAY) {
171 #ifdef DEBUG_ENCRYPTION_TENTACLE
172 LOG(astring("server failed to encrypt blowfish key for ")
173 + item_id._entity.mangled_form());
176 _keys->add(item_id._entity, agreed_key); // add our key for this guy.
180 if (!store_product(dynamic_cast<infoton *>(inf->clone()), item_id))