|
|
873a72 |
diff -urN gnutls-3.3.8.orig/lib/crypto-backend.h gnutls-3.3.8/lib/crypto-backend.h
|
|
|
873a72 |
--- gnutls-3.3.8.orig/lib/crypto-backend.h 2014-07-29 22:22:47.000000000 +0200
|
|
|
873a72 |
+++ gnutls-3.3.8/lib/crypto-backend.h 2014-11-18 09:52:15.420936655 +0100
|
|
|
873a72 |
@@ -77,6 +77,7 @@
|
|
|
873a72 |
|
|
|
873a72 |
typedef struct gnutls_crypto_rnd {
|
|
|
873a72 |
int (*init) (void **ctx);
|
|
|
873a72 |
+ int (*check) (void **ctx);
|
|
|
873a72 |
int (*rnd) (void *ctx, int level, void *data, size_t datasize);
|
|
|
873a72 |
void (*rnd_refresh) (void *ctx);
|
|
|
873a72 |
void (*deinit) (void *ctx);
|
|
|
873a72 |
diff -urN gnutls-3.3.8.orig/lib/gnutls_global.c gnutls-3.3.8/lib/gnutls_global.c
|
|
|
873a72 |
--- gnutls-3.3.8.orig/lib/gnutls_global.c 2014-09-04 21:05:54.000000000 +0200
|
|
|
873a72 |
+++ gnutls-3.3.8/lib/gnutls_global.c 2014-11-18 09:57:18.851879610 +0100
|
|
|
873a72 |
@@ -207,6 +207,16 @@
|
|
|
873a72 |
|
|
|
873a72 |
_gnutls_init++;
|
|
|
873a72 |
if (_gnutls_init > 1) {
|
|
|
873a72 |
+ if (_gnutls_init == 2 && _gnutls_init_ret == 0) {
|
|
|
873a72 |
+ /* some applications may close the urandom fd
|
|
|
873a72 |
+ * before calling gnutls_global_init(). in that
|
|
|
873a72 |
+ * case reopen it */
|
|
|
873a72 |
+ ret = _gnutls_rnd_check();
|
|
|
873a72 |
+ if (ret < 0) {
|
|
|
873a72 |
+ gnutls_assert();
|
|
|
873a72 |
+ goto out;
|
|
|
873a72 |
+ }
|
|
|
873a72 |
+ }
|
|
|
873a72 |
ret = _gnutls_init_ret;
|
|
|
873a72 |
goto out;
|
|
|
873a72 |
}
|
|
|
873a72 |
diff -urN gnutls-3.3.8.orig/lib/nettle/rnd.c gnutls-3.3.8/lib/nettle/rnd.c
|
|
|
873a72 |
--- gnutls-3.3.8.orig/lib/nettle/rnd.c 2014-07-29 22:25:07.000000000 +0200
|
|
|
873a72 |
+++ gnutls-3.3.8/lib/nettle/rnd.c 2014-11-18 09:52:15.420936655 +0100
|
|
|
873a72 |
@@ -255,6 +255,15 @@
|
|
|
873a72 |
return 0;
|
|
|
873a72 |
}
|
|
|
873a72 |
|
|
|
873a72 |
+/* This is called when gnutls_global_init() is called for second time.
|
|
|
873a72 |
+ * It must check whether any resources are still available.
|
|
|
873a72 |
+ * The particular problem it solves is to verify that the urandom fd is still
|
|
|
873a72 |
+ * open (for applications that for some reason closed all fds */
|
|
|
873a72 |
+static int wrap_nettle_rnd_check(void **ctx)
|
|
|
873a72 |
+{
|
|
|
873a72 |
+ return _rnd_system_entropy_check();
|
|
|
873a72 |
+}
|
|
|
873a72 |
+
|
|
|
873a72 |
static int
|
|
|
873a72 |
wrap_nettle_rnd_nonce(void *_ctx, void *data, size_t datasize)
|
|
|
873a72 |
{
|
|
|
873a72 |
@@ -363,6 +372,7 @@
|
|
|
873a72 |
|
|
|
873a72 |
gnutls_crypto_rnd_st _gnutls_rnd_ops = {
|
|
|
873a72 |
.init = wrap_nettle_rnd_init,
|
|
|
873a72 |
+ .check = wrap_nettle_rnd_check,
|
|
|
873a72 |
.deinit = wrap_nettle_rnd_deinit,
|
|
|
873a72 |
.rnd = wrap_nettle_rnd,
|
|
|
873a72 |
.rnd_refresh = wrap_nettle_rnd_refresh,
|
|
|
873a72 |
diff -urN gnutls-3.3.8.orig/lib/nettle/rnd-common.c gnutls-3.3.8/lib/nettle/rnd-common.c
|
|
|
873a72 |
--- gnutls-3.3.8.orig/lib/nettle/rnd-common.c 2014-08-03 14:22:42.000000000 +0200
|
|
|
873a72 |
+++ gnutls-3.3.8/lib/nettle/rnd-common.c 2014-11-18 10:25:56.962112669 +0100
|
|
|
873a72 |
@@ -37,6 +37,10 @@
|
|
|
873a72 |
#include <rnd-common.h>
|
|
|
873a72 |
#include <hash-pjw-bare.h>
|
|
|
873a72 |
|
|
|
873a72 |
+#include <sys/types.h>
|
|
|
873a72 |
+#include <sys/stat.h>
|
|
|
873a72 |
+#include <unistd.h>
|
|
|
873a72 |
+
|
|
|
873a72 |
/* gnulib wants to claim strerror even if it cannot provide it. WTF */
|
|
|
873a72 |
#undef strerror
|
|
|
873a72 |
|
|
|
873a72 |
@@ -94,6 +98,11 @@
|
|
|
873a72 |
|
|
|
873a72 |
get_entropy_func _rnd_get_system_entropy = _rnd_get_system_entropy_win32;
|
|
|
873a72 |
|
|
|
873a72 |
+int _rnd_system_entropy_check(void)
|
|
|
873a72 |
+{
|
|
|
873a72 |
+ return 0;
|
|
|
873a72 |
+}
|
|
|
873a72 |
+
|
|
|
873a72 |
int _rnd_system_entropy_init(void)
|
|
|
873a72 |
{
|
|
|
873a72 |
int old;
|
|
|
873a72 |
@@ -127,7 +136,8 @@
|
|
|
873a72 |
#include <locks.h>
|
|
|
873a72 |
#include "egd.h"
|
|
|
873a72 |
|
|
|
873a72 |
-static int device_fd = -1;
|
|
|
873a72 |
+int _gnutls_urandom_fd = -1;
|
|
|
873a72 |
+static mode_t _gnutls_urandom_fd_mode = 0;
|
|
|
873a72 |
|
|
|
873a72 |
static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size)
|
|
|
873a72 |
{
|
|
|
873a72 |
@@ -137,7 +147,7 @@
|
|
|
873a72 |
for (done = 0; done < size;) {
|
|
|
873a72 |
int res;
|
|
|
873a72 |
do {
|
|
|
873a72 |
- res = read(device_fd, rnd + done, size - done);
|
|
|
873a72 |
+ res = read(_gnutls_urandom_fd, rnd + done, size - done);
|
|
|
873a72 |
} while (res < 0 && errno == EINTR);
|
|
|
873a72 |
|
|
|
873a72 |
if (res <= 0) {
|
|
|
873a72 |
@@ -168,7 +178,7 @@
|
|
|
873a72 |
|
|
|
873a72 |
for (done = 0; done < size;) {
|
|
|
873a72 |
res =
|
|
|
873a72 |
- _rndegd_read(&device_fd, rnd + done, size - done);
|
|
|
873a72 |
+ _rndegd_read(&_gnutls_urandom_fd, rnd + done, size - done);
|
|
|
873a72 |
if (res <= 0) {
|
|
|
873a72 |
if (res < 0) {
|
|
|
873a72 |
_gnutls_debug_log("Failed to read egd.\n");
|
|
|
873a72 |
@@ -186,31 +196,53 @@
|
|
|
873a72 |
|
|
|
873a72 |
get_entropy_func _rnd_get_system_entropy = NULL;
|
|
|
873a72 |
|
|
|
873a72 |
+int _rnd_system_entropy_check(void)
|
|
|
873a72 |
+{
|
|
|
873a72 |
+ int ret;
|
|
|
873a72 |
+ struct stat st;
|
|
|
873a72 |
+
|
|
|
873a72 |
+ ret = fstat(_gnutls_urandom_fd, &st);
|
|
|
873a72 |
+ if (ret < 0 || st.st_mode != _gnutls_urandom_fd_mode) {
|
|
|
873a72 |
+ return _rnd_system_entropy_init();
|
|
|
873a72 |
+ }
|
|
|
873a72 |
+ return 0;
|
|
|
873a72 |
+}
|
|
|
873a72 |
+
|
|
|
873a72 |
int _rnd_system_entropy_init(void)
|
|
|
873a72 |
{
|
|
|
873a72 |
-int old;
|
|
|
873a72 |
+ int old;
|
|
|
873a72 |
+ struct stat st;
|
|
|
873a72 |
|
|
|
873a72 |
- device_fd = open("/dev/urandom", O_RDONLY);
|
|
|
873a72 |
- if (device_fd < 0) {
|
|
|
873a72 |
+ _gnutls_urandom_fd = open("/dev/urandom", O_RDONLY);
|
|
|
873a72 |
+ if (_gnutls_urandom_fd < 0) {
|
|
|
873a72 |
_gnutls_debug_log("Cannot open urandom!\n");
|
|
|
873a72 |
goto fallback;
|
|
|
873a72 |
}
|
|
|
873a72 |
|
|
|
873a72 |
- old = fcntl(device_fd, F_GETFD);
|
|
|
873a72 |
+ old = fcntl(_gnutls_urandom_fd, F_GETFD);
|
|
|
873a72 |
if (old != -1)
|
|
|
873a72 |
- fcntl(device_fd, F_SETFD, old | FD_CLOEXEC);
|
|
|
873a72 |
+ fcntl(_gnutls_urandom_fd, F_SETFD, old | FD_CLOEXEC);
|
|
|
873a72 |
+
|
|
|
873a72 |
+ if (fstat(_gnutls_urandom_fd, &st) >= 0) {
|
|
|
873a72 |
+ _gnutls_urandom_fd_mode = st.st_mode;
|
|
|
873a72 |
+ }
|
|
|
873a72 |
|
|
|
873a72 |
_rnd_get_system_entropy = _rnd_get_system_entropy_urandom;
|
|
|
873a72 |
|
|
|
873a72 |
return 0;
|
|
|
873a72 |
fallback:
|
|
|
873a72 |
- device_fd = _rndegd_connect_socket();
|
|
|
873a72 |
- if (device_fd < 0) {
|
|
|
873a72 |
+ _gnutls_urandom_fd = _rndegd_connect_socket();
|
|
|
873a72 |
+ if (_gnutls_urandom_fd < 0) {
|
|
|
873a72 |
_gnutls_debug_log("Cannot open egd socket!\n");
|
|
|
873a72 |
return
|
|
|
873a72 |
gnutls_assert_val
|
|
|
873a72 |
(GNUTLS_E_RANDOM_DEVICE_ERROR);
|
|
|
873a72 |
}
|
|
|
873a72 |
+
|
|
|
873a72 |
+ if (fstat(_gnutls_urandom_fd, &st) >= 0) {
|
|
|
873a72 |
+ _gnutls_urandom_fd_mode = st.st_mode;
|
|
|
873a72 |
+ }
|
|
|
873a72 |
+
|
|
|
873a72 |
_rnd_get_system_entropy = _rnd_get_system_entropy_egd;
|
|
|
873a72 |
|
|
|
873a72 |
return 0;
|
|
|
873a72 |
@@ -218,9 +250,9 @@
|
|
|
873a72 |
|
|
|
873a72 |
void _rnd_system_entropy_deinit(void)
|
|
|
873a72 |
{
|
|
|
873a72 |
- if (device_fd >= 0) {
|
|
|
873a72 |
- close(device_fd);
|
|
|
873a72 |
- device_fd = -1;
|
|
|
873a72 |
+ if (_gnutls_urandom_fd >= 0) {
|
|
|
873a72 |
+ close(_gnutls_urandom_fd);
|
|
|
873a72 |
+ _gnutls_urandom_fd = -1;
|
|
|
873a72 |
}
|
|
|
873a72 |
}
|
|
|
873a72 |
#endif
|
|
|
873a72 |
diff -urN gnutls-3.3.8.orig/lib/nettle/rnd-common.h gnutls-3.3.8/lib/nettle/rnd-common.h
|
|
|
873a72 |
--- gnutls-3.3.8.orig/lib/nettle/rnd-common.h 2014-07-29 22:22:47.000000000 +0200
|
|
|
873a72 |
+++ gnutls-3.3.8/lib/nettle/rnd-common.h 2014-11-18 09:52:15.420936655 +0100
|
|
|
873a72 |
@@ -50,6 +50,7 @@
|
|
|
873a72 |
void _rnd_get_event(struct event_st *e);
|
|
|
873a72 |
|
|
|
873a72 |
int _rnd_system_entropy_init(void);
|
|
|
873a72 |
+int _rnd_system_entropy_check(void);
|
|
|
873a72 |
void _rnd_system_entropy_deinit(void);
|
|
|
873a72 |
|
|
|
873a72 |
typedef int (*get_entropy_func)(void* rnd, size_t size);
|
|
|
873a72 |
diff -urN gnutls-3.3.8.orig/lib/random.h gnutls-3.3.8/lib/random.h
|
|
|
873a72 |
--- gnutls-3.3.8.orig/lib/random.h 2014-07-29 22:22:47.000000000 +0200
|
|
|
873a72 |
+++ gnutls-3.3.8/lib/random.h 2014-11-18 09:58:19.458267672 +0100
|
|
|
873a72 |
@@ -48,4 +48,13 @@
|
|
|
873a72 |
void _gnutls_rnd_deinit(void);
|
|
|
873a72 |
int _gnutls_rnd_init(void);
|
|
|
873a72 |
|
|
|
873a72 |
+inline static int _gnutls_rnd_check(void)
|
|
|
873a72 |
+{
|
|
|
873a72 |
+ return _gnutls_rnd_ops.check(gnutls_rnd_ctx);
|
|
|
873a72 |
+}
|
|
|
873a72 |
+
|
|
|
873a72 |
+#ifndef _WIN32
|
|
|
873a72 |
+extern int _gnutls_urandom_fd;
|
|
|
873a72 |
+#endif
|
|
|
873a72 |
+
|
|
|
873a72 |
#endif
|
|
|
873a72 |
diff -urN gnutls-3.3.8.orig/tests/init_fds.c gnutls-3.3.8/tests/init_fds.c
|
|
|
873a72 |
--- gnutls-3.3.8.orig/tests/init_fds.c 1970-01-01 01:00:00.000000000 +0100
|
|
|
873a72 |
+++ gnutls-3.3.8/tests/init_fds.c 2014-11-18 10:01:10.484365302 +0100
|
|
|
873a72 |
@@ -0,0 +1,80 @@
|
|
|
873a72 |
+/*
|
|
|
873a72 |
+ * Copyright (C) 2014 Nikos Mavrogiannopoulos
|
|
|
873a72 |
+ *
|
|
|
873a72 |
+ * Author: Nikos Mavrogiannopoulos
|
|
|
873a72 |
+ *
|
|
|
873a72 |
+ * This file is part of GnuTLS.
|
|
|
873a72 |
+ *
|
|
|
873a72 |
+ * GnuTLS is free software; you can redistribute it and/or modify it
|
|
|
873a72 |
+ * under the terms of the GNU General Public License as published by
|
|
|
873a72 |
+ * the Free Software Foundation; either version 3 of the License, or
|
|
|
873a72 |
+ * (at your option) any later version.
|
|
|
873a72 |
+ *
|
|
|
873a72 |
+ * GnuTLS is distributed in the hope that it will be useful, but
|
|
|
873a72 |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
873a72 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
873a72 |
+ * General Public License for more details.
|
|
|
873a72 |
+ *
|
|
|
873a72 |
+ * You should have received a copy of the GNU General Public License
|
|
|
873a72 |
+ * along with GnuTLS; if not, write to the Free Software Foundation,
|
|
|
873a72 |
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
873a72 |
+ */
|
|
|
873a72 |
+
|
|
|
873a72 |
+#ifdef HAVE_CONFIG_H
|
|
|
873a72 |
+#include <config.h>
|
|
|
873a72 |
+#endif
|
|
|
873a72 |
+
|
|
|
873a72 |
+#include <stdio.h>
|
|
|
873a72 |
+#include <unistd.h>
|
|
|
873a72 |
+#include <gnutls/gnutls.h>
|
|
|
873a72 |
+#include <gnutls/crypto.h>
|
|
|
873a72 |
+
|
|
|
873a72 |
+#include "utils.h"
|
|
|
873a72 |
+
|
|
|
873a72 |
+/* See <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=760476>. */
|
|
|
873a72 |
+
|
|
|
873a72 |
+void doit(void)
|
|
|
873a72 |
+{
|
|
|
873a72 |
+#ifndef _WIN32
|
|
|
873a72 |
+ int res;
|
|
|
873a72 |
+ unsigned i;
|
|
|
873a72 |
+ int serial = 0;
|
|
|
873a72 |
+ char buf[128];
|
|
|
873a72 |
+
|
|
|
873a72 |
+ res = read(3, buf, 16);
|
|
|
873a72 |
+ if (res == 16)
|
|
|
873a72 |
+ serial = 1;
|
|
|
873a72 |
+
|
|
|
873a72 |
+ /* close all descriptors */
|
|
|
873a72 |
+ for (i=3;i<1024;i++)
|
|
|
873a72 |
+ close(i);
|
|
|
873a72 |
+
|
|
|
873a72 |
+ res = gnutls_global_init();
|
|
|
873a72 |
+ if (res != 0)
|
|
|
873a72 |
+ fail("global_init\n");
|
|
|
873a72 |
+
|
|
|
873a72 |
+ if (serial != 0) {
|
|
|
873a72 |
+ res = read(3, buf, 16);
|
|
|
873a72 |
+ if (res != 16) {
|
|
|
873a72 |
+ fail("could not open fd, or OS doesn't assign fds in a serial way (%d)\n", res);
|
|
|
873a72 |
+ }
|
|
|
873a72 |
+ }
|
|
|
873a72 |
+
|
|
|
873a72 |
+ res = gnutls_global_init();
|
|
|
873a72 |
+ if (res != 0)
|
|
|
873a72 |
+ fail("global_init2\n");
|
|
|
873a72 |
+
|
|
|
873a72 |
+ gnutls_rnd_refresh();
|
|
|
873a72 |
+
|
|
|
873a72 |
+ res = gnutls_rnd(GNUTLS_RND_RANDOM, buf, sizeof(buf));
|
|
|
873a72 |
+ if (res != 0)
|
|
|
873a72 |
+ fail("gnutls_rnd\n");
|
|
|
873a72 |
+
|
|
|
873a72 |
+ gnutls_global_deinit();
|
|
|
873a72 |
+
|
|
|
873a72 |
+ if (debug)
|
|
|
873a72 |
+ success("init-close success\n");
|
|
|
873a72 |
+#else
|
|
|
873a72 |
+ return;
|
|
|
873a72 |
+#endif
|
|
|
873a72 |
+}
|
|
|
873a72 |
diff -urN gnutls-3.3.8.orig/tests/Makefile.am gnutls-3.3.8/tests/Makefile.am
|
|
|
873a72 |
--- gnutls-3.3.8.orig/tests/Makefile.am 2014-09-13 13:08:01.000000000 +0200
|
|
|
873a72 |
+++ gnutls-3.3.8/tests/Makefile.am 2014-11-18 10:01:10.483365293 +0100
|
|
|
873a72 |
@@ -84,7 +84,7 @@
|
|
|
873a72 |
mini-cert-status mini-rsa-psk global-init sec-params \
|
|
|
873a72 |
fips-test mini-global-load name-constraints x509-extensions \
|
|
|
873a72 |
long-session-id mini-x509-callbacks-intr \
|
|
|
873a72 |
- crlverify
|
|
|
873a72 |
+ crlverify init_fds
|
|
|
873a72 |
|
|
|
873a72 |
if ENABLE_OCSP
|
|
|
873a72 |
ctests += ocsp
|