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