MIRA
RSAFilter.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_RSAFILTER_H_
48 #define _MIRA_RSAFILTER_H_
49 
50 #ifndef Q_MOC_RUN
51 #include <boost/iostreams/concepts.hpp>
52 #include <boost/iostreams/filter/symmetric.hpp>
53 #include <boost/asio/basic_streambuf.hpp>
54 #endif
55 
56 #include <platform/Types.h>
57 #include <error/Exceptions.h>
58 #include <security/RSAKey.h>
59 
60 namespace mira {
61 
63 
65 
66 namespace Private {
67 
69 // An allocator trait for the boost iostream filter
70 
71 template<typename Alloc>
72 struct RSAFilterAllocatorTraits
73 {
74 #ifndef BOOST_NO_STD_ALLOCATOR
75  typedef typename Alloc::template rebind<char>::other type;
76 #else
77  typedef std::allocator<char> type;
78 #endif
79 };
80 
82 // An allocator for the boost iostreams filter
83 
84 template< typename Alloc,
85  typename Base = BOOST_DEDUCED_TYPENAME RSAFilterAllocatorTraits<Alloc>::type >
86 struct RSAFilterAllocator :
87  private Base
88 {
89 private:
90  typedef typename Base::size_type size_type;
91 public:
92  BOOST_STATIC_CONSTANT(bool, custom =
93  (!boost::is_same<std::allocator<char>, Base>::value));
94  typedef typename RSAFilterAllocatorTraits<Alloc>::type allocator_type;
95 
96  static void* allocate(void* self, uint32 items, uint32 size);
97  static void deallocate(void* self, void* address);
98 };
99 
101 // An internal class of the RSA filter class
102 
103 class MIRA_BASE_EXPORT RSAFilterBase
104 {
105 public:
106  typedef char char_type;
107 
108 protected:
110  RSAFilterBase();
111 
113  ~RSAFilterBase();
114 
115  template<typename Alloc>
116  void init(const RSAKey& key, bool encrypt, RSAFilterAllocator<Alloc>& alloc)
117  {
118  initFilter(key, encrypt, &alloc);
119  }
120 
122  bool encryptPublic(const char*& ioSrcBegin,
123  const char* oSrcEnd,
124  char*& ioDestBegin,
125  char* iDestEnd,
126  bool iFlush);
127 
129  bool decryptPrivate(const char*& ioSrcBegin,
130  const char* iSrcEnd,
131  char*& ioDestBegin,
132  char* iDestEnd,
133  bool iFlush);
134 
136  void reset();
137 
138 private:
139  void initFilter(const RSAKey& key, bool encrypt, void* alloc);
140 
141 private:
142  RSAKey mKey;
143 
144  boost::asio::basic_streambuf<> mInputBuffer;
145  boost::asio::basic_streambuf<> mOutputBuffer;
146 
147  uint8* mWrkBuffer;
148  size_t mRSASize;
149  size_t mBlockSize;
150 
151 #ifdef MIRA_USE_OPENSSL3
152  struct KeyCtx;
153  KeyCtx* mCtx;
154 #endif
155 };
156 
158 // Template name: RSAPublicEncryptionImpl
159 
160 template<typename Alloc = std::allocator<char> >
161 class RSAPublicEncryptionImpl :
162  public RSAFilterBase,
163  public RSAFilterAllocator<Alloc>
164 {
165 public:
166  RSAPublicEncryptionImpl(const RSAKey& key);
167  ~RSAPublicEncryptionImpl();
168 
169  bool filter(const char* &ioSrcBegin, const char* iSrcEnd,
170  char* &ioDestBegin, char* iDestEnd, bool iFlush);
171 
172  void close();
173 };
174 
176 // Template name: RSAPrivateDecryptionImpl
177 
178 template<typename Alloc = std::allocator<char> >
179 class RSAPrivateDecryptionImpl :
180  public RSAFilterBase,
181  public RSAFilterAllocator<Alloc>
182 {
183 public:
184  RSAPrivateDecryptionImpl(const RSAKey& key);
185  ~RSAPrivateDecryptionImpl();
186 
187  bool filter(const char* &ioSrcBegin, const char* iSrcEnd,
188  char* &ioDestBegin, char* iDestEnd, bool iFlush);
189 
190  void close();
191 };
192 
194 
195 } // end of namespace Private
196 
198 // BasicRSAPublicEncryptionFilter
199 
200 template<typename Alloc = std::allocator<char> >
201 struct BasicRSAPublicEncryptionFilter :
202  boost::iostreams::symmetric_filter<Private::RSAPublicEncryptionImpl<Alloc>, Alloc>
203 {
204 private:
205  typedef Private::RSAPublicEncryptionImpl<Alloc> impl_type;
206  typedef boost::iostreams::symmetric_filter<impl_type, Alloc> base_type;
207 
208 public:
209  typedef typename base_type::char_type char_type;
210  typedef typename base_type::category category;
211 
212  BasicRSAPublicEncryptionFilter(const RSAKey& key,
213  int bufferSize = boost::iostreams::default_device_buffer_size);
214 };
215 BOOST_IOSTREAMS_PIPABLE(BasicRSAPublicEncryptionFilter, 1)
216 
217 // BasicRSAPrivateDecryptionFilter
219 
220 template<typename Alloc = std::allocator<char> >
221 struct BasicRSAPrivateDecryptionFilter :
222  boost::iostreams::symmetric_filter<Private::RSAPrivateDecryptionImpl<Alloc>, Alloc>
223 {
224 private:
225  typedef Private::RSAPrivateDecryptionImpl<Alloc> impl_type;
226  typedef boost::iostreams::symmetric_filter<impl_type, Alloc> base_type;
227 
228 public:
229  typedef typename base_type::char_type char_type;
230  typedef typename base_type::category category;
231 
232  BasicRSAPrivateDecryptionFilter(const RSAKey& key,
233  int bufferSize = boost::iostreams::default_device_buffer_size);
234 };
235 BOOST_IOSTREAMS_PIPABLE(BasicRSAPrivateDecryptionFilter, 1)
236 
237 
240 
242 
274 typedef BasicRSAPublicEncryptionFilter<> RSAPublicEncryptionFilter;
275 
305 typedef BasicRSAPrivateDecryptionFilter<> RSAPrivateDecryptionFilter;
306 
308 // Template implementation
310 
312 
313 namespace Private {
314 
316 // Implementation of template rsa_allocator
317 
318 template<typename Alloc, typename Base>
319 void* RSAFilterAllocator<Alloc, Base>::allocate(void* self, uint32 items,
320  uint32 size)
321 {
322  size_type len = items * size;
323  char* ptr =
324  static_cast<allocator_type*>(self)->allocate
325  (len + sizeof(size_type)
326  #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
327  , (char*)0
328  #endif
329  );
330  *reinterpret_cast<size_type*>(ptr) = len;
331  return ptr + sizeof(size_type);
332 }
333 
334 template<typename Alloc, typename Base>
335 void RSAFilterAllocator<Alloc, Base>::deallocate(void* self, void* address)
336 {
337  char* ptr = reinterpret_cast<char*>(address) - sizeof(size_type);
338  size_type len = *reinterpret_cast<size_type*>(ptr) + sizeof(size_type);
339  static_cast<allocator_type*>(self)->deallocate(ptr, len);
340 }
341 
343 // Implementation of RSAPublicEncryptionImpl
344 
345 template<typename Alloc>
346 RSAPublicEncryptionImpl<Alloc>::RSAPublicEncryptionImpl(const RSAKey& key)
347 {
348  init(key, true, static_cast<RSAFilterAllocator<Alloc>&>(*this));
349 }
350 
351 template<typename Alloc>
352 RSAPublicEncryptionImpl<Alloc>::~RSAPublicEncryptionImpl()
353 {
354  reset();
355 }
356 
357 template<typename Alloc>
358 bool RSAPublicEncryptionImpl<Alloc>::filter(const char* &ioSrcBegin,
359  const char* iSrcEnd,
360  char* &ioDestBegin,
361  char* iDestEnd, bool iFlush)
362 {
363  return(encryptPublic(ioSrcBegin, iSrcEnd, ioDestBegin, iDestEnd, iFlush));
364 }
365 
366 template<typename Alloc>
367 void RSAPublicEncryptionImpl<Alloc>::close()
368 {
369  reset();
370 }
371 
373 // Implementation of RSAPrivateDecryptionImpl
374 
375 template<typename Alloc>
376 RSAPrivateDecryptionImpl<Alloc>::RSAPrivateDecryptionImpl(const RSAKey& key)
377 {
378  init(key, false, static_cast<RSAFilterAllocator<Alloc>&>(*this));
379 }
380 
381 template<typename Alloc>
382 RSAPrivateDecryptionImpl<Alloc>::~RSAPrivateDecryptionImpl()
383 {
384  reset();
385 }
386 
387 template<typename Alloc>
388 bool RSAPrivateDecryptionImpl<Alloc>::filter(const char* &ioSrcBegin,
389  const char* iSrcEnd,
390  char* &ioDestBegin,
391  char* iDestEnd, bool iFlush)
392 {
393  return(decryptPrivate(ioSrcBegin, iSrcEnd, ioDestBegin, iDestEnd, iFlush));
394 }
395 
396 template<typename Alloc>
397 void RSAPrivateDecryptionImpl<Alloc>::close()
398 {
399  reset();
400 }
401 
403 
404 } // end of namespace Private
405 
407 // Implementation of BasicRSAPublicEncryptionFilter
408 
409 template<typename Alloc>
410 BasicRSAPublicEncryptionFilter<Alloc>::BasicRSAPublicEncryptionFilter(
411  const RSAKey& key, int bufferSize) :
412  base_type(bufferSize, key)
413 {
414  if (!key.isPublicKey())
415  MIRA_THROW(XInvalidConfig, "The key is not a public key.");
416 }
417 
419 // Implementation of BasicRSAPrivateDecryptionFilter
420 
421 template<typename Alloc>
422 BasicRSAPrivateDecryptionFilter<Alloc>::BasicRSAPrivateDecryptionFilter(
423  const RSAKey& key, int bufferSize) :
424  base_type(bufferSize, key)
425 {
426  if (!key.isPrivateKey())
427  MIRA_THROW(XInvalidConfig, "The key is not a private key.");
428 }
429 
431 
433 
435 
436 } // namespaces
437 
438 #endif
Typedefs for OS independent basic data types.
BasicRSAPrivateDecryptionFilter RSAPrivateDecryptionFilter
A RSA private decryption filter for boost::iostreams.
Definition: RSAFilter.h:305
Definition: SyncTimedRead.h:62
Definition of a RSA key (public or private)
Definition: RSAKey.h:71
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
STL namespace.
BasicRSAPublicEncryptionFilter RSAPublicEncryptionFilter
A RSA public encryption filter for boost::iostreams.
Definition: RSAFilter.h:274
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:81
Commonly used exception classes.
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:295
#define MIRA_BASE_EXPORT
This is required because on windows there is a macro defined called ERROR.
Definition: Platform.h:153
A class for a RSA key.