1#!/bin/bash
2#
3# Copyright (C) 2009 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18#
19# This script imports new versions of OpenSSL (http://openssl.org/source) into the
20# Android source tree.  To run, (1) fetch the appropriate tarball from the OpenSSL repository,
21# (2) check the gpg/pgp signature, and then (3) run:
22#   ./import_openssl.sh import openssl-*.tar.gz
23#
24# IMPORTANT: See README.android for additional details.
25
26# turn on exit on error as well as a warning when it happens
27set -e
28trap  "echo WARNING: Exiting on non-zero subprocess exit code" ERR;
29
30# Make sure we're in the right directory.
31cd $(dirname $0)
32
33# Ensure consistent sorting order / tool output.
34export LANG=C
35export LC_ALL=C
36PERL_EXE="perl -C0"
37
38function die() {
39  declare -r message=$1
40
41  echo $message
42  exit 1
43}
44
45function usage() {
46  declare -r message=$1
47
48  if [ ! "$message" = "" ]; then
49    echo $message
50  fi
51  echo "Usage:"
52  echo "  ./import_openssl.sh import </path/to/openssl-*.tar.gz>"
53  echo "  ./import_openssl.sh regenerate <patch/*.patch>"
54  echo "  ./import_openssl.sh generate <patch/*.patch> </path/to/openssl-*.tar.gz>"
55  exit 1
56}
57
58function main() {
59  if [ ! -d patches ]; then
60    die "OpenSSL patch directory patches/ not found"
61  fi
62
63  if [ ! -f openssl.version ]; then
64    die "openssl.version not found"
65  fi
66
67  source ./openssl.version
68  if [ "$OPENSSL_VERSION" == "" ]; then
69    die "Invalid openssl.version; see README.android for more information"
70  fi
71
72  OPENSSL_DIR=openssl-$OPENSSL_VERSION
73  OPENSSL_DIR_ORIG=$OPENSSL_DIR.orig
74
75  if [ ! -f openssl.config ]; then
76    die "openssl.config not found"
77  fi
78
79  source ./openssl.config
80  if [ "$CONFIGURE_ARGS" == "" -o "$UNNEEDED_SOURCES" == "" -o "$NEEDED_SOURCES" == "" ]; then
81    die "Invalid openssl.config; see README.android for more information"
82  fi
83
84  declare -r command=$1
85  shift || usage "No command specified. Try import, regenerate, or generate."
86  if [ "$command" = "import" ]; then
87    declare -r tar=$1
88    shift || usage "No tar file specified."
89    import $tar
90  elif [ "$command" = "regenerate" ]; then
91    declare -r patch=$1
92    shift || usage "No patch file specified."
93    [ -d $OPENSSL_DIR ] || usage "$OPENSSL_DIR not found, did you mean to use generate?"
94    [ -d $OPENSSL_DIR_ORIG ] || usage "$OPENSSL_DIR_ORIG not found, did you mean to use generate?"
95    regenerate $patch
96  elif [ "$command" = "generate" ]; then
97    declare -r patch=$1
98    shift || usage "No patch file specified."
99    declare -r tar=$1
100    shift || usage "No tar file specified."
101    generate $patch $tar
102  else
103    usage "Unknown command specified $command. Try import, regenerate, or generate."
104  fi
105}
106
107# Compute the name of an assembly source file generated by one of the
108# gen_asm_xxxx() functions below. The logic is the following:
109# - if "$2" is not empty, output it directly
110# - otherwise, change the file extension of $1 from .pl to .S and output
111#   it.
112# Usage: default_asm_file "$1" "$2"
113#     or default_asm_file "$@"
114#
115# $1: generator path (perl script)
116# $2: optional output file name.
117function default_asm_file () {
118  if [ "$2" ]; then
119    echo "$2"
120  else
121    echo "${1%%.pl}.S"
122  fi
123}
124
125# Generate an ARM assembly file.
126# $1: generator (perl script)
127# $2: [optional] output file name
128function gen_asm_arm () {
129  local OUT
130  OUT=$(default_asm_file "$@")
131  $PERL_EXE "$1" void "$OUT" > "$OUT"
132}
133
134# Generate an ARMv8 64-bit assembly file.
135# $1: generator (perl script)
136# $2: [optional] output file name
137function gen_asm_arm64 () {
138  local OUT
139  OUT=$(default_asm_file "$@")
140  $PERL_EXE "$1" linux64 "$OUT" > "$OUT"
141}
142
143function gen_asm_mips () {
144  local OUT
145  OUT=$(default_asm_file "$@")
146  # The perl scripts expect to run the target compiler as $CC to determine
147  # the endianess of the target. Setting CC to true is a hack that forces the scripts
148  # to generate little endian output
149  CC=true $PERL_EXE "$1" o32 > "$OUT"
150}
151
152function gen_asm_x86 () {
153  local OUT
154  OUT=$(default_asm_file "$@")
155  $PERL_EXE "$1" elf -fPIC $(print_values_with_prefix -D $OPENSSL_CRYPTO_DEFINES_x86) > "$OUT"
156}
157
158function gen_asm_x86_64 () {
159  local OUT
160  OUT=$(default_asm_file "$@")
161  $PERL_EXE "$1" elf "$OUT" > "$OUT"
162}
163
164
165# Filter all items in a list that match a given pattern.
166# $1: space-separated list
167# $2: egrep pattern.
168# Out: items in $1 that match $2
169function filter_by_egrep() {
170  declare -r pattern=$1
171  shift
172  echo "$@" | tr ' ' '\n' | grep -e "$pattern" | tr '\n' ' '
173}
174
175# Sort and remove duplicates in a space-separated list
176# $1: space-separated list
177# Out: new space-separated list
178function uniq_sort () {
179  echo "$@" | tr ' ' '\n' | sort -u | tr '\n' ' '
180}
181
182function print_autogenerated_header() {
183  echo "# Auto-generated - DO NOT EDIT!"
184  echo "# To regenerate, edit openssl.config, then run:"
185  echo "#     ./import_openssl.sh import /path/to/openssl-$OPENSSL_VERSION.tar.gz"
186  echo "#"
187}
188
189function run_verbose() {
190  echo Running: $@
191  $@
192}
193
194function scan_opensslconf_for_flags() {
195  for flag in "$@"; do
196    awk "/^#define ${flag}$/ { print \$2 }" crypto/opensslconf.h
197  done
198}
199
200CRYPTO_CONF_FLAGS=(
201OPENSSL_CPUID_OBJ
202DES_LONG
203DES_PTR
204DES_RISC1
205DES_RISC2
206DES_UNROLL
207RC4_INT
208RC4_CHUNK
209RC4_INDEX
210)
211
212function check_asm_flags() {
213  local arch="$1"
214  local target="$2"
215  local unsorted_flags
216  local expected_flags
217  local actual_flags
218  local defines="OPENSSL_CRYPTO_DEFINES_$arch"
219
220  PERL=/usr/bin/perl run_verbose ./Configure $CONFIGURE_ARGS $target
221
222  unsorted_flags="$(awk '/^CFLAG=/ { sub(/^CFLAG= .*-Wall /, ""); gsub(/-D/, ""); print; }' Makefile)"
223  unsorted_flags="$unsorted_flags $(scan_opensslconf_for_flags "${CRYPTO_CONF_FLAGS[@]}")"
224
225  expected_flags="$(echo $unsorted_flags | tr ' ' '\n' | sort | tr '\n' ' ')"
226  actual_flags="$(echo ${!defines} | tr ' ' '\n' | sort | tr '\n' ' ')"
227
228  if [[ $actual_flags != $expected_flags ]]; then
229    echo ${defines} is wrong!
230    echo "    $actual_flags"
231    echo Please update to:
232    echo "    $expected_flags"
233    exit 1
234  fi
235}
236
237# Run Configure and generate headers
238# $1: 32 for 32-bit arch, 64 for 64-bit arch, trusty for Trusty
239# $2: 1 if building for static version
240# Out: returns the cflags and depflags in variable $flags
241function generate_build_config_headers() {
242  chmod +x ./Configure
243  local configure_args_bits=CONFIGURE_ARGS_$1
244  local configure_args_stat=''
245  local outname=$1
246  if [[ $2 == 1 ]] ; then
247      configure_args_stat=CONFIGURE_ARGS_STATIC
248      outname="static-$1"
249  fi
250
251  if [[ $1 == trusty ]] ; then
252    PERL=/usr/bin/perl run_verbose ./Configure $CONFIGURE_ARGS_TRUSTY
253  else
254    PERL=/usr/bin/perl run_verbose ./Configure $CONFIGURE_ARGS ${!configure_args_bits} ${!configure_args_stat}
255  fi
256
257  rm -f apps/CA.pl.bak crypto/opensslconf.h.bak
258  mv -f crypto/opensslconf.h crypto/opensslconf-$outname.h
259  cp -f crypto/opensslconf-$outname.h include/openssl/opensslconf-$outname.h
260
261  local tmpfile=$(mktemp tmp.XXXXXXXXXX)
262  (grep -e -D Makefile | grep -v CONFIGURE_ARGS= | grep -v OPTIONS= | \
263      grep -v -e -DOPENSSL_NO_DEPRECATED) > $tmpfile
264  declare -r cflags=$(filter_by_egrep "^-D" $(grep -e "^CFLAG=" $tmpfile))
265  declare -r depflags=$(filter_by_egrep "^-D" $(grep -e "^DEPFLAG=" $tmpfile))
266  rm -f $tmpfile
267
268  flags="$cflags $depflags"
269}
270
271# Run Configure and generate makefiles
272function generate_build_config_mk() {
273  chmod +x ./Configure
274  for bits in 32 64 trusty; do
275    # Header flags are output in $flags, first static, then dynamic
276    generate_build_config_headers $bits 1
277    local flags_static=$flags
278    generate_build_config_headers $bits
279
280    echo "Generating build-config-$bits.mk"
281    (
282      print_autogenerated_header
283
284      echo "openssl_cflags_$bits := \\"
285      for flag in $flags ; do echo "  $flag \\" ; done
286      echo ""
287
288      echo "openssl_cflags_static_$bits := \\"
289      for flag in $flags_static; do echo "  $flag \\" ; done
290      echo ""
291    ) > ../build-config-$bits.mk
292  done
293}
294
295# Generate crypto/opensslconf.h file including arch-specific files
296function generate_opensslconf_h() {
297  echo "Generating opensslconf.h"
298  (
299  echo "// Auto-generated - DO NOT EDIT!"
300  echo "#ifndef OPENSSL_SYS_TRUSTY"
301  echo "#if defined(__LP64__)"
302  echo "#include \"opensslconf-64.h\""
303  echo "#else"
304  echo "#include \"opensslconf-32.h\""
305  echo "#endif"
306  echo "#else"
307  echo "#include \"opensslconf-trusty.h\""
308  echo "#endif"
309  ) > crypto/opensslconf.h
310  # Generate a compatible version for the static library builds
311  echo "Generating opensslconf-static.h"
312  (
313  echo "// Auto-generated - DO NOT EDIT!"
314  echo "#if defined(__LP64__)"
315  echo "#include \"opensslconf-static-64.h\""
316  echo "#else"
317  echo "#include \"opensslconf-static-32.h\""
318  echo "#endif"
319  ) > crypto/opensslconf-static.h
320  # move it to output include files as well
321  cp -f crypto/opensslconf-static.h include/openssl/opensslconf-static.h
322}
323
324# Return the value of a computed variable name.
325# E.g.:
326#   FOO=foo
327#   BAR=bar
328#   echo $(var_value FOO_$BAR)   -> prints the value of ${FOO_bar}
329# $1: Variable name
330# Out: variable value
331var_value() {
332  # Note: don't use 'echo' here, because it's sensitive to values
333  #       that begin with an underscore (e.g. "-n")
334  eval printf \"%s\\n\" \$$1
335}
336
337# Same as var_value, but returns sorted output without duplicates.
338# $1: Variable name
339# Out: variable value (if space-separated list, sorted with no duplicates)
340var_sorted_value() {
341  uniq_sort $(var_value $1)
342}
343
344# Print the values in a list with a prefix
345# $1: prefix to use
346# $2+: values of list
347print_values_with_prefix() {
348  declare -r prefix=$1
349  shift
350  for src; do
351    echo -n " $prefix$src "
352  done
353}
354
355# Print the definition of a given variable in a GNU Make build file.
356# $1: Variable name (e.g. common_src_files)
357# $2: prefix for each variable contents
358# $3+: Variable value (e.g. list of sources)
359print_vardef_with_prefix_in_mk() {
360  declare -r varname=$1
361  declare -r prefix=$2
362  shift
363  shift
364  if [ -z "$1" ]; then
365    echo "$varname :="
366  else
367    echo "$varname := \\"
368    for src; do
369      echo "  $prefix$src \\"
370    done
371  fi
372  echo ""
373}
374# Print the definition of a given variable in a GNU Make build file.
375# $1: Variable name (e.g. common_src_files)
376# $2+: Variable value (e.g. list of sources)
377print_vardef_in_mk() {
378  declare -r varname=$1
379  shift
380  print_vardef_with_prefix_in_mk $varname "" $@
381}
382
383# Same as print_vardef_in_mk, but print a CFLAGS definition from
384# a list of compiler defines.
385# $1: Variable name (e.g. common_cflags)
386# $2: List of defines (e.g. OPENSSL_NO_CAMELLIA ...)
387print_defines_in_mk() {
388  declare -r varname=$1
389  shift
390  if [ -z "$1" ]; then
391    echo "$varname :="
392  else
393    echo "$varname := \\"
394    for def; do
395    echo "  -D$def \\"
396    done
397  fi
398  echo ""
399}
400
401# Generate a configuration file like Crypto-config.mk
402# This uses variable definitions from openssl.config to build a config
403# file that can compute the list of target- and host-specific sources /
404# compiler flags for a given component.
405#
406# $1: Target file name.  (e.g. Crypto-config.mk)
407# $2: Variable prefix.   (e.g. CRYPTO)
408# $3: "host" or "target"
409function generate_config_mk() {
410  declare -r output="$1"
411  declare -r prefix="$2"
412  declare -r all_archs="arm arm64 x86 x86_64 mips"
413
414  echo "Generating $(basename $output)"
415  (
416    print_autogenerated_header
417    echo \
418"# This script will append to the following variables:
419#
420#    LOCAL_CFLAGS
421#    LOCAL_C_INCLUDES
422#    LOCAL_SRC_FILES_\$(TARGET_ARCH)
423#    LOCAL_SRC_FILES_\$(TARGET_2ND_ARCH)
424#    LOCAL_CFLAGS_\$(TARGET_ARCH)
425#    LOCAL_CFLAGS_\$(TARGET_2ND_ARCH)
426#    LOCAL_ADDITIONAL_DEPENDENCIES
427
428
429LOCAL_ADDITIONAL_DEPENDENCIES += \$(LOCAL_PATH)/$(basename $output)
430"
431
432    common_defines=$(var_sorted_value OPENSSL_${prefix}_DEFINES)
433    print_defines_in_mk common_cflags $common_defines
434
435    common_sources=$(var_sorted_value OPENSSL_${prefix}_SOURCES)
436    print_vardef_in_mk common_src_files $common_sources
437
438    common_includes=$(var_sorted_value OPENSSL_${prefix}_INCLUDES)
439    print_vardef_with_prefix_in_mk common_c_includes external/openssl/ $common_includes
440
441    for arch in $all_archs; do
442      arch_defines=$(var_sorted_value OPENSSL_${prefix}_DEFINES_${arch})
443      print_defines_in_mk ${arch}_cflags $arch_defines
444
445      arch_sources=$(var_sorted_value OPENSSL_${prefix}_SOURCES_${arch})
446      print_vardef_in_mk ${arch}_src_files $arch_sources
447
448      arch_exclude_sources=$(var_sorted_value OPENSSL_${prefix}_SOURCES_EXCLUDES_${arch})
449      print_vardef_in_mk ${arch}_exclude_files $arch_exclude_sources
450
451    done
452
453    if [ $prefix == "CRYPTO" ]; then
454      echo "
455# \"Temporary\" hack until this can be fixed in openssl.config
456x86_64_cflags += -DRC4_INT=\"unsigned int\""
457    fi
458
459    if [ $3 == "target" ]; then
460      echo "
461LOCAL_CFLAGS += \$(common_cflags)
462LOCAL_C_INCLUDES += \$(common_c_includes)"
463      for arch in $all_archs; do
464        echo "
465LOCAL_SRC_FILES_${arch} += \$(filter-out \$(${arch}_exclude_files),\$(common_src_files) \$(${arch}_src_files))
466LOCAL_CFLAGS_${arch} += \$(${arch}_cflags)"
467      done
468    else
469      echo "
470LOCAL_CFLAGS += \$(common_cflags)
471LOCAL_C_INCLUDES += \$(common_c_includes) \$(local_c_includes)
472
473ifeq (\$(HOST_OS),linux)
474LOCAL_CFLAGS_x86 += \$(x86_cflags)
475LOCAL_SRC_FILES_x86 += \$(filter-out \$(x86_exclude_files), \$(common_src_files) \$(x86_src_files))
476LOCAL_CFLAGS_x86_64 += \$(x86_64_cflags)
477LOCAL_SRC_FILES_x86_64 += \$(filter-out \$(x86_64_exclude_files), \$(common_src_files) \$(x86_64_src_files))
478else
479\$(warning Unknown host OS \$(HOST_OS))
480LOCAL_SRC_FILES += \$(common_src_files)
481endif"
482    fi
483  ) > "$output"
484}
485
486function import() {
487  declare -r OPENSSL_SOURCE=$1
488  untar $OPENSSL_SOURCE readonly
489  applypatches $OPENSSL_DIR
490  convert_iso8859_to_utf8 $OPENSSL_DIR
491
492  cd $OPENSSL_DIR
493
494  # Check the ASM flags for each arch
495  check_asm_flags arm linux-armv4
496  check_asm_flags arm64 linux-aarch64
497  check_asm_flags x86 linux-elf
498  check_asm_flags x86_64 linux-x86_64
499
500  generate_build_config_mk
501  generate_opensslconf_h
502
503  cp -f LICENSE ../NOTICE
504  touch ../MODULE_LICENSE_BSD_LIKE
505
506  # Avoid checking in symlinks
507  for i in `find include/openssl -type l`; do
508    target=`readlink $i`
509    rm -f $i
510    if [ -f include/openssl/$target ]; then
511      cp include/openssl/$target $i
512    fi
513  done
514
515  # Generate arm asm
516  gen_asm_arm crypto/aes/asm/aes-armv4.pl
517  gen_asm_arm crypto/aes/asm/aesv8-armx.pl
518  gen_asm_arm crypto/aes/asm/bsaes-armv7.pl
519  gen_asm_arm crypto/bn/asm/armv4-gf2m.pl
520  gen_asm_arm crypto/bn/asm/armv4-mont.pl
521  gen_asm_arm crypto/modes/asm/ghash-armv4.pl
522  gen_asm_arm crypto/modes/asm/ghashv8-armx.pl
523  gen_asm_arm crypto/sha/asm/sha1-armv4-large.pl
524  gen_asm_arm crypto/sha/asm/sha256-armv4.pl
525  gen_asm_arm crypto/sha/asm/sha512-armv4.pl
526
527  # Generate armv8 asm
528  gen_asm_arm64 crypto/aes/asm/aesv8-armx.pl crypto/aes/asm/aesv8-armx-64.S
529  gen_asm_arm64 crypto/modes/asm/ghashv8-armx.pl crypto/modes/asm/ghashv8-armx-64.S
530  gen_asm_arm64 crypto/sha/asm/sha1-armv8.pl
531  gen_asm_arm64 crypto/sha/asm/sha512-armv8.pl crypto/sha/asm/sha256-armv8.S
532  gen_asm_arm64 crypto/sha/asm/sha512-armv8.pl
533
534  # Generate mips asm
535  gen_asm_mips crypto/aes/asm/aes-mips.pl
536  gen_asm_mips crypto/bn/asm/mips.pl crypto/bn/asm/bn-mips.S
537  gen_asm_mips crypto/bn/asm/mips-mont.pl
538  gen_asm_mips crypto/sha/asm/sha1-mips.pl
539  gen_asm_mips crypto/sha/asm/sha512-mips.pl crypto/sha/asm/sha256-mips.S
540
541  # Generate x86 asm
542  gen_asm_x86 crypto/x86cpuid.pl
543  gen_asm_x86 crypto/aes/asm/aes-586.pl
544  gen_asm_x86 crypto/aes/asm/vpaes-x86.pl
545  gen_asm_x86 crypto/aes/asm/aesni-x86.pl
546  gen_asm_x86 crypto/bn/asm/bn-586.pl
547  gen_asm_x86 crypto/bn/asm/co-586.pl
548  gen_asm_x86 crypto/bn/asm/x86-mont.pl
549  gen_asm_x86 crypto/bn/asm/x86-gf2m.pl
550  gen_asm_x86 crypto/modes/asm/ghash-x86.pl
551  gen_asm_x86 crypto/sha/asm/sha1-586.pl
552  gen_asm_x86 crypto/sha/asm/sha256-586.pl
553  gen_asm_x86 crypto/sha/asm/sha512-586.pl
554  gen_asm_x86 crypto/md5/asm/md5-586.pl
555  gen_asm_x86 crypto/des/asm/des-586.pl
556  gen_asm_x86 crypto/des/asm/crypt586.pl
557  gen_asm_x86 crypto/bf/asm/bf-586.pl
558
559  # Generate x86_64 asm
560  gen_asm_x86_64 crypto/x86_64cpuid.pl
561  gen_asm_x86_64 crypto/sha/asm/sha1-x86_64.pl
562  gen_asm_x86_64 crypto/sha/asm/sha512-x86_64.pl crypto/sha/asm/sha256-x86_64.S
563  gen_asm_x86_64 crypto/sha/asm/sha512-x86_64.pl
564  gen_asm_x86_64 crypto/modes/asm/ghash-x86_64.pl
565  gen_asm_x86_64 crypto/aes/asm/aesni-x86_64.pl
566  gen_asm_x86_64 crypto/aes/asm/vpaes-x86_64.pl
567  gen_asm_x86_64 crypto/aes/asm/bsaes-x86_64.pl
568  gen_asm_x86_64 crypto/aes/asm/aes-x86_64.pl
569  gen_asm_x86_64 crypto/aes/asm/aesni-sha1-x86_64.pl
570  gen_asm_x86_64 crypto/md5/asm/md5-x86_64.pl
571  gen_asm_x86_64 crypto/bn/asm/modexp512-x86_64.pl
572  gen_asm_x86_64 crypto/bn/asm/x86_64-mont.pl
573  gen_asm_x86_64 crypto/bn/asm/x86_64-gf2m.pl
574  gen_asm_x86_64 crypto/bn/asm/x86_64-mont5.pl
575  gen_asm_x86_64 crypto/rc4/asm/rc4-x86_64.pl
576  gen_asm_x86_64 crypto/rc4/asm/rc4-md5-x86_64.pl
577
578  # Setup android.testssl directory
579  mkdir android.testssl
580  cat test/testssl | \
581    sed 's#../util/shlib_wrap.sh ./ssltest#adb shell /system/bin/ssltest#' | \
582    sed 's#../util/shlib_wrap.sh ../apps/openssl#adb shell /system/bin/openssl#' | \
583    sed 's#adb shell /system/bin/openssl no-dh#[ `adb shell /system/bin/openssl no-dh` = no-dh ]#' | \
584    sed 's#adb shell /system/bin/openssl no-rsa#[ `adb shell /system/bin/openssl no-rsa` = no-dh ]#' | \
585    sed 's#../apps/server2.pem#/sdcard/android.testssl/server2.pem#' | \
586    cat > \
587    android.testssl/testssl
588  chmod +x android.testssl/testssl
589  cat test/Uss.cnf | sed 's#./.rnd#/sdcard/android.testssl/.rnd#' >> android.testssl/Uss.cnf
590  cat test/CAss.cnf | sed 's#./.rnd#/sdcard/android.testssl/.rnd#' >> android.testssl/CAss.cnf
591  cp apps/server2.pem android.testssl/
592  cp ../patches/testssl.sh android.testssl/
593
594  cd ..
595
596  generate_config_mk Crypto-config-target.mk CRYPTO target
597  generate_config_mk Crypto-config-host.mk CRYPTO host
598  generate_config_mk Crypto-config-trusty.mk CRYPTO_TRUSTY target
599  generate_config_mk Ssl-config-target.mk SSL target
600  generate_config_mk Ssl-config-host.mk SSL host
601  generate_config_mk Apps-config-target.mk APPS target
602  generate_config_mk Apps-config-host.mk APPS host
603
604  # Prune unnecessary sources
605  prune
606
607  NEEDED_SOURCES="$NEEDED_SOURCES android.testssl"
608  for i in $NEEDED_SOURCES; do
609    echo "Updating $i"
610    rm -r $i
611    mv $OPENSSL_DIR/$i .
612  done
613
614  cleantar
615}
616
617function regenerate() {
618  declare -r patch=$1
619
620  generatepatch $patch
621}
622
623function generate() {
624  declare -r patch=$1
625  declare -r OPENSSL_SOURCE=$2
626
627  untar $OPENSSL_SOURCE
628  applypatches $OPENSSL_DIR_ORIG $patch
629  prune
630
631  for i in $NEEDED_SOURCES; do
632    echo "Restoring $i"
633    rm -r $OPENSSL_DIR/$i
634    cp -rf $i $OPENSSL_DIR/$i
635  done
636
637  generatepatch $patch
638  cleantar
639}
640
641# Find all files in a sub-directory that are encoded in ISO-8859
642# $1: Directory.
643# Out: list of files in $1 that are encoded as ISO-8859.
644function find_iso8859_files() {
645  find $1 -type f -print0 | xargs -0 file --mime-encoding | grep -i "iso-8859" | cut -d: -f1
646}
647
648# Convert all ISO-8859 files in a given subdirectory to UTF-8
649# $1: Directory name
650function convert_iso8859_to_utf8() {
651  declare -r iso_files=$(find_iso8859_files "$1")
652  for iso_file in $iso_files; do
653    iconv --from-code iso-8859-1 --to-code utf-8 $iso_file > $iso_file.tmp
654    rm -f $iso_file
655    mv $iso_file.tmp $iso_file
656  done
657}
658
659function untar() {
660  declare -r OPENSSL_SOURCE=$1
661  declare -r readonly=$2
662
663  # Remove old source
664  cleantar
665
666  # Process new source
667  tar -zxf $OPENSSL_SOURCE
668  cp -RfP $OPENSSL_DIR $OPENSSL_DIR_ORIG
669  if [ ! -z $readonly ]; then
670    find $OPENSSL_DIR_ORIG -type f -print0 | xargs -0 chmod a-w
671  fi
672}
673
674function prune() {
675  echo "Removing $UNNEEDED_SOURCES"
676  (cd $OPENSSL_DIR_ORIG && rm -rf $UNNEEDED_SOURCES)
677  (cd $OPENSSL_DIR      && rm -r  $UNNEEDED_SOURCES)
678}
679
680function cleantar() {
681  rm -rf $OPENSSL_DIR_ORIG
682  rm -rf $OPENSSL_DIR
683}
684
685function applypatches () {
686  declare -r dir=$1
687  declare -r skip_patch=$2
688
689  cd $dir
690
691  # Apply appropriate patches
692  patches=(../patches/[0-9][0-9][0-9][0-9]-*.patch)
693  for i in "${patches[@]}"; do
694    if [[ $skip_patch != ${i##*/} ]]; then
695      echo "Applying patch $i"
696      patch -p1 < $i || die "Could not apply $i. Fix source and run: $0 regenerate patches/${i##*/}"
697    else
698      echo "Skiping patch ${i##*/}"
699    fi
700
701  done
702
703  # Cleanup patch output
704  find . \( -type f -o -type l \) -name "*.orig" -print0 | xargs -0 rm -f
705
706  cd ..
707}
708
709function generatepatch() {
710  declare -r patch=$1
711
712  # Cleanup stray files before generating patch
713  find $OPENSSL_DIR -type f -name "*.orig" -print0 | xargs -0 rm -f
714  find $OPENSSL_DIR -type f -name "*~" -print0 | xargs -0 rm -f
715
716  # Find the files the patch touches and only keep those in the output patch
717  declare -r sources=`patch -p1 --dry-run -d $OPENSSL_DIR < $patch  | awk '/^patching file / { print $3 }'`
718
719  rm -f $patch
720  touch $patch
721  for i in $sources; do
722    LC_ALL=C TZ=UTC0 diff -aup $OPENSSL_DIR_ORIG/$i $OPENSSL_DIR/$i >> $patch && die "ERROR: No diff for patch $path in file $i"
723  done
724  echo "Generated patch $patch"
725  echo "NOTE To make sure there are not unwanted changes from conflicting patches, be sure to review the generated patch."
726}
727
728main $@
729