Browse Source

Added tqca package to the sources tree. This module is from

the original qca-1.0 sources with the TQt layer added.
This resolves bug report 817.
tags/r14.0.0
Darrell Anderson 7 years ago
commit
c663e43e71

+ 504
- 0
COPYING View File

@@ -0,0 +1,504 @@
1
+		  GNU LESSER GENERAL PUBLIC LICENSE
2
+		       Version 2.1, February 1999
3
+
4
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+[This is the first released version of the Lesser GPL.  It also counts
10
+ as the successor of the GNU Library Public License, version 2, hence
11
+ the version number 2.1.]
12
+
13
+			    Preamble
14
+
15
+  The licenses for most software are designed to take away your
16
+freedom to share and change it.  By contrast, the GNU General Public
17
+Licenses are intended to guarantee your freedom to share and change
18
+free software--to make sure the software is free for all its users.
19
+
20
+  This license, the Lesser General Public License, applies to some
21
+specially designated software packages--typically libraries--of the
22
+Free Software Foundation and other authors who decide to use it.  You
23
+can use it too, but we suggest you first think carefully about whether
24
+this license or the ordinary General Public License is the better
25
+strategy to use in any particular case, based on the explanations below.
26
+
27
+  When we speak of free software, we are referring to freedom of use,
28
+not price.  Our General Public Licenses are designed to make sure that
29
+you have the freedom to distribute copies of free software (and charge
30
+for this service if you wish); that you receive source code or can get
31
+it if you want it; that you can change the software and use pieces of
32
+it in new free programs; and that you are informed that you can do
33
+these things.
34
+
35
+  To protect your rights, we need to make restrictions that forbid
36
+distributors to deny you these rights or to ask you to surrender these
37
+rights.  These restrictions translate to certain responsibilities for
38
+you if you distribute copies of the library or if you modify it.
39
+
40
+  For example, if you distribute copies of the library, whether gratis
41
+or for a fee, you must give the recipients all the rights that we gave
42
+you.  You must make sure that they, too, receive or can get the source
43
+code.  If you link other code with the library, you must provide
44
+complete object files to the recipients, so that they can relink them
45
+with the library after making changes to the library and recompiling
46
+it.  And you must show them these terms so they know their rights.
47
+
48
+  We protect your rights with a two-step method: (1) we copyright the
49
+library, and (2) we offer you this license, which gives you legal
50
+permission to copy, distribute and/or modify the library.
51
+
52
+  To protect each distributor, we want to make it very clear that
53
+there is no warranty for the free library.  Also, if the library is
54
+modified by someone else and passed on, the recipients should know
55
+that what they have is not the original version, so that the original
56
+author's reputation will not be affected by problems that might be
57
+introduced by others.
58
+
59
+  Finally, software patents pose a constant threat to the existence of
60
+any free program.  We wish to make sure that a company cannot
61
+effectively restrict the users of a free program by obtaining a
62
+restrictive license from a patent holder.  Therefore, we insist that
63
+any patent license obtained for a version of the library must be
64
+consistent with the full freedom of use specified in this license.
65
+
66
+  Most GNU software, including some libraries, is covered by the
67
+ordinary GNU General Public License.  This license, the GNU Lesser
68
+General Public License, applies to certain designated libraries, and
69
+is quite different from the ordinary General Public License.  We use
70
+this license for certain libraries in order to permit linking those
71
+libraries into non-free programs.
72
+
73
+  When a program is linked with a library, whether statically or using
74
+a shared library, the combination of the two is legally speaking a
75
+combined work, a derivative of the original library.  The ordinary
76
+General Public License therefore permits such linking only if the
77
+entire combination fits its criteria of freedom.  The Lesser General
78
+Public License permits more lax criteria for linking other code with
79
+the library.
80
+
81
+  We call this license the "Lesser" General Public License because it
82
+does Less to protect the user's freedom than the ordinary General
83
+Public License.  It also provides other free software developers Less
84
+of an advantage over competing non-free programs.  These disadvantages
85
+are the reason we use the ordinary General Public License for many
86
+libraries.  However, the Lesser license provides advantages in certain
87
+special circumstances.
88
+
89
+  For example, on rare occasions, there may be a special need to
90
+encourage the widest possible use of a certain library, so that it becomes
91
+a de-facto standard.  To achieve this, non-free programs must be
92
+allowed to use the library.  A more frequent case is that a free
93
+library does the same job as widely used non-free libraries.  In this
94
+case, there is little to gain by limiting the free library to free
95
+software only, so we use the Lesser General Public License.
96
+
97
+  In other cases, permission to use a particular library in non-free
98
+programs enables a greater number of people to use a large body of
99
+free software.  For example, permission to use the GNU C Library in
100
+non-free programs enables many more people to use the whole GNU
101
+operating system, as well as its variant, the GNU/Linux operating
102
+system.
103
+
104
+  Although the Lesser General Public License is Less protective of the
105
+users' freedom, it does ensure that the user of a program that is
106
+linked with the Library has the freedom and the wherewithal to run
107
+that program using a modified version of the Library.
108
+
109
+  The precise terms and conditions for copying, distribution and
110
+modification follow.  Pay close attention to the difference between a
111
+"work based on the library" and a "work that uses the library".  The
112
+former contains code derived from the library, whereas the latter must
113
+be combined with the library in order to run.
114
+
115
+		  GNU LESSER GENERAL PUBLIC LICENSE
116
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
+
118
+  0. This License Agreement applies to any software library or other
119
+program which contains a notice placed by the copyright holder or
120
+other authorized party saying it may be distributed under the terms of
121
+this Lesser General Public License (also called "this License").
122
+Each licensee is addressed as "you".
123
+
124
+  A "library" means a collection of software functions and/or data
125
+prepared so as to be conveniently linked with application programs
126
+(which use some of those functions and data) to form executables.
127
+
128
+  The "Library", below, refers to any such software library or work
129
+which has been distributed under these terms.  A "work based on the
130
+Library" means either the Library or any derivative work under
131
+copyright law: that is to say, a work containing the Library or a
132
+portion of it, either verbatim or with modifications and/or translated
133
+straightforwardly into another language.  (Hereinafter, translation is
134
+included without limitation in the term "modification".)
135
+
136
+  "Source code" for a work means the preferred form of the work for
137
+making modifications to it.  For a library, complete source code means
138
+all the source code for all modules it contains, plus any associated
139
+interface definition files, plus the scripts used to control compilation
140
+and installation of the library.
141
+
142
+  Activities other than copying, distribution and modification are not
143
+covered by this License; they are outside its scope.  The act of
144
+running a program using the Library is not restricted, and output from
145
+such a program is covered only if its contents constitute a work based
146
+on the Library (independent of the use of the Library in a tool for
147
+writing it).  Whether that is true depends on what the Library does
148
+and what the program that uses the Library does.
149
+  
150
+  1. You may copy and distribute verbatim copies of the Library's
151
+complete source code as you receive it, in any medium, provided that
152
+you conspicuously and appropriately publish on each copy an
153
+appropriate copyright notice and disclaimer of warranty; keep intact
154
+all the notices that refer to this License and to the absence of any
155
+warranty; and distribute a copy of this License along with the
156
+Library.
157
+
158
+  You may charge a fee for the physical act of transferring a copy,
159
+and you may at your option offer warranty protection in exchange for a
160
+fee.
161
+
162
+  2. You may modify your copy or copies of the Library or any portion
163
+of it, thus forming a work based on the Library, and copy and
164
+distribute such modifications or work under the terms of Section 1
165
+above, provided that you also meet all of these conditions:
166
+
167
+    a) The modified work must itself be a software library.
168
+
169
+    b) You must cause the files modified to carry prominent notices
170
+    stating that you changed the files and the date of any change.
171
+
172
+    c) You must cause the whole of the work to be licensed at no
173
+    charge to all third parties under the terms of this License.
174
+
175
+    d) If a facility in the modified Library refers to a function or a
176
+    table of data to be supplied by an application program that uses
177
+    the facility, other than as an argument passed when the facility
178
+    is invoked, then you must make a good faith effort to ensure that,
179
+    in the event an application does not supply such function or
180
+    table, the facility still operates, and performs whatever part of
181
+    its purpose remains meaningful.
182
+
183
+    (For example, a function in a library to compute square roots has
184
+    a purpose that is entirely well-defined independent of the
185
+    application.  Therefore, Subsection 2d requires that any
186
+    application-supplied function or table used by this function must
187
+    be optional: if the application does not supply it, the square
188
+    root function must still compute square roots.)
189
+
190
+These requirements apply to the modified work as a whole.  If
191
+identifiable sections of that work are not derived from the Library,
192
+and can be reasonably considered independent and separate works in
193
+themselves, then this License, and its terms, do not apply to those
194
+sections when you distribute them as separate works.  But when you
195
+distribute the same sections as part of a whole which is a work based
196
+on the Library, the distribution of the whole must be on the terms of
197
+this License, whose permissions for other licensees extend to the
198
+entire whole, and thus to each and every part regardless of who wrote
199
+it.
200
+
201
+Thus, it is not the intent of this section to claim rights or contest
202
+your rights to work written entirely by you; rather, the intent is to
203
+exercise the right to control the distribution of derivative or
204
+collective works based on the Library.
205
+
206
+In addition, mere aggregation of another work not based on the Library
207
+with the Library (or with a work based on the Library) on a volume of
208
+a storage or distribution medium does not bring the other work under
209
+the scope of this License.
210
+
211
+  3. You may opt to apply the terms of the ordinary GNU General Public
212
+License instead of this License to a given copy of the Library.  To do
213
+this, you must alter all the notices that refer to this License, so
214
+that they refer to the ordinary GNU General Public License, version 2,
215
+instead of to this License.  (If a newer version than version 2 of the
216
+ordinary GNU General Public License has appeared, then you can specify
217
+that version instead if you wish.)  Do not make any other change in
218
+these notices.
219
+
220
+  Once this change is made in a given copy, it is irreversible for
221
+that copy, so the ordinary GNU General Public License applies to all
222
+subsequent copies and derivative works made from that copy.
223
+
224
+  This option is useful when you wish to copy part of the code of
225
+the Library into a program that is not a library.
226
+
227
+  4. You may copy and distribute the Library (or a portion or
228
+derivative of it, under Section 2) in object code or executable form
229
+under the terms of Sections 1 and 2 above provided that you accompany
230
+it with the complete corresponding machine-readable source code, which
231
+must be distributed under the terms of Sections 1 and 2 above on a
232
+medium customarily used for software interchange.
233
+
234
+  If distribution of object code is made by offering access to copy
235
+from a designated place, then offering equivalent access to copy the
236
+source code from the same place satisfies the requirement to
237
+distribute the source code, even though third parties are not
238
+compelled to copy the source along with the object code.
239
+
240
+  5. A program that contains no derivative of any portion of the
241
+Library, but is designed to work with the Library by being compiled or
242
+linked with it, is called a "work that uses the Library".  Such a
243
+work, in isolation, is not a derivative work of the Library, and
244
+therefore falls outside the scope of this License.
245
+
246
+  However, linking a "work that uses the Library" with the Library
247
+creates an executable that is a derivative of the Library (because it
248
+contains portions of the Library), rather than a "work that uses the
249
+library".  The executable is therefore covered by this License.
250
+Section 6 states terms for distribution of such executables.
251
+
252
+  When a "work that uses the Library" uses material from a header file
253
+that is part of the Library, the object code for the work may be a
254
+derivative work of the Library even though the source code is not.
255
+Whether this is true is especially significant if the work can be
256
+linked without the Library, or if the work is itself a library.  The
257
+threshold for this to be true is not precisely defined by law.
258
+
259
+  If such an object file uses only numerical parameters, data
260
+structure layouts and accessors, and small macros and small inline
261
+functions (ten lines or less in length), then the use of the object
262
+file is unrestricted, regardless of whether it is legally a derivative
263
+work.  (Executables containing this object code plus portions of the
264
+Library will still fall under Section 6.)
265
+
266
+  Otherwise, if the work is a derivative of the Library, you may
267
+distribute the object code for the work under the terms of Section 6.
268
+Any executables containing that work also fall under Section 6,
269
+whether or not they are linked directly with the Library itself.
270
+
271
+  6. As an exception to the Sections above, you may also combine or
272
+link a "work that uses the Library" with the Library to produce a
273
+work containing portions of the Library, and distribute that work
274
+under terms of your choice, provided that the terms permit
275
+modification of the work for the customer's own use and reverse
276
+engineering for debugging such modifications.
277
+
278
+  You must give prominent notice with each copy of the work that the
279
+Library is used in it and that the Library and its use are covered by
280
+this License.  You must supply a copy of this License.  If the work
281
+during execution displays copyright notices, you must include the
282
+copyright notice for the Library among them, as well as a reference
283
+directing the user to the copy of this License.  Also, you must do one
284
+of these things:
285
+
286
+    a) Accompany the work with the complete corresponding
287
+    machine-readable source code for the Library including whatever
288
+    changes were used in the work (which must be distributed under
289
+    Sections 1 and 2 above); and, if the work is an executable linked
290
+    with the Library, with the complete machine-readable "work that
291
+    uses the Library", as object code and/or source code, so that the
292
+    user can modify the Library and then relink to produce a modified
293
+    executable containing the modified Library.  (It is understood
294
+    that the user who changes the contents of definitions files in the
295
+    Library will not necessarily be able to recompile the application
296
+    to use the modified definitions.)
297
+
298
+    b) Use a suitable shared library mechanism for linking with the
299
+    Library.  A suitable mechanism is one that (1) uses at run time a
300
+    copy of the library already present on the user's computer system,
301
+    rather than copying library functions into the executable, and (2)
302
+    will operate properly with a modified version of the library, if
303
+    the user installs one, as long as the modified version is
304
+    interface-compatible with the version that the work was made with.
305
+
306
+    c) Accompany the work with a written offer, valid for at
307
+    least three years, to give the same user the materials
308
+    specified in Subsection 6a, above, for a charge no more
309
+    than the cost of performing this distribution.
310
+
311
+    d) If distribution of the work is made by offering access to copy
312
+    from a designated place, offer equivalent access to copy the above
313
+    specified materials from the same place.
314
+
315
+    e) Verify that the user has already received a copy of these
316
+    materials or that you have already sent this user a copy.
317
+
318
+  For an executable, the required form of the "work that uses the
319
+Library" must include any data and utility programs needed for
320
+reproducing the executable from it.  However, as a special exception,
321
+the materials to be distributed need not include anything that is
322
+normally distributed (in either source or binary form) with the major
323
+components (compiler, kernel, and so on) of the operating system on
324
+which the executable runs, unless that component itself accompanies
325
+the executable.
326
+
327
+  It may happen that this requirement contradicts the license
328
+restrictions of other proprietary libraries that do not normally
329
+accompany the operating system.  Such a contradiction means you cannot
330
+use both them and the Library together in an executable that you
331
+distribute.
332
+
333
+  7. You may place library facilities that are a work based on the
334
+Library side-by-side in a single library together with other library
335
+facilities not covered by this License, and distribute such a combined
336
+library, provided that the separate distribution of the work based on
337
+the Library and of the other library facilities is otherwise
338
+permitted, and provided that you do these two things:
339
+
340
+    a) Accompany the combined library with a copy of the same work
341
+    based on the Library, uncombined with any other library
342
+    facilities.  This must be distributed under the terms of the
343
+    Sections above.
344
+
345
+    b) Give prominent notice with the combined library of the fact
346
+    that part of it is a work based on the Library, and explaining
347
+    where to find the accompanying uncombined form of the same work.
348
+
349
+  8. You may not copy, modify, sublicense, link with, or distribute
350
+the Library except as expressly provided under this License.  Any
351
+attempt otherwise to copy, modify, sublicense, link with, or
352
+distribute the Library is void, and will automatically terminate your
353
+rights under this License.  However, parties who have received copies,
354
+or rights, from you under this License will not have their licenses
355
+terminated so long as such parties remain in full compliance.
356
+
357
+  9. You are not required to accept this License, since you have not
358
+signed it.  However, nothing else grants you permission to modify or
359
+distribute the Library or its derivative works.  These actions are
360
+prohibited by law if you do not accept this License.  Therefore, by
361
+modifying or distributing the Library (or any work based on the
362
+Library), you indicate your acceptance of this License to do so, and
363
+all its terms and conditions for copying, distributing or modifying
364
+the Library or works based on it.
365
+
366
+  10. Each time you redistribute the Library (or any work based on the
367
+Library), the recipient automatically receives a license from the
368
+original licensor to copy, distribute, link with or modify the Library
369
+subject to these terms and conditions.  You may not impose any further
370
+restrictions on the recipients' exercise of the rights granted herein.
371
+You are not responsible for enforcing compliance by third parties with
372
+this License.
373
+
374
+  11. If, as a consequence of a court judgment or allegation of patent
375
+infringement or for any other reason (not limited to patent issues),
376
+conditions are imposed on you (whether by court order, agreement or
377
+otherwise) that contradict the conditions of this License, they do not
378
+excuse you from the conditions of this License.  If you cannot
379
+distribute so as to satisfy simultaneously your obligations under this
380
+License and any other pertinent obligations, then as a consequence you
381
+may not distribute the Library at all.  For example, if a patent
382
+license would not permit royalty-free redistribution of the Library by
383
+all those who receive copies directly or indirectly through you, then
384
+the only way you could satisfy both it and this License would be to
385
+refrain entirely from distribution of the Library.
386
+
387
+If any portion of this section is held invalid or unenforceable under any
388
+particular circumstance, the balance of the section is intended to apply,
389
+and the section as a whole is intended to apply in other circumstances.
390
+
391
+It is not the purpose of this section to induce you to infringe any
392
+patents or other property right claims or to contest validity of any
393
+such claims; this section has the sole purpose of protecting the
394
+integrity of the free software distribution system which is
395
+implemented by public license practices.  Many people have made
396
+generous contributions to the wide range of software distributed
397
+through that system in reliance on consistent application of that
398
+system; it is up to the author/donor to decide if he or she is willing
399
+to distribute software through any other system and a licensee cannot
400
+impose that choice.
401
+
402
+This section is intended to make thoroughly clear what is believed to
403
+be a consequence of the rest of this License.
404
+
405
+  12. If the distribution and/or use of the Library is restricted in
406
+certain countries either by patents or by copyrighted interfaces, the
407
+original copyright holder who places the Library under this License may add
408
+an explicit geographical distribution limitation excluding those countries,
409
+so that distribution is permitted only in or among countries not thus
410
+excluded.  In such case, this License incorporates the limitation as if
411
+written in the body of this License.
412
+
413
+  13. The Free Software Foundation may publish revised and/or new
414
+versions of the Lesser General Public License from time to time.
415
+Such new versions will be similar in spirit to the present version,
416
+but may differ in detail to address new problems or concerns.
417
+
418
+Each version is given a distinguishing version number.  If the Library
419
+specifies a version number of this License which applies to it and
420
+"any later version", you have the option of following the terms and
421
+conditions either of that version or of any later version published by
422
+the Free Software Foundation.  If the Library does not specify a
423
+license version number, you may choose any version ever published by
424
+the Free Software Foundation.
425
+
426
+  14. If you wish to incorporate parts of the Library into other free
427
+programs whose distribution conditions are incompatible with these,
428
+write to the author to ask for permission.  For software which is
429
+copyrighted by the Free Software Foundation, write to the Free
430
+Software Foundation; we sometimes make exceptions for this.  Our
431
+decision will be guided by the two goals of preserving the free status
432
+of all derivatives of our free software and of promoting the sharing
433
+and reuse of software generally.
434
+
435
+			    NO WARRANTY
436
+
437
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
+
447
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456
+DAMAGES.
457
+
458
+		     END OF TERMS AND CONDITIONS
459
+
460
+           How to Apply These Terms to Your New Libraries
461
+
462
+  If you develop a new library, and you want it to be of the greatest
463
+possible use to the public, we recommend making it free software that
464
+everyone can redistribute and change.  You can do so by permitting
465
+redistribution under these terms (or, alternatively, under the terms of the
466
+ordinary General Public License).
467
+
468
+  To apply these terms, attach the following notices to the library.  It is
469
+safest to attach them to the start of each source file to most effectively
470
+convey the exclusion of warranty; and each file should have at least the
471
+"copyright" line and a pointer to where the full notice is found.
472
+
473
+    <one line to give the library's name and a brief idea of what it does.>
474
+    Copyright (C) <year>  <name of author>
475
+
476
+    This library is free software; you can redistribute it and/or
477
+    modify it under the terms of the GNU Lesser General Public
478
+    License as published by the Free Software Foundation; either
479
+    version 2.1 of the License, or (at your option) any later version.
480
+
481
+    This library is distributed in the hope that it will be useful,
482
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
483
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
484
+    Lesser General Public License for more details.
485
+
486
+    You should have received a copy of the GNU Lesser General Public
487
+    License along with this library; if not, write to the Free Software
488
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
489
+
490
+Also add information on how to contact you by electronic and paper mail.
491
+
492
+You should also get your employer (if you work as a programmer) or your
493
+school, if any, to sign a "copyright disclaimer" for the library, if
494
+necessary.  Here is a sample; alter the names:
495
+
496
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
497
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498
+
499
+  <signature of Ty Coon>, 1 April 1990
500
+  Ty Coon, President of Vice
501
+
502
+That's all there is to it!
503
+
504
+

+ 12
- 0
INSTALL View File

@@ -0,0 +1,12 @@
1
+Installing QCA
2
+--------------
3
+
4
+Installation should be straightforward:
5
+
6
+  ./configure
7
+  make
8
+  make install
9
+
10
+NOTE: You may also need to run '/sbin/ldconfig' or a similar tool to
11
+      get the new library files recognized by the system.  If you are
12
+      using Linux, just run it for good measure.

+ 29
- 0
README View File

@@ -0,0 +1,29 @@
1
+Qt Cryptographic Architecture
2
+-----------------------------
3
+Version: API v1.0, Plugin v1
4
+Author: Justin Karneges <justin@affinix.com>
5
+Date: September 10th 2003
6
+
7
+This library provides an easy API for the following features:
8
+
9
+  SSL/TLS
10
+  X509
11
+  SASL
12
+  RSA
13
+  Hashing (SHA1, MD5)
14
+  Ciphers (BlowFish, 3DES, AES)
15
+
16
+Functionality is supplied via plugins.  This is useful for avoiding
17
+dependence on a particular crypto library and makes upgrading easier,
18
+as there is no need to recompile your application when adding or
19
+upgrading a crypto plugin.  Also, by pushing crypto functionality into
20
+plugins, your application is free of legal issues, such as export
21
+regulation.
22
+
23
+And of course, you get a very simple crypto API for Qt, where you can
24
+do things like:
25
+
26
+  TQString hash = QCA::SHA1::hashToString(blockOfData);
27
+
28
+Have fun!
29
+

+ 6
- 0
TODO View File

@@ -0,0 +1,6 @@
1
+* plugins: thread safety ?
2
+
3
+* dsa
4
+* diffie-hellman
5
+* entropy
6
+

+ 492
- 0
configure View File

@@ -0,0 +1,492 @@
1
+#!/bin/sh
2
+
3
+show_usage() {
4
+cat <<EOT
5
+Usage: ./configure [OPTION]...
6
+
7
+This script creates necessary configuration files to build/install.
8
+
9
+Main options:
10
+  --prefix=[path]   Base path for build/install.  Default: /usr/local
11
+  --qtdir=[path]    Directory where Qt is installed.
12
+  --help            This help text.
13
+
14
+EOT
15
+}
16
+
17
+while [ $# -gt 0 ]; do
18
+	case "$1" in
19
+		--prefix=*)
20
+			PREFIX=`expr "${1}" : "--prefix=\(.*\)"`
21
+			shift
22
+			;;
23
+
24
+		--qtdir=*)
25
+			QTDIR=`expr "${1}" : "--qtdir=\(.*\)"`
26
+			shift
27
+			;;
28
+
29
+		--debug)
30
+			QC_DEBUG="Y"
31
+			shift
32
+			;;
33
+		--help) show_usage; exit ;;
34
+		*) show_usage; exit ;;
35
+	esac
36
+done
37
+
38
+PREFIX=${PREFIX:-/usr/local}
39
+
40
+echo "Configuring TQt Cryptographic Architecture (QCA) ..."
41
+
42
+if [ "$QC_DEBUG" = "Y" ]; then
43
+echo
44
+echo PREFIX=$PREFIX
45
+echo QTDIR=$QTDIR
46
+echo
47
+fi
48
+
49
+printf "Verifying TQt 3.x Multithreaded (MT) build environment ... "
50
+
51
+if [ -z "$QTDIR" ]; then
52
+	if [ "$QC_DEBUG" = "Y" ]; then
53
+		echo \$QTDIR not set... trying to find Qt manually
54
+	fi
55
+	for p in /usr/lib/tqt /usr/share/tqt /usr/share/tqt3 /usr/local/lib/tqt /usr/local/share/tqt /usr/lib/tqt3 /usr/local/lib/tqt3 /usr/lib/qt /usr/share/qt /usr/share/qt3 /usr/local/lib/qt /usr/local/share/qt /usr/lib/qt3 /usr/local/lib/qt3 /usr/X11R6/share/qt /usr/qt/3 ; do
56
+		if [ -d "$p/mkspecs" ]; then
57
+			QTDIR=$p
58
+			break;
59
+		fi;
60
+	done
61
+	if [ -z "$QTDIR" ]; then
62
+		echo fail
63
+		echo
64
+		echo Unable to find Qt 'mkspecs'. Please set QTDIR
65
+		echo manually. Perhaps you need to install Qt 3
66
+		echo development utilities. You may download them either
67
+		echo from the vendor of your operating system or from
68
+		echo www.trolltech.com
69
+		echo
70
+		exit 1;
71
+	fi
72
+fi
73
+
74
+if [ ! -x "$QTDIR/bin/qmake" ]; then
75
+	if [ "$QC_DEBUG" = "Y" ]; then
76
+		echo Warning: qmake not in \$QTDIR/bin/qmake
77
+		echo trying to find it in \$PATH
78
+	fi
79
+	qm=`type -p qmake`
80
+	if [ -x "$qm" ]; then
81
+		if [ "$QC_DEBUG" = "Y" ]; then
82
+			echo qmake found in $qm
83
+		fi
84
+	else
85
+		echo fail
86
+		echo
87
+		echo Sorry, you seem to have a very unusual setup,
88
+		echo or I missdetected \$QTDIR=$QTDIR
89
+		echo
90
+		echo Please set \$QTDIR manually and make sure that
91
+		echo \$QTDIR/bin/qmake exists.
92
+		echo
93
+		exit 1;
94
+	fi
95
+else
96
+	qm=$QTDIR/bin/qmake
97
+fi
98
+
99
+gen_files() {
100
+cat >$1/modules.cpp <<EOT
101
+
102
+EOT
103
+cat >$1/modules_new.cpp <<EOT
104
+
105
+EOT
106
+cat >$1/conf.cpp <<EOT
107
+#include<stdio.h>
108
+#include<stdlib.h>
109
+#include<tqstring.h>
110
+#include<tqdict.h>
111
+#include<tqptrlist.h>
112
+#include<tqfileinfo.h>
113
+#include<tqfile.h>
114
+#include<tqdir.h>
115
+#include<tqstringlist.h>
116
+
117
+class Conf;
118
+
119
+class ConfObj
120
+{
121
+public:
122
+	ConfObj(Conf *c);
123
+	virtual ~ConfObj();
124
+
125
+	virtual TQString name() const=0;
126
+	virtual TQString shortname() const=0;
127
+	virtual bool exec()=0;
128
+
129
+	Conf *conf;
130
+	bool required;
131
+	bool disabled;
132
+};
133
+
134
+typedef TQPtrList<ConfObj> ConfObjList;
135
+typedef TQPtrListIterator<ConfObj> ConfObjListIt;
136
+
137
+class Conf
138
+{
139
+public:
140
+	Conf() : vars(17)
141
+	{
142
+		list.setAutoDelete(true);
143
+		vars.setAutoDelete(true);
144
+
145
+		vars.insert("QMAKE_INCDIR_X11", new TQString(X11_INC));
146
+		vars.insert("QMAKE_LIBDIR_X11", new TQString(X11_LIBDIR));
147
+		vars.insert("QMAKE_LIBS_X11",   new TQString(X11_LIB));
148
+		vars.insert("QMAKE_CC",         new TQString(CC));
149
+	}
150
+
151
+	~Conf()
152
+	{
153
+	}
154
+
155
+	void added(ConfObj *o)
156
+	{
157
+		list.append(o);
158
+	}
159
+
160
+	TQString getenv(const TQString &var)
161
+	{
162
+		char *p = ::getenv(var.latin1());
163
+		if(!p)
164
+			return TQString::null;
165
+		return TQString(p);
166
+	}
167
+
168
+	bool exec()
169
+	{
170
+		ConfObjListIt it(list);
171
+		for(ConfObj *o; (o = it.current()); ++it) {
172
+			// if this was a disabled-by-default option, check if it was enabled
173
+			if(o->disabled) {
174
+				TQString v = TQString("QC_ENABLE_") + o->shortname();
175
+				if(getenv(v) != "Y")
176
+					continue;
177
+			}
178
+			// and the opposite?
179
+			else {
180
+				TQString v = TQString("QC_DISABLE_") + o->shortname();
181
+				if(getenv(v) == "Y")
182
+					continue;
183
+			}
184
+
185
+			printf("Checking for %s ...", o->name().latin1());
186
+			fflush(stdout);
187
+			bool ok = o->exec();
188
+			if(ok)
189
+				printf(" yes\n");
190
+			else
191
+				printf(" no\n");
192
+			if(!ok && o->required) {
193
+				printf("\nError: need %s!\n", o->name().latin1());
194
+				return false;
195
+			}
196
+		}
197
+		return true;
198
+	}
199
+
200
+	const TQString & qvar(const TQString &s)
201
+	{
202
+		TQString *p = vars.find(s);
203
+		if(p)
204
+			return *p;
205
+		else
206
+			return blank;
207
+	}
208
+
209
+	TQString expandIncludes(const TQString &inc)
210
+	{
211
+		return TQString("-I") + inc;
212
+	}
213
+
214
+	TQString expandLibs(const TQString &lib)
215
+	{
216
+		return TQString("-L") + lib;
217
+	}
218
+
219
+	int doCommand(const TQString &s)
220
+	{
221
+		//printf("[%s]\n", s.latin1());
222
+		int r = system((s + " 1>/dev/null 2>/dev/null").latin1());
223
+		//printf("returned: %d\n", r);
224
+		return r;
225
+	}
226
+
227
+	bool doCompileAndLink(const TQString &filedata, const TQString &flags, int *retcode=0)
228
+	{
229
+		TQDir dir(".");
230
+		TQString fname = "atest.c";
231
+		TQString out = "atest";
232
+		TQFile f(fname);
233
+		TQCString cs = filedata.latin1();
234
+		if(!f.open(IO_WriteOnly | IO_Truncate))
235
+			return false;
236
+		f.writeBlock(cs.data(), cs.length());
237
+		f.close();
238
+
239
+		TQString str = qvar("QMAKE_CC") + ' ' + fname + " -o " + out + ' ' + flags;
240
+		int r = doCommand(str);
241
+		if(r == 0 && retcode)
242
+			*retcode = doCommand(TQString("./") + out);
243
+		dir.remove(fname);
244
+		dir.remove(out);
245
+		if(r != 0)
246
+			return false;
247
+		return true;
248
+	}
249
+
250
+	bool checkHeader(const TQString &path, const TQString &h)
251
+	{
252
+		TQFileInfo fi(path + '/' + h);
253
+		if(fi.exists())
254
+			return true;
255
+		return false;
256
+	}
257
+
258
+	bool findHeader(const TQString &h, const TQStringList &ext, TQString *inc)
259
+	{
260
+		if(checkHeader("/usr/include", h)) {
261
+			*inc = "";
262
+			return true;
263
+		}
264
+		TQStringList dirs;
265
+		dirs += "/usr/local/include";
266
+		dirs += ext;
267
+		for(TQStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
268
+			if(checkHeader(*it, h)) {
269
+				*inc = *it;
270
+				return true;
271
+			}
272
+		}
273
+		return false;
274
+	}
275
+
276
+	bool checkLibrary(const TQString &path, const TQString &name)
277
+	{
278
+		TQString str =
279
+			"int main()\n"
280
+			"{\n"
281
+			"    return 0;\n"
282
+			"}\n";
283
+
284
+		TQString extra;
285
+		if(!path.isEmpty())
286
+			extra += TQString("-L") + path + ' ';
287
+		extra += TQString("-l") + name;
288
+		if(!doCompileAndLink(str, extra))
289
+			return false;
290
+		return true;
291
+	}
292
+
293
+	bool findLibrary(const TQString &name, TQString *lib)
294
+	{
295
+		if(checkLibrary("", name)) {
296
+			*lib = "";
297
+			return true;
298
+		}
299
+		if(checkLibrary("/usr/local/lib", name)) {
300
+			*lib = "/usr/local/lib";
301
+			return true;
302
+		}
303
+		return false;
304
+	}
305
+
306
+	void addDefine(const TQString &str)
307
+	{
308
+		if(DEFINES.isEmpty())
309
+			DEFINES = str;
310
+		else
311
+			DEFINES += TQString(" ") + str;
312
+	}
313
+
314
+	void addLib(const TQString &str)
315
+	{
316
+		if(LIBS.isEmpty())
317
+			LIBS = str;
318
+		else
319
+			LIBS += TQString(" ") + str;
320
+	}
321
+
322
+	void addIncludePath(const TQString &str)
323
+	{
324
+		if(INCLUDEPATH.isEmpty())
325
+			INCLUDEPATH = str;
326
+		else
327
+			INCLUDEPATH += TQString(" ") + str;
328
+	}
329
+
330
+	void addExtra(const TQString &str)
331
+	{
332
+		extra += str + '\n';
333
+	}
334
+
335
+	TQString DEFINES;
336
+	TQString INCLUDEPATH;
337
+	TQString LIBS;
338
+	TQString extra;
339
+
340
+private:
341
+	ConfObjList list;
342
+	TQDict<TQString> vars;
343
+	TQString blank;
344
+};
345
+
346
+ConfObj::ConfObj(Conf *c)
347
+{
348
+	conf = c;
349
+	conf->added(this);
350
+	required = false;
351
+	disabled = false;
352
+}
353
+
354
+ConfObj::~ConfObj()
355
+{
356
+}
357
+
358
+#include"modules.cpp"
359
+
360
+//----------------------------------------------------------------------------
361
+// main
362
+//----------------------------------------------------------------------------
363
+int main()
364
+{
365
+	Conf *conf = new Conf;
366
+	ConfObj *o;
367
+	o = 0;
368
+#include"modules_new.cpp"
369
+
370
+	printf("ok\n");
371
+	bool success = false;
372
+	if(conf->exec()) {
373
+		TQFile f("conf.pri");
374
+		if(!f.open(IO_WriteOnly | IO_Truncate)) {
375
+			printf("Error writing %s\n", f.name().latin1());
376
+			return 1;
377
+		}
378
+
379
+		TQString str;
380
+		str += "# qconf\n";
381
+    str += "QT_PATH_PLUGINS = " + TQString(tqInstallPathPlugins()) + '\n';
382
+		if(!conf->DEFINES.isEmpty())
383
+			str += "DEFINES += " + conf->DEFINES + '\n';
384
+		if(!conf->INCLUDEPATH.isEmpty())
385
+			str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n';
386
+		if(!conf->LIBS.isEmpty())
387
+			str += "LIBS += " + conf->LIBS + '\n';
388
+		if(!conf->extra.isEmpty())
389
+			str += conf->extra;
390
+		str += '\n';
391
+
392
+		char *p = getenv("BINDIR");
393
+		if(p) {
394
+			str += TQString("target.path = ") + p + '\n';
395
+			str += "INSTALLS += target\n";
396
+		}
397
+
398
+		TQCString cs = str.latin1();
399
+		f.writeBlock(cs.data(), cs.length());
400
+		f.close();
401
+		success = true;
402
+	}
403
+	delete conf;
404
+
405
+	if(success)
406
+		return 0;
407
+	else
408
+		return 1;
409
+}
410
+
411
+EOT
412
+cat >$1/conf.pro <<EOT
413
+TEMPLATE = app
414
+CONFIG += qt x11 thread console
415
+TARGET = conf
416
+INCLUDEPATH += '/usr/include/tqt'
417
+
418
+DEFINES += X11_INC='"\$\$QMAKE_INCDIR_X11"'
419
+DEFINES += X11_LIBDIR='"\$\$QMAKE_LIBDIR_X11"'
420
+DEFINES += X11_LIB='"\$\$QMAKE_LIBS_X11"'
421
+DEFINES += CC='"\$\$QMAKE_CC"'
422
+
423
+SOURCES += conf.cpp
424
+
425
+EOT
426
+}
427
+
428
+export PREFIX
429
+export QTDIR
430
+rm -rf .qconftemp
431
+(
432
+	mkdir .qconftemp
433
+	gen_files .qconftemp
434
+	cd .qconftemp
435
+	$qm conf.pro >/dev/null
436
+	QTDIR=$QTDIR make clean >/dev/null 2>&1
437
+	QTDIR=$QTDIR make >../conf.log 2>&1
438
+)
439
+
440
+if [ "$?" != "0" ]; then
441
+	rm -rf .qconftemp
442
+	echo fail
443
+	echo
444
+	echo "There was an error compiling 'conf'.  Be sure you have a proper"
445
+	echo "TQt 3.x Multithreaded (MT) build environment set up."
446
+	if [ ! -f "$QTDIR/lib/libtqt-mt.so.3" ]; then
447
+		echo
448
+		echo "One possible reason is that you don't have"
449
+		echo "libtqt-mt.so.3 installed in $QTDIR/lib/."
450
+	fi
451
+	echo
452
+	exit 1;
453
+fi
454
+
455
+.qconftemp/conf
456
+ret="$?"
457
+if [ "$ret" = "1" ]; then
458
+	rm -rf .qconftemp
459
+	echo
460
+	exit 1;
461
+else
462
+	if [ "$ret" != "0" ]; then
463
+		rm -rf .qconftemp
464
+		echo fail
465
+		echo
466
+		echo Unexpected error launching 'conf'
467
+		echo
468
+		exit 1;
469
+	fi
470
+fi
471
+rm -rf .qconftemp
472
+
473
+if [ -x "./qcextra" ]; then
474
+	./qcextra
475
+fi
476
+# run qmake
477
+$qm qca.pro
478
+if [ "$?" != "0" ]; then
479
+	echo
480
+	exit 1;
481
+fi
482
+cat >Makefile.tmp <<EOT
483
+export QTDIR = $QTDIR
484
+EOT
485
+cat Makefile >> Makefile.tmp
486
+rm -f Makefile
487
+cp -f Makefile.tmp Makefile
488
+rm -f Makefile.tmp
489
+
490
+echo
491
+echo Good, your configure finished.  Now run \'make\'.
492
+echo

+ 65
- 0
examples/certtest/certtest.cpp View File

@@ -0,0 +1,65 @@
1
+#include<tqdom.h>
2
+#include<tqfile.h>
3
+#include"base64.h"
4
+#include"qca.h"
5
+
6
+TQCA::Cert readCertXml(const TQDomElement &e)
7
+{
8
+	TQCA::Cert cert;
9
+	// there should be one child data tag
10
+	TQDomElement data = e.elementsByTagName("data").item(0).toElement();
11
+	if(!data.isNull())
12
+		cert.fromDER(Base64::stringToArray(data.text()));
13
+	return cert;
14
+}
15
+
16
+void showCertInfo(const TQCA::Cert &cert)
17
+{
18
+	printf(" CN: %s\n", cert.subject()["CN"].latin1());
19
+	printf(" Valid from: %s, until %s\n",
20
+		cert.notBefore().toString().latin1(),
21
+		cert.notAfter().toString().latin1());
22
+	printf(" PEM:\n%s\n", cert.toPEM().latin1());
23
+}
24
+
25
+int main()
26
+{
27
+	if(!TQCA::isSupported(TQCA::CAP_X509)) {
28
+		printf("X509 not supported!\n");
29
+		return 1;
30
+	}
31
+
32
+	// open the Psi rootcerts file
33
+	TQFile f("/usr/local/share/psi/certs/rootcert.xml");
34
+	if(!f.open(IO_ReadOnly)) {
35
+		printf("unable to open %s\n", f.name().latin1());
36
+		return 1;
37
+	}
38
+	TQDomDocument doc;
39
+	doc.setContent(&f);
40
+	f.close();
41
+
42
+	TQDomElement base = doc.documentElement();
43
+	if(base.tagName() != "store") {
44
+		printf("wrong format of %s\n", f.name().latin1());
45
+		return 1;
46
+	}
47
+	TQDomNodeList cl = base.elementsByTagName("certificate");
48
+	if(cl.count() == 0) {
49
+		printf("no certs found in %s\n", f.name().latin1());
50
+		return 1;
51
+	}
52
+
53
+	for(int n = 0; n < (int)cl.count(); ++n) {
54
+		printf("-- Cert %d --\n", n);
55
+		TQCA::Cert cert = readCertXml(cl.item(n).toElement());
56
+		if(cert.isNull()) {
57
+			printf("error reading cert\n");
58
+			continue;
59
+		}
60
+		showCertInfo(cert);
61
+	}
62
+
63
+	return 0;
64
+}
65
+

+ 8
- 0
examples/certtest/certtest.pro View File

@@ -0,0 +1,8 @@
1
+TEMPLATE = app
2
+CONFIG += thread console
3
+TARGET = certtest
4
+
5
+INCLUDEPATH += ../common
6
+HEADERS += ../common/base64.h
7
+SOURCES += ../common/base64.cpp certtest.cpp
8
+include(../examples.pri)

+ 89
- 0
examples/ciphertest/ciphertest.cpp View File

@@ -0,0 +1,89 @@
1
+#include"qca.h"
2
+#include<stdio.h>
3
+
4
+static TQCString arrayToCString(const TQByteArray &);
5
+static TQByteArray cstringToArray(const TQCString &);
6
+static void doDynTest(TQCA::Cipher *c, const TQString &name, const TQCString &cs);
7
+
8
+int main(int argc, char **argv)
9
+{
10
+	TQCA::init();
11
+	TQCString cs = (argc >= 2) ? argv[1] : "hello";
12
+
13
+	// AES128 test
14
+	if(!TQCA::isSupported(TQCA::CAP_AES128))
15
+		printf("AES128 not supported!\n");
16
+	else {
17
+		// encrypt
18
+		TQByteArray key = TQCA::AES128::generateKey();
19
+		TQByteArray iv = TQCA::AES128::generateIV();
20
+		printf("aes128:key:%s\n", TQCA::arrayToHex(key).latin1());
21
+		printf("aes128:iv:%s\n", TQCA::arrayToHex(iv).latin1());
22
+		TQCA::AES128 c(TQCA::Encrypt, TQCA::CBC, key, iv);
23
+		c.update(cstringToArray(cs));
24
+		TQByteArray f = c.final();
25
+		TQString result = TQCA::arrayToHex(f);
26
+		printf(">aes128(\"%s\") = [%s]\n", cs.data(), result.latin1());
27
+
28
+		// decrypt
29
+		TQCA::AES128 d(TQCA::Decrypt, TQCA::CBC, key, iv);
30
+		d.update(f);
31
+		TQCString dec = arrayToCString(d.final());
32
+		printf("<aes128(\"%s\") = [%s]\n", result.latin1(), dec.data());
33
+	}
34
+
35
+	// BlowFish, TripleDES, and AES256 tested dynamically
36
+	if(!TQCA::isSupported(TQCA::CAP_BlowFish))
37
+		printf("BlowFish not supported!\n");
38
+	else
39
+		doDynTest(new TQCA::BlowFish, "bfish", cs);
40
+
41
+	if(!TQCA::isSupported(TQCA::CAP_TripleDES))
42
+		printf("TripleDES not supported!\n");
43
+	else
44
+		doDynTest(new TQCA::TripleDES, "3des", cs);
45
+
46
+	if(!TQCA::isSupported(TQCA::CAP_AES256))
47
+		printf("AES256 not supported!\n");
48
+	else
49
+		doDynTest(new TQCA::AES256, "aes256", cs);
50
+
51
+	return 0;
52
+}
53
+
54
+TQCString arrayToCString(const TQByteArray &a)
55
+{
56
+	TQCString cs;
57
+	cs.resize(a.size()+1);
58
+	memcpy(cs.data(), a.data(), a.size());
59
+	return cs;
60
+}
61
+
62
+TQByteArray cstringToArray(const TQCString &cs)
63
+{
64
+	TQByteArray a(cs.length());
65
+	memcpy(a.data(), cs.data(), a.size());
66
+	return a;
67
+}
68
+
69
+void doDynTest(TQCA::Cipher *c, const TQString &name, const TQCString &cs)
70
+{
71
+	// encrypt
72
+	TQByteArray key = c->dyn_generateKey();
73
+	TQByteArray iv = c->dyn_generateIV();
74
+	printf("%s:key:%s\n", name.latin1(), TQCA::arrayToHex(key).latin1());
75
+	printf("%s:iv:%s\n", name.latin1(), TQCA::arrayToHex(iv).latin1());
76
+	c->reset(TQCA::Encrypt, TQCA::CBC, key, iv);
77
+	c->update(cstringToArray(cs));
78
+	TQByteArray f = c->final();
79
+	TQString result = TQCA::arrayToHex(f);
80
+	printf(">%s(\"%s\") = [%s]\n", name.latin1(), cs.data(), result.latin1());
81
+
82
+	// decrypt
83
+	c->reset(TQCA::Decrypt, TQCA::CBC, key, iv);
84
+	c->update(f);
85
+	TQCString dec = arrayToCString(c->final());
86
+	printf("<%s(\"%s\") = [%s]\n", name.latin1(), result.latin1(), dec.data());
87
+	delete c;
88
+}
89
+

+ 6
- 0
examples/ciphertest/ciphertest.pro View File

@@ -0,0 +1,6 @@
1
+TEMPLATE = app
2
+CONFIG += thread console
3
+TARGET = ciphertest
4
+
5
+SOURCES += ciphertest.cpp
6
+include(../examples.pri)

+ 173
- 0
examples/common/base64.cpp View File

@@ -0,0 +1,173 @@
1
+/*
2
+ * base64.cpp - Base64 converting functions
3
+ * Copyright (C) 2003  Justin Karneges
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with this library; if not, write to the Free Software
17
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
+ *
19
+ */
20
+
21
+#include"base64.h"
22
+
23
+//! \class Base64 base64.h
24
+//! \brief Base64 conversion functions.
25
+//!
26
+//! Converts Base64 data between arrays and strings.
27
+//!
28
+//! \code
29
+//! #include "base64.h"
30
+//!
31
+//! ...
32
+//!
33
+//! // encode a block of data into base64
34
+//! TQByteArray block(1024);
35
+//! TQByteArray enc = Base64::encode(block);
36
+//!
37
+//!  \endcode
38
+
39
+//!
40
+//! Encodes array \a s and returns the result.
41
+TQByteArray Base64::encode(const TQByteArray &s)
42
+{
43
+	int i;
44
+	int len = s.size();
45
+	char tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
46
+	int a, b, c;
47
+
48
+	TQByteArray p((len+2)/3*4);
49
+	int at = 0;
50
+	for( i = 0; i < len; i += 3 ) {
51
+		a = ((unsigned char)s[i] & 3) << 4;
52
+		if(i + 1 < len) {
53
+			a += (unsigned char)s[i + 1] >> 4;
54
+			b = ((unsigned char)s[i + 1] & 0xF) << 2;
55
+			if(i + 2 < len) {
56
+				b += (unsigned char)s[i + 2] >> 6;
57
+				c = (unsigned char)s[i + 2] & 0x3F;
58
+			}
59
+			else
60
+				c = 64;
61
+		}
62
+		else
63
+			b = c = 64;
64
+
65
+		p[at++] = tbl[(unsigned char)s[i] >> 2];
66
+		p[at++] = tbl[a];
67
+		p[at++] = tbl[b];
68
+		p[at++] = tbl[c];
69
+	}
70
+	return p;
71
+}
72
+
73
+//!
74
+//! Decodes array \a s and returns the result.
75
+TQByteArray Base64::decode(const TQByteArray &s)
76
+{
77
+	// return value
78
+	TQByteArray p;
79
+
80
+	// -1 specifies invalid
81
+	// 64 specifies eof
82
+	// everything else specifies data
83
+
84
+	char tbl[] = {
85
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
86
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
87
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
88
+		52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,
89
+		-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
90
+		15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
91
+		-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
92
+		41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
93
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
94
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
95
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
96
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
97
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
98
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
99
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
100
+		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
101
+	};
102
+
103
+	// this should be a multiple of 4
104
+	int len = s.size();
105
+
106
+	if(len % 4)
107
+		return p;
108
+
109
+	p.resize(len / 4 * 3);
110
+
111
+	int i;
112
+	int at = 0;
113
+
114
+	int a, b, c, d;
115
+	c = d = 0;
116
+
117
+	for( i = 0; i < len; i += 4 ) {
118
+		a = tbl[(int)s[i]];
119
+		b = tbl[(int)s[i + 1]];
120
+		c = tbl[(int)s[i + 2]];
121
+		d = tbl[(int)s[i + 3]];
122
+		if((a == 64 || b == 64) || (a < 0 || b < 0 || c < 0 || d < 0)) {
123
+			p.resize(0);
124
+			return p;
125
+		}
126
+		p[at++] = ((a & 0x3F) << 2) | ((b >> 4) & 0x03);
127
+		p[at++] = ((b & 0x0F) << 4) | ((c >> 2) & 0x0F);
128
+		p[at++] = ((c & 0x03) << 6) | ((d >> 0) & 0x3F);
129
+	}
130
+
131
+	if(c & 64)
132
+		p.resize(at - 2);
133
+	else if(d & 64)
134
+		p.resize(at - 1);
135
+
136
+	return p;
137
+}
138
+
139
+//!
140
+//! Encodes array \a a and returns the result as a string.
141
+TQString Base64::arrayToString(const TQByteArray &a)
142
+{
143
+	TQByteArray b = encode(a);
144
+	TQCString c;
145
+	c.resize(b.size()+1);
146
+	memcpy(c.data(), b.data(), b.size());
147
+	return TQString::fromLatin1(c);
148
+}
149
+
150
+//!
151
+//! Decodes string \a s and returns the result as an array.
152
+TQByteArray Base64::stringToArray(const TQString &s)
153
+{
154
+	if(s.isEmpty())
155
+		return TQByteArray();
156
+	const char *c = s.latin1();
157
+	int len = strlen(c);
158
+	TQByteArray b(len);
159
+	memcpy(b.data(), c, len);
160
+	TQByteArray a = decode(b);
161
+	return a;
162
+}
163
+
164
+//!
165
+//! Encodes string \a s and returns the result as a string.
166
+TQString Base64::encodeString(const TQString &s)
167
+{
168
+	TQCString c = s.utf8();
169
+	int len = c.length();
170
+	TQByteArray b(len);
171
+	memcpy(b.data(), c.data(), len);
172
+	return arrayToString(b);
173
+}

+ 36
- 0
examples/common/base64.h View File

@@ -0,0 +1,36 @@
1
+/*
2
+ * base64.h - Base64 converting functions
3
+ * Copyright (C) 2003  Justin Karneges
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with this library; if not, write to the Free Software
17
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
+ *
19
+ */
20
+
21
+#ifndef CS_BASE64_H
22
+#define CS_BASE64_H
23
+
24
+#include<qstring.h>
25
+
26
+class Base64
27
+{
28
+public:
29
+	static TQByteArray encode(const TQByteArray &);
30
+	static TQByteArray decode(const TQByteArray &);
31
+	static TQString arrayToString(const TQByteArray &);
32
+	static TQByteArray stringToArray(const TQString &);
33
+	static TQString encodeString(const TQString &);
34
+};
35
+
36
+#endif

+ 7
- 0
examples/examples.pri View File

@@ -0,0 +1,7 @@
1
+# change/remove these entries, depending on the installation prefix
2
+INCLUDEPATH += /usr/local/include
3
+LIBS += -L/usr/local/lib
4
+
5
+# link
6
+LIBS += -lqca
7
+

+ 11
- 0
examples/examples.pro View File

@@ -0,0 +1,11 @@
1
+TEMPLATE = subdirs
2
+
3
+SUBDIRS += \
4
+	hashtest \
5
+	ciphertest \
6
+	rsatest \
7
+	certtest \
8
+	ssltest \
9
+	sslservtest \
10
+	sasltest
11
+

+ 25
- 0
examples/hashtest/hashtest.cpp View File

@@ -0,0 +1,25 @@
1
+#include"qca.h"
2
+#include<stdio.h>
3
+
4
+int main(int argc, char **argv)
5
+{
6
+	TQCA::init();
7
+	TQCString cs = (argc >= 2) ? argv[1] : "hello";
8
+
9
+	if(!TQCA::isSupported(TQCA::CAP_SHA1))
10
+		printf("SHA1 not supported!\n");
11
+	else {
12
+		TQString result = TQCA::SHA1::hashToString(cs);
13
+		printf("sha1(\"%s\") = [%s]\n", cs.data(), result.latin1());
14
+	}
15
+
16
+	if(!TQCA::isSupported(TQCA::CAP_MD5))
17
+		printf("MD5 not supported!\n");
18
+	else {
19
+		TQString result = TQCA::MD5::hashToString(cs);
20
+		printf("md5(\"%s\") = [%s]\n", cs.data(), result.latin1());
21
+	}
22
+
23
+	return 0;
24
+}
25
+

+ 6
- 0
examples/hashtest/hashtest.pro View File

@@ -0,0 +1,6 @@
1
+TEMPLATE = app
2
+CONFIG += thread console
3
+TARGET = hashtest
4
+
5
+SOURCES += hashtest.cpp
6
+include(../examples.pri)

+ 86
- 0
examples/rsatest/rsatest.cpp View File

@@ -0,0 +1,86 @@
1
+#include<tqfile.h>
2
+#include<tqfileinfo.h>
3
+#include"qca.h"
4
+#include<stdio.h>
5
+
6
+//#define USE_FILE
7
+
8
+TQCA::RSAKey readKeyFile(const TQString &name)
9
+{
10
+	TQCA::RSAKey k;
11
+	TQFile f(name);
12
+	if(!f.open(IO_ReadOnly)) {
13
+		printf("Unable to open %s\n", name.latin1());
14
+		return k;
15
+	}
16
+	TQByteArray der = f.readAll();
17
+	f.close();
18
+	printf("Read %s [%d bytes]\n", name.latin1(), der.size());
19
+
20
+	if(!k.fromDER(der)) {
21
+		printf("%s: Error importing DER format.\n", name.latin1());
22
+		return k;
23
+	}
24
+	char *yes = "yes";
25
+	char *no = "no";
26
+	printf("Successfully imported %s (enc=%s, dec=%s)\n",
27
+		name.latin1(),
28
+		k.havePublic() ? yes : no,
29
+		k.havePrivate() ? yes : no);
30
+
31
+	printf("Converting to DER: %d bytes\n", k.toDER().size());
32
+	printf("Converting to PEM:\n%s\n", k.toPEM().latin1());
33
+	return k;
34
+}
35
+
36
+int main(int argc, char **argv)
37
+{
38
+	TQCA::init();
39
+	TQCString cs = (argc >= 2) ? argv[1] : "hello";
40
+
41
+	if(!TQCA::isSupported(TQCA::CAP_RSA))
42
+		printf("RSA not supported!\n");
43
+	else {
44
+#ifdef USE_FILE
45
+		TQCA::RSAKey pubkey = readKeyFile("keypublic.der");
46
+		if(pubkey.isNull())
47
+			return 1;
48
+		TQCA::RSAKey seckey = readKeyFile("keyprivate.der");
49
+		if(seckey.isNull())
50
+			return 1;
51
+#else
52
+		TQCA::RSAKey seckey = TQCA::RSA::generateKey(1024);
53
+		if(seckey.isNull())
54
+			return 1;
55
+		TQCA::RSAKey pubkey = seckey;
56
+#endif
57
+		// encrypt some data
58
+		TQByteArray a(cs.length());
59
+		memcpy(a.data(), cs.data(), a.size());
60
+
61
+		TQCA::RSA op;
62
+		op.setKey(pubkey);
63
+		TQByteArray result;
64
+		if(!op.encrypt(a, &result)) {
65
+			printf("Error encrypting.\n");
66
+			return 1;
67
+		}
68
+		TQString rstr = TQCA::arrayToHex(result);
69
+		printf(">rsa(\"%s\") = [%s]\n", cs.data(), rstr.latin1());
70
+
71
+		// now decrypt it
72
+		op.setKey(seckey);
73
+		TQByteArray dec;
74
+		if(!op.decrypt(result, &dec)) {
75
+			printf("Error decrypting.\n");
76
+			return 1;
77
+		}
78
+		TQCString dstr;
79
+		dstr.resize(dec.size()+1);
80
+		memcpy(dstr.data(), dec.data(), dec.size());
81
+		printf("<rsa(\"%s\") = [%s]\n", rstr.latin1(), dstr.data());
82
+	}
83
+
84
+	return 0;
85
+}
86
+

+ 6
- 0
examples/rsatest/rsatest.pro View File

@@ -0,0 +1,6 @@
1
+TEMPLATE = app
2
+CONFIG += thread console
3
+TARGET = rsatest
4
+
5
+SOURCES += rsatest.cpp
6
+include(../examples.pri)

+ 615
- 0
examples/sasltest/sasltest.cpp View File

@@ -0,0 +1,615 @@
1
+#include<tqapplication.h>
2
+#include<tqtimer.h>
3
+#include<tqsocket.h>
4
+#include<tqserversocket.h>
5
+#include<stdio.h>
6
+
7
+#ifdef Q_OS_UNIX
8
+#include<unistd.h>
9
+#endif
10
+
11
+#include"base64.h"
12
+#include"qca.h"
13
+
14
+#define PROTO_NAME "foo"
15
+#define PROTO_PORT 8001
16
+
17
+static TQString prompt(const TQString &s)
18
+{
19
+	printf("* %s ", s.latin1());
20
+	fflush(stdout);
21
+	char line[256];
22
+	fgets(line, 255, stdin);
23
+	TQString result = line;
24
+	if(result[result.length()-1] == '\n')
25
+		result.truncate(result.length()-1);
26
+	return result;
27
+}
28
+
29
+class ClientTest : public TQObject
30
+{
31
+	Q_OBJECT
32
+public:
33
+	ClientTest()
34
+	{
35
+		sock = new TQSocket;
36
+		connect(sock, SIGNAL(connected()), SLOT(sock_connected()));
37
+		connect(sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
38
+		connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
39
+		connect(sock, SIGNAL(error(int)), SLOT(sock_error(int)));
40
+
41
+		sasl = new QCA::SASL;
42
+		connect(sasl, SIGNAL(clientFirstStep(const TQString &, const TQByteArray *)), SLOT(sasl_clientFirstStep(const TQString &, const TQByteArray *)));
43
+		connect(sasl, SIGNAL(nextStep(const TQByteArray &)), SLOT(sasl_nextStep(const TQByteArray &)));
44
+		connect(sasl, SIGNAL(needParams(bool, bool, bool, bool)), SLOT(sasl_needParams(bool, bool, bool, bool)));
45
+		connect(sasl, SIGNAL(authenticated()), SLOT(sasl_authenticated()));
46
+		connect(sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead()));
47
+		connect(sasl, SIGNAL(readyReadOutgoing(int)), SLOT(sasl_readyReadOutgoing(int)));
48
+		connect(sasl, SIGNAL(error(int)), SLOT(sasl_error(int)));
49
+	}
50
+
51
+	~ClientTest()
52
+	{
53
+		delete sock;
54
+		delete sasl;
55
+	}
56
+
57
+	void start(const TQString &_host, int port, const TQString &user="", const TQString &pass="")
58
+	{
59
+		mode = 0;
60
+		host = _host;
61
+		sock->connectToHost(host, port);
62
+		sasl->setMinimumSSF(0);
63
+		sasl->setMaximumSSF(256);
64
+
65
+		if(!user.isEmpty()) {
66
+			sasl->setUsername(user);
67
+			sasl->setAuthzid(user);
68
+		}
69
+		if(!pass.isEmpty())
70
+			sasl->setPassword(pass);
71
+	}
72
+
73
+signals:
74
+	void quit();
75
+
76
+private slots:
77
+	void sock_connected()
78
+	{
79
+		printf("Connected to server.  Awaiting mechanism list...\n");
80
+	}
81
+
82
+	void sock_connectionClosed()
83
+	{
84
+		printf("Connection closed by peer.\n");
85
+		quit();
86
+	}
87
+
88
+	void sock_error(int x)
89
+	{
90
+		TQString s;
91
+		if(x == TQSocket::ErrConnectionRefused)
92
+			s = "connection refused or timed out";
93
+		else if(x == TQSocket::ErrHostNotFound)
94
+			s = "host not found";
95
+		else if(x == TQSocket::ErrSocketRead)
96
+			s = "read error";
97
+
98
+		printf("Socket error: %s\n", s.latin1());
99
+		quit();
100
+	}
101
+
102
+	void sock_readyRead()
103
+	{
104
+		if(mode == 2) {
105
+			int avail = sock->bytesAvailable();
106
+			TQByteArray a(avail);
107
+			int n = sock->readBlock(a.data(), a.size());
108
+			a.resize(n);
109
+			printf("Read %d bytes\n", a.size());
110
+			sasl->writeIncoming(a);
111
+		}
112
+		else {
113
+			if(sock->canReadLine()) {
114
+				TQString line = sock->readLine();
115
+				line.truncate(line.length()-1); // chop the newline
116
+				handleLine(line);
117
+			}
118
+		}
119
+	}
120
+
121
+	void sasl_clientFirstStep(const TQString &mech, const TQByteArray *clientInit)
122
+	{
123
+		printf("Choosing mech: %s\n", mech.latin1());
124
+		TQString line = mech;
125
+		if(clientInit) {
126
+			TQCString cs(clientInit->data(), clientInit->size()+1);
127
+			line += ' ';
128
+			line += cs;
129
+		}
130
+		sendLine(line);
131
+	}
132
+
133
+	void sasl_nextStep(const TQByteArray &stepData)
134
+	{
135
+		TQCString cs(stepData.data(), stepData.size()+1);
136
+		TQString line = "C";
137
+		if(!stepData.isEmpty()) {
138
+			line += ',';
139
+			line += cs;
140
+		}
141
+		sendLine(line);
142
+	}
143
+
144
+	void sasl_needParams(bool user, bool authzid, bool pass, bool realm)
145
+	{
146
+		TQString username;
147
+		if(user || authzid)
148
+			username = prompt("Username:");
149
+		if(user) {
150
+			sasl->setUsername(username);
151
+		}
152
+		if(authzid) {
153
+			sasl->setAuthzid(username);
154
+		}
155
+		if(pass) {
156
+			sasl->setPassword(prompt("Password (not hidden!) :"));
157
+		}
158
+		if(realm) {
159
+			sasl->setRealm(prompt("Realm:"));
160
+		}
161
+		sasl->continueAfterParams();
162
+	}
163
+
164
+	void sasl_authenticated()
165
+	{
166
+		printf("SASL success!\n");
167
+		printf("SSF: %d\n", sasl->ssf());
168
+	}
169
+
170
+	void sasl_readyRead()
171
+	{
172
+		TQByteArray a = sasl->read();
173
+		int oldsize = inbuf.size();
174
+		inbuf.resize(oldsize + a.size());
175
+		memcpy(inbuf.data() + oldsize, a.data(), a.size());
176
+		processInbuf();
177
+	}
178
+
179
+	void sasl_readyReadOutgoing(int)
180
+	{
181
+		TQByteArray a = sasl->readOutgoing();
182
+		sock->writeBlock(a.data(), a.size());
183
+	}
184
+
185
+	void sasl_error(int)
186
+	{
187
+		printf("SASL error!\n");
188
+		quit();
189
+		return;
190
+	}
191
+
192
+private:
193
+	TQSocket *sock;
194
+	QCA::SASL *sasl;
195
+	int mode;
196
+	TQString host;
197
+	TQByteArray inbuf;
198
+
199
+	void processInbuf()
200
+	{
201
+		TQStringList list;
202
+		for(int n = 0; n < (int)inbuf.size(); ++n) {
203
+			if(inbuf[n] == '\n') {
204
+				TQCString cs(inbuf.data(), n+1);
205
+				char *p = inbuf.data();
206
+				++n;
207
+				int x = inbuf.size() - n;
208
+				memmove(p, p + n, x);
209
+				inbuf.resize(x);
210
+				list += TQString::fromUtf8(cs);
211
+				// start over, basically
212
+				n = -1;
213
+			}
214
+		}
215
+
216
+		for(TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
217
+			handleLine(*it);
218
+	}
219
+
220
+	void handleLine(const TQString &line)
221
+	{
222
+		printf("Reading: [%s]\n", line.latin1());
223
+		if(mode == 0) {
224
+			// first line is the method list
225
+			TQStringList mechlist = TQStringList::split(' ', line);
226
+			++mode;
227
+
228
+			// kick off the client
229
+			sasl->setAllowAnonymous(false);
230
+			if(!sasl->startClient(PROTO_NAME, host, mechlist)) {
231
+				printf("Error starting client!\n");
232
+				quit();
233
+			}
234
+		}
235
+		else if(mode == 1) {
236
+			TQString type, rest;
237
+			int n = line.find(',');
238
+			if(n != -1) {
239
+				type = line.mid(0, n);
240
+				rest = line.mid(n+1);
241
+			}
242
+			else {
243
+				type = line;
244
+				rest = "";
245
+			}
246
+
247
+			if(type == "C") {
248
+				TQCString cs = rest.latin1();
249
+				TQByteArray buf(cs.length());
250
+				memcpy(buf.data(), cs.data(), buf.size());
251
+				sasl->putStep(buf);
252
+			}
253
+			else if(type == "E") {
254
+				printf("Authentication failed.\n");
255
+				quit();
256
+				return;
257
+			}
258
+			else if(type == "A") {
259
+				printf("Authentication success.\n");
260
+				++mode;
261
+				sock_readyRead(); // any extra data?
262
+				return;
263
+			}
264
+			else {
265
+				printf("Bad format from peer, closing.\n");
266
+				quit();
267
+				return;
268
+			}
269
+		}
270
+		else {
271
+		}
272
+	}
273
+
274
+	void sendLine(const TQString &line)
275
+	{
276
+		printf("Writing: {%s}\n", line.latin1());
277
+		TQString s = line + '\n';
278
+		TQCString cs = s.latin1();
279
+		if(mode == 2) {
280
+			TQByteArray a(cs.length());
281
+			memcpy(a.data(), cs.data(), a.size());
282
+			sasl->write(a);
283
+		}
284
+		else
285
+			sock->writeBlock(cs.data(), cs.length());
286
+	}
287
+};
288
+
289
+class ServerTest : public QServerSocket
290
+{
291
+	Q_OBJECT
292
+public:
293
+	ServerTest(const TQString &_str, int _port) : QServerSocket(_port), port(_port)
294
+	{
295
+		sock = 0;
296
+		sasl = 0;
297
+		realm = TQString::null;
298
+		str = _str;
299
+	}
300
+
301
+	~ServerTest()
302
+	{
303
+		delete sock;
304
+		delete sasl;
305
+	}
306
+
307
+	void start()
308
+	{
309
+		if(!ok()) {
310
+			printf("Error binding to port %d!\n", port);
311
+			TTQTimer::singleShot(0, this, SIGNAL(quit()));
312
+			return;
313
+		}
314
+		char myhostname[256];
315
+		int r = gethostname(myhostname, sizeof(myhostname)-1);
316
+		if(r == -1) {
317
+			printf("Error getting hostname!\n");
318
+			TTQTimer::singleShot(0, this, SIGNAL(quit()));
319
+			return;
320
+		}
321
+		host = myhostname;
322
+		printf("Listening on %s:%d ...\n", host.latin1(), port);
323
+	}
324
+
325
+	void newConnection(int s)
326
+	{
327
+		// Note: only 1 connection supported at a time in this example!
328
+		if(sock) {
329
+			TQSocket tmp;
330
+			tmp.setSocket(s);
331
+			printf("Connection ignored, already have one active.\n");
332
+			return;
333
+		}
334
+
335
+		printf("Connection received!  Starting SASL handshake...\n");
336
+
337
+		sock = new TQSocket;
338
+		connect(sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
339
+		connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
340
+		connect(sock, SIGNAL(error(int)), SLOT(sock_error(int)));
341
+		connect(sock, SIGNAL(bytesWritten(int)), SLOT(sock_bytesWritten(int)));
342
+
343
+		sasl = new QCA::SASL;
344
+		connect(sasl, SIGNAL(authCheck(const TQString &, const TQString &)), SLOT(sasl_authCheck(const TQString &, const TQString &)));
345
+		connect(sasl, SIGNAL(nextStep(const TQByteArray &)), SLOT(sasl_nextStep(const TQByteArray &)));
346
+		connect(sasl, SIGNAL(authenticated()), SLOT(sasl_authenticated()));
347
+		connect(sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead()));
348
+		connect(sasl, SIGNAL(readyReadOutgoing(int)), SLOT(sasl_readyReadOutgoing(int)));
349
+		connect(sasl, SIGNAL(error(int)), SLOT(sasl_error(int)));
350
+
351
+		sock->setSocket(s);
352
+		mode = 0;
353
+		inbuf.resize(0);
354
+
355
+		sasl->setMinimumSSF(0);
356
+		sasl->setMaximumSSF(256);
357
+
358
+		TQStringList mechlist;
359
+		if(!sasl->startServer(PROTO_NAME, host, realm, &mechlist)) {
360
+			printf("Error starting server!\n");
361
+			quit();
362
+		}
363
+		TQString str;
364
+		bool first = true;
365
+		for(TQStringList::ConstIterator it = mechlist.begin(); it != mechlist.end(); ++it) {
366
+			if(!first)
367
+				str += ' ';
368
+			str += *it;
369
+			first = false;
370
+		}
371
+		sendLine(str);
372
+	}
373
+
374
+signals:
375
+	void quit();
376
+
377
+private slots:
378
+	void sock_connectionClosed()
379
+	{
380
+		printf("Connection closed by peer.\n");
381
+		close();
382
+	}
383
+
384
+	void sock_error(int x)
385
+	{
386
+		TQString s;
387
+		if(x == TQSocket::ErrConnectionRefused)
388
+			s = "connection refused or timed out";
389
+		else if(x == TQSocket::ErrHostNotFound)
390
+			s = "host not found";
391
+		else if(x == TQSocket::ErrSocketRead)
392
+			s = "read error";
393
+
394
+		printf("Socket error: %s\n", s.latin1());
395
+		close();
396
+	}
397
+
398
+	void sock_readyRead()
399
+	{
400
+		if(sock->canReadLine()) {
401
+			TQString line = sock->readLine();
402
+			line.truncate(line.length()-1); // chop the newline
403
+			handleLine(line);
404
+		}
405
+	}
406
+
407
+	void sock_bytesWritten(int x)
408
+	{
409
+		if(mode == 2) {
410
+			toWrite -= x;
411
+			if(toWrite <= 0) {
412
+				printf("Sent, closing.\n");
413
+				close();
414
+			}
415
+		}
416
+	}
417
+
418
+	void sasl_nextStep(const TQByteArray &stepData)
419
+	{
420
+		TQCString cs(stepData.data(), stepData.size()+1);
421
+		TQString line = "C";
422
+		if(!stepData.isEmpty()) {
423
+			line += ',';
424
+			line += cs;
425
+		}
426
+		sendLine(line);
427
+	}
428
+
429
+	void sasl_authCheck(const TQString &user, const TQString &authzid)
430
+	{
431
+		printf("AuthCheck: User: [%s], Authzid: [%s]\n", user.latin1(), authzid.latin1());
432
+		sasl->continueAfterAuthCheck();
433
+	}
434
+
435
+	void sasl_authenticated()
436
+	{
437
+		sendLine("A");
438
+		printf("Authentication success.\n");
439
+		++mode;
440
+		printf("SSF: %d\n", sasl->ssf());
441
+		sendLine(str);
442
+	}
443
+
444
+	void sasl_readyRead()
445
+	{
446
+		TQByteArray a = sasl->read();
447
+		int oldsize = inbuf.size();
448
+		inbuf.resize(oldsize + a.size());
449
+		memcpy(inbuf.data() + oldsize, a.data(), a.size());
450
+		processInbuf();
451
+	}
452
+
453
+	void sasl_readyReadOutgoing(int)
454
+	{
455
+		TQByteArray a = sasl->readOutgoing();
456
+		toWrite = a.size();
457
+		sock->writeBlock(a.data(), a.size());
458
+	}
459
+
460
+	void sasl_error(int x)
461
+	{
462
+		if(x == QCA::SASL::ErrAuth) {
463
+			sendLine("E");
464
+			printf("Authentication failed.\n");
465
+			close();
466
+		}
467
+		else {
468
+			printf("SASL security layer error!\n");
469
+			close();
470
+		}
471
+	}
472
+
473
+private:
474
+	TQSocket *sock;
475
+	QCA::SASL *sasl;
476
+	TQString host, realm;
477
+	int port;
478
+	int mode;
479
+	TQString str;
480
+	TQByteArray inbuf;
481
+	int toWrite;
482
+
483
+	void processInbuf()
484
+	{
485
+	}
486
+
487
+	void handleLine(const TQString &line)
488
+	{
489
+		printf("Reading: [%s]\n", line.latin1());
490
+		if(mode == 0) {
491
+			int n = line.find(' ');
492
+			if(n != -1) {
493
+				TQString mech = line.mid(0, n);
494
+				TQCString cs = line.mid(n+1).latin1();
495
+				TQByteArray clientInit(cs.length());
496
+				memcpy(clientInit.data(), cs.data(), clientInit.size());
497
+				sasl->putServerFirstStep(mech, clientInit);
498
+			}
499
+			else
500
+				sasl->putServerFirstStep(line);
501
+			++mode;
502
+		}
503
+		else if(mode == 1) {
504
+			TQString type, rest;
505
+			int n = line.find(',');
506
+			if(n != -1) {
507
+				type = line.mid(0, n);
508
+				rest = line.mid(n+1);
509
+			}
510
+			else {
511
+				type = line;
512
+				rest = "";
513
+			}
514
+
515
+			if(type == "C") {
516
+				TQCString cs = rest.latin1();
517
+				TQByteArray buf(cs.length());
518
+				memcpy(buf.data(), cs.data(), buf.size());
519
+				sasl->putStep(buf);
520
+			}
521
+			else {
522
+				printf("Bad format from peer, closing.\n");
523
+				close();
524
+				return;
525
+			}
526
+		}
527
+	}
528
+
529
+	void sendLine(const TQString &line)
530
+	{
531
+		printf("Writing: {%s}\n", line.latin1());
532
+		TQString s = line + '\n';
533
+		TQCString cs = s.latin1();
534
+		if(mode == 2) {
535
+			TQByteArray a(cs.length());
536
+			memcpy(a.data(), cs.data(), a.size());
537
+			sasl->write(a);
538
+		}
539
+		else
540
+			sock->writeBlock(cs.data(), cs.length());
541
+	}
542
+
543
+	void close()
544
+	{
545
+		sock->deleteLater();
546
+		sock = 0;
547
+		delete sasl;
548
+		sasl = 0;
549
+	}
550
+};
551
+
552
+#include"sasltest.moc"
553
+
554
+void usage()
555
+{
556
+	printf("usage: sasltest client [host] [user] [pass]\n");
557
+	printf("       sasltest server [string]\n\n");
558
+}
559
+
560
+int main(int argc, char **argv)
561
+{
562
+	TQApplication app(argc, argv, false);
563
+
564
+	TQString host, user, pass;
565
+	TQString str = "Hello, World";
566
+	bool server;
567
+	if(argc < 2) {
568
+		usage();
569
+		return 0;
570
+	}
571
+	TQString arg = argv[1];
572
+	if(arg == "client") {
573
+		if(argc < 3) {
574
+			usage();
575
+			return 0;
576
+		}
577
+		host = argv[2];
578
+		if(argc >= 4)
579
+			user = argv[3];
580
+		if(argc >= 5)
581
+			pass = argv[4];
582
+		server = false;
583
+	}
584
+	else if(arg == "server") {
585
+		if(argc >= 3)
586
+			str = argv[2];
587
+		server = true;
588
+	}
589
+	else {
590
+		usage();
591
+		return 0;
592
+	}
593
+
594
+	if(!QCA::isSupported(QCA::CAP_SASL)) {
595
+		printf("SASL not supported!\n");
596
+		return 1;
597
+	}
598
+
599
+	if(server) {
600
+		ServerTest *s = new ServerTest(str, PROTO_PORT);
601
+		TQObject::connect(s, SIGNAL(quit()), &app, SLOT(quit()));
602
+		s->start();
603
+		app.exec();
604
+		delete s;
605
+	}
606
+	else {
607
+		ClientTest *c = new ClientTest;
608
+		TQObject::connect(c, SIGNAL(quit()), &app, SLOT(quit()));
609
+		c->start(host, PROTO_PORT, user, pass);
610
+		app.exec();
611
+		delete c;
612
+	}
613
+
614
+	return 0;
615
+}

+ 8
- 0
examples/sasltest/sasltest.pro View File

@@ -0,0 +1,8 @@
1
+TEMPLATE = app
2
+CONFIG += thread console
3
+TARGET = sasltest
4
+
5
+INCLUDEPATH += ../common
6
+HEADERS += ../common/base64.h
7
+SOURCES += ../common/base64.cpp sasltest.cpp
8
+include(../examples.pri)

+ 294
- 0
examples/sslservtest/sslservtest.cpp View File

@@ -0,0 +1,294 @@
1
+#include<tqapplication.h>
2
+#include<tqfile.h>
3
+#include<tqsocket.h>
4
+#include<tqserversocket.h>
5
+#include<tqvaluelist.h>
6
+#include<tqtimer.h>
7
+#include"qca.h"
8
+
9
+char pemdata_cert[] =
10
+	"-----BEGIN CERTIFICATE-----\n"
11
+	"MIIDbjCCAtegAwIBAgIBADANBgkqhkiG9w0BAQQFADCBhzELMAkGA1UEBhMCVVMx\n"
12
+	"EzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNVBAcTBklydmluZTEYMBYGA1UEChMP\n"
13
+	"RXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtleGFtcGxlLmNvbTEiMCAGCSqGSIb3\n"
14
+	"DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbTAeFw0wMzA3MjQwNzMwMDBaFw0wMzA4\n"
15
+	"MjMwNzMwMDBaMIGHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEP\n"
16
+	"MA0GA1UEBxMGSXJ2aW5lMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNV\n"
17
+	"BAMTC2V4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu\n"
18
+	"Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCobzCF268K2sRp473gvBTT\n"
19
+	"4AgSL1kjeF8N57vxS1P8zWrWMXNs4LuH0NRZmKTajeboy0br8xw+smIy3AbaKAwW\n"
20
+	"WZToesxebu3m9VeA8dqWyOaUMjoxAcgVYesgVaMpjRe7fcWdJnX1wJoVVPuIcO8m\n"
21
+	"a+AAPByfTORbzpSTmXAQAwIDAQABo4HnMIHkMB0GA1UdDgQWBBTvFierzLmmYMq0\n"
22
+	"cB/+5rK1bNR56zCBtAYDVR0jBIGsMIGpgBTvFierzLmmYMq0cB/+5rK1bNR566GB\n"
23
+	"jaSBijCBhzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNV\n"
24
+	"BAcTBklydmluZTEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtl\n"
25
+	"eGFtcGxlLmNvbTEiMCAGCSqGSIb3DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbYIB\n"
26
+	"ADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAGqGhXf7xNOnYNtFO7gz\n"
27
+	"K6RdZGHFI5q1DAEz4hhNBC9uElh32XGX4wN7giz3zLC8v9icL/W4ff/K5NDfv3Gf\n"
28
+	"gQe/+Wo9Be3H3ul6uwPPFnx4+PIOF2a5TW99H9smyxWdNjnFtcUte4al3RszcMWG\n"
29
+	"x3iqsWosGtj6F+ridmKoqKLu\n"
30
+	"-----END CERTIFICATE-----\n";
31
+
32
+char pemdata_privkey[] =
33
+	"-----BEGIN RSA PRIVATE KEY-----\n"
34
+	"MIICXAIBAAKBgQCobzCF268K2sRp473gvBTT4AgSL1kjeF8N57vxS1P8zWrWMXNs\n"
35
+	"4LuH0NRZmKTajeboy0br8xw+smIy3AbaKAwWWZToesxebu3m9VeA8dqWyOaUMjox\n"
36
+	"AcgVYesgVaMpjRe7fcWdJnX1wJoVVPuIcO8ma+AAPByfTORbzpSTmXAQAwIDAQAB\n"
37
+	"AoGAP83u+aYghuIcaWhmM03MLf69z/WztKYSi/fu0BcS977w67bL3MC9CVPoPRB/\n"
38
+	"0nLSt/jZIuRzHKUCYfXLerSU7v0oXDTy6GPzWMh/oXIrpF0tYNbwWF7LSq2O2gGZ\n"
39
+	"XtA9MSmUNNJaKzQQeXjqdVFOY8A0Pho+k2KByBiCi+ChkcECQQDRUuyX0+PKJtA2\n"
40
+	"M36BOTFpy61BAv+JRlXUnHuevOfQWl6NR6YGygqCyH1sWtP1sa9S4wWys3DFH+5A\n"
41
+	"DkuAqk7zAkEAzf4eUH2hp5CIMsXH+WpIzKj09oY1it2CAKjVq4rUELf8iXvmGoFl\n"
42
+	"000spua4MjHNUYm7LR0QaKesKrMyGZUesQJAL8aLdYPJI+SD9Tr/jqLtIkZ4frQe\n"
43
+	"eshw4pvsoyheiHF3zyshO791crAr4EVCx3sMlxB1xnmqLXPCPyCEHxO//QJBAIBY\n"
44
+	"IYkjDZJ6ofGIe1UyXJNvfdkPu9J+ut4wU5jjEcgs6mK62J6RGuFxhy2iOQfFMdjo\n"
45
+	"yL+OCUg7mDCun7uCxrECQAtSvnLOFMjO5qExRjFtwi+b1rcSekd3Osk/izyRFSzg\n"
46
+	"Or+AL56/EKfiogNnFipgaXIbb/xj785Cob6v96XoW1I=\n"
47
+	"-----END RSA PRIVATE KEY-----\n";
48
+
49
+class LayerTracker
50
+{
51
+public:
52
+	struct Item
53
+	{
54
+		int plain;
55
+		int encoded;
56
+	};
57
+
58
+	LayerTracker()
59
+	{
60
+		p = 0;
61
+	}
62
+
63
+	void reset()
64
+	{
65
+		p = 0;
66
+		list.clear();
67
+	}
68
+
69
+	void addPlain(int plain)
70
+	{
71
+		p += plain;
72
+	}
73
+
74
+	void specifyEncoded(int encoded, int plain)
75
+	{
76
+		// can't specify more bytes than we have
77
+		if(plain > p)
78
+			plain = p;
79
+		p -= plain;
80
+		Item i;
81
+		i.plain = plain;
82
+		i.encoded = encoded;
83
+		list += i;
84
+	}
85
+
86
+	int finished(int encoded)
87
+	{
88
+		int plain = 0;
89
+		for(TQValueList<Item>::Iterator it = list.begin(); it != list.end();) {
90
+			Item &i = *it;
91
+
92
+			// not enough?
93
+			if(encoded < i.encoded) {
94
+				i.encoded -= encoded;
95
+				break;
96
+			}
97
+
98
+			encoded -= i.encoded;
99
+			plain += i.plain;
100
+			it = list.remove(it);
101
+		}
102
+		return plain;
103
+	}
104
+
105
+	int p;
106
+	TQValueList<Item> list;
107
+};
108
+
109
+class SecureServerTest : public QServerSocket
110
+{
111
+	Q_OBJECT
112
+public:
113
+	enum { Idle, Handshaking, Active, Closing };
114
+
115
+	SecureServerTest(int _port) : QServerSocket(_port), port(_port)
116
+	{
117
+		sock = new TQSocket;
118
+		connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
119
+		connect(sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
120
+		connect(sock, SIGNAL(error(int)), SLOT(sock_error(int)));
121
+		connect(sock, SIGNAL(bytesWritten(int)), SLOT(sock_bytesWritten(int)));
122
+
123
+		ssl = new QCA::TLS;
124
+		connect(ssl, SIGNAL(handshaken()), SLOT(ssl_handshaken()));
125
+		connect(ssl, SIGNAL(readyRead()), SLOT(ssl_readyRead()));
126
+		connect(ssl, SIGNAL(readyReadOutgoing(int)), SLOT(ssl_readyReadOutgoing(int)));
127
+		connect(ssl, SIGNAL(closed()), SLOT(ssl_closed()));
128
+		connect(ssl, SIGNAL(error(int)), SLOT(ssl_error(int)));
129
+
130
+		cert.fromPEM(pemdata_cert);
131
+		privkey.fromPEM(pemdata_privkey);
132
+
133
+		mode = Idle;
134
+	}
135
+
136
+	~SecureServerTest()
137
+	{
138
+		delete ssl;
139
+		delete sock;
140
+	}
141
+
142
+	void start()
143
+	{
144
+		if(cert.isNull() || privkey.isNull()) {
145
+			printf("Error loading cert and/or private key!\n");
146
+			TTQTimer::singleShot(0, this, SIGNAL(quit()));
147
+			return;
148
+		}
149
+		if(!ok()) {
150
+			printf("Error binding to port %d!\n", port);
151
+			TTQTimer::singleShot(0, this, SIGNAL(quit()));
152
+			return;
153
+		}
154
+		printf("Listening on port %d ...\n", port);
155
+	}
156
+
157
+	void newConnection(int s)
158
+	{
159
+		// Note: only 1 connection supported at a time in this example!
160
+		if(sock->isOpen()) {
161
+			TQSocket tmp;
162
+			tmp.setSocket(s);
163
+			printf("throwing away extra connection\n");
164
+			return;
165
+		}
166
+		mode = Handshaking;
167
+		sock->setSocket(s);
168
+		printf("Connection received!  Starting TLS handshake...\n");
169
+		ssl->setCertificate(cert, privkey);
170
+		ssl->startServer();
171
+	}
172
+
173
+signals:
174
+	void quit();
175
+
176
+private slots:
177
+	void sock_readyRead()
178
+	{
179
+		TQByteArray buf(sock->bytesAvailable());
180
+		int num = sock->readBlock(buf.data(), buf.size());
181
+		if(num < (int)buf.size())
182
+			buf.resize(num);
183
+		ssl->writeIncoming(buf);
184
+	}
185
+
186
+	void sock_connectionClosed()
187
+	{
188
+		printf("Connection closed.\n");
189
+	}
190
+
191
+	void sock_bytesWritten(int x)
192
+	{
193
+		if(mode == Active && sent) {
194
+			int bytes = layer.finished(x);
195
+			bytesLeft -= bytes;
196
+
197
+			if(bytesLeft == 0) {
198
+				mode = Closing;
199
+				printf("SSL shutdown\n");
200
+				ssl->close();
201
+			}
202
+		}
203
+	}
204
+
205
+	void sock_error(int)
206
+	{
207
+		printf("Socket error.\n");
208
+	}
209
+
210
+	void ssl_handshaken()
211
+	{
212
+		printf("Successful SSL handshake.  Waiting for newline.\n");
213
+		layer.reset();
214
+		bytesLeft = 0;
215
+		sent = false;
216
+		mode = Active;
217
+	}
218
+
219
+	void ssl_readyRead()
220
+	{
221
+		TQByteArray a = ssl->read();
222
+		TQString str =
223
+			"<html>\n"
224
+			"<head><title>Test</title></head>\n"
225
+			"<body>this is only a test</body>\n"
226
+			"</html>\n";
227
+		TQCString cs = str.latin1();
228
+		TQByteArray b(cs.length());
229
+		memcpy(b.data(), cs.data(), b.size());
230
+
231
+		printf("Sending test response...\n");
232
+		sent = true;
233
+		layer.addPlain(b.size());
234
+		ssl->write(b);
235
+	}
236
+
237
+	void ssl_readyReadOutgoing(int plainBytes)
238
+	{
239
+		TQByteArray a = ssl->readOutgoing();
240
+		layer.specifyEncoded(a.size(), plainBytes);
241
+		sock->writeBlock(a.data(), a.size());
242
+	}
243
+
244
+	void ssl_closed()
245
+	{
246
+		printf("Closing.\n");
247
+		sock->close();
248
+	}
249
+
250
+	void ssl_error(int x)
251
+	{
252
+		if(x == QCA::TLS::ErrHandshake) {
253
+			printf("SSL Handshake Error!  Closing.\n");
254
+			sock->close();
255
+		}
256
+		else {
257
+			printf("SSL Error!  Closing.\n");
258
+			sock->close();
259
+		}
260
+	}
261
+
262
+private:
263
+	int port;
264
+	TQSocket *sock;
265
+	QCA::TLS *ssl;
266
+	QCA::Cert cert;
267
+	QCA::RSAKey privkey;
268
+
269
+	bool sent;
270
+	int mode;
271
+	int bytesLeft;
272
+	LayerTracker layer;
273
+};
274
+
275
+#include"sslservtest.moc"
276
+
277
+int main(int argc, char **argv)
278
+{
279
+	TQApplication app(argc, argv, false);
280
+	int port = argc > 1 ? TQString(argv[1]).toInt() : 8000;
281
+
282
+	if(!QCA::isSupported(QCA::CAP_TLS)) {
283
+		printf("TLS not supported!\n");
284
+		return 1;
285
+	}
286
+
287
+	SecureServerTest *s = new SecureServerTest(port);
288
+	TQObject::connect(s, SIGNAL(quit()), &app, SLOT(quit()));
289
+	s->start();
290
+	app.exec();
291
+	delete s;
292
+
293
+	return 0;
294
+}

+ 6
- 0
examples/sslservtest/sslservtest.pro View File

@@ -0,0 +1,6 @@
1
+TEMPLATE = app
2
+CONFIG += thread console
3
+TARGET = sslservtest
4
+
5
+SOURCES += sslservtest.cpp
6
+include(../examples.pri)

+ 276
- 0
examples/ssltest/ssltest.cpp View File

@@ -0,0 +1,276 @@
1
+#include<tqapplication.h>
2
+#include<tqdom.h>
3
+#include<tqfile.h>
4
+#include<tqsocket.h>
5
+#include<tqptrlist.h>
6
+#include"base64.h"
7
+#include"qca.h"
8
+
9
+TQCA::Cert readCertXml(const TQDomElement &e)
10
+{
11
+	TQCA::Cert cert;
12
+	// there should be one child data tag
13
+	TQDomElement data = e.elementsByTagName("data").item(0).toElement();
14
+	if(!data.isNull())
15
+		cert.fromDER(Base64::stringToArray(data.text()));
16
+	return cert;
17
+}
18
+
19
+void showCertInfo(const TQCA::Cert &cert)
20
+{
21
+	printf("-- Cert --\n");
22
+	printf(" CN: %s\n", cert.subject()["CN"].latin1());
23
+	printf(" Valid from: %s, until %s\n",
24
+		cert.notBefore().toString().latin1(),
25
+		cert.notAfter().toString().latin1());
26
+	printf(" PEM:\n%s\n", cert.toPEM().latin1());
27
+}
28
+
29
+TQPtrList<TQCA::Cert> getRootCerts(const TQString &store)
30
+{
31
+	TQPtrList<TQCA::Cert> list;
32
+
33
+	// open the Psi rootcerts file
34
+	TQFile f(store);
35
+	if(!f.open(IO_ReadOnly)) {
36
+		printf("unable to open %s\n", f.name().latin1());
37
+		return list;
38
+	}
39
+	TQDomDocument doc;
40
+	doc.setContent(&f);
41
+	f.close();
42
+
43
+	TQDomElement base = doc.documentElement();
44
+	if(base.tagName() != "store") {
45
+		printf("wrong format of %s\n", f.name().latin1());
46
+		return list;
47
+	}
48
+	TQDomNodeList cl = base.elementsByTagName("certificate");
49
+	if(cl.count() == 0) {
50
+		printf("no certs found in %s\n", f.name().latin1());
51
+		return list;
52
+	}
53
+
54
+	int num = 0;
55
+	for(int n = 0; n < (int)cl.count(); ++n) {
56
+		TQCA::Cert *cert = new TQCA::Cert(readCertXml(cl.item(n).toElement()));
57
+		if(cert->isNull()) {
58
+			printf("error reading cert\n");
59
+			delete cert;
60
+			continue;
61
+		}
62
+
63
+		++num;
64
+		list.append(cert);
65
+	}
66
+	printf("imported %d root certs\n", num);
67
+
68
+	return list;
69
+}
70
+
71
+TQString resultToString(int result)
72
+{
73
+	TQString s;
74
+	switch(result) {
75
+		case TQCA::TLS::NoCert:
76
+			s = TQObject::tr("No certificate presented.");
77
+			break;
78
+		case TQCA::TLS::Valid:
79
+			break;
80
+		case TQCA::TLS::HostMismatch:
81
+			s = TQObject::tr("Hostname mismatch.");
82
+			break;
83
+		case TQCA::TLS::Rejected:
84
+			s = TQObject::tr("Root CA rejects the specified purpose.");
85
+			break;
86
+		case TQCA::TLS::Untrusted:
87
+			s = TQObject::tr("Not trusted for the specified purpose.");
88
+			break;
89
+		case TQCA::TLS::SignatureFailed:
90
+			s = TQObject::tr("Invalid signature.");
91
+			break;
92
+		case TQCA::TLS::InvalidCA:
93
+			s = TQObject::tr("Invalid CA certificate.");
94
+			break;
95
+		case TQCA::TLS::InvalidPurpose:
96
+			s = TQObject::tr("Invalid certificate purpose.");
97
+			break;
98
+		case TQCA::TLS::SelfSigned:
99
+			s = TQObject::tr("Certificate is self-signed.");
100
+			break;
101
+		case TQCA::TLS::Revoked:
102
+			s = TQObject::tr("Certificate has been revoked.");