Submitted By: Fernando de Oliveira <famobr at yahoo dot com dot br>
Date: 2013-07-13
Initial Package Version: 2.4.1
Update:  Modify instruction creating certificates to use LC_ALL=C
         2013-07-20         
Upstream Status: Not Submitted
Origin: DJ Lucas <dj AT linuxfromscratch DOT org>, Bruce Dubbs (mydate function)
Description: Allows the build to generate a valid JDK cacerts file using the
             system installed CA certificates.

diff -Naurp icedtea-2.4.1.orig/acinclude.m4 icedtea-2.4.1/acinclude.m4
--- icedtea-2.4.1.orig/acinclude.m4	2013-07-05 16:56:07.728174173 -0300
+++ icedtea-2.4.1/acinclude.m4	2013-07-13 10:27:24.263437661 -0300
@@ -295,6 +295,178 @@ AC_DEFUN_ONCE([IT_WITH_OPENJDK_SRC_DIR],
   AM_CONDITIONAL(OPENJDK_SRC_DIR_HARDLINKABLE, test "x${openjdk_src_dir_hardlinkable}" = "xyes")
 ])
 
+AC_DEFUN([IT_WITH_CACERTS],
+[
+  AC_MSG_CHECKING([whether a cacerts file is provided for distribution])
+  AC_ARG_WITH([cacerts],
+              [AS_HELP_STRING(--with-cacerts=FILE,specify the location of a pre-generated cacerts file for distribution)],
+  [
+    if test -f "${withval}"; then
+      CACERTS_FILE="${withval}"
+      cacerts_file_set=yes
+    else
+      CACERTS_FILE=
+    fi
+  ],
+  [
+    CACERTS_FILE=
+  ])
+  if test x"${CACERTS_FILE}" = "x"; then
+    cacerts_file_set=no
+    CACERTS_FILE="no"
+  fi
+  AC_MSG_RESULT(${CACERTS_FILE})
+  AC_SUBST(CACERTS_FILE)
+  AM_CONDITIONAL([CACERTS_FILE_SET], test x"${cacerts_file_set}" = "xyes")
+])
+
+AC_DEFUN([IT_GENERATE_CACERTS],
+[
+  AC_REQUIRE([IT_WITH_CACERTS])
+  AC_MSG_CHECKING([whether to generate a cacerts file for distribution])
+  AC_ARG_ENABLE([cacerts-generation],
+              [AS_HELP_STRING(--enable-cacerts-generation, generate a cacerts file for distribution [[default=auto]])],
+  [
+    case "${enableval}" in
+      no)
+        generate_cacerts=no
+        ;;
+      *)
+        generate_cacerts=yes
+        ;;
+    esac
+  ],
+  [
+    if test x"${cacerts_file_set}" = "xno"; then
+      generate_cacerts=forced
+    else
+      if test x"${cacerts_file_set}" = "xyes"; then
+        generate_cacerts=no
+      else
+        generate_cacerts=yes
+      fi
+    fi
+  ])
+  AC_MSG_RESULT([$generate_cacerts])
+  AM_CONDITIONAL([GENERATE_CACERTS], test x"${generate_cacerts}" = "xyes" -o x"${generate_cacerts}" = "xforced")
+])
+
+AC_DEFUN([IT_GET_LOCAL_CACERTS],
+[
+  AC_MSG_CHECKING([for a local x509 certificate directory])
+  AC_ARG_WITH([ca-dir],
+              [AS_HELP_STRING(--with-ca-dir=DIR, specify a top-level local x509 certificate directory for cacerts generation)],
+  [
+    if test -d "${withval}"; then
+      CADIR="${withval}"
+    else
+      if test x"${withval}" = "xno"; then
+        CADIR=no
+      else
+        CADIR=
+      fi
+    fi
+  ],
+  [
+    CADIR=
+  ])
+  if test x"${CADIR}" = "x"; then
+    for dir in /etc/pki/tls/certs \
+      /usr/share/ca-certificates \
+      /etc/ssl/certs \
+      /etc/certs ; do
+        if test -d "${dir}"; then
+          CADIR="${dir}"
+          break
+        fi
+    done
+    if test x"${CADIR}" = "x"; then
+      CADIR=no
+    fi
+  fi
+  AC_MSG_RESULT(${CADIR})
+  AC_SUBST(CADIR)
+
+  AC_MSG_CHECKING([for a local x509 certificate file])
+  AC_ARG_WITH([ca-file],
+              [AS_HELP_STRING(--with-ca-file=FILE, specify a local x509 certificate file for cacerts generation)],
+  [
+    if test -f "${withval}"; then
+      CAFILE="${withval}"
+    else
+      if test x"${withval}" = "xno"; then
+        CAFILE=no
+      else
+        CAFILE=
+      fi
+    fi
+  ],
+  [
+    CAFILE=
+  ])
+  if test x"${CAFILE}" = "x"; then
+    for file in /etc/pki/tls/certs/ca-bundle.crt \
+      /etc/ssl/certs/ca-bundle.crt \
+      /etc/ssl/ca-bundle.crt \
+      /etc/ca-bundle.crt ; do
+        if test -e "${file}"; then
+          CAFILE=$file
+          break
+        fi
+    done
+    if test x"${CAFILE}" = "x"; then
+      CAFILE=no
+    fi
+  fi
+  AC_MSG_RESULT(${CAFILE})
+  AC_SUBST(CAFILE)
+  if test "${CADIR}x" = "nox" -a "${CAFILE}x" = "nox"; then
+    AC_MSG_ERROR([You must supply a cacerts file or a list of CA certificates to generate one.])
+  fi
+])
+
+AC_DEFUN([IT_FIND_OPENSSL],
+[
+  AC_MSG_CHECKING([for openssl])
+  AC_ARG_WITH([openssl],
+              [AS_HELP_STRING(--with-openssl=PATH, specify the path of the openssl utility)],
+  [
+    if test -x "${withval}" -a -f "${withval}"; then
+      OPENSSL="${withval}"
+    else
+      if test x"${withval}" = "xno"; then
+        OPENSSL="no"
+      else
+        OPENSSL=
+      fi
+    fi
+  ],
+  [
+    OPENSSL=
+  ])
+  if test x"${OPENSSL}" = "x"; then
+
+    OPENSSL=$(
+      IFS=":"
+      for dir in ${withval}:${PATH}; do
+        if test -x "${dir}/openssl" -a -f "${dir}/openssl"; then
+          FOUNDSSL="${dir}/openssl"
+          break
+        fi
+      done
+      echo "${FOUNDSSL}"
+      )
+    if test x"${OPENSSL}" = "x"; then
+      OPENSSL=no
+    fi
+  fi
+  AC_MSG_RESULT(${OPENSSL})
+  AC_SUBST(OPENSSL)
+  if test x"${OPENSSL}" = "xno"; then
+    AC_MSG_ERROR([You must supply a cacerts file or have openssl available to generate one.])
+  fi
+])
+
 AC_DEFUN_ONCE([IT_CAN_HARDLINK_TO_SOURCE_TREE],
 [
   AC_CACHE_CHECK([if we can hard link rather than copy from ${abs_top_srcdir}], it_cv_hardlink_src, [
diff -Naurp icedtea-2.4.1.orig/configure.ac icedtea-2.4.1/configure.ac
--- icedtea-2.4.1.orig/configure.ac	2013-07-05 16:56:07.728174173 -0300
+++ icedtea-2.4.1/configure.ac	2013-07-13 10:27:24.263437661 -0300
@@ -76,6 +76,13 @@ AM_CONDITIONAL([ENABLE_DOCS], [test x$EN
 AC_MSG_RESULT(${ENABLE_DOCS})
 
 IT_LOCATE_NSS
+IT_GENERATE_CACERTS
+
+if test x"${generate_cacerts}" = "xyes" -o x"${generate_cacerts}" = "xforced"; then
+    IT_GET_LOCAL_CACERTS
+    IT_FIND_OPENSSL
+fi
+
 IT_GET_PKGVERSION
 IT_GET_LSB_DATA
 
diff -Naurp icedtea-2.4.1.orig/Makefile.am icedtea-2.4.1/Makefile.am
--- icedtea-2.4.1.orig/Makefile.am	2013-07-13 10:06:36.306626335 -0300
+++ icedtea-2.4.1/Makefile.am	2013-07-13 10:31:21.427108406 -0300
@@ -799,7 +799,8 @@ clean-local: clean-tests clean-pulse-jav
  clean-icedtea-debug-stage2 clean-icedtea-stage1 clean-add-zero clean-add-zero-debug \
  clean-add-cacao clean-add-cacao-debug clean-rt clean-rewrite-rhino clean-rewriter \
  clean-add-systemtap clean-add-systemtap-debug clean-add-pulseaudio clean-add-pulseaudio-debug \
- clean-add-nss clean-add-tzdata-support clean-add-tzdata-support-debug clean-cryptocheck
+ clean-add-nss clean-add-tzdata-support clean-add-tzdata-support-debug clean-cryptocheck \
+ clean-cacerts clean-cacerts-debug
 	if [ -e bootstrap ]; then \
 	  rmdir bootstrap ; \
 	fi
@@ -834,7 +835,8 @@ install:
 	clean-add-nss clean-add-tzdata-support clean-add-tzdata-support-debug \
 	clean-add-systemtap-boot clean-add-pulseaudio-boot clean-add-tzdata-support-boot \
 	clean-check-crypto clean-check-crypto-debug clean-check-crypto-boot \
-	clean-add-archive clean-add-archive-debug clean-add-archive-boot clean-cryptocheck
+	clean-add-archive clean-add-archive-debug clean-add-archive-boot clean-cryptocheck \
+	clean-cacerts clean-cacerts-debug
 
 env:
 	@echo 'unset JAVA_HOME'
@@ -1735,6 +1737,13 @@ endif
 if ENABLE_JAMVM
 	printf -- '-jamvm ALIASED_TO -server\n' >> $(BUILD_JRE_ARCH_DIR)/jvm.cfg
 endif
+if GENERATE_CACERTS
+	$(ARCH_PREFIX) $(MAKE) add-cacerts
+else
+if CACERTS_FILE_SET
+	$(ARCH_PREFIX) $(MAKE) add-cacerts
+endif
+endif
 	@echo "IcedTea is served:" $(BUILD_OUTPUT_DIR)
 	mkdir -p stamps
 	touch $@
@@ -1866,6 +1875,13 @@ endif
 if ENABLE_JAMVM
 	printf -- '-jamvm ALIASED_TO -server\n' >> $(BUILD_DEBUG_JRE_ARCH_DIR)/jvm.cfg
 endif
+if GENERATE_CACERTS
+	$(ARCH_PREFIX) $(MAKE) add-cacerts-debug
+else
+if CACERTS_FILE_SET
+	$(ARCH_PREFIX) $(MAKE) add-cacerts-debug
+endif
+endif
 	@echo "IcedTea (debug build) is served:" \
 	  $(DEBUG_BUILD_OUTPUT_DIR)
 	mkdir -p stamps
@@ -2154,6 +2170,69 @@ else
 	@echo "HotSpot is served:" $(BUILD_OUTPUT_DIR)/j2sdk-image
 endif
 
+# CA Certs
+stamps/generate-cacerts.stamp:
+if GENERATE_CACERTS
+	if test -n "${CADIR}"; then \
+	  sh scripts/mkcacerts.sh -d "${CADIR}" \
+	    -k $(BUILD_OUTPUT_DIR)/j2sdk-image/bin/keytool \
+	    -s $(OPENSSL) \
+	    -o $(BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts; \
+	else \
+	  sh scripts/mkcacerts.sh -f "${CAFILE}" \
+	    -k $(BUILD_OUTPUT_DIR)/j2sdk-image/bin/keytool \
+	    -s $(OPENSSL) \
+	    -o $(BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts; \
+	fi
+endif
+	touch stamps/generate-cacerts.stamp
+
+stamps/add-cacerts.stamp: stamps/generate-cacerts.stamp
+if CACERTS_FILE_SET
+	cp $(CACERTS_FILE) $(BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts
+endif
+	cp $(BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts \
+	   $(BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/security/cacerts
+	touch stamps/add-cacerts.stamp
+
+clean-cacerts:
+	rm -f $(BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts
+	rm -f $(BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/security/cacerts
+	rm -f stamps/add-cacerts.stamp
+	rm -f stamps/generate-cacerts.stamp
+
+stamps/generate-cacerts-debug.stamp:
+if GENERATE_CACERTS
+	if test -n "${CADIR}"; then \
+	  sh scripts/mkcacerts.sh -d "${CADIR}" \
+	    -k $(DEBUG_BUILD_OUTPUT_DIR)/j2sdk-image/bin/keytool \
+	    -s $(OPENSSL) \
+	    -o $(DEBUG_BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts; \
+	else \
+	  sh scripts/mkcacerts.sh -f "${CAFILE}" \
+	    -k $(DEBUG_BUILD_OUTPUT_DIR)/j2sdk-image/bin/keytool \
+	    -s $(OPENSSL) \
+	    -o $(DEBUG_BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts; \
+	fi
+endif
+	touch stamps/generate-cacerts-debug.stamp
+
+stamps/add-cacerts-debug.stamp: stamps/generate-cacerts-debug.stamp
+if CACERTS_FILE_SET
+	cp $(CACERTS_FILE) $(DEBUG_BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts
+endif
+	cp $(DEBUG_BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts \
+	   $(DEBUG_BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/security/cacerts
+	touch stamps/add-cacerts-debug.stamp
+
+clean-cacerts-debug:
+	rm -f $(DEBUG_BUILD_OUTPUT_DIR)/j2re-image/lib/security/cacerts
+	rm -f $(DEBUG_BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/security/cacerts
+	rm -f stamps/add-cacerts-debug.stamp
+	rm -f stamps/generate-cacerts-debug.stamp
+
+# end of CA Certs
+
 # PulseAudio based mixer
 # (pulse-java)
 if ENABLE_PULSE_JAVA
@@ -2716,6 +2795,10 @@ add-tzdata-support: stamps/add-tzdata-su
 
 add-tzdata-support-debug: stamps/add-tzdata-support-debug.stamp
 
+add-cacerts: stamps/add-cacerts.stamp
+
+add-cacerts-debug: stamps/add-cacerts-debug.stamp
+
 add-zero: stamps/add-zero.stamp
 
 add-zero-debug: stamps/add-zero-debug.stamp
diff -Naurp icedtea-2.4.1.orig/scripts/mkcacerts.sh icedtea-2.4.1/scripts/mkcacerts.sh
--- icedtea-2.4.1.orig/scripts/mkcacerts.sh	1969-12-31 21:00:00.000000000 -0300
+++ icedtea-2.4.1/scripts/mkcacerts.sh	2013-07-13 10:27:24.267437573 -0300
@@ -0,0 +1,208 @@
+#!/bin/sh
+# Simple script to extract x509 certificates and create a JRE cacerts file.
+
+function get_args()
+    {
+        if test -z "${1}" ; then
+            showhelp
+            exit 1
+        fi
+
+        while test -n "${1}" ; do
+            case "${1}" in
+                -f | --cafile)
+                    check_arg $1 $2
+                    CAFILE="${2}"
+                    shift 2
+                ;;
+                -d | --cadir)
+                    check_arg $1 $2
+                    CADIR="${2}"
+                    shift 2
+                ;;
+                -o | --outfile)
+                    check_arg $1 $2
+                    OUTFILE="${2}"
+                    shift 2
+                ;;
+                -k | --keytool)
+                    check_arg $1 $2
+                    KEYTOOL="${2}"
+                    shift 2
+                ;;
+                -s | --openssl)
+                    check_arg $1 $2
+                    OPENSSL="${2}"
+                    shift 2
+                ;;
+                -h | --help)
+                     showhelp
+                     exit 0
+                ;;
+                *)
+                   showhelp
+                   exit 1
+                ;;
+            esac
+        done
+    }
+
+function check_arg()
+    {
+        echo "${2}" | grep -v "^-" > /dev/null
+        if [ -z "$?" -o ! -n "$2" ]; then
+            echo "Error:  $1 requires a valid argument."
+            exit 1
+        fi
+    }
+
+# The date binary is not reliable on 32bit systems for dates after 2038
+function mydate()
+    {
+        local y=$( echo $1 | cut -d" " -f4 )
+        local M=$( echo $1 | cut -d" " -f1 )
+        local d=$( echo $1 | cut -d" " -f2 )
+        local m
+
+        if [ ${d} -lt 10 ]; then d="0${d}"; fi
+
+        case $M in
+            Jan) m="01";;
+            Feb) m="02";;
+            Mar) m="03";;
+            Apr) m="04";;
+            May) m="05";;
+            Jun) m="06";;
+            Jul) m="07";;
+            Aug) m="08";;
+            Sep) m="09";;
+            Oct) m="10";;
+            Nov) m="11";;
+            Dec) m="12";;
+        esac
+
+        certdate="${y}${m}${d}"
+    }
+
+function showhelp()
+    {
+        echo "`basename ${0}` creates a valid cacerts file for use with IcedTea."
+        echo ""
+        echo "        -f  --cafile        The path to a file containing PEM formated CA"
+        echo "                            certificates.  May not be used with -d/--cadir."
+        echo "        -d  --cadir         The path to a diectory of PEM formatted CA"
+        echo "                            certificates.  May not be used with -f/--cafile."
+        echo "        -o  --outfile       The path to the output file."
+        echo ""
+        echo "        -k  --keytool       The path to the java keytool utility."
+        echo ""
+        echo "        -s  --openssl       The path to the openssl utility."
+        echo ""
+        echo "        -h  --help          Show this help message and exit."
+        echo ""
+        echo ""
+    }
+
+# Initialize empty variables so that the shell does not polute the script
+CAFILE=""
+CADIR=""
+OUTFILE=""
+OPENSSL=""
+KEYTOOL=""
+certdate=""
+date=""
+today=$( date +%Y%m%d )
+
+# Process command line arguments
+get_args ${@}
+
+# Handle common errors
+if test "${CAFILE}x" == "x" -a "${CADIR}x" == "x" ; then
+    echo "ERROR!  You must provide an x509 certificate store!"
+    echo "\'$(basename ${0}) --help\' for more info."
+    echo ""
+    exit 1
+fi
+
+if test "${CAFILE}x" != "x" -a "${CADIR}x" != "x" ; then
+    echo "ERROR!  You cannot provide two x509 certificate stores!"
+    echo "\'$(basename ${0}) --help\' for more info."
+    echo ""
+    exit 1
+fi
+
+if test "${KEYTOOL}x" == "x" ; then
+    echo "ERROR!  You must provide a valid keytool program!"
+    echo "\'$(basename ${0}) --help\' for more info."
+    echo ""
+    exit 1
+fi
+
+if test "${OPENSSL}x" == "x" ; then
+    echo "ERROR!  You must provide a valid path to openssl!"
+    echo "\'$(basename ${0}) --help\' for more info."
+    echo ""
+    exit 1
+fi
+
+if test "${OUTFILE}x" == "x" ; then
+    echo "ERROR!  You must provide a valid output file!"
+    echo "\'$(basename ${0}) --help\' for more info."
+    echo ""
+    exit 1
+fi
+
+# Get on with the work
+
+# If using a CAFILE, split it into individual files in a temp directory
+if test "${CAFILE}x" != "x" ; then
+    TEMPDIR=`mktemp -d`
+    CADIR="${TEMPDIR}"
+
+    # Get a list of staring lines for each cert
+    CERTLIST=`grep -n "^-----BEGIN" "${CAFILE}" | cut -d ":" -f 1`
+
+    # Get a list of ending lines for each cert
+    ENDCERTLIST=`grep -n "^-----END" "${CAFILE}" | cut -d ":" -f 1`
+
+    # Start a loop
+    for certbegin in `echo "${CERTLIST}"` ; do
+        for certend in `echo "${ENDCERTLIST}"` ; do
+            if test "${certend}" -gt "${certbegin}"; then
+                break
+            fi
+        done
+        sed -n "${certbegin},${certend}p" "${CAFILE}" > "${CADIR}/${certbegin}.pem"
+        keyhash=`${OPENSSL} x509 -noout -in "${CADIR}/${certbegin}.pem" -hash`
+        echo "Generated PEM file with hash:  ${keyhash}."
+    done
+fi
+
+# Write the output file
+for cert in `find "${CADIR}" -type f -name "*.pem" -o -name "*.crt"`
+do
+
+    # Make sure the certificate date is valid...
+    date=$( ${OPENSSL} x509 -enddate -in "${cert}" -noout | sed 's/^notAfter=//' )
+    mydate "${date}"
+    if test "${certdate}" -lt "${today}" ; then
+        echo "${cert} expired on ${certdate}! Skipping..."
+        unset date certdate
+        continue
+    fi
+    unset date certdate
+    ls "${cert}"
+    tempfile=`mktemp`
+    certbegin=`grep -n "^-----BEGIN" "${cert}" | cut -d ":" -f 1`
+    certend=`grep -n "^-----END" "${cert}" | cut -d ":" -f 1`
+    sed -n "${certbegin},${certend}p" "${cert}" > "${tempfile}"
+    echo yes | env LC_ALL=C "${KEYTOOL}" -import -alias `basename "${cert}"` -keystore \
+                   "${OUTFILE}" -storepass 'changeit' -file "${tempfile}"
+    rm "${tempfile}"
+done
+
+if test "${TEMPDIR}x" != "x" ; then
+    rm -rf "${TEMPDIR}"
+fi
+exit 0
+
