2 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * 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.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
24 #include <gnutls_int.h>
25 #include <gnutls_errors.h>
29 #include <sys/types.h>
33 # include <Wincrypt.h>
36 # ifdef HAVE_PTHREAD_LOCKS
40 # if defined(HAVE_GETPWUID_R)
45 /* We need to disable gnulib's replacement wrappers to get native
46 Windows interfaces. */
51 /* System specific function wrappers.
54 /* wrappers for write() and writev()
59 system_errno (gnutls_transport_ptr p
)
61 int tmperr
= WSAGetLastError ();
81 WSASetLastError (tmperr
);
87 system_write (gnutls_transport_ptr ptr
, const void *data
, size_t data_size
)
89 return send (GNUTLS_POINTER_TO_INT (ptr
), data
, data_size
, 0);
93 system_errno (gnutls_transport_ptr_t ptr
)
95 #if defined(_AIX) || defined(AIX)
96 if (errno
== 0) errno
= EAGAIN
;
103 system_writev (gnutls_transport_ptr_t ptr
, const giovec_t
* iovec
,
106 return writev (GNUTLS_POINTER_TO_INT (ptr
), (struct iovec
*) iovec
,
113 system_read (gnutls_transport_ptr_t ptr
, void *data
, size_t data_size
)
115 return recv (GNUTLS_POINTER_TO_INT (ptr
), data
, data_size
, 0);
118 /* Wait for data to be received within a timeout period in milliseconds.
119 * To catch a termination it will also try to receive 0 bytes from the
120 * socket if select reports to proceed.
122 * Returns -1 on error, 0 on timeout, positive value if data are available for reading.
124 int system_recv_timeout(gnutls_transport_ptr_t ptr
, unsigned int ms
)
129 int fd
= GNUTLS_POINTER_TO_INT(ptr
);
135 tv
.tv_usec
= ms
* 1000;
137 while(tv
.tv_usec
>= 1000000)
139 tv
.tv_usec
-= 1000000;
143 ret
= select(fd
+1, &rfds
, NULL
, NULL
, &tv
);
147 ret2
= recv(fd
, NULL
, 0, MSG_PEEK
);
156 #ifdef HAVE_WIN32_LOCKS
159 /* FIXME: win32 locks are untested */
161 gnutls_system_mutex_init (void **priv
)
163 CRITICAL_SECTION
*lock
= malloc (sizeof (CRITICAL_SECTION
));
166 return GNUTLS_E_MEMORY_ERROR
;
168 InitializeCriticalSection (lock
);
176 gnutls_system_mutex_deinit (void **priv
)
178 DeleteCriticalSection ((CRITICAL_SECTION
*) * priv
);
185 gnutls_system_mutex_lock (void **priv
)
187 EnterCriticalSection ((CRITICAL_SECTION
*) * priv
);
192 gnutls_system_mutex_unlock (void **priv
)
194 LeaveCriticalSection ((CRITICAL_SECTION
*) * priv
);
198 #endif /* WIN32_LOCKS */
200 #ifdef HAVE_PTHREAD_LOCKS
203 gnutls_system_mutex_init (void **priv
)
205 pthread_mutex_t
*lock
= malloc (sizeof (pthread_mutex_t
));
209 return GNUTLS_E_MEMORY_ERROR
;
211 ret
= pthread_mutex_init (lock
, NULL
);
216 return GNUTLS_E_LOCKING_ERROR
;
225 gnutls_system_mutex_deinit (void **priv
)
227 pthread_mutex_destroy ((pthread_mutex_t
*) * priv
);
233 gnutls_system_mutex_lock (void **priv
)
235 if (pthread_mutex_lock ((pthread_mutex_t
*) * priv
))
238 return GNUTLS_E_LOCKING_ERROR
;
245 gnutls_system_mutex_unlock (void **priv
)
247 if (pthread_mutex_unlock ((pthread_mutex_t
*) * priv
))
250 return GNUTLS_E_LOCKING_ERROR
;
256 #endif /* PTHREAD_LOCKS */
261 gnutls_system_mutex_init (void **priv
)
267 gnutls_system_mutex_deinit (void **priv
)
273 gnutls_system_mutex_lock (void **priv
)
279 gnutls_system_mutex_unlock (void **priv
)
284 #endif /* NO_LOCKS */
286 gnutls_time_func gnutls_time
= time
;
287 mutex_init_func gnutls_mutex_init
= gnutls_system_mutex_init
;
288 mutex_deinit_func gnutls_mutex_deinit
= gnutls_system_mutex_deinit
;
289 mutex_lock_func gnutls_mutex_lock
= gnutls_system_mutex_lock
;
290 mutex_unlock_func gnutls_mutex_unlock
= gnutls_system_mutex_unlock
;
292 #define CONFIG_PATH ".gnutls"
294 /* Returns a path to store user-specific configuration
297 int _gnutls_find_config_path(char* path
, size_t max_size
)
299 char tmp_home_dir
[1024];
300 const char *home_dir
= getenv ("HOME");
303 if (home_dir
== NULL
|| home_dir
[0] == '\0')
305 const char *home_drive
= getenv ("HOMEDRIVE");
306 const char *home_path
= getenv ("HOMEPATH");
308 if (home_drive
!= NULL
&& home_path
!= NULL
)
310 snprintf(tmp_home_dir
, sizeof(tmp_home_dir
), "%s%s", home_drive
, home_path
);
317 home_dir
= tmp_home_dir
;
319 #elif defined(HAVE_GETPWUID_R)
320 if (home_dir
== NULL
|| home_dir
[0] == '\0')
326 getpwuid_r(getuid(), &_pwd
, buf
, sizeof(buf
), &pwd
);
329 snprintf(tmp_home_dir
, sizeof(tmp_home_dir
), "%s", pwd
->pw_dir
);
336 home_dir
= tmp_home_dir
;
339 if (home_dir
== NULL
|| home_dir
[0] == '\0')
342 home_dir
= tmp_home_dir
;
346 if (home_dir
== NULL
|| home_dir
[0] == 0)
349 snprintf(path
, max_size
, "%s/"CONFIG_PATH
, home_dir
);
355 * gnutls_x509_trust_list_add_system_trust:
356 * @list: The structure of the list
357 * @tl_flags: GNUTLS_TL_*
358 * @tl_vflags: gnutls_certificate_verify_flags if flags specifies GNUTLS_TL_VERIFY_CRL
360 * This function adds the system's default trusted certificate
361 * authorities to the trusted list. Note that on unsupported system
362 * this function returns %GNUTLS_E_UNIMPLEMENTED_FEATURE.
364 * Returns: The number of added elements or a negative error code on error.
369 gnutls_x509_trust_list_add_system_trust(gnutls_x509_trust_list_t list
,
370 unsigned int tl_flags
, unsigned int tl_vflags
)
372 #if !defined(DEFAULT_TRUST_STORE_PKCS11) && !defined(DEFAULT_TRUST_STORE_FILE) && !defined(_WIN32)
373 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
376 const char* crl_file
=
377 # ifdef DEFAULT_CRL_FILE
389 const CERT_CONTEXT
*cert
;
390 const CRL_CONTEXT
*crl
;
393 if (i
==0) store
= CertOpenSystemStore(0, "ROOT");
394 else store
= CertOpenSystemStore(0, "CA");
396 if (store
== NULL
) return GNUTLS_E_FILE_ERROR
;
398 cert
= CertEnumCertificatesInStore(store
, NULL
);
399 crl
= CertEnumCRLsInStore(store
, NULL
);
403 if (cert
->dwCertEncodingType
== X509_ASN_ENCODING
)
405 data
.data
= cert
->pbCertEncoded
;
406 data
.size
= cert
->cbCertEncoded
;
407 if (gnutls_x509_trust_list_add_trust_mem(list
, &data
, NULL
, GNUTLS_X509_FMT_DER
, tl_flags
, tl_vflags
) > 0)
410 cert
= CertEnumCertificatesInStore(store
, cert
);
415 if (crl
->dwCertEncodingType
== X509_ASN_ENCODING
)
417 data
.data
= crl
->pbCrlEncoded
;
418 data
.size
= crl
->cbCrlEncoded
;
419 gnutls_x509_trust_list_add_trust_mem(list
, NULL
, &data
, GNUTLS_X509_FMT_DER
, tl_flags
, tl_vflags
);
421 crl
= CertEnumCRLsInStore(store
, crl
);
423 CertCloseStore(store
, 0);
427 # if defined(ENABLE_PKCS11) && defined(DEFAULT_TRUST_STORE_PKCS11)
428 ret
= gnutls_x509_trust_list_add_trust_file(list
, DEFAULT_TRUST_STORE_PKCS11
, crl_file
,
429 GNUTLS_X509_FMT_DER
, tl_flags
, tl_vflags
);
434 # ifdef DEFAULT_TRUST_STORE_FILE
435 ret
= gnutls_x509_trust_list_add_trust_file(list
, DEFAULT_TRUST_STORE_FILE
, crl_file
,
436 GNUTLS_X509_FMT_PEM
, tl_flags
, tl_vflags
);