gwenhywfar  5.10.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  int trustFileSet=0;
508 
509 #if GWEN_TLS_USE_SYSTEM_CERTIFICATES
510  /* disable setting of default trust file as discussed on aqbanking-users.
511  * The rationale is that without this file being set gnutls should behave
512  * correctly on each system.
513  * On Linux systems it should use the standard mechanism of the underlying
514  * distribution. On Windows the default CA store should be used (if given
515  * "--with-default-trust-store-file" to "./configure" of GNUTLS).
516  */
517  if (trustFileSet==0) {
518  /* Adds the system's default trusted CAs in order to verify client or server certificates. */
519  rv=gnutls_certificate_set_x509_system_trust(xio->credentials);
520  if (rv<=0) {
521  DBG_WARN(GWEN_LOGDOMAIN, "gnutls_certificate_set_x509_system_trust: %d (%s)", rv, gnutls_strerror(rv));
522  }
523  else {
524  DBG_INFO(GWEN_LOGDOMAIN, "Added %d default trusted certs from system", rv);
525  trustFileSet=1;
526  }
527  }
528 #endif
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  }
637 
638  /* possibly set trust file */
639  if (xio->localTrustFile) {
640  rv=gnutls_certificate_set_x509_trust_file(xio->credentials,
641  xio->localTrustFile,
642  GNUTLS_X509_FMT_PEM);
643  if (rv<=0) {
645  "gnutls_certificate_set_x509_trust_file(%s): %d (%s)",
646  (xio->localTrustFile)?(xio->localTrustFile):"-none-",
647  rv, gnutls_strerror(rv));
648  gnutls_certificate_free_credentials(xio->credentials);
649  gnutls_deinit(xio->session);
650  return GWEN_ERROR_GENERIC;
651  }
652  else {
654  "Added %d trusted certs", rv);
655  }
656  }
657 
658  /* possibly set DH params */
659  if (xio->dhParamFile) {
660  GWEN_BUFFER *dbuf;
661 
662  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
663  rv=GWEN_SyncIo_Tls__readFile(xio->dhParamFile, dbuf);
664  if (rv) {
665  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
666  GWEN_Buffer_free(dbuf);
667  gnutls_certificate_free_credentials(xio->credentials);
668  gnutls_deinit(xio->session);
669  return rv;
670  }
671  else {
672  gnutls_datum_t d;
673  gnutls_dh_params_t dh_params=NULL;
674 
675  rv=gnutls_dh_params_init(&dh_params);
676  if (rv<0) {
677  GWEN_Buffer_free(dbuf);
678  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_dh_params_init: %d (%s)", rv, gnutls_strerror(rv));
679  gnutls_certificate_free_credentials(xio->credentials);
680  gnutls_deinit(xio->session);
681  return GWEN_ERROR_GENERIC;
682  }
683 
684  d.size=GWEN_Buffer_GetUsedBytes(dbuf);
685  d.data=(unsigned char *)GWEN_Buffer_GetStart(dbuf);
686 
687  rv=gnutls_dh_params_import_pkcs3(dh_params, &d, GNUTLS_X509_FMT_PEM);
688  if (rv<0) {
689  GWEN_Buffer_free(dbuf);
690  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_dh_params_import_pkcs3: %d (%s)", rv, gnutls_strerror(rv));
691  gnutls_certificate_free_credentials(xio->credentials);
692  gnutls_deinit(xio->session);
693  return GWEN_ERROR_GENERIC;
694  }
695  GWEN_Buffer_free(dbuf);
696 
697  gnutls_certificate_set_dh_params(xio->credentials, dh_params);
698  }
699  }
700 
701  /* set credentials in TLS session */
702  rv=gnutls_credentials_set(xio->session, GNUTLS_CRD_CERTIFICATE, xio->credentials);
703  if (rv<0) {
704  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_credentials_set: %d (%s)", rv, gnutls_strerror(rv));
705  gnutls_certificate_free_credentials(xio->credentials);
706  gnutls_deinit(xio->session);
707  return GWEN_ERROR_GENERIC;
708  }
709 
710  /* if hostname set try to set it */
711  if (xio->hostName) {
712  rv=gnutls_server_name_set(xio->session, GNUTLS_NAME_DNS, xio->hostName, strlen(xio->hostName));
713  if (rv!=GNUTLS_E_SUCCESS) {
714  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_server_name_set: %d (%s), ignoring", rv, gnutls_strerror(rv));
715  }
716  }
717 
718  /* we use our own push/pull functions */
719  gnutls_transport_set_ptr(xio->session, (gnutls_transport_ptr_t)sio);
720  gnutls_transport_set_push_function(xio->session, GWEN_SyncIo_Tls_Push);
721  gnutls_transport_set_pull_function(xio->session, GWEN_SyncIo_Tls_Pull);
722 #if GNUTLS_VERSION_NUMBER < 0x020c00
723  /* This function must be set to 0 in GNUTLS versions < 2.12.0 because we use
724  * custom push/pull functions.
725  * In GNUTLS 2.12.x this is set to 0 and since version 3 this functions is removed
726  * completely.
727  * So we only call this function now for GNUTLS < 2.12.0.
728  */
729  gnutls_transport_set_lowat(xio->session, 0);
730 #endif
731 
732  xio->prepared=1;
733 
734  return 0;
735 }
736 
737 
738 
740 {
741  GWEN_SYNCIO_TLS *xio;
742 
743  assert(sio);
744  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
745  assert(xio);
746 
747  if (xio->prepared) {
748  gnutls_certificate_free_credentials(xio->credentials);
749  gnutls_deinit(xio->session);
750  xio->prepared=0;
751  }
752 }
753 
754 
755 
757 {
758  GWEN_SYNCIO_TLS *xio;
759  const gnutls_datum_t *cert_list;
760  unsigned int cert_list_size;
761  size_t size;
762  GWEN_SSLCERTDESCR *certDescr;
763  char buffer1[64];
764  time_t t0;
765  int rv;
766  uint32_t lflags;
767  uint32_t errFlags=0;
768  int i;
769  unsigned int status;
770  GWEN_BUFFER *sbuf=NULL;
771 
772  assert(sio);
773  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
774  assert(xio);
775 
776  lflags=GWEN_SyncIo_GetFlags(sio);
777 
778  if (xio->peerCertDescr) {
779  GWEN_SslCertDescr_free(xio->peerCertDescr);
780  xio->peerCertDescr=NULL;
781  }
782  xio->peerCertFlags=0;
783 
784  t0=time(NULL);
785  if (t0<0) {
786  DBG_WARN(GWEN_LOGDOMAIN, "Could not get system time");
787  errFlags|=GWEN_SSL_CERT_FLAGS_SYSTEM;
788  }
789 
790  /* create new cert description, check cert on the fly */
791  certDescr=GWEN_SslCertDescr_new();
792 
793  /* some general tests */
795  gnutls_certificate_set_verify_flags(xio->credentials,
796  GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
797 
798  rv=gnutls_certificate_verify_peers2(xio->session, &status);
799  if (rv<0) {
800  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_certificate_verify_peers2: %d (%s)", rv, gnutls_strerror(rv));
801  GWEN_SslCertDescr_free(certDescr);
803  }
804 
805  if (gnutls_certificate_type_get(xio->session)!=GNUTLS_CRT_X509) {
806  DBG_INFO(GWEN_LOGDOMAIN, "Certificate is not X.509");
807 
808  GWEN_SslCertDescr_free(certDescr);
810  }
811 
812  if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
813  DBG_INFO(GWEN_LOGDOMAIN, "Signer not found");
815  I18N("Signer not found"));
817  }
818 
819  if (status & GNUTLS_CERT_INVALID) {
820  DBG_INFO(GWEN_LOGDOMAIN, "Certificate is not trusted");
822  I18N("Certificate is not trusted"));
823  errFlags|=GWEN_SSL_CERT_FLAGS_INVALID;
824  }
825 
826  if (status & GNUTLS_CERT_REVOKED) {
827  DBG_INFO(GWEN_LOGDOMAIN, "Certificate has been revoked");
829  I18N("Certificate has been revoked"));
830  errFlags|=GWEN_SSL_CERT_FLAGS_REVOKED;
831  }
832 
833  cert_list=gnutls_certificate_get_peers(xio->session, &cert_list_size);
834  if (cert_list==NULL || cert_list_size==0) {
835  DBG_INFO(GWEN_LOGDOMAIN, "No peer certificates found");
836  return GWEN_ERROR_NO_DATA;
837  }
838 
839  for (i=0; i<(int) cert_list_size; i++) {
840  gnutls_x509_crt_t cert;
841  time_t t;
842 
843  rv=gnutls_x509_crt_init(&cert);
844  if (rv!=0) {
845  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_init: %d (%s)", rv, gnutls_strerror(rv));
846  return GWEN_ERROR_GENERIC;
847  }
848 
849  rv=gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER); /* TODO: shouldn't we use the index?? */
850  if (rv!=0) {
851  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_import: %d (%s)", rv, gnutls_strerror(rv));
852  gnutls_x509_crt_deinit(cert);
853  return GWEN_ERROR_GENERIC;
854  }
855 
856  if (i==0) {
857  gnutls_datum_t n= {NULL, 0};
858  gnutls_datum_t e= {NULL, 0};
859 
860  /* get public key from cert, if any */
861  rv=gnutls_x509_crt_get_pk_rsa_raw(cert, &n, &e);
862  if (rv!=0) {
863  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_pk_rsa_raw: %d (%s)", rv, gnutls_strerror(rv));
864  }
865  else {
866  GWEN_BUFFER *kbuf;
867 
868  DBG_INFO(GWEN_LOGDOMAIN, "Key stored within certificate, extracting (modlen=%d, explen=%d)",
869  n.size, e.size);
870 
871  kbuf=GWEN_Buffer_new(0, 256, 0, 1);
872 
873  if (n.data && n.size) {
874  /* store public modulus */
875  GWEN_Text_ToHexBuffer((const char *)(n.data), n.size, kbuf, 0, 0, 0);
877  GWEN_Buffer_Reset(kbuf);
878  }
879 
880  if (e.data && e.size) {
881  /* store public exponent */
882  GWEN_Text_ToHexBuffer((const char *)(e.data), e.size, kbuf, 0, 0, 0);
884  GWEN_Buffer_Reset(kbuf);
885  }
886 
887  GWEN_Buffer_free(kbuf);
888  if (n.data)
889  gcry_free(n.data);
890  if (e.data)
891  gcry_free(e.data);
892  }
893 
894  /* get fingerprint (MD5) */
895  size=16;
896  rv=gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_MD5, buffer1, &size);
897  if (rv!=0) {
898  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_fingerprint(MD5): %d (%s)", rv, gnutls_strerror(rv));
899  GWEN_SslCertDescr_free(certDescr);
900  gnutls_x509_crt_deinit(cert);
901  return GWEN_ERROR_GENERIC;
902  }
903  else {
904  GWEN_BUFFER *dbuf;
905 
906  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
907  if (GWEN_Text_ToHexBuffer(/* GCC4 pointer-signedness fix: */ buffer1,
908  size, dbuf, 2, ':', 0)) {
910  "Could not convert fingerprint to hex");
911  }
912  else {
914  }
915  GWEN_Buffer_free(dbuf);
916  }
917 
918  /* get fingerprint (SHA1) */
919  size=sizeof(buffer1);
920  rv=gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, buffer1, &size);
921  if (rv!=0) {
922  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_fingerprint(SHA1): %d (%s)", rv, gnutls_strerror(rv));
923  GWEN_SslCertDescr_free(certDescr);
924  gnutls_x509_crt_deinit(cert);
925  return GWEN_ERROR_GENERIC;
926  }
927  else {
928  GWEN_BUFFER *dbuf;
929 
930  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
931  if (GWEN_Text_ToHexBuffer(/* GCC4 pointer-signedness fix: */ buffer1,
932  size, dbuf, 2, ':', 0)) {
934  "Could not convert fingerprint to hex");
935  }
936  else {
938  }
939  GWEN_Buffer_free(dbuf);
940  }
941 
942  /* get fingerprint (SHA512) */
943  size=sizeof(buffer1);
944  rv=gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA512, buffer1, &size);
945  if (rv!=0) {
946  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_fingerprint(SHA512): %d (%s)", rv, gnutls_strerror(rv));
947  GWEN_SslCertDescr_free(certDescr);
948  gnutls_x509_crt_deinit(cert);
949  return GWEN_ERROR_GENERIC;
950  }
951  else {
952  GWEN_BUFFER *dbuf;
953 
954  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
955  if (GWEN_Text_ToHexBuffer(/* GCC4 pointer-signedness fix: */ buffer1,
956  size, dbuf, 2, ':', 0)) {
958  "Could not convert fingerprint to hex");
959  }
960  else {
962  }
963  GWEN_Buffer_free(dbuf);
964  }
965 
966 
967  if (xio->hostName) {
968  DBG_INFO(GWEN_LOGDOMAIN, "Checking hostname [%s]", xio->hostName);
969  if (!gnutls_x509_crt_check_hostname(cert, xio->hostName)) {
971  "Certificate was not issued for this host");
973  I18N("Certificate was not issued for this host"));
975  }
976  else {
977  DBG_INFO(GWEN_LOGDOMAIN, "Cert is for this server");
978  }
979  }
980  else {
982  "Hostname is not set, unable to verify the sender");
984  I18N("No hostname to verify the sender!"));
985  }
986 
987  }
988 
989  /* get activation time */
990  t=gnutls_x509_crt_get_activation_time(cert);
991  if (t<0) {
992  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_activation_time: %d (%s)", rv, gnutls_strerror(rv));
994  }
995  else {
996  if (t>t0) {
997  DBG_INFO(GWEN_LOGDOMAIN, "Cert is not yet active");
999  }
1000  if (i==0) {
1001  GWEN_TIME *ti;
1002 
1003  ti=GWEN_Time_fromSeconds(t);
1004  if (ti)
1005  GWEN_SslCertDescr_SetNotBefore(certDescr, ti);
1006  GWEN_Time_free(ti);
1007  }
1008  }
1009 
1010  /* get expiration time */
1011  t=gnutls_x509_crt_get_expiration_time(cert);
1012  if (t<0) {
1013  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_expiration_time: %d (%s)", rv, gnutls_strerror(rv));
1014  errFlags|=GWEN_SSL_CERT_FLAGS_BAD_DATA;
1015  }
1016  else {
1017  if (t<t0) {
1018  DBG_INFO(GWEN_LOGDOMAIN, "Cert has expired");
1019  errFlags|=GWEN_SSL_CERT_FLAGS_EXPIRED;
1020  }
1021  if (i==0) {
1022  GWEN_TIME *ti;
1023 
1024  ti=GWEN_Time_fromSeconds(t);
1025  if (ti)
1026  GWEN_SslCertDescr_SetNotAfter(certDescr, ti);
1027  GWEN_Time_free(ti);
1028  }
1029  }
1030 
1031  if (i==0) {
1032  /* get owner information, but only for first cert */
1033  size=sizeof(buffer1)-1;
1034  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, buffer1, &size);
1035  if (rv==0) {
1036  GWEN_SslCertDescr_SetCommonName(certDescr, buffer1);
1037  if (xio->hostName && strcasecmp(xio->hostName, buffer1)!=0) {
1038  DBG_INFO(GWEN_LOGDOMAIN, "Owner of certificate does not match hostname");
1040  }
1041  }
1042 
1043  size=sizeof(buffer1)-1;
1044  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, 0, buffer1, &size);
1045  if (rv==0)
1046  GWEN_SslCertDescr_SetOrganizationName(certDescr, buffer1);
1047 
1048  size=sizeof(buffer1)-1;
1049  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, 0, buffer1, &size);
1050  if (rv==0)
1051  GWEN_SslCertDescr_SetOrganizationalUnitName(certDescr, buffer1);
1052 
1053  size=sizeof(buffer1)-1;
1054  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_LOCALITY_NAME, 0, 0, buffer1, &size);
1055  if (rv==0)
1056  GWEN_SslCertDescr_SetLocalityName(certDescr, buffer1);
1057 
1058  size=sizeof(buffer1)-1;
1059  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, 0, buffer1, &size);
1060  if (rv==0)
1061  GWEN_SslCertDescr_SetStateOrProvinceName(certDescr, buffer1);
1062 
1063  size=sizeof(buffer1)-1;
1064  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COUNTRY_NAME, 0, 0, buffer1, &size);
1065  if (rv==0)
1066  GWEN_SslCertDescr_SetCountryName(certDescr, buffer1);
1067  }
1068 
1069  gnutls_x509_crt_deinit(cert);
1070  }
1071 
1072  /* done */
1073  if (errFlags)
1074  GWEN_SslCertDescr_SetIsError(certDescr, 1);
1075  else
1076  errFlags|=GWEN_SSL_CERT_FLAGS_OK;
1077 
1078  sbuf=GWEN_Buffer_new(0, 256, 0, 1);
1079 
1080  if (errFlags & GWEN_SSL_CERT_FLAGS_SIGNER_NOT_FOUND) {
1081  if (GWEN_Buffer_GetUsedBytes(sbuf))
1082  GWEN_Buffer_AppendString(sbuf, "; ");
1083  GWEN_Buffer_AppendString(sbuf, I18N("Signer not found"));
1084  }
1085 
1086  if (errFlags & GWEN_SSL_CERT_FLAGS_INVALID) {
1087  if (GWEN_Buffer_GetUsedBytes(sbuf))
1088  GWEN_Buffer_AppendString(sbuf, "; ");
1089  GWEN_Buffer_AppendString(sbuf, I18N("Certificate is not trusted"));
1090  }
1091 
1092  if (errFlags & GWEN_SSL_CERT_FLAGS_REVOKED) {
1093  if (GWEN_Buffer_GetUsedBytes(sbuf))
1094  GWEN_Buffer_AppendString(sbuf, "; ");
1095  GWEN_Buffer_AppendString(sbuf, I18N("Certificate has been revoked"));
1096  }
1097 
1098  if (errFlags & GWEN_SSL_CERT_FLAGS_EXPIRED) {
1099  if (GWEN_Buffer_GetUsedBytes(sbuf))
1100  GWEN_Buffer_AppendString(sbuf, "; ");
1101  GWEN_Buffer_AppendString(sbuf, I18N("Certificate has expired"));
1102  }
1103 
1104  if (errFlags & GWEN_SSL_CERT_FLAGS_NOT_ACTIVE) {
1105  if (GWEN_Buffer_GetUsedBytes(sbuf))
1106  GWEN_Buffer_AppendString(sbuf, "; ");
1107  GWEN_Buffer_AppendString(sbuf, I18N("Certificate is not active yet"));
1108  }
1109 
1110  if (errFlags & GWEN_SSL_CERT_FLAGS_BAD_HOSTNAME) {
1111  if (GWEN_Buffer_GetUsedBytes(sbuf))
1112  GWEN_Buffer_AppendString(sbuf, "; ");
1113  GWEN_Buffer_AppendString(sbuf, I18N("Certificate owner does not match hostname"));
1114  }
1115 
1116  if (errFlags & GWEN_SSL_CERT_FLAGS_BAD_DATA) {
1117  if (GWEN_Buffer_GetUsedBytes(sbuf))
1118  GWEN_Buffer_AppendString(sbuf, "; ");
1119  GWEN_Buffer_AppendString(sbuf, I18N("Certificate contains invalid information"));
1120  }
1121 
1122  if (errFlags & GWEN_SSL_CERT_FLAGS_SYSTEM) {
1123  if (GWEN_Buffer_GetUsedBytes(sbuf))
1124  GWEN_Buffer_AppendString(sbuf, "; ");
1125  GWEN_Buffer_AppendString(sbuf, I18N("A system error occurred while checking the certificate"));
1126  }
1127 
1128  if (errFlags & GWEN_SSL_CERT_FLAGS_OK) {
1129  if (GWEN_Buffer_GetUsedBytes(sbuf))
1130  GWEN_Buffer_AppendString(sbuf, "; ");
1131  GWEN_Buffer_AppendString(sbuf, I18N("The certificate is valid"));
1132  }
1133 
1135  GWEN_SslCertDescr_SetStatusFlags(certDescr, errFlags);
1136  GWEN_Buffer_free(sbuf);
1137 
1138 #if 0
1139  if (1) {
1140  GWEN_DB_NODE *dbTest;
1141 
1142  dbTest=GWEN_DB_Group_new("Cert");
1143  GWEN_SslCertDescr_toDb(certDescr, dbTest);
1144  GWEN_DB_Dump(dbTest, 2);
1145  GWEN_DB_Group_free(dbTest);
1146  }
1147 #endif
1148 
1149  xio->peerCertDescr=certDescr;
1150  xio->peerCertFlags=errFlags;
1151 
1152  return 0;
1153 }
1154 
1155 
1156 
1157 ssize_t GWEN_SyncIo_Tls_Pull(gnutls_transport_ptr_t p, void *buf, size_t len)
1158 {
1159  GWEN_SYNCIO *sio;
1160  GWEN_SYNCIO_TLS *xio;
1161  GWEN_SYNCIO *baseIo;
1162  int rv;
1163 
1164  sio=(GWEN_SYNCIO *) p;
1165  assert(sio);
1166  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1167  assert(xio);
1168 
1169  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PULL: %d bytes", (int)len);
1170  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1171  assert(baseIo);
1172 
1173  rv=GWEN_SyncIo_Read(baseIo, buf, len);
1174  if (rv<0) {
1175  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1176  gnutls_transport_set_errno(xio->session, errno);
1177  return (ssize_t)-1;
1178  }
1179 
1180  gnutls_transport_set_errno(xio->session, 0);
1181  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PULL: returning %d bytes", rv);
1182  /*GWEN_Text_DumpString(buf, rv, 2);*/
1183  return rv;
1184 }
1185 
1186 
1187 
1188 ssize_t GWEN_SyncIo_Tls_Push(gnutls_transport_ptr_t p, const void *buf, size_t len)
1189 {
1190  GWEN_SYNCIO *sio;
1191  GWEN_SYNCIO_TLS *xio;
1192  GWEN_SYNCIO *baseIo;
1193  int rv;
1194 
1195  sio=(GWEN_SYNCIO *) p;
1196  assert(sio);
1197  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1198  assert(xio);
1199 
1200  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PUSH: %d bytes", (int)len);
1201  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1202  assert(baseIo);
1203 
1204  rv=GWEN_SyncIo_Write(baseIo, buf, len);
1205  if (rv<0) {
1206  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1207  gnutls_transport_set_errno(xio->session, errno);
1208  return (ssize_t)-1;
1209  }
1210 
1211  gnutls_transport_set_errno(xio->session, 0);
1212  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PUSH: returning %d bytes", rv);
1213  /*GWEN_Text_DumpString(buf, rv, 2);*/
1214  return rv;
1215 }
1216 
1217 
1218 
1220 {
1221  GWEN_SYNCIO_TLS *xio;
1222  const char *s;
1223  gnutls_kx_algorithm_t kx;
1224  GWEN_BUFFER *cbuf;
1225  GWEN_BUFFER *sbuf;
1226 
1227  assert(sio);
1228  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1229  assert(xio);
1230 
1231  cbuf=GWEN_Buffer_new(0, 256, 0, 1);
1232  sbuf=GWEN_Buffer_new(0, 256, 0, 1);
1233 
1234  /* protocol */
1235  s=gnutls_protocol_get_name(gnutls_protocol_get_version(xio->session));
1236  if (s && *s) {
1237  if (GWEN_Buffer_GetUsedBytes(cbuf))
1238  GWEN_Buffer_AppendString(cbuf, " ");
1239  GWEN_Buffer_AppendString(cbuf, "Protocol: ");
1240  GWEN_Buffer_AppendString(cbuf, s);
1241 
1242  GWEN_Buffer_AppendString(sbuf, s);
1243  }
1244  GWEN_Buffer_AppendString(sbuf, ":");
1245 
1246  /* key exchange algorithm */
1247  kx=gnutls_kx_get(xio->session);
1248  s=gnutls_kx_get_name(kx);
1249  if (s && *s) {
1250  if (GWEN_Buffer_GetUsedBytes(cbuf))
1251  GWEN_Buffer_AppendString(cbuf, " ");
1252  GWEN_Buffer_AppendString(cbuf, "Key exchange algorithm: ");
1253  GWEN_Buffer_AppendString(cbuf, s);
1254  GWEN_Buffer_AppendString(sbuf, s);
1255  }
1256  GWEN_Buffer_AppendString(sbuf, "-");
1257 
1258  /* cipher */
1259  s=gnutls_cipher_get_name(gnutls_cipher_get(xio->session));
1260  if (s && *s) {
1261  if (GWEN_Buffer_GetUsedBytes(cbuf))
1262  GWEN_Buffer_AppendString(cbuf, " ");
1263  GWEN_Buffer_AppendString(cbuf, "cipher algorithm: ");
1264  GWEN_Buffer_AppendString(cbuf, s);
1265  GWEN_Buffer_AppendString(sbuf, s);
1266  }
1267  GWEN_Buffer_AppendString(sbuf, ":");
1268 
1269  /* MAC algorithm */
1270  s=gnutls_mac_get_name(gnutls_mac_get(xio->session));
1271  if (s && *s) {
1272  if (GWEN_Buffer_GetUsedBytes(cbuf))
1273  GWEN_Buffer_AppendString(cbuf, " ");
1274  GWEN_Buffer_AppendString(cbuf, "MAC algorithm: ");
1275  GWEN_Buffer_AppendString(cbuf, s);
1276  GWEN_Buffer_AppendString(sbuf, s);
1277  }
1278 
1279 
1281  GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Info, I18N("TLS: SSL-Ciphers negotiated: %s"), GWEN_Buffer_GetStart(sbuf));
1282  GWEN_Buffer_free(cbuf);
1283  GWEN_Buffer_free(sbuf);
1284 
1285  /* possibly show warning */
1286  switch (gnutls_cipher_get(xio->session)) {
1287  case GNUTLS_CIPHER_ARCFOUR_128:
1288  case GNUTLS_CIPHER_3DES_CBC:
1289  case GNUTLS_CIPHER_AES_128_CBC:
1290  case GNUTLS_CIPHER_ARCFOUR_40:
1291  case GNUTLS_CIPHER_CAMELLIA_128_CBC:
1292  GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error, I18N("TLS: Warning - The server has chosen unsafe SSL-Ciphers!"));
1293  break;
1294  case GNUTLS_CIPHER_AES_256_CBC:
1295  case GNUTLS_CIPHER_CAMELLIA_256_CBC:
1296  case GNUTLS_CIPHER_RC2_40_CBC:
1297  case GNUTLS_CIPHER_DES_CBC:
1298 #ifdef GNUTLS_CIPHER_AES_192_CBC
1299  case GNUTLS_CIPHER_AES_192_CBC: /* new in gnutls-2.9.8, so i.e. not available in gnutls-2.8.x */
1300 #endif
1301  default:
1302  break;
1303  }
1304 }
1305 
1306 
1307 
1309 {
1310  GWEN_SYNCIO_TLS *xio;
1311  GWEN_SYNCIO *baseIo;
1312  int rv;
1313 
1314  assert(sio);
1315  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1316  assert(xio);
1317 
1318  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1319  assert(baseIo);
1320 
1323  DBG_ERROR(GWEN_LOGDOMAIN, "Base layer is not connected");
1324  return GWEN_ERROR_NOT_CONNECTED;
1325  }
1326  }
1327  else {
1328  DBG_INFO(GWEN_LOGDOMAIN, "Connecting base layer");
1329  rv=GWEN_SyncIo_Connect(baseIo);
1330  if (rv<0) {
1331  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1332  return rv;
1333  }
1334  DBG_INFO(GWEN_LOGDOMAIN, "Base layer connected");
1335  }
1336 
1337  rv=GWEN_SyncIo_Tls_Prepare(sio);
1338  if (rv<0) {
1339  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1340  GWEN_SyncIo_Disconnect(baseIo);
1341  return rv;
1342  }
1343 
1344  do {
1345  rv=gnutls_handshake(xio->session);
1346  }
1347  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1348 
1349  if (rv) {
1350  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_handshake: %d (%s) [%s]",
1351  rv, gnutls_strerror(rv), gnutls_error_is_fatal(rv)?"fatal":"non-fatal");
1352  if (rv==GNUTLS_E_UNEXPECTED_PACKET_LENGTH) {
1355  I18N("A TLS handshake error occurred. "
1356  "If you are using AqBanking you should "
1357  "consider enabling the option "
1358  "\"force SSLv3\" in the user settings "
1359  "dialog."));
1360  }
1361  else {
1364  I18N("TLS Handshake Error: %d (%s)"),
1365  rv,
1366  gnutls_strerror(rv));
1367  }
1370  GWEN_SyncIo_Disconnect(baseIo);
1371  return GWEN_ERROR_SSL;
1372  }
1373  else {
1374  /* show session info */
1376 
1377  /* check certificate */
1380  if (rv<0) {
1382  DBG_ERROR(GWEN_LOGDOMAIN, "No peer certificate when needed, aborting connection");
1385  GWEN_SyncIo_Disconnect(baseIo);
1386  return GWEN_ERROR_SSL_SECURITY;
1387  }
1388  else {
1389  DBG_INFO(GWEN_LOGDOMAIN, "SSL connected (insecure)");
1391  return 0;
1392  }
1393  }
1394  else {
1395  /* present cert to the user */
1396  rv=GWEN_SyncIo_Tls_CheckCert(sio, xio->peerCertDescr);
1397  if (rv<0) {
1398  DBG_ERROR(GWEN_LOGDOMAIN, "Peer cert not accepted (%d), aborting", rv);
1401  GWEN_SyncIo_Disconnect(baseIo);
1402  return GWEN_ERROR_SSL_SECURITY;
1403  }
1404  else {
1405  DBG_INFO(GWEN_LOGDOMAIN, "SSL connected (secure)");
1408  return 0;
1409  }
1410  }
1411  }
1412 }
1413 
1414 
1415 
1417 {
1418  GWEN_SYNCIO_TLS *xio;
1419  GWEN_SYNCIO *baseIo;
1420  int rv;
1421 
1422  assert(sio);
1423  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1424  assert(xio);
1425 
1426  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1427  assert(baseIo);
1428 
1430  DBG_INFO(GWEN_LOGDOMAIN, "Not connected");
1432  GWEN_SyncIo_Disconnect(baseIo);
1433  return GWEN_ERROR_NOT_CONNECTED;
1434  }
1435 
1436  do {
1437  rv=gnutls_bye(xio->session, GNUTLS_SHUT_RDWR);
1438  }
1439  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1440 
1441  if (rv) {
1442  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_bye: %d (%s)", rv, gnutls_strerror(rv));
1445  I18N("Error on gnutls_bye: %d (%s)"),
1446  rv,
1447  gnutls_strerror(rv));
1450  GWEN_SyncIo_Disconnect(baseIo);
1451  return GWEN_ERROR_SSL;
1452  }
1453 
1456  GWEN_SyncIo_Disconnect(baseIo);
1457  return 0;
1458 }
1459 
1460 
1461 
1463  uint8_t *buffer,
1464  uint32_t size)
1465 {
1466  GWEN_SYNCIO_TLS *xio;
1467  GWEN_SYNCIO *baseIo;
1468  int rv;
1469 
1470  assert(sio);
1471  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1472  assert(xio);
1473 
1474  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1475  assert(baseIo);
1476 
1478  DBG_INFO(GWEN_LOGDOMAIN, "Not connected");
1480  GWEN_SyncIo_Disconnect(baseIo);
1481  return GWEN_ERROR_NOT_CONNECTED;
1482  }
1483 
1484  do {
1485  rv=gnutls_record_recv(xio->session, buffer, size);
1486  }
1487  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1488 
1489  if (rv<0) {
1490  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_record_recv: %d (%s)", rv, gnutls_strerror(rv));
1491 #if 0
1494  I18N("Error on gnutls_record_recv: %d (%s)"),
1495  rv,
1496  gnutls_strerror(rv));
1497 #endif
1500  GWEN_SyncIo_Disconnect(baseIo);
1501 #ifdef GNUTLS_E_PREMATURE_TERMINATION
1502  if (rv==GNUTLS_E_PREMATURE_TERMINATION) {
1504  DBG_ERROR(GWEN_LOGDOMAIN, "Detected premature disconnect by server (violates specs!), ignoring.");
1505  return 0; /* report EOF */
1506  }
1507  else {
1508  DBG_ERROR(GWEN_LOGDOMAIN, "Detected premature disconnect by server (violates specs!)");
1510  }
1511  }
1512 #endif
1513  return GWEN_ERROR_SSL;
1514  }
1515 
1516 #ifdef GWEN_TLS_DEBUG
1517  DBG_ERROR(0, "Received this:");
1518  GWEN_Text_DumpString((const char *) buffer, rv, 2);
1519 #endif
1520 
1521  return rv;
1522 }
1523 
1524 
1525 
1527  const uint8_t *buffer,
1528  uint32_t size)
1529 {
1530  GWEN_SYNCIO_TLS *xio;
1531  GWEN_SYNCIO *baseIo;
1532  int rv;
1533 
1534  assert(sio);
1535  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1536  assert(xio);
1537 
1538 #ifdef GWEN_TLS_DEBUG
1539  DBG_ERROR(0, "Sending this:");
1540  GWEN_Text_DumpString((const char *) buffer, size, 2);
1541 #endif
1542 
1543  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1544  assert(baseIo);
1545 
1547  DBG_INFO(GWEN_LOGDOMAIN, "Not connected");
1549  GWEN_SyncIo_Disconnect(baseIo);
1550  return GWEN_ERROR_NOT_CONNECTED;
1551  }
1552 
1553  do {
1554  rv=gnutls_record_send(xio->session, buffer, size);
1555  }
1556  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1557 
1558  if (rv<0) {
1559  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_record_send: %d (%s)", rv, gnutls_strerror(rv));
1562  I18N("Error on gnutls_record_send: %d (%s)"),
1563  rv,
1564  gnutls_strerror(rv));
1567  GWEN_SyncIo_Disconnect(baseIo);
1568  return GWEN_ERROR_SSL;
1569  }
1570 
1571  return rv;
1572 }
1573 
1574 
1575 
1576 
1577 
1578 
1579 
void GWEN_SslCertDescr_SetStateOrProvinceName(GWEN_SSLCERTDESCR *st, const char *d)
void GWEN_SyncIo_Tls_UndoPrepare(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:739
struct GWEN_TIME GWEN_TIME
Definition: gwentime.h:43
GWENHYWFAR_API int GWEN_Gui_ProgressLog(uint32_t id, GWEN_LOGGER_LEVEL level, const char *text)
Definition: gui_virtual.c:444
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:1188
#define I18N(m)
Definition: error.c:42
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
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:1420
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:421
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:152
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:224
#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:125
#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:390
#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:406
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:62
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:245
#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:124
GWENHYWFAR_API int GWEN_Gui_ProgressLog2(uint32_t id, GWEN_LOGGER_LEVEL level, const char *text,...)
Definition: gui_virtual.c:458
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:56
#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:1462
int GWEN_SyncIo_Tls_GetPeerCert(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:756
ssize_t GWEN_SyncIo_Tls_Pull(gnutls_transport_ptr_t p, void *buf, size_t len)
Definition: syncio_tls.c:1157
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:1416
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:398
void GWEN_SyncIo_Tls_ShowCipherInfo(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:1219
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:181
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:173
int GWENHYWFAR_CB GWEN_SyncIo_Tls_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition: syncio_tls.c:1526
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:1308
GWENHYWFAR_API int GWEN_Gui_CheckCert(const GWEN_SSLCERTDESCR *cert, GWEN_SYNCIO *sio, uint32_t guiid)
Definition: gui_cert.c:30
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition: stringlist.c:50
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)