feisty meow concerns codebase 2.140
encryption_tentacle.cpp
Go to the documentation of this file.
1/*****************************************************************************\
2* *
3* Name : encryption_tentacle *
4* Author : Chris Koeritz *
5* *
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\*****************************************************************************/
14
15#include "encryption_tentacle.h"
16#include "encryption_wrapper.h"
17#include "key_repository.h"
18
20#include <crypto/rsa_crypto.h>
24
25using namespace basis;
26using namespace crypto;
27using namespace loggers;
28using namespace structures;
29using namespace textual;
30
31namespace octopi {
32
33#undef LOG
34#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
35
36#define DEBUG_ENCRYPTION_TENTACLE
37 // uncomment for noisier code.
38
40
43 (encryption_infoton::encryption_classifier(), false),
44 _server_side(true),
45 _keys(new key_repository),
46 _rsa_private(NULL_POINTER)
47{
48}
49
52 (encryption_infoton::encryption_classifier(), false),
53 _server_side(false),
54 _keys(new key_repository),
55 _rsa_private(new rsa_crypto(private_key))
56{
57}
58
61 (encryption_infoton::encryption_classifier(), false),
62 _server_side(false),
63 _keys(new key_repository),
64 _rsa_private(new rsa_crypto(key_size))
65{
66}
67
69{
70 WHACK(_rsa_private);
71 WHACK(_keys);
72}
73
74key_repository &encryption_tentacle::keys() const { return *_keys; }
75
77{ return *_rsa_private; }
78
80 byte_array &packed_form, infoton * &reformed)
81{
83 return NO_HANDLER;
84
85 return reconstituter(classifier, packed_form, reformed,
87}
88
90{
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.
94}
95
97 const octopus_request_id &item_id, byte_array &transformed)
98{
99 FUNCDEF("consume");
100 transformed.reset();
101 encryption_infoton *inf = dynamic_cast<encryption_infoton *>(&to_chow);
102 if (!inf) {
103 // this package is not explicitly an encryption infoton. we need to
104 // decrypt it using what we already know.
105
106 encryption_wrapper *wrap = dynamic_cast<encryption_wrapper *>(&to_chow);
107 if (!wrap) {
108#ifdef DEBUG_ENCRYPTION_TENTACLE
109// LOG(astring("got a stray infoton that was not encrypted: ")
110// + to_chow.text_form());
111#endif
112 // this signals that we were expecting an encrypted package.
113 return ENCRYPTION_MISMATCH;
114 }
115
116 octenc_key_record record;
117 octenc_key_record *rec = _keys->lock(item_id._entity);
118 if (!rec) {
119#ifdef DEBUG_ENCRYPTION_TENTACLE
120 LOG(astring("no key stored for entity ")
121 + item_id._entity.mangled_form()
122 + "; rejecting packet.");
123#endif
124 return DISALLOWED;
125 }
126 record = *rec;
127 _keys->unlock(rec);
128
129 byte_array decro;
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
133 // original infoton.
134 transformed = decro; // set the decrypted blob.
135 return PARTIAL;
136 }
137
138#ifdef DEBUG_ENCRYPTION_TENTACLE
139 LOG(astring("denying client ") + item_id._entity.mangled_form()
140 + " due to erroneous decryption");
141#endif
142
143 // the infoton's client is not authorized; it needs to be dropped.
144 return DISALLOWED;
145 }
146
147 // reaching here means this is explicitly an encryption startup request.
148
149 if (!_server_side) {
150 // client's side must track the key we were given for decryption. we'll
151 // use that from now on.
153 outcome ret = inf->extract_response(*_rsa_private, new_key);
154 if (ret != OKAY) {
155#ifdef DEBUG_ENCRYPTION_TENTACLE
156 LOG(astring("client failed to process encrypted blowfish key for ")
157 + item_id._entity.mangled_form());
158#endif
159 } else {
160 _keys->add(item_id._entity, new_key); // add our key for this guy.
161 }
162 // we do not store a copy of the infoton; it's just done now.
163 return ret;
164 } else {
165 // server's side need to process a key request and send it back using
166 // the public key the requester provided.
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());
174#endif
175 } else {
176 _keys->add(item_id._entity, agreed_key); // add our key for this guy.
177 }
178 }
179
180 if (!store_product(dynamic_cast<infoton *>(inf->clone()), item_id))
181 return NO_SPACE;
182 return OKAY;
183}
184
185} //namespace.
186
#define LOG(s)
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
Definition array.h:349
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
A very common template for a dynamic array of bytes.
Definition byte_array.h:36
Outcomes describe the state of completion for an operation.
Definition outcome.h:31
Provides BlowFish encryption on byte_arrays using the OpenSSL package.
static int minimum_key_size()
returns the minimum key size (in bits) supported here.
bool decrypt(const basis::byte_array &source, basis::byte_array &target) const
decrypts the "target" array from the encrypted "source" array.
Supports public key encryption and decryption.
Definition rsa_crypto.h:33
Encapsulates the chit-chat necessary to establish an encrypted connection.
basis::outcome extract_response(const crypto::rsa_crypto &private_key, crypto::blowfish_crypto &new_key) const
used by the client to extract the shared blowfish key from the server.
basis::outcome prepare_blowfish_key(crypto::blowfish_crypto &new_key)
performs the server side's job on the current key.
virtual clonable * clone() const
must be provided to allow creation of a copy of this object.
static const structures::string_array & encryption_classifier()
returns the classifier for this type of infoton.
virtual void expunge(const octopus_entity &to_remove)
throws out any keys we were maintaining for this entity.
key_repository & keys() const
provides access to our list of keys.
const crypto::rsa_crypto & private_key() const
provides access to the key held here.
virtual basis::outcome consume(infoton &to_chow, const octopus_request_id &item_id, basis::byte_array &transformed)
the base class handles the processing of the request in "to_chow".
encryption_tentacle()
this tentacle will implement the server side.
virtual basis::outcome reconstitute(const structures::string_array &classifier, basis::byte_array &packed_form, infoton *&reformed)
recreates a "reformed" infoton from a packed form.
Wraps an encrypted infoton when the octopus is in an encrypted mode.
basis::byte_array _wrapped
the encrypted data that's held here.
An infoton is an individual request parcel with accompanying information.
Definition infoton.h:32
void unlock(octenc_key_record *to_unlock)
drops the lock on the key record in "to_unlock".
basis::outcome add(const octopus_entity &ent, const crypto::blowfish_crypto &key)
adds a "key" for the "ent". this will fail if one is already listed.
octenc_key_record * lock(const octopus_entity &ent)
locates the key for "ent", if it's stored.
Tracks the keys that have been assigned for a secure channel.
crypto::blowfish_crypto _key
used for communicating with an entity.
Provides a way of identifying users of an octopus object.
Definition entity_defs.h:35
basis::astring mangled_form() const
returns the combined string form of the identifier.
Identifies requests made on an octopus by users.
octopus_entity _entity
the entity.
provides prefab implementations for parts of the tentacle object.
@ PARTIAL
processing of request is partially done.
Definition tentacle.h:74
@ ENCRYPTION_MISMATCH
there is a disconnect regarding encryption.
Definition tentacle.h:75
@ NO_HANDLER
no handler for that type of infoton.
Definition tentacle.h:73
bool store_product(infoton *product, const octopus_request_id &original_id)
used by tentacles to store the objects they produce from infotons.
Definition tentacle.cpp:118
An array of strings with some additional helpful methods.
#define formal(parameter)
This macro just eats what it's passed; it marks unused formal parameters.
Definition definitions.h:48
#define NULL_POINTER
The value representing a pointer to nothing.
Definition definitions.h:32
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition enhance_cpp.h:54
The guards collection helps in testing preconditions and reporting errors.
Definition array.h:30
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
Definition functions.h:121
A logger that sends to the console screen using the standard output device.
basis::outcome reconstituter(const structures::string_array &classifier, basis::byte_array &packed_form, infoton *&reformed, contents *formal(junk))
< reconstituter should work for most infotons to restore flattened infotons.
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55