=== modified file 'configure.in' --- configure.in 2011-06-21 17:10:10 +0000 +++ configure.in 2011-06-24 07:30:10 +0000 @@ -174,6 +174,7 @@ OPTION_DEFAULT_ON([gconf],[don't compile with GConf support]) OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support]) OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) +OPTION_DEFAULT_ON([secure-random],[don't compile secure-random support]) ## For the times when you want to build Emacs but don't have ## a suitable makeinfo, and can live without the manuals. @@ -1999,6 +2000,32 @@ AC_SUBST(LIBGNUTLS_LIBS) AC_SUBST(LIBGNUTLS_CFLAGS) +case $with_secure_random in + urandom | yes) AC_CHECK_FILE("/dev/urandom", HAVE_RANDOMDEV=yes, HAVE_RANDOMDEV=no) + if test "${HAVE_RANDOMDEV}" = "no"; then + AC_DEFINE(SECURE_RANDOM_TYPE, 1, [Set 1 if /dev/urandom exists.]) + AC_DEFINE(RANDOMDEV, "/dev/urandom", [Define if /dev/urandom exists]) + fi + ;; + gnutls) if test -z "$HAVE_GNUTLS"; then + PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 2.6.0], HAVE_GNUTLS=yes, HAVE_GNUTLS=no) + fi + if test "$HAVE_GNUTLS" = yes; then + AC_DEFINE(SECURE_RANDOM_TYPE, 2, [Set to 2 if using GnuTLS.]) + fi + ;; + openssl) PKG_CHECK_MODULES([LIBOPENSSL], [openssl >= 0.9.8], HAVE_OPENSSL=yes, HAVE_OPENSSL=no) + if test "$HAVE_OPENSSL" = "yes"; then + AC_DEFINE(SECURE_RANDOM_TYPE, 3, [Set to 3 if using OpenSSL.]) + fi + CFLAGS="$CFLAGS $LIBOPENSSL_CFLAGS" + LIBS="$LIBOPENSSL_LIBS $LIBS" + ;; +esac + +AC_SUBST(LIBOPENSSL_LIBS) +AC_SUBST(LIBOPENSSL_CFLAGS) + dnl Do not put whitespace before the #include statements below. dnl Older compilers (eg sunos4 cc) choke on it. HAVE_XAW3D=no === modified file 'src/Makefile.in' --- src/Makefile.in 2011-05-21 02:04:48 +0000 +++ src/Makefile.in 2011-06-24 06:28:33 +0000 @@ -269,6 +269,9 @@ LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBOPENSSL_LIBS = @LIBOPENSSL_LIBS@ +LIBOPENSSL_CFLAGS = @LIBOPENSSL_CFLAGS@ + INTERVALS_H = dispextern.h intervals.h composite.h GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ @@ -307,7 +310,7 @@ $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \ $(GCONF_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) $(PROFILING_CFLAGS) \ - $(LIBGNUTLS_CFLAGS) \ + $(LIBGNUTLS_CFLAGS) $(LIBOPENSSL_CFLAGS) \ $(C_WARNINGS_SWITCH) $(CFLAGS) ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS) @@ -383,7 +386,7 @@ $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(GCONF_LIBS) $(LIBSELINUX_LIBS) \ $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ - $(LIBGNUTLS_LIBS) \ + $(LIBGNUTLS_LIBS) $(LIBOPENSSL_LIBS) \ $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC) all: emacs$(EXEEXT) $(OTHER_FILES) === modified file 'src/fileio.c' --- src/fileio.c 2011-06-19 19:06:16 +0000 +++ src/fileio.c 2011-06-24 07:23:58 +0000 @@ -5420,7 +5420,76 @@ args[6] = predicate; RETURN_UNGCPRO (Ffuncall (7, args)); } + +#if SECURE_RANDOM_TYPE==1 + +DEFUN ("secure-random-bytes", Fsecure_random_bytes, Ssecure_random_bytes, 1, 1, 0, + doc: /* Return N cryptographically strong pseudo-random bytes. */) + (Lisp_Object n) +{ + register int nbytes; + int fd; + Lisp_Object val; + struct stat st; + + CHECK_NATNUM (n); + + /* Return empty string for 0 bytes */ + if (XFASTINT(n) == 0) + return build_string (""); + + if ((stat (RANDOMDEV, &st) < 0) +#ifdef S_ISCHR + || (!S_ISCHR (st.st_mode)) +#endif + ) + error ("Secure random device does not exist"); + + val = make_uninit_string (XFASTINT (n)); + + fd = emacs_open (RANDOMDEV, O_RDONLY | O_NONBLOCK, 0); + nbytes = emacs_read (fd, SDATA (val), XFASTINT (n)); + emacs_close (fd); + if (nbytes < XFASTINT (n)) + error ("IO error reading secure random device"); + + return val; +} + +#elif SECURE_RANDOM_TYPE==2 || SECURE_RANDOM_TYPE==3 + +#ifdef SECURE_RANDOM_TYPE==2 +#include +#include +#else +#include +#endif + +DEFUN ("secure-random-bytes", Fsecure_random_bytes, Ssecure_random_bytes, 1, 1, 0, + doc: /* Return N cryptographically strong pseudo-random bytes. */) + (Lisp_Object n) +{ + Lisp_Object val; + + CHECK_NATNUM (n); + + /* Return empty string for 0 bytes */ + if (XFASTINT(n) == 0) + return build_string (""); + + val = make_uninit_string (XFASTINT (n)); + +#if SECURE_RANDOM_TYPE==2 + if (gnutls_rnd (GNUTLS_RND_NONCE, SDATA (val), XFASTINT (n)) < 0) +#else + if (RAND_bytes (SDATA (val), XFASTINT (n)) == 0) +#endif + error ("Failed to generate random data"); + + return val; +} +#endif /* SECURE_RANDOM_TYPE */ void syms_of_fileio (void) @@ -5701,6 +5770,9 @@ defsubr (&Smake_directory_internal); defsubr (&Sdelete_directory_internal); defsubr (&Sdelete_file); +#ifdef SECURE_RANDOM_TYPE + defsubr (&Ssecure_random_bytes); +#endif defsubr (&Srename_file); defsubr (&Sadd_name_to_file); defsubr (&Smake_symbolic_link);