gwenhywfar  5.14.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_SIGNATURE_FAILURE) {
820  DBG_INFO(GWEN_LOGDOMAIN, "Certificate signature failure");
822  I18N("Certificate signature failure"));
823  errFlags|=GWEN_SSL_CERT_FLAGS_INVALID;
824  }
825 
826  if (status & GNUTLS_CERT_INVALID) {
827  DBG_INFO(GWEN_LOGDOMAIN, "Certificate is not trusted");
829  I18N("Certificate is not trusted"));
830  errFlags|=GWEN_SSL_CERT_FLAGS_INVALID;
831  }
832 
833  if (status & GNUTLS_CERT_REVOKED) {
834  DBG_INFO(GWEN_LOGDOMAIN, "Certificate has been revoked");
836  I18N("Certificate has been revoked"));
837  errFlags|=GWEN_SSL_CERT_FLAGS_REVOKED;
838  }
839 
840  cert_list=gnutls_certificate_get_peers(xio->session, &cert_list_size);
841  if (cert_list==NULL || cert_list_size==0) {
842  DBG_INFO(GWEN_LOGDOMAIN, "No peer certificates found");
843  return GWEN_ERROR_NO_DATA;
844  }
845 
846  for (i=0; i<(int) cert_list_size; i++) {
847  gnutls_x509_crt_t cert;
848  time_t t;
849 
850  rv=gnutls_x509_crt_init(&cert);
851  if (rv!=0) {
852  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_init: %d (%s)", rv, gnutls_strerror(rv));
853  return GWEN_ERROR_GENERIC;
854  }
855 
856  rv=gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER); /* TODO: shouldn't we use the index?? */
857  if (rv!=0) {
858  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_import: %d (%s)", rv, gnutls_strerror(rv));
859  gnutls_x509_crt_deinit(cert);
860  return GWEN_ERROR_GENERIC;
861  }
862 
863  if (i==0) {
864  gnutls_datum_t n= {NULL, 0};
865  gnutls_datum_t e= {NULL, 0};
866 
867  /* get public key from cert, if any */
868  rv=gnutls_x509_crt_get_pk_rsa_raw(cert, &n, &e);
869  if (rv!=0) {
870  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_pk_rsa_raw: %d (%s)", rv, gnutls_strerror(rv));
871  }
872  else {
873  GWEN_BUFFER *kbuf;
874 
875  DBG_INFO(GWEN_LOGDOMAIN, "Key stored within certificate, extracting (modlen=%d, explen=%d)",
876  n.size, e.size);
877 
878  kbuf=GWEN_Buffer_new(0, 256, 0, 1);
879 
880  if (n.data && n.size) {
881  /* store public modulus */
882  GWEN_Text_ToHexBuffer((const char *)(n.data), n.size, kbuf, 0, 0, 0);
884  GWEN_Buffer_Reset(kbuf);
885  }
886 
887  if (e.data && e.size) {
888  /* store public exponent */
889  GWEN_Text_ToHexBuffer((const char *)(e.data), e.size, kbuf, 0, 0, 0);
891  GWEN_Buffer_Reset(kbuf);
892  }
893 
894  GWEN_Buffer_free(kbuf);
895  if (n.data)
896  gcry_free(n.data);
897  if (e.data)
898  gcry_free(e.data);
899  }
900 
901  /* get fingerprint (MD5) */
902  size=16;
903  rv=gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_MD5, buffer1, &size);
904  if (rv!=0) {
905  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_fingerprint(MD5): %d (%s)", rv, gnutls_strerror(rv));
906  GWEN_SslCertDescr_free(certDescr);
907  gnutls_x509_crt_deinit(cert);
908  return GWEN_ERROR_GENERIC;
909  }
910  else {
911  GWEN_BUFFER *dbuf;
912 
913  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
914  if (GWEN_Text_ToHexBuffer(/* GCC4 pointer-signedness fix: */ buffer1,
915  size, dbuf, 2, ':', 0)) {
917  "Could not convert fingerprint to hex");
918  }
919  else {
921  }
922  GWEN_Buffer_free(dbuf);
923  }
924 
925  /* get fingerprint (SHA1) */
926  size=sizeof(buffer1);
927  rv=gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, buffer1, &size);
928  if (rv!=0) {
929  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_fingerprint(SHA1): %d (%s)", rv, gnutls_strerror(rv));
930  GWEN_SslCertDescr_free(certDescr);
931  gnutls_x509_crt_deinit(cert);
932  return GWEN_ERROR_GENERIC;
933  }
934  else {
935  GWEN_BUFFER *dbuf;
936 
937  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
938  if (GWEN_Text_ToHexBuffer(/* GCC4 pointer-signedness fix: */ buffer1,
939  size, dbuf, 2, ':', 0)) {
941  "Could not convert fingerprint to hex");
942  }
943  else {
945  }
946  GWEN_Buffer_free(dbuf);
947  }
948 
949  /* get fingerprint (SHA512) */
950  size=sizeof(buffer1);
951  rv=gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA512, buffer1, &size);
952  if (rv!=0) {
953  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_fingerprint(SHA512): %d (%s)", rv, gnutls_strerror(rv));
954  GWEN_SslCertDescr_free(certDescr);
955  gnutls_x509_crt_deinit(cert);
956  return GWEN_ERROR_GENERIC;
957  }
958  else {
959  GWEN_BUFFER *dbuf;
960 
961  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
962  if (GWEN_Text_ToHexBuffer(/* GCC4 pointer-signedness fix: */ buffer1,
963  size, dbuf, 2, ':', 0)) {
965  "Could not convert fingerprint to hex");
966  }
967  else {
969  }
970  GWEN_Buffer_free(dbuf);
971  }
972 
973 
974  if (xio->hostName) {
975  DBG_INFO(GWEN_LOGDOMAIN, "Checking hostname [%s]", xio->hostName);
976  if (!gnutls_x509_crt_check_hostname(cert, xio->hostName)) {
978  "Certificate was not issued for this host");
980  I18N("Certificate was not issued for this host"));
982  }
983  else {
984  DBG_INFO(GWEN_LOGDOMAIN, "Cert is for this server");
985  }
986  }
987  else {
989  "Hostname is not set, unable to verify the sender");
991  I18N("No hostname to verify the sender!"));
992  }
993 
994  }
995 
996  /* get activation time */
997  t=gnutls_x509_crt_get_activation_time(cert);
998  if (t<0) {
999  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_activation_time: %d (%s)", rv, gnutls_strerror(rv));
1000  errFlags|=GWEN_SSL_CERT_FLAGS_BAD_DATA;
1001  }
1002  else {
1003  if (t>t0) {
1004  DBG_INFO(GWEN_LOGDOMAIN, "Cert is not yet active");
1006  }
1007  if (i==0) {
1008  GWEN_TIME *ti;
1009 
1010  ti=GWEN_Time_fromSeconds(t);
1011  if (ti)
1012  GWEN_SslCertDescr_SetNotBefore(certDescr, ti);
1013  GWEN_Time_free(ti);
1014  }
1015  }
1016 
1017  /* get expiration time */
1018  t=gnutls_x509_crt_get_expiration_time(cert);
1019  if (t<0) {
1020  DBG_INFO(GWEN_LOGDOMAIN, "gnutls_x509_crt_get_expiration_time: %d (%s)", rv, gnutls_strerror(rv));
1021  errFlags|=GWEN_SSL_CERT_FLAGS_BAD_DATA;
1022  }
1023  else {
1024  if (t<t0) {
1025  DBG_INFO(GWEN_LOGDOMAIN, "Cert has expired");
1026  errFlags|=GWEN_SSL_CERT_FLAGS_EXPIRED;
1027  }
1028  if (i==0) {
1029  GWEN_TIME *ti;
1030 
1031  ti=GWEN_Time_fromSeconds(t);
1032  if (ti)
1033  GWEN_SslCertDescr_SetNotAfter(certDescr, ti);
1034  GWEN_Time_free(ti);
1035  }
1036  }
1037 
1038  if (i==0) {
1039  /* get owner information, but only for first cert */
1040  size=sizeof(buffer1)-1;
1041  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, buffer1, &size);
1042  if (rv==0) {
1043  GWEN_SslCertDescr_SetCommonName(certDescr, buffer1);
1044  }
1045 
1046  size=sizeof(buffer1)-1;
1047  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, 0, buffer1, &size);
1048  if (rv==0)
1049  GWEN_SslCertDescr_SetOrganizationName(certDescr, buffer1);
1050 
1051  size=sizeof(buffer1)-1;
1052  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, 0, buffer1, &size);
1053  if (rv==0)
1054  GWEN_SslCertDescr_SetOrganizationalUnitName(certDescr, buffer1);
1055 
1056  size=sizeof(buffer1)-1;
1057  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_LOCALITY_NAME, 0, 0, buffer1, &size);
1058  if (rv==0)
1059  GWEN_SslCertDescr_SetLocalityName(certDescr, buffer1);
1060 
1061  size=sizeof(buffer1)-1;
1062  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, 0, buffer1, &size);
1063  if (rv==0)
1064  GWEN_SslCertDescr_SetStateOrProvinceName(certDescr, buffer1);
1065 
1066  size=sizeof(buffer1)-1;
1067  rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COUNTRY_NAME, 0, 0, buffer1, &size);
1068  if (rv==0)
1069  GWEN_SslCertDescr_SetCountryName(certDescr, buffer1);
1070  }
1071 
1072  gnutls_x509_crt_deinit(cert);
1073  }
1074 
1075  /* done */
1076  if (errFlags)
1077  GWEN_SslCertDescr_SetIsError(certDescr, 1);
1078  else
1079  errFlags|=GWEN_SSL_CERT_FLAGS_OK;
1080 
1081  sbuf=GWEN_Buffer_new(0, 256, 0, 1);
1082 
1083  if (errFlags & GWEN_SSL_CERT_FLAGS_SIGNER_NOT_FOUND) {
1084  if (GWEN_Buffer_GetUsedBytes(sbuf))
1085  GWEN_Buffer_AppendString(sbuf, "; ");
1086  GWEN_Buffer_AppendString(sbuf, I18N("Signer not found"));
1087  }
1088 
1089  if (errFlags & GWEN_SSL_CERT_FLAGS_INVALID) {
1090  if (GWEN_Buffer_GetUsedBytes(sbuf))
1091  GWEN_Buffer_AppendString(sbuf, "; ");
1092  GWEN_Buffer_AppendString(sbuf, I18N("Certificate is not trusted"));
1093  }
1094 
1095  if (errFlags & GWEN_SSL_CERT_FLAGS_REVOKED) {
1096  if (GWEN_Buffer_GetUsedBytes(sbuf))
1097  GWEN_Buffer_AppendString(sbuf, "; ");
1098  GWEN_Buffer_AppendString(sbuf, I18N("Certificate has been revoked"));
1099  }
1100 
1101  if (errFlags & GWEN_SSL_CERT_FLAGS_EXPIRED) {
1102  if (GWEN_Buffer_GetUsedBytes(sbuf))
1103  GWEN_Buffer_AppendString(sbuf, "; ");
1104  GWEN_Buffer_AppendString(sbuf, I18N("Certificate has expired"));
1105  }
1106 
1107  if (errFlags & GWEN_SSL_CERT_FLAGS_NOT_ACTIVE) {
1108  if (GWEN_Buffer_GetUsedBytes(sbuf))
1109  GWEN_Buffer_AppendString(sbuf, "; ");
1110  GWEN_Buffer_AppendString(sbuf, I18N("Certificate is not active yet"));
1111  }
1112 
1113  if (errFlags & GWEN_SSL_CERT_FLAGS_BAD_HOSTNAME) {
1114  if (GWEN_Buffer_GetUsedBytes(sbuf))
1115  GWEN_Buffer_AppendString(sbuf, "; ");
1116  GWEN_Buffer_AppendString(sbuf, I18N("Certificate owner does not match hostname"));
1117  }
1118 
1119  if (errFlags & GWEN_SSL_CERT_FLAGS_BAD_DATA) {
1120  if (GWEN_Buffer_GetUsedBytes(sbuf))
1121  GWEN_Buffer_AppendString(sbuf, "; ");
1122  GWEN_Buffer_AppendString(sbuf, I18N("Certificate contains invalid information"));
1123  }
1124 
1125  if (errFlags & GWEN_SSL_CERT_FLAGS_SYSTEM) {
1126  if (GWEN_Buffer_GetUsedBytes(sbuf))
1127  GWEN_Buffer_AppendString(sbuf, "; ");
1128  GWEN_Buffer_AppendString(sbuf, I18N("A system error occurred while checking the certificate"));
1129  }
1130 
1131  if (errFlags & GWEN_SSL_CERT_FLAGS_OK) {
1132  if (GWEN_Buffer_GetUsedBytes(sbuf))
1133  GWEN_Buffer_AppendString(sbuf, "; ");
1134  GWEN_Buffer_AppendString(sbuf, I18N("The certificate is valid"));
1135  }
1136 
1138  GWEN_SslCertDescr_SetStatusFlags(certDescr, errFlags);
1139  GWEN_Buffer_free(sbuf);
1140 
1141 #if 0
1142  if (1) {
1143  GWEN_DB_NODE *dbTest;
1144 
1145  dbTest=GWEN_DB_Group_new("Cert");
1146  GWEN_SslCertDescr_toDb(certDescr, dbTest);
1147  GWEN_DB_Dump(dbTest, 2);
1148  GWEN_DB_Group_free(dbTest);
1149  }
1150 #endif
1151 
1152  xio->peerCertDescr=certDescr;
1153  xio->peerCertFlags=errFlags;
1154 
1155  return 0;
1156 }
1157 
1158 
1159 
1160 ssize_t GWEN_SyncIo_Tls_Pull(gnutls_transport_ptr_t p, void *buf, size_t len)
1161 {
1162  GWEN_SYNCIO *sio;
1163  GWEN_SYNCIO_TLS *xio;
1164  GWEN_SYNCIO *baseIo;
1165  int rv;
1166 
1167  sio=(GWEN_SYNCIO *) p;
1168  assert(sio);
1169  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1170  assert(xio);
1171 
1172  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PULL: %d bytes", (int)len);
1173  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1174  assert(baseIo);
1175 
1176  rv=GWEN_SyncIo_Read(baseIo, buf, len);
1177  if (rv<0) {
1178  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1179  gnutls_transport_set_errno(xio->session, errno);
1180  return (ssize_t)-1;
1181  }
1182 
1183  gnutls_transport_set_errno(xio->session, 0);
1184  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PULL: returning %d bytes", rv);
1185  /*GWEN_Text_DumpString(buf, rv, 2);*/
1186  return rv;
1187 }
1188 
1189 
1190 
1191 ssize_t GWEN_SyncIo_Tls_Push(gnutls_transport_ptr_t p, const void *buf, size_t len)
1192 {
1193  GWEN_SYNCIO *sio;
1194  GWEN_SYNCIO_TLS *xio;
1195  GWEN_SYNCIO *baseIo;
1196  int rv;
1197 
1198  sio=(GWEN_SYNCIO *) p;
1199  assert(sio);
1200  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1201  assert(xio);
1202 
1203  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PUSH: %d bytes", (int)len);
1204  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1205  assert(baseIo);
1206 
1207  rv=GWEN_SyncIo_Write(baseIo, buf, len);
1208  if (rv<0) {
1209  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1210  gnutls_transport_set_errno(xio->session, errno);
1211  return (ssize_t)-1;
1212  }
1213 
1214  gnutls_transport_set_errno(xio->session, 0);
1215  DBG_VERBOUS(GWEN_LOGDOMAIN, "TLS PUSH: returning %d bytes", rv);
1216  /*GWEN_Text_DumpString(buf, rv, 2);*/
1217  return rv;
1218 }
1219 
1220 
1221 
1223 {
1224  GWEN_SYNCIO_TLS *xio;
1225  const char *s;
1226  gnutls_kx_algorithm_t kx;
1227  GWEN_BUFFER *cbuf;
1228  GWEN_BUFFER *sbuf;
1229 
1230  assert(sio);
1231  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1232  assert(xio);
1233 
1234  cbuf=GWEN_Buffer_new(0, 256, 0, 1);
1235  sbuf=GWEN_Buffer_new(0, 256, 0, 1);
1236 
1237  /* protocol */
1238  s=gnutls_protocol_get_name(gnutls_protocol_get_version(xio->session));
1239  if (s && *s) {
1240  if (GWEN_Buffer_GetUsedBytes(cbuf))
1241  GWEN_Buffer_AppendString(cbuf, " ");
1242  GWEN_Buffer_AppendString(cbuf, "Protocol: ");
1243  GWEN_Buffer_AppendString(cbuf, s);
1244 
1245  GWEN_Buffer_AppendString(sbuf, s);
1246  }
1247  GWEN_Buffer_AppendString(sbuf, ":");
1248 
1249  /* key exchange algorithm */
1250  kx=gnutls_kx_get(xio->session);
1251  s=gnutls_kx_get_name(kx);
1252  if (s && *s) {
1253  if (GWEN_Buffer_GetUsedBytes(cbuf))
1254  GWEN_Buffer_AppendString(cbuf, " ");
1255  GWEN_Buffer_AppendString(cbuf, "Key exchange algorithm: ");
1256  GWEN_Buffer_AppendString(cbuf, s);
1257  GWEN_Buffer_AppendString(sbuf, s);
1258  }
1259  GWEN_Buffer_AppendString(sbuf, "-");
1260 
1261  /* cipher */
1262  s=gnutls_cipher_get_name(gnutls_cipher_get(xio->session));
1263  if (s && *s) {
1264  if (GWEN_Buffer_GetUsedBytes(cbuf))
1265  GWEN_Buffer_AppendString(cbuf, " ");
1266  GWEN_Buffer_AppendString(cbuf, "cipher algorithm: ");
1267  GWEN_Buffer_AppendString(cbuf, s);
1268  GWEN_Buffer_AppendString(sbuf, s);
1269  }
1270  GWEN_Buffer_AppendString(sbuf, ":");
1271 
1272  /* MAC algorithm */
1273  s=gnutls_mac_get_name(gnutls_mac_get(xio->session));
1274  if (s && *s) {
1275  if (GWEN_Buffer_GetUsedBytes(cbuf))
1276  GWEN_Buffer_AppendString(cbuf, " ");
1277  GWEN_Buffer_AppendString(cbuf, "MAC algorithm: ");
1278  GWEN_Buffer_AppendString(cbuf, s);
1279  GWEN_Buffer_AppendString(sbuf, s);
1280  }
1281 
1282 
1284  GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Info, I18N("TLS: SSL-Ciphers negotiated: %s"), GWEN_Buffer_GetStart(sbuf));
1285  GWEN_Buffer_free(cbuf);
1286  GWEN_Buffer_free(sbuf);
1287 
1288  /* possibly show warning */
1289  switch (gnutls_cipher_get(xio->session)) {
1290  case GNUTLS_CIPHER_ARCFOUR_128:
1291  case GNUTLS_CIPHER_3DES_CBC:
1292  case GNUTLS_CIPHER_AES_128_CBC:
1293  case GNUTLS_CIPHER_ARCFOUR_40:
1294  case GNUTLS_CIPHER_CAMELLIA_128_CBC:
1295  GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error, I18N("TLS: Warning - The server has chosen unsafe SSL-Ciphers!"));
1296  break;
1297  case GNUTLS_CIPHER_AES_256_CBC:
1298  case GNUTLS_CIPHER_CAMELLIA_256_CBC:
1299  case GNUTLS_CIPHER_RC2_40_CBC:
1300  case GNUTLS_CIPHER_DES_CBC:
1301 #ifdef GNUTLS_CIPHER_AES_192_CBC
1302  case GNUTLS_CIPHER_AES_192_CBC: /* new in gnutls-2.9.8, so i.e. not available in gnutls-2.8.x */
1303 #endif
1304  default:
1305  break;
1306  }
1307 }
1308 
1309 
1310 
1312 {
1313  GWEN_SYNCIO_TLS *xio;
1314  GWEN_SYNCIO *baseIo;
1315  int rv;
1316 
1317  assert(sio);
1318  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1319  assert(xio);
1320 
1321  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1322  assert(baseIo);
1323 
1326  DBG_ERROR(GWEN_LOGDOMAIN, "Base layer is not connected");
1327  return GWEN_ERROR_NOT_CONNECTED;
1328  }
1329  }
1330  else {
1331  DBG_INFO(GWEN_LOGDOMAIN, "Connecting base layer");
1332  rv=GWEN_SyncIo_Connect(baseIo);
1333  if (rv<0) {
1334  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1335  return rv;
1336  }
1337  DBG_INFO(GWEN_LOGDOMAIN, "Base layer connected");
1338  }
1339 
1340  rv=GWEN_SyncIo_Tls_Prepare(sio);
1341  if (rv<0) {
1342  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1343  GWEN_SyncIo_Disconnect(baseIo);
1344  return rv;
1345  }
1346 
1347  do {
1348  rv=gnutls_handshake(xio->session);
1349  }
1350  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1351 
1352  if (rv) {
1353  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_handshake: %d (%s) [%s]",
1354  rv, gnutls_strerror(rv), gnutls_error_is_fatal(rv)?"fatal":"non-fatal");
1355  if (rv==GNUTLS_E_UNEXPECTED_PACKET_LENGTH) {
1358  I18N("A TLS handshake error occurred. "
1359  "If you are using AqBanking you should "
1360  "consider enabling the option "
1361  "\"force SSLv3\" in the user settings "
1362  "dialog."));
1363  }
1364  else {
1367  I18N("TLS Handshake Error: %d (%s)"),
1368  rv,
1369  gnutls_strerror(rv));
1370  }
1373  GWEN_SyncIo_Disconnect(baseIo);
1374  return GWEN_ERROR_SSL;
1375  }
1376  else {
1377  /* show session info */
1379 
1380  /* check certificate */
1383  if (rv<0) {
1385  DBG_ERROR(GWEN_LOGDOMAIN, "No peer certificate when needed, aborting connection");
1388  GWEN_SyncIo_Disconnect(baseIo);
1389  return GWEN_ERROR_SSL_SECURITY;
1390  }
1391  else {
1392  DBG_INFO(GWEN_LOGDOMAIN, "SSL connected (insecure)");
1394  return 0;
1395  }
1396  }
1397  else {
1398  /* present cert to the user */
1399  rv=GWEN_SyncIo_Tls_CheckCert(sio, xio->peerCertDescr);
1400  if (rv<0) {
1401  DBG_ERROR(GWEN_LOGDOMAIN, "Peer cert not accepted (%d), aborting", rv);
1404  GWEN_SyncIo_Disconnect(baseIo);
1405  return GWEN_ERROR_SSL_SECURITY;
1406  }
1407  else {
1408  DBG_INFO(GWEN_LOGDOMAIN, "SSL connected (secure)");
1411  return 0;
1412  }
1413  }
1414  }
1415 }
1416 
1417 
1418 
1420 {
1421  GWEN_SYNCIO_TLS *xio;
1422  GWEN_SYNCIO *baseIo;
1423  int rv;
1424 
1425  assert(sio);
1426  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1427  assert(xio);
1428 
1429  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1430  assert(baseIo);
1431 
1433  DBG_INFO(GWEN_LOGDOMAIN, "Not connected");
1435  GWEN_SyncIo_Disconnect(baseIo);
1436  return GWEN_ERROR_NOT_CONNECTED;
1437  }
1438 
1439  do {
1440  rv=gnutls_bye(xio->session, GNUTLS_SHUT_RDWR);
1441  }
1442  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1443 
1444  if (rv) {
1445  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_bye: %d (%s)", rv, gnutls_strerror(rv));
1448  I18N("Error on gnutls_bye: %d (%s)"),
1449  rv,
1450  gnutls_strerror(rv));
1453  GWEN_SyncIo_Disconnect(baseIo);
1454  return GWEN_ERROR_SSL;
1455  }
1456 
1459  GWEN_SyncIo_Disconnect(baseIo);
1460  return 0;
1461 }
1462 
1463 
1464 
1466  uint8_t *buffer,
1467  uint32_t size)
1468 {
1469  GWEN_SYNCIO_TLS *xio;
1470  GWEN_SYNCIO *baseIo;
1471  int rv;
1472 
1473  assert(sio);
1474  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1475  assert(xio);
1476 
1477  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1478  assert(baseIo);
1479 
1481  DBG_INFO(GWEN_LOGDOMAIN, "Not connected");
1483  GWEN_SyncIo_Disconnect(baseIo);
1484  return GWEN_ERROR_NOT_CONNECTED;
1485  }
1486 
1487  do {
1488  rv=gnutls_record_recv(xio->session, buffer, size);
1489  }
1490  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1491 
1492  if (rv<0) {
1493  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_record_recv: %d (%s)", rv, gnutls_strerror(rv));
1494 #if 0
1497  I18N("Error on gnutls_record_recv: %d (%s)"),
1498  rv,
1499  gnutls_strerror(rv));
1500 #endif
1503  GWEN_SyncIo_Disconnect(baseIo);
1504 #ifdef GNUTLS_E_PREMATURE_TERMINATION
1505  if (rv==GNUTLS_E_PREMATURE_TERMINATION) {
1507  DBG_ERROR(GWEN_LOGDOMAIN, "Detected premature disconnect by server (violates specs!), ignoring.");
1508  return 0; /* report EOF */
1509  }
1510  else {
1511  DBG_ERROR(GWEN_LOGDOMAIN, "Detected premature disconnect by server (violates specs!)");
1513  }
1514  }
1515 #endif
1516  return GWEN_ERROR_SSL;
1517  }
1518 
1519 #ifdef GWEN_TLS_DEBUG
1520  DBG_ERROR(0, "Received this:");
1521  GWEN_Text_DumpString((const char *) buffer, rv, 2);
1522 #endif
1523 
1524  return rv;
1525 }
1526 
1527 
1528 
1530  const uint8_t *buffer,
1531  uint32_t size)
1532 {
1533  GWEN_SYNCIO_TLS *xio;
1534  GWEN_SYNCIO *baseIo;
1535  int rv;
1536 
1537  assert(sio);
1538  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_TLS, sio);
1539  assert(xio);
1540 
1541 #ifdef GWEN_TLS_DEBUG
1542  DBG_ERROR(0, "Sending this:");
1543  GWEN_Text_DumpString((const char *) buffer, size, 2);
1544 #endif
1545 
1546  baseIo=GWEN_SyncIo_GetBaseIo(sio);
1547  assert(baseIo);
1548 
1550  DBG_INFO(GWEN_LOGDOMAIN, "Not connected");
1552  GWEN_SyncIo_Disconnect(baseIo);
1553  return GWEN_ERROR_NOT_CONNECTED;
1554  }
1555 
1556  do {
1557  rv=gnutls_record_send(xio->session, buffer, size);
1558  }
1559  while (rv==GNUTLS_E_AGAIN || rv==GNUTLS_E_INTERRUPTED);
1560 
1561  if (rv<0) {
1562  DBG_ERROR(GWEN_LOGDOMAIN, "gnutls_record_send: %d (%s)", rv, gnutls_strerror(rv));
1565  I18N("Error on gnutls_record_send: %d (%s)"),
1566  rv,
1567  gnutls_strerror(rv));
1570  GWEN_SyncIo_Disconnect(baseIo);
1571  return GWEN_ERROR_SSL;
1572  }
1573 
1574  return rv;
1575 }
1576 
1577 
1578 
1579 
1580 
1581 
1582 
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
#define DBG_ERROR(dbg_logger, format,...)
Definition: debug.h:97
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:1191
#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
#define DBG_NOTICE(dbg_logger, format,...)
Definition: debug.h:152
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
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 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:468
const char * GWEN_SyncIo_Tls_GetLocalKeyFile(const GWEN_SYNCIO *sio)
Definition: syncio_tls.c:194
#define GWEN_LOGDOMAIN
Definition: logger.h:32
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
#define DBG_VERBOUS(dbg_logger, format,...)
Definition: debug.h:224
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:548
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:653
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:451
#define DBG_WARN(dbg_logger, format,...)
Definition: debug.h:125
#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
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:1465
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:1160
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:1419
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
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:1222
GWEN_SYNCIO_DISCONNECT_FN GWEN_SyncIo_SetDisconnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_DISCONNECT_FN fn)
Definition: syncio.c:265
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:1529
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 DBG_INFO(dbg_logger, format,...)
Definition: debug.h:181
#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:300
int GWENHYWFAR_CB GWEN_SyncIo_Tls_Connect(GWEN_SYNCIO *sio)
Definition: syncio_tls.c:1311
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:992
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:279
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)