~ubuntu-branches/ubuntu/wily/afnix/wily

« back to all changes in this revision

Viewing changes to src/srv/tls/shl/TlsSuite.cpp

  • Committer: Package Import Robot
  • Author(s): Nobuhiro Iwamatsu
  • Date: 2015-07-11 02:00:35 UTC
  • mfrom: (10.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20150711020035-2nhpztq7s15qyc0v
Tags: 2.5.1-1
* New upstream release. (Closes: #789968)
* Update debian/control.
  - Update Standards-Version to 3.9.6.
* Add support mips64(el) and ppc64el. (Closes: #741508, #748146)
* Add patches/support-gcc-5.x.patch. (Closes: #777767)
  - Fix build with gcc-5.x.
* Add patches/Disable-NET0001.als.patch.
  - Disable test of NET0001.als.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ---------------------------------------------------------------------------
 
2
// - TlsSuite.cpp                                                            -
 
3
// - afnix:tls service - tls cipher suite class implementation               -
 
4
// ---------------------------------------------------------------------------
 
5
// - This program is free software;  you can redistribute it  and/or  modify -
 
6
// - it provided that this copyright notice is kept intact.                  -
 
7
// -                                                                         -
 
8
// - This program  is  distributed in  the hope  that it will be useful, but -
 
9
// - without  any  warranty;  without  even   the   implied    warranty   of -
 
10
// - merchantability or fitness for a particular purpose.  In no event shall -
 
11
// - the copyright holder be liable for any  direct, indirect, incidental or -
 
12
// - special damages arising in any way out of the use of this software.     -
 
13
// ---------------------------------------------------------------------------
 
14
// - copyright (c) 1999-2015 amaury darsch                                   -
 
15
// ---------------------------------------------------------------------------
 
16
 
 
17
#include "Vector.hpp"
 
18
#include "Boolean.hpp"
 
19
#include "Integer.hpp"
 
20
#include "Utility.hpp"
 
21
#include "TlsSuite.hpp"
 
22
#include "QuarkZone.hpp"
 
23
#include "Exception.hpp"
 
24
 
 
25
namespace afnix {
 
26
 
 
27
  // -------------------------------------------------------------------------
 
28
  // - private section                                                       -
 
29
  // -------------------------------------------------------------------------
 
30
 
 
31
  // the cipher list definition
 
32
  static const TlsSuite::s_cinfo TLS_LIST_CFR[7] {
 
33
    // 0x00, 0x00
 
34
    {"TLS_NULL_WITH_NULL_NULL",      "2246", "1.0", "", 0x0000U,
 
35
     TlsSuite::TLS_EXCH_NIL, 
 
36
     TlsSuite::TLS_CIFR_NIL, TlsSuite::TLS_CPAD_NIL, 0L,
 
37
          TlsSuite::TLS_HASH_NIL, 0L},
 
38
    // 0x00, 0x01
 
39
    {"TLS_RSA_WITH_NULL_MD5",        "2246", "1.0", "", 0x0001U,
 
40
     TlsSuite::TLS_EXCH_RSA, 
 
41
     TlsSuite::TLS_CIFR_NIL, TlsSuite::TLS_CPAD_NIL, 0L,
 
42
     TlsSuite::TLS_HASH_MD5, 0L},
 
43
    // 0x00, 0x02
 
44
    {"TLS_RSA_WITH_NULL_SHA",        "2246", "1.0", "", 0x0002U,
 
45
     TlsSuite::TLS_EXCH_RSA, 
 
46
     TlsSuite::TLS_CIFR_NIL, TlsSuite::TLS_CPAD_NIL, 0L,
 
47
     TlsSuite::TLS_HASH_SHA, 1L},
 
48
    // 0x00, 0x04
 
49
    {"TLS_RSA_WITH_RC4_128_MD5",     "2246", "1.0", "", 0x0004U,
 
50
     TlsSuite::TLS_EXCH_RSA, 
 
51
     TlsSuite::TLS_CIFR_RC4, TlsSuite::TLS_CPAD_NIL, 128L,
 
52
     TlsSuite::TLS_HASH_MD5, 0L},
 
53
    // 0x00, 0x05
 
54
    {"TLS_RSA_WITH_RC4_128_SHA",     "2246", "1.0", "", 0x0005U,
 
55
     TlsSuite::TLS_EXCH_RSA, 
 
56
     TlsSuite::TLS_CIFR_RC4, TlsSuite::TLS_CPAD_NIL, 128L,
 
57
     TlsSuite::TLS_HASH_SHA, 1L},
 
58
    // 0x00, 0x2F
 
59
    {"TLS_RSA_WITH_AES_128_CBC_SHA", "3268", "1.0", "", 0x002FU,
 
60
     TlsSuite::TLS_EXCH_RSA, 
 
61
     TlsSuite::TLS_CIFR_AES, TlsSuite::TLS_CPAD_CBC, 128L,
 
62
     TlsSuite::TLS_HASH_SHA, 1L},
 
63
    // 0x00, 0x35
 
64
    {"TLS_RSA_WITH_AES_256_CBC_SHA", "3268", "1.0", "", 0x0035U,
 
65
     TlsSuite::TLS_EXCH_RSA, 
 
66
     TlsSuite::TLS_CIFR_AES, TlsSuite::TLS_CPAD_CBC, 256L,
 
67
        TlsSuite::TLS_HASH_SHA, 1L}
 
68
  };
 
69
  // the cipher list size
 
70
  static const long TLS_SIZE_CFR = 
 
71
    sizeof (TLS_LIST_CFR) / sizeof (TlsSuite::s_cinfo);
 
72
 
 
73
  // find a cipher info structure index by code
 
74
  static inline long tls_find_cinfo (const t_word code) {
 
75
    for (long k = 0L; k < TLS_SIZE_CFR; k++) {
 
76
      if (TLS_LIST_CFR[k].d_code == code) return k;
 
77
    }
 
78
    // not found
 
79
    return -1;
 
80
  }
 
81
 
 
82
  // convert a tls code into a string representation
 
83
  static inline String tls_to_string (const t_word code) {
 
84
    t_byte ucod = (t_byte) (code >> 8);
 
85
    t_byte lcod = (t_byte) (code & 0x00FF);
 
86
    String sval = Utility::tohexa (ucod, true, true) + ", " +
 
87
      Utility::tohexa (lcod, true, true);
 
88
    return sval;
 
89
  }
 
90
 
 
91
  // fill a property list with a cipher info by index
 
92
  static Plist& tls_add_plist (Plist& plst, const TlsSuite::s_cinfo& cinf) {
 
93
    // get name and info
 
94
    String name = cinf.d_name;
 
95
    String info = cinf.d_rfcr + ':' + cinf.d_vmin + ':' + cinf.d_vmax;
 
96
    String scod = tls_to_string (cinf.d_code);
 
97
    plst.add (name, info, scod);
 
98
    return plst;
 
99
  }
 
100
 
 
101
  // get a cipher info print table
 
102
  static PrintTable* tls_get_table (void) {
 
103
    // create a five columns table
 
104
    PrintTable* ptbl = new PrintTable (5);
 
105
    // set the header
 
106
    ptbl->sethead (0, "NAME");
 
107
    ptbl->sethead (1, "RFC");
 
108
    ptbl->sethead (2, "MINV");
 
109
    ptbl->sethead (3, "MAXV");
 
110
    ptbl->sethead (4, "CODE");
 
111
    // loop and fill table
 
112
    for (long k = 0L; k < TLS_SIZE_CFR; k++) {
 
113
      long row = ptbl->add ();
 
114
      ptbl->set (row, 0, TLS_LIST_CFR[k].d_name);
 
115
      ptbl->set (row, 1, TLS_LIST_CFR[k].d_rfcr);
 
116
      ptbl->set (row, 2, TLS_LIST_CFR[k].d_vmin);
 
117
      ptbl->set (row, 3, TLS_LIST_CFR[k].d_vmax);
 
118
      ptbl->set (row, 4, tls_to_string (TLS_LIST_CFR[k].d_code));
 
119
    }
 
120
    return ptbl;
 
121
  }
 
122
 
 
123
  // -------------------------------------------------------------------------
 
124
  // - public section                                                        -
 
125
  // -------------------------------------------------------------------------
 
126
 
 
127
  // create a default cipher info structure
 
128
 
 
129
  TlsSuite::s_cinfo::s_cinfo (void) {
 
130
    d_name = "TLS_NULL_WITH_NULL_NULL";
 
131
    d_rfcr = "2246";
 
132
    d_vmin = "1.0";
 
133
    d_vmax = "";
 
134
    d_code = 0x0000U;
 
135
    d_exch = TLS_EXCH_NIL;
 
136
    d_cifr = TLS_CIFR_NIL;
 
137
    d_cpad = TLS_CPAD_NIL;
 
138
    d_csiz = 0L;
 
139
    d_hash = TLS_HASH_NIL;
 
140
    d_hsiz = 0L;
 
141
  }
 
142
 
 
143
  // create a cipher with a brace initializer list
 
144
 
 
145
  TlsSuite::s_cinfo::s_cinfo (const String& name, const String& rfcr, 
 
146
                              const String& vmin, const String& vmax, 
 
147
                              const t_word  code, const t_exch  exch,
 
148
                              const t_cifr  cifr, const t_cpad  cpad,
 
149
                              const long    csiz, const t_hash  hash,
 
150
                              const long    hsiz) {
 
151
    d_name = name;
 
152
    d_rfcr = rfcr;
 
153
    d_vmin = vmin;
 
154
    d_vmax = vmax;
 
155
    d_code = code;
 
156
    d_exch = exch;
 
157
    d_cifr = cifr;
 
158
    d_cpad = cpad;
 
159
    d_csiz = csiz;
 
160
    d_hash = hash;
 
161
    d_hsiz = hsiz;
 
162
  }
 
163
  
 
164
  // copy construct this cipher info
 
165
 
 
166
  TlsSuite::s_cinfo::s_cinfo (const s_cinfo& that) {
 
167
    d_name = that.d_name;
 
168
    d_rfcr = that.d_rfcr;
 
169
    d_vmin = that.d_vmin;
 
170
    d_vmax = that.d_vmax;
 
171
    d_code = that.d_code;
 
172
    d_exch = that.d_exch;
 
173
    d_cifr = that.d_cifr;
 
174
    d_cpad = that.d_cpad;
 
175
    d_csiz = that.d_csiz;
 
176
    d_hash = that.d_hash;
 
177
    d_hsiz = that.d_hsiz;
 
178
  }
 
179
 
 
180
  // assign a cipher info to this one
 
181
 
 
182
  TlsSuite::s_cinfo& TlsSuite::s_cinfo::operator = (const s_cinfo& that) {
 
183
    // check for self-assignation
 
184
    if (this == &that) return *this;
 
185
    // assign localy
 
186
    d_name = that.d_name;
 
187
    d_rfcr = that.d_rfcr;
 
188
    d_vmin = that.d_vmin;
 
189
    d_vmax = that.d_vmax;
 
190
    d_code = that.d_code;
 
191
    d_exch = that.d_exch;
 
192
    d_cifr = that.d_cifr;
 
193
    d_cpad = that.d_cpad;
 
194
    d_csiz = that.d_csiz;
 
195
    d_hash = that.d_hash;
 
196
    d_hsiz = that.d_hsiz;
 
197
    return *this;
 
198
  }
 
199
 
 
200
  // convert a cipher code to a word
 
201
  
 
202
  t_word TlsSuite::toword (const t_byte ucod, const t_byte lcod) {
 
203
    t_word result = ucod;
 
204
    result = result << 8; result += lcod;
 
205
    return result;
 
206
  }
 
207
 
 
208
  // convert a tls suite code to a upper code
 
209
 
 
210
  t_byte TlsSuite::toucod (const t_word code) {
 
211
    t_byte result = (t_byte) (code >> 8);
 
212
    return result;
 
213
  }
 
214
 
 
215
  // convert a tls suite code to a lpper code
 
216
 
 
217
  t_byte TlsSuite::tolcod (const t_word code) {
 
218
    t_byte result = (t_byte) (code & 0x0FU);
 
219
    return result;
 
220
  }
 
221
 
 
222
  // -------------------------------------------------------------------------
 
223
  // - class section                                                         -
 
224
  // -------------------------------------------------------------------------
 
225
 
 
226
  // create a default suite
 
227
 
 
228
  TlsSuite::TlsSuite (void) {
 
229
    d_size = 0L;
 
230
    d_slen = 0L;
 
231
    p_slst = nilp;
 
232
  }
 
233
 
 
234
  // create a suite by size
 
235
 
 
236
  TlsSuite::TlsSuite (const long size) {
 
237
    if (size < 0L) {
 
238
      throw Exception ("tls-error", "invalid suite size");
 
239
    }
 
240
    d_size = size;
 
241
    d_slen = 0L;
 
242
    p_slst = (d_size == 0L) ? nilp : new t_word[d_size];
 
243
    reset ();
 
244
  }
 
245
 
 
246
  // destroy this suite
 
247
 
 
248
  TlsSuite::~TlsSuite (void) {
 
249
    reset ();
 
250
    delete [] p_slst;
 
251
  }
 
252
 
 
253
  // return the class name
 
254
  
 
255
  String TlsSuite::repr (void) const {
 
256
    return "TlsSuite";
 
257
  }
 
258
 
 
259
  // reset the 
 
260
 
 
261
  void TlsSuite::reset (void) {
 
262
    wrlock ();
 
263
    try {
 
264
      d_slen = 0L;
 
265
      for (long k = 0L; k < d_size; k++) p_slst[k] = nilw;
 
266
      unlock ();
 
267
    } catch (...) {
 
268
      unlock ();
 
269
      throw;
 
270
    }
 
271
  }
 
272
 
 
273
  // get the cipher list info as a plist
 
274
 
 
275
  Plist TlsSuite::getinfo (void) const {
 
276
    rdlock ();
 
277
    try {
 
278
      // create a result plist
 
279
      Plist plst;
 
280
      // loop in the list
 
281
      for (long k = 0L; k < d_slen; k++) {
 
282
        if (isvalid (p_slst[k]) == true) {
 
283
          tls_add_plist (plst, getcinfo (p_slst[k]));
 
284
        }
 
285
      }
 
286
      // here it is
 
287
      unlock ();
 
288
      return plst;
 
289
    } catch (...) {
 
290
      unlock ();
 
291
      throw;
 
292
    }
 
293
  }
 
294
 
 
295
  // get the number of ciphers in the list
 
296
 
 
297
  long TlsSuite::length (void) const {
 
298
    rdlock ();
 
299
    try {
 
300
      long result = d_slen;
 
301
      unlock ();
 
302
      return result;
 
303
    } catch (...) {
 
304
      unlock ();
 
305
      throw;
 
306
    }
 
307
  }
 
308
 
 
309
  // pop the first valid cipher code
 
310
 
 
311
  t_word TlsSuite::pop (void) const {
 
312
    rdlock ();
 
313
    try {
 
314
      for (long k = 0L; k < d_slen; k++) {
 
315
        if (isvalid (p_slst[k]) == true) {
 
316
          t_word result = p_slst[k];
 
317
          unlock ();
 
318
          return result;
 
319
        }
 
320
      }
 
321
      unlock ();
 
322
    } catch (...) {
 
323
      unlock ();
 
324
      throw;
 
325
    }
 
326
    throw Exception ("tls-error", "cannot find any valid cipher");
 
327
  }
 
328
 
 
329
  // get a tls suite code by index
 
330
 
 
331
  t_word TlsSuite::get (const long idx) const {
 
332
    rdlock ();
 
333
    try {
 
334
      if ((idx < 0L) || (idx >= d_slen)) {
 
335
        throw Exception ("tls-error", "invalid tls suite index");
 
336
      }
 
337
      t_word result = p_slst[idx];
 
338
      unlock ();
 
339
      return result;
 
340
    } catch (...) {
 
341
      unlock ();
 
342
      throw;
 
343
    }
 
344
  }
 
345
 
 
346
  // add a new cipher in the list by code
 
347
 
 
348
  void TlsSuite::add (const t_word code) {
 
349
    wrlock ();
 
350
    try {
 
351
      // check size invariant
 
352
      if (d_slen > d_size) {
 
353
        throw Exception ("internal-error", "inconsisten tls suite size");
 
354
      }
 
355
      // check for resize
 
356
      if (d_slen == d_size) {
 
357
        long    size = (d_size == 0L) ? 1L : 2L * d_size;
 
358
        t_word* slst = new t_word[size];
 
359
        for (long k = 0;      k < d_size; k++) slst[k] = p_slst[k];
 
360
        for (long k = d_size; k < size;   k++) slst[k] = nilw;
 
361
        d_size = size;
 
362
        delete [] p_slst; p_slst = slst;
 
363
      }
 
364
      // here it is
 
365
      p_slst[d_slen++] = code;
 
366
      unlock ();
 
367
    } catch (...) {
 
368
      unlock ();
 
369
      throw;
 
370
    }
 
371
  }
 
372
 
 
373
  // add a new cipher in the list by tls code
 
374
  
 
375
  void TlsSuite::add (const t_byte ucod, const t_byte lcod) {
 
376
    wrlock ();
 
377
    try {
 
378
      // convert into a word code
 
379
      t_word code = TlsSuite::toword (ucod, lcod);
 
380
      // and now push it
 
381
      add (code);
 
382
      unlock ();
 
383
    } catch (...) {
 
384
      unlock ();
 
385
      throw;
 
386
    }
 
387
  }
 
388
  
 
389
  // check if a cipher is valid by code
 
390
 
 
391
  bool TlsSuite::isvalid (const t_word code) const {
 
392
    rdlock ();
 
393
    try {
 
394
      // find a standard structure info index by code
 
395
      long cidx = tls_find_cinfo (code);
 
396
      // format result
 
397
      bool result = (cidx == -1) ? false : true;
 
398
      unlock ();
 
399
      return result;
 
400
    } catch (...) {
 
401
      unlock ();
 
402
      throw;
 
403
    }
 
404
  }
 
405
 
 
406
  // check if a cipher is valid by code
 
407
  
 
408
  bool TlsSuite::isvalid (const t_byte ucod, const t_byte lcod) const {
 
409
    rdlock ();
 
410
    try {
 
411
      // convert into a word code
 
412
      t_word code = TlsSuite::toword (ucod, lcod);
 
413
      // and now test for it
 
414
      bool result = isvalid (code);
 
415
      unlock ();
 
416
      return result;
 
417
    } catch (...) {
 
418
      unlock ();
 
419
      throw;
 
420
    }
 
421
  }
 
422
 
 
423
  // find a cipher info structure by code
 
424
 
 
425
  TlsSuite::s_cinfo TlsSuite::getcinfo (const t_word code) const {
 
426
    rdlock ();
 
427
    try {
 
428
      // find a standard structure info index by code
 
429
      long cidx = tls_find_cinfo (code);
 
430
      if (cidx == -1) {
 
431
        throw Exception ("tls-error", "cannot find cipher info with code",
 
432
                         Utility::tohexa (code, true, true));
 
433
      }
 
434
      TlsSuite::s_cinfo result = TLS_LIST_CFR[cidx];
 
435
      unlock ();
 
436
      return result;
 
437
    } catch (...) {
 
438
      unlock ();
 
439
      throw;
 
440
    }
 
441
  }
 
442
 
 
443
  // find a cipher info structure by tls code
 
444
 
 
445
  TlsSuite::s_cinfo TlsSuite::getcinfo (const t_byte ucod, 
 
446
                                        const t_byte lcod) const {
 
447
    rdlock ();
 
448
    try {
 
449
      // convert into a word code
 
450
      t_word code = TlsSuite::toword (ucod, lcod);
 
451
      // and get the cipher info
 
452
      TlsSuite::s_cinfo result = getcinfo (code);
 
453
      unlock ();
 
454
      return result;
 
455
    } catch (...) {
 
456
      unlock ();
 
457
      throw;
 
458
    }
 
459
  }
 
460
 
 
461
  // get cipher suite as a print table
 
462
 
 
463
  PrintTable* TlsSuite::gettinfo (void) const {
 
464
    rdlock ();
 
465
    try {
 
466
      PrintTable* result = tls_get_table ();
 
467
      unlock ();
 
468
      return result;
 
469
    } catch (...) {
 
470
      unlock ();
 
471
      throw;
 
472
    }
 
473
  }
 
474
 
 
475
  // -------------------------------------------------------------------------
 
476
  // - object section                                                        -
 
477
  // -------------------------------------------------------------------------
 
478
 
 
479
  // the quark zone
 
480
  static const long QUARK_ZONE_LENGTH = 3;
 
481
  static QuarkZone  zone (QUARK_ZONE_LENGTH);
 
482
 
 
483
  // the object supported quarks
 
484
  static const long QUARK_LENGTH   = zone.intern ("length");
 
485
  static const long QUARK_VALIDP   = zone.intern ("valid-p");
 
486
  static const long QUARK_GETTINFO = zone.intern ("get-info-table");
 
487
 
 
488
  // create a new object in a generic way
 
489
 
 
490
  Object* TlsSuite::mknew (Vector* argv) {
 
491
    // get the number of arguments
 
492
    long argc = (argv == nilp) ? 0 : argv->length ();
 
493
    
 
494
    // check for 0 argument
 
495
    if (argc == 0) return new TlsSuite;
 
496
    // check for 1 argument
 
497
    if (argc == 1) {
 
498
      long size = argv->getlong (0);
 
499
      return new TlsSuite (size);
 
500
    }
 
501
    // too many arguments
 
502
    throw Exception ("argument-error", 
 
503
                     "too many argument with tls cipher suite");
 
504
  }
 
505
 
 
506
  // return true if the given quark is defined
 
507
 
 
508
  bool TlsSuite::isquark (const long quark, const bool hflg) const {
 
509
    rdlock ();
 
510
    if (zone.exists (quark) == true) {
 
511
      unlock ();
 
512
      return true;
 
513
    }
 
514
    bool result = hflg ? TlsInfos::isquark (quark, hflg) : false;
 
515
    unlock ();
 
516
    return result;
 
517
  }
 
518
  
 
519
  // apply this object with a set of arguments and a quark
 
520
 
 
521
  Object* TlsSuite::apply (Runnable* robj, Nameset* nset, const long quark,
 
522
                           Vector* argv) {
 
523
    // get the number of arguments
 
524
    long argc = (argv == nilp) ? 0 : argv->length ();
 
525
    
 
526
    // check for 0 argument
 
527
    if (argc == 0) {
 
528
      if (quark == QUARK_LENGTH)   return new Integer (length ());
 
529
      if (quark == QUARK_GETTINFO) return gettinfo ();
 
530
    }
 
531
    // check for 1 argument
 
532
    if (argc == 1) {
 
533
      if (quark == QUARK_VALIDP) {
 
534
        t_word code = argv->getword (0);
 
535
        return new Boolean (isvalid (code));
 
536
      }
 
537
    }
 
538
    // call the tls infos method
 
539
    return TlsInfos::apply (robj, nset, quark, argv);
 
540
  }
 
541
}