Home | History | Annotate | Download | only in openssl
      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
     27 set -e
     28 trap  "echo WARNING: Exiting on non-zero subprocess exit code" ERR;
     29 
     30 function die() {
     31   declare -r message=$1
     32 
     33   echo $message
     34   exit 1
     35 }
     36 
     37 function usage() {
     38   declare -r message=$1
     39 
     40   if [ ! "$message" = "" ]; then
     41     echo $message
     42   fi
     43   echo "Usage:"
     44   echo "  ./import_openssl.sh import </path/to/openssl-*.tar.gz>"
     45   echo "  ./import_openssl.sh regenerate <patch/*.patch>"
     46   echo "  ./import_openssl.sh generate <patch/*.patch> </path/to/openssl-*.tar.gz>"
     47   exit 1
     48 }
     49 
     50 function main() {
     51   if [ ! -d patches ]; then
     52     die "OpenSSL patch directory patches/ not found"
     53   fi
     54 
     55   if [ ! -f openssl.version ]; then
     56     die "openssl.version not found"
     57   fi
     58 
     59   source openssl.version
     60   if [ "$OPENSSL_VERSION" == "" ]; then
     61     die "Invalid openssl.version; see README.android for more information"
     62   fi
     63 
     64   OPENSSL_DIR=openssl-$OPENSSL_VERSION
     65   OPENSSL_DIR_ORIG=$OPENSSL_DIR.orig
     66 
     67   if [ ! -f openssl.config ]; then
     68     die "openssl.config not found"
     69   fi
     70 
     71   source openssl.config
     72   if [ "$CONFIGURE_ARGS" == "" -o "$UNNEEDED_SOURCES" == "" -o "$NEEDED_SOURCES" == "" ]; then
     73     die "Invalid openssl.config; see README.android for more information"
     74   fi
     75 
     76   declare -r command=$1
     77   shift || usage "No command specified. Try import, regenerate, or generate."
     78   if [ "$command" = "import" ]; then
     79     declare -r tar=$1
     80     shift || usage "No tar file specified."
     81     import $tar
     82   elif [ "$command" = "regenerate" ]; then
     83     declare -r patch=$1
     84     shift || usage "No patch file specified."
     85     [ -d $OPENSSL_DIR ] || usage "$OPENSSL_DIR not found, did you mean to use generate?"
     86     [ -d $OPENSSL_DIR_ORIG_ORIG ] || usage "$OPENSSL_DIR_ORIG not found, did you mean to use generate?"
     87     regenerate $patch
     88   elif [ "$command" = "generate" ]; then
     89     declare -r patch=$1
     90     shift || usage "No patch file specified."
     91     declare -r tar=$1
     92     shift || usage "No tar file specified."
     93     generate $patch $tar
     94   else
     95     usage "Unknown command specified $command. Try import, regenerate, or generate."
     96   fi
     97 }
     98 
     99 function import() {
    100   declare -r OPENSSL_SOURCE=$1
    101 
    102   untar $OPENSSL_SOURCE readonly
    103   applypatches $OPENSSL_DIR
    104 
    105   cd $OPENSSL_DIR
    106 
    107   # Configure source (and print Makefile defines for review, see README.android)
    108   ./Configure $CONFIGURE_ARGS
    109   rm -f apps/CA.pl.bak crypto/opensslconf.h.bak
    110   echo
    111   echo BEGIN Makefile defines to compare with android-config.mk
    112   echo
    113   grep -e -D Makefile | grep -v CONFIGURE_ARGS= | grep -v OPTIONS= | grep -v -e -DOPENSSL_NO_DEPRECATED
    114   echo
    115   echo END Makefile defines to compare with android-config.mk
    116   echo
    117 
    118   # TODO(): Fixup android-config.mk
    119 
    120   cp -f LICENSE ../NOTICE
    121   touch ../MODULE_LICENSE_BSD_LIKE
    122 
    123   # Avoid checking in symlinks
    124   for i in `find include/openssl -type l`; do
    125     target=`readlink $i`
    126     rm -f $i
    127     if [ -f include/openssl/$target ]; then
    128       cp include/openssl/$target $i
    129     fi
    130   done
    131 
    132   # Copy Makefiles
    133   cp ../patches/apps_Android.mk apps/Android.mk
    134   cp ../patches/crypto_Android.mk crypto/Android.mk
    135   cp ../patches/ssl_Android.mk ssl/Android.mk
    136 
    137   # Generate asm
    138   perl crypto/aes/asm/aes-armv4.pl         > crypto/aes/asm/aes-armv4.s
    139   perl crypto/bn/asm/armv4-mont.pl         > crypto/bn/asm/armv4-mont.s
    140   perl crypto/sha/asm/sha1-armv4-large.pl  > crypto/sha/asm/sha1-armv4-large.s
    141   perl crypto/sha/asm/sha256-armv4.pl      > crypto/sha/asm/sha256-armv4.s
    142   perl crypto/sha/asm/sha512-armv4.pl      > crypto/sha/asm/sha512-armv4.s
    143 
    144   # Setup android.testssl directory
    145   mkdir android.testssl
    146   cat test/testssl | \
    147     sed 's#../util/shlib_wrap.sh ./ssltest#adb shell /system/bin/ssltest#' | \
    148     sed 's#../util/shlib_wrap.sh ../apps/openssl#adb shell /system/bin/openssl#' | \
    149     sed 's#adb shell /system/bin/openssl no-dh#[ `adb shell /system/bin/openssl no-dh` = no-dh ]#' | \
    150     sed 's#adb shell /system/bin/openssl no-rsa#[ `adb shell /system/bin/openssl no-rsa` = no-dh ]#' | \
    151     sed 's#../apps/server2.pem#/sdcard/android.testssl/server2.pem#' | \
    152     cat > \
    153     android.testssl/testssl
    154   chmod +x android.testssl/testssl
    155   cat test/Uss.cnf | sed 's#./.rnd#/sdcard/android.testssl/.rnd#' >> android.testssl/Uss.cnf
    156   cat test/CAss.cnf | sed 's#./.rnd#/sdcard/android.testssl/.rnd#' >> android.testssl/CAss.cnf
    157   cp apps/server2.pem android.testssl/
    158   cp ../patches/testssl.sh android.testssl/
    159 
    160   cd ..
    161 
    162   # Prune unnecessary sources
    163   prune
    164 
    165   NEEDED_SOURCES="$NEEDED_SOURCES android.testssl"
    166   for i in $NEEDED_SOURCES; do
    167     echo "Updating $i"
    168     rm -r $i
    169     mv $OPENSSL_DIR/$i .
    170   done
    171 
    172   cleantar
    173 }
    174 
    175 function regenerate() {
    176   declare -r patch=$1
    177 
    178   generatepatch $patch
    179 }
    180 
    181 function generate() {
    182   declare -r patch=$1
    183   declare -r OPENSSL_SOURCE=$2
    184 
    185   untar $OPENSSL_SOURCE
    186   applypatches $OPENSSL_DIR_ORIG $patch
    187   prune
    188 
    189   for i in $NEEDED_SOURCES; do
    190     echo "Restoring $i"
    191     rm -r $OPENSSL_DIR/$i
    192     cp -rf $i $OPENSSL_DIR/$i
    193   done
    194 
    195   generatepatch $patch
    196   cleantar
    197 }
    198 
    199 function untar() {
    200   declare -r OPENSSL_SOURCE=$1
    201   declare -r readonly=$2
    202 
    203   # Remove old source
    204   cleantar
    205 
    206   # Process new source
    207   tar -zxf $OPENSSL_SOURCE
    208   mv $OPENSSL_DIR $OPENSSL_DIR_ORIG
    209   if [ ! -z $readonly ]; then
    210     find $OPENSSL_DIR_ORIG -type f -print0 | xargs -0 chmod a-w
    211   fi
    212   tar -zxf $OPENSSL_SOURCE
    213 }
    214 
    215 function prune() {
    216   echo "Removing $UNNEEDED_SOURCES"
    217   (cd $OPENSSL_DIR_ORIG && rm -rf $UNNEEDED_SOURCES)
    218   (cd $OPENSSL_DIR      && rm -r  $UNNEEDED_SOURCES)
    219 }
    220 
    221 function cleantar() {
    222   rm -rf $OPENSSL_DIR_ORIG
    223   rm -rf $OPENSSL_DIR
    224 }
    225 
    226 function applypatches () {
    227   declare -r dir=$1
    228   declare -r skip_patch=$2
    229 
    230   cd $dir
    231 
    232   # Apply appropriate patches
    233   for i in $OPENSSL_PATCHES; do
    234     if [ ! "$skip_patch" = "patches/$i" ]; then
    235       echo "Applying patch $i"
    236       patch -p1 < ../patches/$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i"
    237     else
    238       echo "Skiping patch $i"
    239     fi
    240 
    241   done
    242 
    243   # Cleanup patch output
    244   find . -type f -name "*.orig" -print0 | xargs -0 rm -f
    245 
    246   cd ..
    247 }
    248 
    249 function generatepatch() {
    250   declare -r patch=$1
    251 
    252   # Cleanup stray files before generating patch
    253   find $BOUNCYCASTLE_DIR -type f -name "*.orig" -print0 | xargs -0 rm -f
    254   find $BOUNCYCASTLE_DIR -type f -name "*~" -print0 | xargs -0 rm -f
    255 
    256   declare -r variable_name=OPENSSL_PATCHES_`basename $patch .patch | sed s/-/_/`_SOURCES
    257   # http://tldp.org/LDP/abs/html/ivr.html
    258   eval declare -r sources=\$$variable_name
    259   rm -f $patch
    260   touch $patch
    261   for i in $sources; do
    262     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"
    263   done
    264   echo "Generated patch $patch"
    265   echo "NOTE To make sure there are not unwanted changes from conflicting patches, be sure to review the generated patch."
    266 }
    267 
    268 main $@
    269