[gnutls-dev] [PATCH] error handling large CA files
Ian Peters
itp@ximian.com
Wed Mar 12 03:48:02 2003
--=-YxLKElOogtn7nNzqZUTd
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
On Tue, 2003-03-11 at 16:41, Ian Peters wrote:
> The attached patch fixes these three functions to read passed file into
> a heap-allocated buffer, parse the memory, and then free the buffer.
> You'll probably want to tweak things to fit into gnutls better
> stylistically.
Of course, -this- attached patch does the same, but doesn't leak file
descriptors. :-)
Ian
--=-YxLKElOogtn7nNzqZUTd
Content-Disposition: attachment; filename=gnutls-0.8.4-large-ca-file.patch
Content-Type: text/x-patch; name=gnutls-0.8.4-large-ca-file.patch; charset=UTF-8
Content-Transfer-Encoding: 7bit
diff -Nru -x '*~' -x '*.o' -x '*.orig' -x '*.rej' gnutls-0.8.4.orig/lib/gnutls_x509.c gnutls-0.8.4/lib/gnutls_x509.c
--- gnutls-0.8.4.orig/lib/gnutls_x509.c 2003-02-04 07:52:24.000000000 -0500
+++ gnutls-0.8.4/lib/gnutls_x509.c 2003-03-11 21:43:53.000000000 -0500
@@ -1602,26 +1602,68 @@
}
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+extern int errno;
+static int read_file(const char *filename, char **data, int *len)
+{
+ int fd;
+ struct stat s;
+ char *buf;
+ unsigned int bytes_read = 0;
+
+ if ((fd = open( filename, O_RDONLY)) < 0) {
+ gnutls_assert();
+ return GNUTLS_E_FILE_ERROR;
+ }
+
+ if ((fstat( fd, &s)) < 0) {
+ gnutls_assert();
+ close(fd);
+ return GNUTLS_E_FILE_ERROR;
+ }
+
+ buf = gnutls_malloc(s.st_size + 1);
+ buf[s.st_size] = 0;
+
+ while (bytes_read < s.st_size) {
+ int ret;
+ ret = read( fd, buf + bytes_read, s.st_size - bytes_read);
+ if (ret < 0 && errno != EINTR && errno != EAGAIN) {
+ gnutls_assert();
+ gnutls_free(buf);
+ close(fd);
+ return GNUTLS_E_FILE_ERROR;
+ }
+ bytes_read += ret;
+ }
+
+ close(fd);
+
+ *data = buf;
+ *len = s.st_size + 1;
+ return 0;
+}
+
/* Reads a certificate file
*/
static int read_cert_file(gnutls_certificate_credentials res, const char *certfile,
gnutls_x509_certificate_format type)
{
int siz;
- char x[MAX_FILE_SIZE];
- FILE *fd1;
-
- fd1 = fopen(certfile, "rb");
- if (fd1 == NULL)
- return GNUTLS_E_FILE_ERROR;
-
- siz = fread(x, 1, sizeof(x)-1, fd1);
- fclose(fd1);
-
- x[siz] = 0;
+ char *x;
+ int ret;
- return read_cert_mem( res, x, siz, type);
+ if ((ret = read_file( certfile, &x, &siz)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ ret = read_cert_mem( res, x, siz, type);
+ gnutls_free(x);
+ return ret;
}
/* Reads a base64 encoded CA file (file contains multiple certificate
@@ -1631,21 +1673,17 @@
gnutls_x509_certificate_format type)
{
int siz;
- char x[MAX_FILE_SIZE];
- FILE *fd1;
+ char *x;
+ int ret;
- fd1 = fopen(cafile, "rb");
- if (fd1 == NULL) {
+ if ((ret = read_file( cafile, &x, &siz)) < 0) {
gnutls_assert();
- return GNUTLS_E_FILE_ERROR;
+ return ret;
}
- siz = fread(x, 1, sizeof(x)-1, fd1);
- fclose(fd1);
-
- x[siz] = 0;
-
- return read_ca_mem( res, x, siz, type);
+ ret = read_ca_mem( res, x, siz, type);
+ gnutls_free(x);
+ return ret;
}
@@ -1656,19 +1694,17 @@
gnutls_x509_certificate_format type)
{
int siz;
- char x[MAX_FILE_SIZE];
- FILE *fd2;
-
- fd2 = fopen(keyfile, "rb");
- if (fd2 == NULL)
- return GNUTLS_E_FILE_ERROR;
-
- siz = fread(x, 1, sizeof(x)-1, fd2);
- fclose(fd2);
+ char *x;
+ int ret;
- x[siz] = 0;
+ if ((ret = read_file( keyfile, &x, &siz)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
- return read_key_mem( res, x, siz, type);
+ ret = read_key_mem( res, x, siz, type);
+ gnutls_free(x);
+ return ret;
}
/**
--=-YxLKElOogtn7nNzqZUTd--