gwenhywfar  5.4.1
syncio_tls.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Wed Apr 28 2010
3  copyright : (C) 2010, 2016 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #define DISABLE_DEBUGLOG
30 
31 /*#define GWEN_TLS_DEBUG*/
32 
33 /* #define GWEN_TLS_USE_OLD_CODE */
34 
35 #include "syncio_tls_p.h"
36 #include "i18n_l.h"
37 
38 #include <gwenhywfar/misc.h>
39 #include <gwenhywfar/debug.h>
40 #include <gwenhywfar/gui.h>
41 #include <gwenhywfar/gui.h>
42 #include <gwenhywfar/pathmanager.h>
43 #include <gwenhywfar/directory.h>
44 #include <gwenhywfar/gwenhywfar.h>
45 #include <gwenhywfar/text.h>
46 
47 #include <assert.h>
48 #include <errno.h>
49 #include <string.h>
50 #include <stdlib.h>
51 
52 #include <gnutls/gnutls.h>
53 #include <gnutls/x509.h>
54 #include <gcrypt.h>
55 
56 
57 
58 GWEN_INHERIT(GWEN_SYNCIO, GWEN_SYNCIO_TLS)
59 
60 
61 #ifndef OS_WIN32
63  "/etc/ssl/certs/ca-certificates.crt",
64  "/etc/ssl/ca-bundle.pem",
65  NULL
66 };
67 #endif
68 
69 
70 
71 
73 {
74  GWEN_SYNCIO *sio;
75  GWEN_SYNCIO_TLS *xio;
76 
77  assert(baseIo);
79  GWEN_NEW_OBJECT(GWEN_SYNCIO_TLS, xio);
80  GWEN_INHERIT_SETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio, xio, GWEN_SyncIo_Tls_FreeData);
81 
82  /* preset data */
83  xio->checkCertFn=GWEN_SyncIo_Tls_Internal_CheckCert;
84 
85  /* set virtual functions */
90 
91  return sio;
92 }
93 
94 
95 
97 {
98  GWEN_SYNCIO_TLS *xio;
99 
100  xio=(GWEN_SYNCIO_TLS *) p;
101  free(xio->localCertFile);
102  free(xio->localKeyFile);
103  free(xio->localTrustFile);
104  free(xio->dhParamFile);
105  free(xio->hostName);
106  GWEN_SslCertDescr_free(xio->peerCertDescr);
107  GWEN_FREE_OBJECT(xio);
108 }
109 
110 
111 
113 {
114  GWEN_SYNCIO_TLS *xio;
116 
117  assert(sio);
118  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
119  assert(xio);
120 
121  oldF=xio->checkCertFn;
122  xio->checkCertFn=f;
123  return oldF;
124 }
125 
126 
127 
129  const GWEN_SSLCERTDESCR *cert)
130 {
131  GWEN_SYNCIO_TLS *xio;
132 
133  assert(sio);
134  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
135  assert(xio);
136 
137  DBG_WARN(GWEN_LOGDOMAIN, "No checkCertFn set, using GWEN_GUI");
138  return GWEN_Gui_CheckCert(cert, sio, 0);
139 }
140 
141 
142 
144 {
145  GWEN_SYNCIO_TLS *xio;
146 
147  assert(sio);
148  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
149  assert(xio);
150 
151  if (xio->checkCertFn) {
152  /* try my own checkCert function first */
153  return xio->checkCertFn(sio, cert);
154  }
155  else {
156  /* none set, call the check cert function of GWEN_GUI (for older code) */
157  DBG_ERROR(GWEN_LOGDOMAIN, "No checkCertFn set, falling back to GUI (SNH!)");
158  return GWEN_SyncIo_Tls_Internal_CheckCert(sio, cert);
159  }
160 }
161 
162 
163 
165 {
166  GWEN_SYNCIO_TLS *xio;
167 
168  assert(sio);
169  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
170  assert(xio);
171 
172  return xio->localCertFile;
173 }
174 
175 
176 
178 {
179  GWEN_SYNCIO_TLS *xio;
180 
181  assert(sio);
182  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
183  assert(xio);
184 
185  free(xio->localCertFile);
186  if (s)
187  xio->localCertFile=strdup(s);
188  else
189  xio->localCertFile=NULL;
190 }
191 
192 
193 
195 {
196  GWEN_SYNCIO_TLS *xio;
197 
198  assert(sio);
199  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
200  assert(xio);
201 
202  return xio->localKeyFile;
203 }
204 
205 
206 
208 {
209  GWEN_SYNCIO_TLS *xio;
210 
211  assert(sio);
212  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
213  assert(xio);
214 
215  free(xio->localKeyFile);
216  if (s)
217  xio->localKeyFile=strdup(s);
218  else
219  xio->localKeyFile=NULL;
220 }
221 
222 
223 
225 {
226  GWEN_SYNCIO_TLS *xio;
227 
228  assert(sio);
229  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
230  assert(xio);
231 
232  return xio->localTrustFile;
233 }
234 
235 
236 
238 {
239  GWEN_SYNCIO_TLS *xio;
240 
241  assert(sio);
242  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
243  assert(xio);
244 
245  free(xio->localTrustFile);
246  if (s)
247  xio->localTrustFile=strdup(s);
248  else
249  xio->localTrustFile=NULL;
250 }
251 
252 
253 
255 {
256  GWEN_SYNCIO_TLS *xio;
257 
258  assert(sio);
259  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
260  assert(xio);
261 
262  return xio->dhParamFile;
263 }
264 
265 
266 
268 {
269  GWEN_SYNCIO_TLS *xio;
270 
271  assert(sio);
272  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
273  assert(xio);
274 
275  free(xio->dhParamFile);
276  if (s)
277  xio->dhParamFile=strdup(s);
278  else
279  xio->dhParamFile=NULL;
280 }
281 
282 
283 
285 {
286  GWEN_SYNCIO_TLS *xio;
287 
288  assert(sio);
289  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
290  assert(xio);
291 
292  return xio->hostName;
293 }
294 
295 
296 
298 {
299  GWEN_SYNCIO_TLS *xio;
300 
301  assert(sio);
302  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
303  assert(xio);
304 
305  free(xio->hostName);
306  if (s)
307  xio->hostName=strdup(s);
308  else
309  xio->hostName=NULL;
310 }
311 
312 
313 
315 {
316  GWEN_SYNCIO_TLS *xio;
317 
318  assert(sio);
319  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
320  assert(xio);
321 
322  return xio->peerCertDescr;
323 }
324 
325 
326 
327 int GWEN_SyncIo_Tls__readFile(const char *fname, GWEN_BUFFER *buf)
328 {
329  FILE *f;
330 
331  f=fopen(fname, "r");
332  if (f==NULL)
333  return GWEN_ERROR_IO;
334 
335  while (!feof(f)) {
336  int rv;
337 
338  GWEN_Buffer_AllocRoom(buf, 512);
339  rv=fread(GWEN_Buffer_GetPosPointer(buf), 1, 512, f);
340  if (rv==0)
341  break;
342  else if (rv<0) {
343  DBG_INFO(GWEN_LOGDOMAIN, "fread(%s): %s", fname, strerror(errno));
344  fclose(f);
345  return GWEN_ERROR_IO;
346  }
347  else {
348  GWEN_Buffer_IncrementPos(buf, rv);
350  }
351  }
352  fclose(f);
353  return 0;
354 }
355 
356 
357 
358 
359 #if GWEN_TLS_USE_SYSTEM_CERTIFICATES
360 # ifndef OS_WIN32
361 static int GWEN_SyncIo_Tls_AddCaCertFolder(GWEN_SYNCIO *sio, const char *folder)
362 {
363  GWEN_SYNCIO_TLS *xio;
364  int rv;
365  int successfullTustFileCount=0;
366 
367  assert(sio);
368  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
369  assert(xio);
370 
371  if (folder && *folder) {
372  GWEN_STRINGLIST *fileList;
373 
374  fileList=GWEN_StringList_new();
375  rv=GWEN_Directory_GetMatchingFilesRecursively(folder, fileList, "*.crt");
376  if (rv<0) {
378  "Error reading list of certificate files (%d) in folder [%s]",
379  rv, folder);
380  }
381  else {
383 
384  se=GWEN_StringList_FirstEntry(fileList);
385  while (se) {
386  const char *s;
387 
389  if (s && *s) {
390  rv=gnutls_certificate_set_x509_trust_file(xio->credentials,
391  s,
392  GNUTLS_X509_FMT_PEM);
393  if (rv<=0) {
395  "gnutls_certificate_set_x509_trust_file(%s): %d (%s)",
396  s, rv, gnutls_strerror(rv));
397  }
398  else {
399  DBG_INFO(GWEN_LOGDOMAIN, "Added %d trusted certs from [%s]", rv, s);
400  successfullTustFileCount++;
401  }
402  }
403 
405  } /* while */
406  }
407  GWEN_StringList_free(fileList);
408  }
409 
410  if (successfullTustFileCount==0) {
411  DBG_ERROR(GWEN_LOGDOMAIN, "No files added from folder [%s]", folder);
412  }
413 
414  return successfullTustFileCount;
415 }
416 # endif
417 #endif
418 
419 
420 
422 {
423  GWEN_SYNCIO_TLS *xio;
424  int rv;
425  uint32_t lflags;
426  const char *custom_ciphers;
427  const char *errPos=NULL;
428 
429  assert(sio);
430  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
431  assert(xio);
432 
433  lflags=GWEN_SyncIo_GetFlags(sio);
434  DBG_INFO(GWEN_LOGDOMAIN, "Preparing SSL (%08x)", lflags);
435 
436  /* init session */
437  if (lflags & GWEN_SYNCIO_FLAGS_PASSIVE) {
438  DBG_INFO(GWEN_LOGDOMAIN, "Init as server");
439  rv=gnutls_init(&xio->session, GNUTLS_SERVER);
440  }
441  else {
442  DBG_INFO(GWEN_LOGDOMAIN, "Init as client");
443  rv=gnutls_init(&xio->session, GNUTLS_CLIENT);
444  }
445  if (rv) {
446  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_init: %d (%s)", rv, gnutls_strerror(rv));
447  return GWEN_ERROR_GENERIC;
448  }
449 
450  /* set cipher priorities */
451  custom_ciphers=getenv("GWEN_TLS_CIPHER_PRIORITIES");
452  /* TODO: make custom ciphers configurable as priority string? */
453  if (custom_ciphers && *custom_ciphers) { /* use cipher list from env var */
454  GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Info, I18N("TLS: SSL cipher priority list: %s"), custom_ciphers);
455  rv=gnutls_priority_set_direct(xio->session, custom_ciphers, &errPos);
456  if (rv!=GNUTLS_E_SUCCESS) {
457  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_priority_set_direct using '%s' failed: %s (%d) [%s]",
458  custom_ciphers, gnutls_strerror(rv), rv, errPos?errPos:"");
459  gnutls_deinit(xio->session);
460  return GWEN_ERROR_GENERIC;
461  }
462  }
463  else { /* use default ciphers from GnuTLS */
464  GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Notice, I18N("Using GnuTLS default ciphers."));
465  rv=gnutls_set_default_priority(xio->session);
466  if (rv!=GNUTLS_E_SUCCESS) {
467  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_set_default_priority failed: %s (%d)", gnutls_strerror(rv), rv);
468  gnutls_deinit(xio->session);
469  return GWEN_ERROR_GENERIC;
470  }
471  }
472 
473  /* protect against too-many-known-ca problem */
474  gnutls_handshake_set_max_packet_length(xio->session, 64*1024);
475 
476  /* let a server request peer certs */
477  if ((lflags & GWEN_SYNCIO_FLAGS_PASSIVE) &&
479  gnutls_certificate_server_set_request(xio->session, GNUTLS_CERT_REQUIRE);
480 
481  /* prepare cert credentials */
482  rv=gnutls_certificate_allocate_credentials(&xio->credentials);
483  if (rv) {
484  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_certificate_allocate_credentials: %d (%s)", rv, gnutls_strerror(rv));
485  gnutls_deinit(xio->session);
486  return GWEN_ERROR_GENERIC;
487  }
488 
489  /* possibly set key file and cert file */
490  if (xio->localCertFile && xio->localKeyFile) {
491  rv=gnutls_certificate_set_x509_key_file(xio->credentials,
492  xio->localCertFile,
493  xio->localKeyFile,
494  GNUTLS_X509_FMT_PEM);
495  if (rv<0) {
496  if (rv) {
497  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_certificate_set_x509_key_file: %d (%s)", rv, gnutls_strerror(rv));
498  gnutls_certificate_free_credentials(xio->credentials);
499  gnutls_deinit(xio->session);
500  return GWEN_ERROR_GENERIC;
501  }
502  }
503  }
504 
505  /* find default trust file if none is selected */
507 #if GWEN_TLS_USE_SYSTEM_CERTIFICATES
508  /* disable setting of default trust file as discussed on aqbanking-users.
509  * The rationale is that without this file being set gnutls should behave
510  * correctly on each system.
511  * On Linux systems it should use the standard mechanism of the underlying
512  * distribution. On Windows the default CA store should be used (if given
513  * "--with-default-trust-store-file" to "./configure" of GNUTLS).
514  */
515  int trustFileSet=0;
516 
517 
518  if (trustFileSet==0) {
519  /* Adds the system's default trusted CAs in order to verify client or server certificates. */
520  rv=gnutls_certificate_set_x509_system_trust(xio->credentials);
521  if (rv<=0) {
522  DBG_WARN(GWEN_LOGDOMAIN, "gnutls_certificate_set_x509_system_trust: %d (%s)", rv, gnutls_strerror(rv));
523  }
524  else {
525  DBG_INFO(GWEN_LOGDOMAIN, "Added %d default trusted certs from system", rv);
526  trustFileSet=1;
527  }
528  }
529 
530  /* try to find OpenSSL certificates */
531 # ifdef OS_WIN32
532  if (trustFileSet==0) {
533  char defaultPath[2*MAX_PATH+1];
534  const char *defaultFile = "ca-bundle.crt";
535  GWEN_STRINGLIST *paths;
536  GWEN_BUFFER *nbuf;
537 
538  if (GWEN_Directory_GetPrefixDirectory(defaultPath, sizeof(defaultPath))) {
539  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_certificate_set_x509_key_file: could not get install prefix");
540  return GWEN_ERROR_GENERIC;
541  }
542  if (strcat_s(defaultPath, sizeof(defaultPath), "\\share\\gwenhywfar")) {
543  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_certificate_set_x509_key_file: no memory on creating search path");
544  return GWEN_ERROR_GENERIC;
545  }
546 
547  paths=GWEN_StringList_new();
548  GWEN_StringList_AppendString(paths, defaultPath, 0, 0);
549 
550  nbuf=GWEN_Buffer_new(0, 256, 0, 1);
551  rv=GWEN_Directory_FindFileInPaths(paths, defaultFile, nbuf);
552  GWEN_StringList_free(paths);
553  if (rv==0) {
555  "Using default ca-bundle from [%s]",
556  GWEN_Buffer_GetStart(nbuf));
557 
558  rv=gnutls_certificate_set_x509_trust_file(xio->credentials,
559  GWEN_Buffer_GetStart(nbuf),
560  GNUTLS_X509_FMT_PEM);
561  if (rv<=0) {
563  "gnutls_certificate_set_x509_trust_file(%s): %d (%s)",
564  GWEN_Buffer_GetStart(nbuf), rv, gnutls_strerror(rv));
565  }
566  else {
568  "Added %d trusted certs from [%s]", rv, GWEN_Buffer_GetStart(nbuf));
569  trustFileSet=1;
570  }
571  }
572  GWEN_Buffer_free(nbuf);
573  }
574 # endif
575 
576 
577 # ifndef OS_WIN32
578  /* try to finde certificate bundle */
579  if (trustFileSet==0) {
580  int i;
581  const char *sCertFile=NULL;
582 
583  for (i=0; ; i++) {
584  sCertFile=SYNCIO_TLS_SYSTEM_CERTFILES[i];
585  if (sCertFile==NULL)
586  break;
588  DBG_INFO(GWEN_LOGDOMAIN, "Found system-wide cert bundle in %s", sCertFile);
589  break;
590  }
591  }
592 
593  if (sCertFile && *sCertFile) {
594  rv=gnutls_certificate_set_x509_trust_file(xio->credentials, sCertFile, GNUTLS_X509_FMT_PEM);
595  if (rv<=0) {
596  DBG_WARN(GWEN_LOGDOMAIN, "gnutls_certificate_set_x509_trust_file(%s): %d (%s)", sCertFile, rv, gnutls_strerror(rv));
597  }
598  else {
599  DBG_INFO(GWEN_LOGDOMAIN, "Added %d trusted certs from [%s]", rv, sCertFile);
600  trustFileSet=1;
601  }
602  }
603  else {
604  DBG_ERROR(GWEN_LOGDOMAIN, "No system-wide certificate bundle found.");
605  }
606  }
607 
608  /* try to find ca-certificates (at least available on Debian systems) */
609  if (trustFileSet==0) {
610  rv=GWEN_Directory_GetPath("/usr/share/ca-certificates", GWEN_PATH_FLAGS_NAMEMUSTEXIST);
611  if (rv>=0) {
612  rv=GWEN_SyncIo_Tls_AddCaCertFolder(sio, "/usr/share/ca-certificates");
613  if (rv<=0) {
614  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
615  }
616  else {
617  trustFileSet=1;
618  }
619  }
620  }
621 
622 # endif
623 
624 
625  if (trustFileSet==0) {
626 
627  /* TODO: use gnutls_certificate_set_x509_system_trust() */
628  trustFileSet=1;
629  }
630 
631 
632 
633  if (trustFileSet==0) {
634  DBG_WARN(GWEN_LOGDOMAIN, "No default bundle file found");
635  }
636 #endif
637  }
638 
639  /* possibly set trust file */
640  if (xio->localTrustFile) {
641  rv=gnutls_certificate_set_x509_trust_file(xio->credentials,
642  xio->localTrustFile,
643  GNUTLS_X509_FMT_PEM);
644  if (rv<=0) {
646  "gnutls_certificate_set_x509_trust_file(%s): %d (%s)",
647  (xio->localTrustFile)?(xio->localTrustFile):"-none-",
648  rv, gnutls_strerror(rv));
649  gnutls_certificate_free_credentials(xio->credentials);
650  gnutls_deinit(xio->session);
651  return GWEN_ERROR_GENERIC;
652  }
653  else {
655  "Added %d trusted certs", rv);
656  }
657  }
658 
659  /* possibly set DH params */
660  if (xio->dhParamFile) {
661  GWEN_BUFFER *dbuf;
662 
663  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
664  rv=GWEN_SyncIo_Tls__readFile(xio->dhParamFile, dbuf);
665  if (rv) {
666  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
667  GWEN_Buffer_free(dbuf);
668  gnutls_certificate_free_credentials(xio->credentials);
669  gnutls_deinit(xio->session);
670  return rv;
671  }
672  else {
673  gnutls_datum_t d;
674  gnutls_dh_params_t dh_params=NULL;
675 
676  rv=gnutls_dh_params_init(&dh_params);
677  if (rv<0) {
678  GWEN_Buffer_free(dbuf);
679  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_dh_params_init: %d (%s)", rv, gnutls_strerror(rv));
680  gnutls_certificate_free_credentials(xio->credentials);
681  gnutls_deinit(xio->session);
682  return GWEN_ERROR_GENERIC;
683  }
684 
685  d.size=GWEN_Buffer_GetUsedBytes(dbuf);
686  d.data=(unsigned char *)GWEN_Buffer_GetStart(dbuf);
687 
688  rv=gnutls_dh_params_import_pkcs3(dh_params, &d, GNUTLS_X509_FMT_PEM);
689  if (rv<0) {
690  GWEN_Buffer_free(dbuf);
691  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_dh_params_import_pkcs3: %d (%s)", rv, gnutls_strerror(rv));
692  gnutls_certificate_free_credentials(xio->credentials);
693  gnutls_deinit(xio->session);
694  return GWEN_ERROR_GENERIC;
695  }
696  GWEN_Buffer_free(dbuf);
697 
698  gnutls_certificate_set_dh_params(xio->credentials, dh_params);
699  }
700  }
701 
702  /* set credentials in TLS session */
703  rv=gnutls_credentials_set(xio->session, GNUTLS_CRD_CERTIFICATE, xio->credentials);
704  if (rv<0) {
705  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_credentials_set: %d (%s)", rv, gnutls_strerror(rv));
706  gnutls_certificate_free_credentials(xio->credentials);
707  gnutls_deinit(xio->session);
708  return GWEN_ERROR_GENERIC;
709  }
710 
711  /* we use our own push/pull functions */
712  gnutls_transport_set_ptr(xio->session, (gnutls_transport_ptr_t)sio);
713  gnutls_transport_set_push_function(xio->session, GWEN_SyncIo_Tls_Push);
714  gnutls_transport_set_pull_function(xio->session, GWEN_SyncIo_Tls_Pull);
715 #if GNUTLS_VERSION_NUMBER < 0x020c00
716  /* This function must be set to 0 in GNUTLS versions < 2.12.0 because we use
717  * custom push/pull functions.
718  * In GNUTLS 2.12.x this is set to 0 and since version 3 this functions is removed
719  * completely.
720  * So we only call this function now for GNUTLS < 2.12.0.
721  */
722  gnutls_transport_set_lowat(xio->session, 0);
723 #endif
724 
725  xio->prepared=1;
726 
727  return 0;
728 }
729 
730 
731 
733 {
734  GWEN_SYNCIO_TLS *xio;
735 
736  assert(sio);
737  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
738  assert(xio);
739 
740  if (xio->prepared) {
741  gnutls_certificate_free_credentials(xio->credentials);
742  gnutls_deinit(xio->session);
743  xio->prepared=0;
744  }
745 }
746 
747 
748 
750 {
751  GWEN_SYNCIO_TLS *xio;
752  const gnutls_datum_t *cert_list;
753  unsigned int cert_list_size;
754  size_t size;
755  GWEN_SSLCERTDESCR *certDescr;
756  char buffer1[64];
757  time_t t0;
758  int rv;
759  uint32_t lflags;
760  uint32_t errFlags=0;
761  int i;
762  unsigned int status;
763  GWEN_BUFFER *sbuf=NULL;
764 
765  assert(sio);
766  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
767  assert(xio);
768 
769  lflags=GWEN_SyncIo_GetFlags(sio);
770 
771  if (xio->peerCertDescr) {
772  GWEN_SslCertDescr_free(xio->peerCertDescr);
773  xio->peerCertDescr=NULL;
774  }
775  xio->peerCertFlags=0;
776 
777  t0=time(NULL);
778  if (t0<0) {
779  DBG_WARN(GWEN_LOGDOMAIN, "Could not get system time");
780  errFlags|=GWEN_SSL_CERT_FLAGS_SYSTEM;
781  }
782 
783  /* create new cert description, check cert on the fly */
784  certDescr=GWEN_SslCertDescr_new();
785 
786  /* some general tests */
788  gnutls_certificate_set_verify_flags(xio->credentials,
789  GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
790 
791  rv=gnutls_certificate_verify_peers2(xio->session, &status);
792  if (rv<0) {
793  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_certificate_verify_peers2: %d (%s)", rv, gnutls_strerror(rv));
794  GWEN_SslCertDescr_free(certDescr);
796  }
797 
798  if (gnutls_certificate_type_get(xio->session)!=GNUTLS_CRT_X509) {
799  DBG_INFO(GWEN_LOGDOMAIN, "Certificate is not X.509");
800 
801  GWEN_SslCertDescr_free(certDescr);
803  }
804 
805  if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
806  DBG_INFO(GWEN_LOGDOMAIN, "Signer not found");
808  I18N("Signer not found"));
810  }
811 
812  if (status & GNUTLS_CERT_INVALID) {
813  DBG_INFO(GWEN_LOGDOMAIN, "Certificate is not trusted");
815  I18N("Certificate is not trusted"));
816  errFlags|=GWEN_SSL_CERT_FLAGS_INVALID;
817  }
818 
819  if (status & GNUTLS_CERT_REVOKED) {
820  DBG_INFO(GWEN_LOGDOMAIN, "Certificate has been revoked");
822  I18N("Certificate has been revoked"));
823  errFlags|=GWEN_SSL_CERT_FLAGS_REVOKED;
824  }
825 
826  cert_list=gnutls_certificate_get_peers(xio->session, &cert_list_size);
827  if (cert_list==NULL || cert_list_size==0) {
828  DBG_INFO(GWEN_LOGDOMAIN, "No peer certificates found");
829  return GWEN_ERROR_NO_DATA;
830  }
831 
832  for (i=0; i<(int) cert_list_size; i++) {
833  gnutls_x509_crt_t cert;
834  time_t t;
835 
836  rv=gnutls_x509_crt_init(&cert);
837  if (rv!=0) {
838  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_init: %d (%s)", rv, gnutls_strerror(rv));
839  return GWEN_ERROR_GENERIC;
840  }
841 
842  rv=gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER); /* TODO: shouldn't we use the index?? */
843  if (rv!=0) {
844  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_import: %d (%s)", rv, gnutls_strerror(rv));
845  gnutls_x509_crt_deinit(cert);
846  return GWEN_ERROR_GENERIC;
847  }
848 
849  if (i==0) {
850  gnutls_datum_t n= {NULL, 0};
851  gnutls_datum_t e= {NULL, 0};
852 
853  /* get public key from cert, if any */
854  rv=gnutls_x509_crt_get_pk_rsa_raw(cert, &n, &e);
855  if (rv!=0) {
856  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_pk_rsa_raw: %d (%s)", rv, gnutls_strerror(rv));
857  }
858  else {
859  GWEN_BUFFER *kbuf;
860 
861  DBG_INFO(GWEN_LOGDOMAIN, "Key stored within certificate, extracting (modlen=%d, explen=%d)",
862  n.size, e.size);
863 
864  kbuf=GWEN_Buffer_new(0, 256, 0, 1);
865 
866  if (n.data && n.size) {
867  /* store public modulus */
868  GWEN_Text_ToHexBuffer((const char *)(n.data), n.size, kbuf, 0, 0, 0);
870  GWEN_Buffer_Reset(kbuf);
871  }
872 
873  if (e.data && e.size) {
874  /* store public exponent */
875  GWEN_Text_ToHexBuffer((const char *)(e.data), e.size, kbuf, 0, 0, 0);
877  GWEN_Buffer_Reset(kbuf);
878  }
879 
880  GWEN_Buffer_free(kbuf);
881  if (n.data)
882  gcry_free(n.data);
883  if (e.data)
884  gcry_free(e.data);
885  }
886 
887  /* get fingerprint (MD5) */
888  size=16;
889  rv=gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_MD5, buffer1, &size);
890  if (rv!=0) {
891  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_fingerprint(MD5): %d (%s)", rv, gnutls_strerror(rv));
892  GWEN_SslCertDescr_free(certDescr);
893  gnutls_x509_crt_deinit(cert);
894  return GWEN_ERROR_GENERIC;
895  }
896  else {
897  GWEN_BUFFER *dbuf;
898 
899  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
900  if (GWEN_Text_ToHexBuffer(/* GCC4 pointer-signedness fix: */ buffer1,
901  size, dbuf, 2, ':', 0)) {
903  "Could not convert fingerprint to hex");
904  }
905  else {
907  }
908  GWEN_Buffer_free(dbuf);
909  }
910 
911  /* get fingerprint (SHA1) */
912  size=sizeof(buffer1);
913  rv=gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, buffer1, &size);
914  if (rv!=0) {
915  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_fingerprint(SHA1): %d (%s)", rv, gnutls_strerror(rv));
916  GWEN_SslCertDescr_free(certDescr);
917  gnutls_x509_crt_deinit(cert);
918  return GWEN_ERROR_GENERIC;
919  }
920  else {
921  GWEN_BUFFER *dbuf;
922 
923  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
924  if (GWEN_Text_ToHexBuffer(/* GCC4 pointer-signedness fix: */ buffer1,
925  size, dbuf, 2, ':', 0)) {
927  "Could not convert fingerprint to hex");
928  }
929  else {
931  }
932  GWEN_Buffer_free(dbuf);
933  }
934 
935  /* get fingerprint (SHA512) */
936  size=sizeof(buffer1);
937  rv=gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA512, buffer1, &size);
938  if (rv!=0) {
939  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_fingerprint(SHA512): %d (%s)", rv, gnutls_strerror(rv));
940  GWEN_SslCertDescr_free(certDescr);
941  gnutls_x509_crt_deinit(cert);
942  return GWEN_ERROR_GENERIC;
943  }
944  else {
945  GWEN_BUFFER *dbuf;
946 
947  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
948  if (GWEN_Text_ToHexBuffer(/* GCC4 pointer-signedness fix: */ buffer1,
949  size, dbuf, 2, ':', 0)) {
951  "Could not convert fingerprint to hex");
952  }
953  else {
955  }
956  GWEN_Buffer_free(dbuf);
957  }
958 
959 
960  if (xio->hostName) {
961  DBG_INFO(GWEN_LOGDOMAIN, "Checking hostname [%s]", xio->hostName);
962  if (!gnutls_x509_crt_check_hostname(cert, xio->hostName)) {
964  "Certificate was not issued for this host");
966  I18N("Certificate was not issued for this host"));
968  }
969  else {
970  DBG_INFO(GWEN_LOGDOMAIN, "Cert is for this server");
971  }
972  }
973  else {
975  "Hostname is not set, unable to verify the sender");
977  I18N("No hostname to verify the sender!"));
978  }
979 
980  }
981 
982  /* get activation time */
983  t=gnutls_x509_crt_get_activation_time(cert);
984  if (t<0) {
985  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_activation_time: %d (%s)", rv, gnutls_strerror(rv));
987  }
988  else {
989  if (t>t0) {
990  DBG_INFO(GWEN_LOGDOMAIN, "Cert is not yet active");
992  }
993  if (i==0) {
994  GWEN_TIME *ti;
995 
996  ti=GWEN_Time_fromSeconds(t);
997  if (ti)
998  GWEN_SslCertDescr_SetNotBefore(certDescr, ti);
999  GWEN_Time_free(ti);
1000  }
1001  }
1002 
1003  /* get expiration time */
1004  t=gnutls_x509_crt_get_expiration_time(cert);
1005  if (t<0) {
1006  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_expiration_time: %d (%s)", rv, gnutls_strerror(rv));
1007  errFlags|=GWEN_SSL_CERT_FLAGS_BAD_DATA;
1008  }
1009  else {
1010  if (t<t0) {
1011  DBG_INFO(GWEN_LOGDOMAIN, "Cert has expired");
1012  errFlags|=GWEN_SSL_CERT_FLAGS_EXPIRED;
1013  }
1014  if (i==0) {
1015  GWEN_TIME *ti;
1016 
1017  ti=GWEN_Time_fromSeconds(t);
1018  if (ti)
1019  GWEN_SslCertDescr_SetNotAfter(certDescr, ti);
1020  GWEN_Time_free(ti);
1021  }
1022  }
1023 
1024  if (i==0) {
1025  /* get owner information, but only for first cert */
1026  size=sizeof(buffer1)-1;
1027  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, buffer1, &size);
1028  if (rv==0) {
1029  GWEN_SslCertDescr_SetCommonName(certDescr, buffer1);
1030  if (xio->hostName && strcasecmp(xio->hostName, buffer1)!=0) {
1031  DBG_INFO(GWEN_LOGDOMAIN, "Owner of certificate does not match hostname");
1033  }
1034  }
1035 
1036  size=sizeof(buffer1)-1;
1037  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, 0, buffer1, &size);
1038  if (rv==0)
1039  GWEN_SslCertDescr_SetOrganizationName(certDescr, buffer1);
1040 
1041  size=sizeof(buffer1)-1;
1042  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, 0, buffer1, &size);
1043  if (rv==0)
1044  GWEN_SslCertDescr_SetOrganizationalUnitName(certDescr, buffer1);
1045 
1046  size=sizeof(buffer1)-1;
1047  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_LOCALITY_NAME, 0, 0, buffer1, &size);
1048  if (rv==0)
1049  GWEN_SslCertDescr_SetLocalityName(certDescr, buffer1);
1050 
1051  size=sizeof(buffer1)-1;
1052  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, 0, buffer1, &size);
1053  if (rv==0)
1054  GWEN_SslCertDescr_SetStateOrProvinceName(certDescr, buffer1);
1055 
1056  size=sizeof(buffer1)-1;
1057  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COUNTRY_NAME, 0, 0, buffer1, &size);
1058  if (rv==0)
1059  GWEN_SslCertDescr_SetCountryName(certDescr, buffer1);
1060  }
1061 
1062  gnutls_x509_crt_deinit(cert);
1063  }
1064 
1065  /* done */
1066  if (errFlags)
1067  GWEN_SslCertDescr_SetIsError(certDescr, 1);
1068  else
1069  errFlags|=GWEN_SSL_CERT_FLAGS_OK;
1070 
1071  sbuf=GWEN_Buffer_new(0, 256, 0, 1);
1072 
1073  if (errFlags & GWEN_SSL_CERT_FLAGS_SIGNER_NOT_FOUND) {
1074  if (GWEN_Buffer_GetUsedBytes(sbuf))
1075  GWEN_Buffer_AppendString(sbuf, "; ");
1076  GWEN_Buffer_AppendString(sbuf, I18N("Signer not found"));
1077  }
1078 
1079  if (errFlags & GWEN_SSL_CERT_FLAGS_INVALID) {
1080  if (GWEN_Buffer_GetUsedBytes(sbuf))
1081  GWEN_Buffer_AppendString(sbuf, "; ");
1082  GWEN_Buffer_AppendString(sbuf, I18N("Certificate is not trusted"));
1083  }
1084 
1085  if (errFlags & GWEN_SSL_CERT_FLAGS_REVOKED) {
1086  if (GWEN_Buffer_GetUsedBytes(sbuf))
1087  GWEN_Buffer_AppendString(sbuf, "; ");
1088  GWEN_Buffer_AppendString(sbuf, I18N("Certificate has been revoked"));
1089  }
1090 
1091  if (errFlags & GWEN_SSL_CERT_FLAGS_EXPIRED) {
1092  if (GWEN_Buffer_GetUsedBytes(sbuf))
1093  GWEN_Buffer_AppendString(sbuf, "; ");
1094  GWEN_Buffer_AppendString(sbuf, I18N("Certificate has expired"));
1095  }
1096 
1097  if (errFlags & GWEN_SSL_CERT_FLAGS_NOT_ACTIVE) {
1098  if (GWEN_Buffer_GetUsedBytes(sbuf))
1099  GWEN_Buffer_AppendString(sbuf, "; ");
1100  GWEN_Buffer_AppendString(sbuf, I18N("Certificate is not active yet"));
1101  }
1102 
1103  if (errFlags & GWEN_SSL_CERT_FLAGS_BAD_HOSTNAME) {
1104  if (GWEN_Buffer_GetUsedBytes(sbuf))
1105  GWEN_Buffer_AppendString(sbuf, "; ");
1106  GWEN_Buffer_AppendString(sbuf, I18N("Certificate owner does not match hostname"));
1107  }
1108 
1109  if (errFlags & GWEN_SSL_CERT_FLAGS_BAD_DATA) {
1110  if (GWEN_Buffer_GetUsedBytes(sbuf))
1111  GWEN_Buffer_AppendString(sbuf, "; ");
1112  GWEN_Buffer_AppendString(sbuf, I18N("Certificate contains invalid information"));
1113  }
1114 
1115  if (errFlags & GWEN_SSL_CERT_FLAGS_SYSTEM) {
1116  if (GWEN_Buffer_GetUsedBytes(sbuf))
1117  GWEN_Buffer_AppendString(sbuf, "; ");
1118  GWEN_Buffer_AppendString(sbuf, I18N("A system error occurred while checking the certificate"));
1119  }
1120 
1121  if (errFlags & GWEN_SSL_CERT_FLAGS_OK) {
1122  if (GWEN_Buffer_GetUsedBytes(sbuf))
1123  GWEN_Buffer_AppendString(sbuf, "; ");
1124  GWEN_Buffer_AppendString(sbuf, I18N("The certificate is valid"));
1125  }
1126 
1128  GWEN_SslCertDescr_SetStatusFlags(certDescr, errFlags);
1129  GWEN_Buffer_free(sbuf);
1130 
1131 #if 0
1132  if (1) {
1133  GWEN_DB_NODE *dbTest;
1134 
1135  dbTest=GWEN_DB_Group_new("Cert");
1136  GWEN_SslCertDescr_toDb(certDescr, dbTest);
1137  GWEN_DB_Dump(dbTest, 2);
1138  GWEN_DB_Group_free(dbTest);
1139  }
1140 #endif
1141 
1142  xio->peerCertDescr=certDescr;
1143  xio->peerCertFlags=errFlags;
1144 
1145  return 0;
1146 }
1147 
1148 
1149 
1150 ssize_t GWEN_SyncIo_Tls_Pull(gnutls_transport_ptr_t p, void *buf, size_t len)
1151 {
1152  GWEN_SYNCIO *sio;
1153  GWEN_SYNCIO_TLS *xio;
1154  GWEN_SYNCIO *baseIo;
1155  int rv;
1156 
1157  sio=(GWEN_SYNCIO *) p;
1158  assert(sio);
1159  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1160  assert(xio);
1161 
1162  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PULL: %d bytes", (int)len);
1163  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1164  assert(baseIo);
1165 
1166  rv=GWEN_SyncIo_Read(baseIo, buf, len);
1167  if (rv<0) {
1168  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1169  gnutls_transport_set_errno(xio->session, errno);
1170  return (ssize_t)-1;
1171  }
1172 
1173  gnutls_transport_set_errno(xio->session, 0);
1174  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PULL: returning %d bytes", rv);
1175  /*GWEN_Text_DumpString(buf, rv, 2);*/
1176  return rv;
1177 }
1178 
1179 
1180 
1181 ssize_t GWEN_SyncIo_Tls_Push(gnutls_transport_ptr_t p, const void *buf, size_t len)
1182 {
1183  GWEN_SYNCIO *sio;
1184  GWEN_SYNCIO_TLS *xio;
1185  GWEN_SYNCIO *baseIo;
1186  int rv;
1187 
1188  sio=(GWEN_SYNCIO *) p;
1189  assert(sio);
1190  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1191  assert(xio);
1192 
1193  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PUSH: %d bytes", (int)len);
1194  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1195  assert(baseIo);
1196 
1197  rv=GWEN_SyncIo_Write(baseIo, buf, len);
1198  if (rv<0) {
1199  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1200  gnutls_transport_set_errno(xio->session, errno);
1201  return (ssize_t)-1;
1202  }
1203 
1204  gnutls_transport_set_errno(xio->session, 0);
1205  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PUSH: returning %d bytes", rv);
1206  /*GWEN_Text_DumpString(buf, rv, 2);*/
1207  return rv;
1208 }
1209 
1210 
1211 
1213 {
1214  GWEN_SYNCIO_TLS *xio;
1215  const char *s;
1216  gnutls_kx_algorithm_t kx;
1217  GWEN_BUFFER *cbuf;
1218  GWEN_BUFFER *sbuf;
1219 
1220  assert(sio);
1221  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1222  assert(xio);
1223 
1224  cbuf=GWEN_Buffer_new(0, 256, 0, 1);
1225  sbuf=GWEN_Buffer_new(0, 256, 0, 1);
1226 
1227  /* protocol */
1228  s=gnutls_protocol_get_name(gnutls_protocol_get_version(xio->session));
1229  if (s && *s) {
1230  if (GWEN_Buffer_GetUsedBytes(cbuf))
1231  GWEN_Buffer_AppendString(cbuf, " ");
1232  GWEN_Buffer_AppendString(cbuf, "Protocol: ");
1233  GWEN_Buffer_AppendString(cbuf, s);
1234 
1235  GWEN_Buffer_AppendString(sbuf, s);
1236  }
1237  GWEN_Buffer_AppendString(sbuf, ":");
1238 
1239  /* key exchange algorithm */
1240  kx=gnutls_kx_get(xio->session);
1241  s=gnutls_kx_get_name(kx);
1242  if (s && *s) {
1243  if (GWEN_Buffer_GetUsedBytes(cbuf))
1244  GWEN_Buffer_AppendString(cbuf, " ");
1245  GWEN_Buffer_AppendString(cbuf, "Key exchange algorithm: ");
1246  GWEN_Buffer_AppendString(cbuf, s);
1247  GWEN_Buffer_AppendString(sbuf, s);
1248  }
1249  GWEN_Buffer_AppendString(sbuf, "-");
1250 
1251  /* cipher */
1252  s=gnutls_cipher_get_name(gnutls_cipher_get(xio->session));
1253  if (s && *s) {
1254  if (GWEN_Buffer_GetUsedBytes(cbuf))
1255  GWEN_Buffer_AppendString(cbuf, " ");
1256  GWEN_Buffer_AppendString(cbuf, "cipher algorithm: ");
1257  GWEN_Buffer_AppendString(cbuf, s);
1258  GWEN_Buffer_AppendString(sbuf, s);
1259  }
1260  GWEN_Buffer_AppendString(sbuf, ":");
1261 
1262  /* MAC algorithm */
1263  s=gnutls_mac_get_name(gnutls_mac_get(xio->session));
1264  if (s && *s) {
1265  if (GWEN_Buffer_GetUsedBytes(cbuf))
1266  GWEN_Buffer_AppendString(cbuf, " ");
1267  GWEN_Buffer_AppendString(cbuf, "MAC algorithm: ");
1268  GWEN_Buffer_AppendString(cbuf, s);
1269  GWEN_Buffer_AppendString(sbuf, s);
1270  }
1271 
1272 
1274  GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Info, I18N("TLS: SSL-Ciphers negotiated: %s"), GWEN_Buffer_GetStart(sbuf));
1275  GWEN_Buffer_free(cbuf);
1276  GWEN_Buffer_free(sbuf);
1277 
1278  /* possibly show warning */
1279  switch (gnutls_cipher_get(xio->session)) {
1280  case GNUTLS_CIPHER_ARCFOUR_128:
1281  case GNUTLS_CIPHER_3DES_CBC:
1282  case GNUTLS_CIPHER_AES_128_CBC:
1283  case GNUTLS_CIPHER_ARCFOUR_40:
1284  case GNUTLS_CIPHER_CAMELLIA_128_CBC:
1285  GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error, I18N("TLS: Warning - The server has chosen unsafe SSL-Ciphers!"));
1286  break;
1287  case GNUTLS_CIPHER_AES_256_CBC:
1288  case GNUTLS_CIPHER_CAMELLIA_256_CBC:
1289  case GNUTLS_CIPHER_RC2_40_CBC:
1290  case GNUTLS_CIPHER_DES_CBC:
1291 #ifdef GNUTLS_CIPHER_AES_192_CBC
1292  case GNUTLS_CIPHER_AES_192_CBC: /* new in gnutls-2.9.8, so i.e. not available in gnutls-2.8.x */
1293 #endif
1294  default:
1295  break;
1296  }
1297 }
1298 
1299 
1300 
1302 {
1303  GWEN_SYNCIO_TLS *xio;
1304  GWEN_SYNCIO *baseIo;
1305  int rv;
1306 
1307  assert(sio);
1308  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1309  assert(xio);
1310 
1311  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1312  assert(baseIo);
1313 
1316  DBG_ERROR(GWEN_LOGDOMAIN, "Base layer is not connected");
1317  return GWEN_ERROR_NOT_CONNECTED;
1318  }
1319  }
1320  else {
1321  DBG_INFO(GWEN_LOGDOMAIN, "Connecting base layer");
1322  rv=GWEN_SyncIo_Connect(baseIo);
1323  if (rv<0) {
1324  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1325  return rv;
1326  }
1327  DBG_INFO(GWEN_LOGDOMAIN, "Base layer connected");
1328  }
1329 
1330  rv=GWEN_SyncIo_Tls_Prepare(sio);
1331  if (rv<0) {
1332  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1333  GWEN_SyncIo_Disconnect(baseIo);
1334  return rv;
1335  }
1336 
1337  do {
1338  rv=gnutls_handshake(xio->session);
1339  }
1340  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1341 
1342  if (rv) {
1343  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_handshake: %d (%s) [%s]",
1344  rv, gnutls_strerror(rv), gnutls_error_is_fatal(rv)?"fatal":"non-fatal");
1345  if (rv==GNUTLS_E_UNEXPECTED_PACKET_LENGTH) {
1348  I18N("A TLS handshake error occurred. "
1349  "If you are using AqBanking you should "
1350  "consider enabling the option "
1351  "\"force SSLv3\" in the user settings "
1352  "dialog."));
1353  }
1354  else {
1357  I18N("TLS Handshake Error: %d (%s)"),
1358  rv,
1359  gnutls_strerror(rv));
1360  }
1363  GWEN_SyncIo_Disconnect(baseIo);
1364  return GWEN_ERROR_SSL;
1365  }
1366  else {
1367  /* show session info */
1369 
1370  /* check certificate */
1373  if (rv<0) {
1375  DBG_ERROR(GWEN_LOGDOMAIN, "No peer certificate when needed, aborting connection");
1378  GWEN_SyncIo_Disconnect(baseIo);
1379  return GWEN_ERROR_SSL_SECURITY;
1380  }
1381  else {
1382  DBG_INFO(GWEN_LOGDOMAIN, "SSL connected (insecure)");
1384  return 0;
1385  }
1386  }
1387  else {
1388  /* present cert to the user */
1389  rv=GWEN_SyncIo_Tls_CheckCert(sio, xio->peerCertDescr);
1390  if (rv<0) {
1391  DBG_ERROR(GWEN_LOGDOMAIN, "Peer cert not accepted (%d), aborting", rv);
1394  GWEN_SyncIo_Disconnect(baseIo);
1395  return GWEN_ERROR_SSL_SECURITY;
1396  }
1397  else {
1398  DBG_INFO(GWEN_LOGDOMAIN, "SSL connected (secure)");
1401  return 0;
1402  }
1403  }
1404  }
1405 }
1406 
1407 
1408 
1410 {
1411  GWEN_SYNCIO_TLS *xio;
1412  GWEN_SYNCIO *baseIo;
1413  int rv;
1414 
1415  assert(sio);
1416  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1417  assert(xio);
1418 
1419  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1420  assert(baseIo);
1421 
1423  DBG_INFO(GWEN_LOGDOMAIN, "Not connected");
1425  GWEN_SyncIo_Disconnect(baseIo);
1426  return GWEN_ERROR_NOT_CONNECTED;
1427  }
1428 
1429  do {
1430  rv=gnutls_bye(xio->session, GNUTLS_SHUT_RDWR);
1431  }
1432  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1433 
1434  if (rv) {
1435  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_bye: %d (%s)", rv, gnutls_strerror(rv));
1438  I18N("Error on gnutls_bye: %d (%s)"),
1439  rv,
1440  gnutls_strerror(rv));
1443  GWEN_SyncIo_Disconnect(baseIo);
1444  return GWEN_ERROR_SSL;
1445  }
1446 
1449  GWEN_SyncIo_Disconnect(baseIo);
1450  return 0;
1451 }
1452 
1453 
1454 
1456  uint8_t *buffer,
1457  uint32_t size)
1458 {
1459  GWEN_SYNCIO_TLS *xio;
1460  GWEN_SYNCIO *baseIo;
1461  int rv;
1462 
1463  assert(sio);
1464  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1465  assert(xio);
1466 
1467  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1468  assert(baseIo);
1469 
1471  DBG_INFO(GWEN_LOGDOMAIN, "Not connected");
1473  GWEN_SyncIo_Disconnect(baseIo);
1474  return GWEN_ERROR_NOT_CONNECTED;
1475  }
1476 
1477  do {
1478  rv=gnutls_record_recv(xio->session, buffer, size);
1479  }
1480  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1481 
1482  if (rv<0) {
1483  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_record_recv: %d (%s)", rv, gnutls_strerror(rv));
1484 #if 0
1487  I18N("Error on gnutls_record_recv: %d (%s)"),
1488  rv,
1489  gnutls_strerror(rv));
1490 #endif
1493  GWEN_SyncIo_Disconnect(baseIo);
1494 #ifdef GNUTLS_E_PREMATURE_TERMINATION
1495  if (rv==GNUTLS_E_PREMATURE_TERMINATION) {
1497  DBG_ERROR(GWEN_LOGDOMAIN, "Detected premature disconnect by server (violates specs!), ignoring.");
1498  return 0; /* report EOF */
1499  }
1500  else {
1501  DBG_ERROR(GWEN_LOGDOMAIN, "Detected premature disconnect by server (violates specs!)");
1503  }
1504  }
1505 #endif
1506  return GWEN_ERROR_SSL;
1507  }
1508 
1509 #ifdef GWEN_TLS_DEBUG
1510  DBG_ERROR(0, "Received this:");
1511  GWEN_Text_DumpString((const char *) buffer, rv, 2);
1512 #endif
1513 
1514  return rv;
1515 }
1516 
1517 
1518 
1520  const uint8_t *buffer,
1521  uint32_t size)
1522 {
1523  GWEN_SYNCIO_TLS *xio;
1524  GWEN_SYNCIO *baseIo;
1525  int rv;
1526 
1527  assert(sio);
1528  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1529  assert(xio);
1530 
1531 #ifdef GWEN_TLS_DEBUG
1532  DBG_ERROR(0, "Sending this:");
1533  GWEN_Text_DumpString((const char *) buffer, size, 2);
1534 #endif
1535 
1536  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1537  assert(baseIo);
1538 
1540  DBG_INFO(GWEN_LOGDOMAIN, "Not connected");
1542  GWEN_SyncIo_Disconnect(baseIo);
1543  return GWEN_ERROR_NOT_CONNECTED;
1544  }
1545 
1546  do {
1547  rv=gnutls_record_send(xio->session, buffer, size);
1548  }
1549  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1550 
1551  if (rv<0) {
1552  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_record_send: %d (%s)", rv, gnutls_strerror(rv));
1555  I18N("Error on gnutls_record_send: %d (%s)"),
1556  rv,
1557  gnutls_strerror(rv));
1560  GWEN_SyncIo_Disconnect(baseIo);
1561  return GWEN_ERROR_SSL;
1562  }
1563 
1564  return rv;
1565 }
1566 
1567 
1568 
1569 
1570 
1571 
1572 
void GWEN_SslCertDescr_SetStateOrProvinceName(GWEN_SSLCERTDESCR *st, const char *d)
void GWEN_SyncIo_Tls_UndoPrepare(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:732
struct GWEN_TIME GWEN_TIME
Definition: gwentime.h:43
int GWEN_Gui_ProgressLog(uint32_t id, GWEN_LOGGER_LEVEL level, const char *text)
Definition: gui.c:1003
struct GWEN_SSLCERTDESCR GWEN_SSLCERTDESCR
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
ssize_t GWEN_SyncIo_Tls_Push(gnutls_transport_ptr_t p, const void *buf, size_t len)
Definition: syncio_tls.c:1181
#define I18N(m)
Definition: error.c:42
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:51
int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio)
Definition: syncio.c:97
#define GWEN_SSL_CERT_FLAGS_INVALID
void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert)
Definition: db.c:1418
void GWEN_SyncIo_SubFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:188
#define GWEN_SYNCIO_TLS_FLAGS_ALLOW_V1_CA_CRT
Definition: syncio_tls.h:38
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:285
GWENHYWFAR_CB int GWEN_SyncIo_Tls_Internal_CheckCert(GWEN_SYNCIO *sio, const GWEN_SSLCERTDESCR *cert)
Definition: syncio_tls.c:128
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:419
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
GWENHYWFAR_API int GWEN_Directory_GetPrefixDirectory(char *buffer, unsigned int size)
void GWEN_SyncIo_Tls_SetLocalTrustFile(GWEN_SYNCIO *sio, const char *s)
Definition: syncio_tls.c:237
int GWEN_SyncIo_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition: syncio.c:133
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)
Definition: text.c:1283
#define DBG_NOTICE(dbg_logger, format, args...)
Definition: debug.h:151
void GWEN_SyncIo_Tls_SetDhParamFile(GWEN_SYNCIO *sio, const char *s)
Definition: syncio_tls.c:267
const char * SYNCIO_TLS_SYSTEM_CERTFILES[]
Definition: syncio_tls.c:62
GWEN_SYNCIO_WRITE_FN GWEN_SyncIo_SetWriteFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_WRITE_FN fn)
Definition: syncio.c:304
const char * GWEN_SyncIo_Tls_GetRemoteHostName(const GWEN_SYNCIO *sio)
Definition: syncio_tls.c:284
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
void GWEN_SslCertDescr_SetOrganizationName(GWEN_SSLCERTDESCR *st, const char *d)
GWEN_SYNCIO_CONNECT_FN GWEN_SyncIo_SetConnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_CONNECT_FN fn)
Definition: syncio.c:252
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:217
#define GWEN_SSL_CERT_FLAGS_EXPIRED
uint32_t GWEN_SyncIo_GetFlags(const GWEN_SYNCIO *sio)
Definition: syncio.c:161
const char * GWEN_SyncIo_Tls_GetDhParamFile(const GWEN_SYNCIO *sio)
Definition: syncio_tls.c:254
void GWEN_SslCertDescr_SetPubKeyModulus(GWEN_SSLCERTDESCR *st, const char *d)
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition: buffer.c:469
const char * GWEN_SyncIo_Tls_GetLocalKeyFile(const GWEN_SYNCIO *sio)
Definition: syncio_tls.c:194
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:124
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_SyncIo_SetStatus(GWEN_SYNCIO *sio, GWEN_SYNCIO_STATUS st)
Definition: syncio.c:206
#define GWEN_SYNCIO_TLS_FLAGS_SECURE
Definition: syncio_tls.h:47
const char * GWEN_SyncIo_Tls_GetLocalCertFile(const GWEN_SYNCIO *sio)
Definition: syncio_tls.c:164
GWENHYWFAR_API int GWEN_Directory_GetMatchingFilesRecursively(const char *folder, GWEN_STRINGLIST *sl, const char *mask)
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
GWEN_SYNCIO * GWEN_SyncIo_GetBaseIo(const GWEN_SYNCIO *sio)
Definition: syncio.c:224
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition: buffer.c:549
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:386
#define GWEN_ERROR_IO
Definition: error.h:123
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:402
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:452
#define GWEN_SSL_CERT_FLAGS_OK
#define GWEN_ERROR_NOT_CONNECTED
Definition: error.h:120
#define GWEN_ERROR_SSL
Definition: error.h:105
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:58
void GWEN_SslCertDescr_SetLocalityName(GWEN_SSLCERTDESCR *st, const char *d)
#define GWEN_SSL_CERT_FLAGS_SYSTEM
#define GWEN_SYNCIO_TLS_FLAGS_NEED_PEER_CERT
Definition: syncio_tls.h:39
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void GWEN_SslCertDescr_SetFingerPrintSha512(GWEN_SSLCERTDESCR *st, const char *d)
void GWEN_SslCertDescr_SetIsError(GWEN_SSLCERTDESCR *st, int d)
struct GWEN_SYNCIO GWEN_SYNCIO
Definition: syncio.h:40
void GWEN_SslCertDescr_SetPubKeyExponent(GWEN_SSLCERTDESCR *st, const char *d)
GWEN_SYNCIO * GWEN_SyncIo_Tls_new(GWEN_SYNCIO *baseIo)
Definition: syncio_tls.c:72
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:241
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
int GWEN_SyncIo_Tls_Prepare(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:421
#define MAX_PATH
Definition: testlib.c:122
int GWEN_Gui_ProgressLog2(uint32_t id, GWEN_LOGGER_LEVEL level, const char *fmt,...)
Definition: gui.c:1015
int GWEN_SyncIo_Tls_CheckCert(GWEN_SYNCIO *sio, const GWEN_SSLCERTDESCR *cert)
Definition: syncio_tls.c:143
#define GWEN_ERROR_SSL_PREMATURE_CLOSE
Definition: error.h:133
void GWEN_SslCertDescr_SetCountryName(GWEN_SSLCERTDESCR *st, const char *d)
GWENHYWFAR_API int GWEN_Directory_FindFileInPaths(const GWEN_STRINGLIST *paths, const char *filePath, GWEN_BUFFER *fbuf)
#define GWEN_PATH_FLAGS_VARIABLE
Definition: path.h:111
GWEN_SSLCERTDESCR * GWEN_SyncIo_Tls_GetPeerCertDescr(const GWEN_SYNCIO *sio)
Definition: syncio_tls.c:314
#define GWEN_SYNCIO_TLS_FLAGS_IGN_PREMATURE_CLOSE
Definition: syncio_tls.h:45
#define GWEN_ERROR_SSL_SECURITY
Definition: error.h:129
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:54
#define GWEN_ERROR_GENERIC
Definition: error.h:62
void GWEN_SyncIo_Tls_SetRemoteHostName(GWEN_SYNCIO *sio, const char *s)
Definition: syncio_tls.c:297
#define GWEN_SYNCIO_FLAGS_PASSIVE
Definition: syncio.h:57
#define GWEN_SYNCIO_TLS_FLAGS_REQUEST_CERT
Definition: syncio_tls.h:36
void GWEN_SyncIo_Tls_SetLocalKeyFile(GWEN_SYNCIO *sio, const char *s)
Definition: syncio_tls.c:207
void GWEN_SslCertDescr_SetOrganizationalUnitName(GWEN_SSLCERTDESCR *st, const char *d)
GWEN_SYNCIO_STATUS GWEN_SyncIo_GetStatus(const GWEN_SYNCIO *sio)
Definition: syncio.c:197
int GWENHYWFAR_CB GWEN_SyncIo_Tls_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition: syncio_tls.c:1455
int GWEN_SyncIo_Tls_GetPeerCert(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:749
ssize_t GWEN_SyncIo_Tls_Pull(gnutls_transport_ptr_t p, void *buf, size_t len)
Definition: syncio_tls.c:1150
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
GWENHYWFAR_API void GWEN_Time_free(GWEN_TIME *t)
Definition: gwentime_all.c:462
int GWENHYWFAR_CB GWEN_SyncIo_Tls_Disconnect(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:1409
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:179
#define GWEN_SYNCIO_TLS_FLAGS_ADD_TRUSTED_CAS
Definition: syncio_tls.h:40
#define GWEN_SSL_CERT_FLAGS_SIGNER_NOT_FOUND
int GWENHYWFAR_CB(* GWEN_SIO_TLS_CHECKCERT_FN)(GWEN_SYNCIO *sio, const GWEN_SSLCERTDESCR *cert)
Definition: syncio_tls.h:84
#define GWEN_SSL_CERT_FLAGS_BAD_HOSTNAME
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
void GWEN_SyncIo_Tls_SetLocalCertFile(GWEN_SYNCIO *sio, const char *s)
Definition: syncio_tls.c:177
#define GWEN_SSL_CERT_FLAGS_REVOKED
#define GWEN_SYNCIO_TLS_TYPE
Definition: syncio_tls.h:33
int GWEN_SslCertDescr_toDb(const GWEN_SSLCERTDESCR *st, GWEN_DB_NODE *db)
void GWENHYWFAR_CB GWEN_SyncIo_Tls_FreeData(GWEN_UNUSED void *bp, void *p)
Definition: syncio_tls.c:96
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
Definition: syncio.c:109
void GWEN_SslCertDescr_SetNotAfter(GWEN_SSLCERTDESCR *st, const GWEN_TIME *d)
GWEN_SYNCIO * GWEN_SyncIo_new(const char *typeName, GWEN_SYNCIO *baseIo)
Definition: syncio.c:51
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:394
void GWEN_SyncIo_Tls_ShowCipherInfo(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:1212
GWEN_SYNCIO_DISCONNECT_FN GWEN_SyncIo_SetDisconnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_DISCONNECT_FN fn)
Definition: syncio.c:265
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
GWEN_SIO_TLS_CHECKCERT_FN GWEN_SyncIo_Tls_SetCheckCertFn(GWEN_SYNCIO *sio, GWEN_SIO_TLS_CHECKCERT_FN f)
Definition: syncio_tls.c:112
GWENHYWFAR_API int GWEN_Directory_GetPath(const char *path, unsigned int flags)
void GWEN_SslCertDescr_SetStatusText(GWEN_SSLCERTDESCR *st, const char *d)
int GWEN_SyncIo_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition: syncio.c:147
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:171
int GWENHYWFAR_CB GWEN_SyncIo_Tls_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition: syncio_tls.c:1519
void GWEN_SslCertDescr_SetNotBefore(GWEN_SSLCERTDESCR *st, const GWEN_TIME *d)
#define GWEN_INHERIT(bt, t)
Definition: inherit.h:264
GWEN_SYNCIO_READ_FN GWEN_SyncIo_SetReadFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_READ_FN fn)
Definition: syncio.c:291
#define GWEN_ERROR_NO_DATA
Definition: error.h:94
GWENHYWFAR_API GWEN_TIME * GWEN_Time_fromSeconds(uint32_t s)
Definition: gwentime_all.c:77
#define GWEN_INHERIT_SETDATA(bt, t, element, data, fn)
Definition: inherit.h:292
int GWENHYWFAR_CB GWEN_SyncIo_Tls_Connect(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:1301
int GWEN_Gui_CheckCert(const GWEN_SSLCERTDESCR *cd, GWEN_SYNCIO *sio, uint32_t guiid)
Definition: gui.c:1276
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition: stringlist.c:46
void GWEN_SslCertDescr_SetFingerPrint(GWEN_SSLCERTDESCR *st, const char *d)
#define GWEN_PATH_FLAGS_NAMEMUSTEXIST
Definition: path.h:84
void GWEN_SslCertDescr_free(GWEN_SSLCERTDESCR *st)
int GWEN_Text_ToHexBuffer(const char *src, unsigned l, GWEN_BUFFER *buf, unsigned int groupsize, char delimiter, int skipLeadingZeroes)
Definition: text.c:777
GWEN_SSLCERTDESCR * GWEN_SslCertDescr_new(void)
#define GWEN_UNUSED
#define GWEN_SSL_CERT_FLAGS_BAD_DATA
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
int GWEN_SyncIo_Tls__readFile(const char *fname, GWEN_BUFFER *buf)
Definition: syncio_tls.c:327
#define GWEN_INHERIT_GETDATA(bt, t, element)
Definition: inherit.h:271
void GWEN_SslCertDescr_SetCommonName(GWEN_SSLCERTDESCR *st, const char *d)
#define GWEN_SSL_CERT_FLAGS_NOT_ACTIVE
const char * GWEN_SyncIo_Tls_GetLocalTrustFile(const GWEN_SYNCIO *sio)
Definition: syncio_tls.c:224
void GWEN_SslCertDescr_SetFingerPrintSha1(GWEN_SSLCERTDESCR *st, const char *d)
void GWEN_SslCertDescr_SetStatusFlags(GWEN_SSLCERTDESCR *st, uint32_t d)