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   # Generate arm asm
    133   perl crypto/aes/asm/aes-armv4.pl         > crypto/aes/asm/aes-armv4.s
    134   perl crypto/bn/asm/armv4-gf2m.pl         > crypto/bn/asm/armv4-gf2m.s
    135   perl crypto/bn/asm/armv4-mont.pl         > crypto/bn/asm/armv4-mont.s
    136   perl crypto/modes/asm/ghash-armv4.pl     > crypto/modes/asm/ghash-armv4.s
    137   perl crypto/sha/asm/sha1-armv4-large.pl  > crypto/sha/asm/sha1-armv4-large.s
    138   perl crypto/sha/asm/sha256-armv4.pl      > crypto/sha/asm/sha256-armv4.s
    139   perl crypto/sha/asm/sha512-armv4.pl      > crypto/sha/asm/sha512-armv4.s
    140 
    141   # Generate mips asm
    142   # The perl scripts expect to run the target compiler as $CC to determine
    143   # the endianess of the target. Setting CC to true is a hack that forces the scripts
    144   # to generate little endian output
    145   CC=true perl crypto/aes/asm/aes-mips.pl o32      > crypto/aes/asm/aes-mips.s
    146   CC=true perl crypto/bn/asm/mips.pl o32           > crypto/bn/asm/bn-mips.s
    147   CC=true perl crypto/bn/asm/mips-mont.pl o32      > crypto/bn/asm/mips-mont.s
    148   CC=true perl crypto/sha/asm/sha1-mips.pl o32     > crypto/sha/asm/sha1-mips.s
    149   CC=true perl crypto/sha/asm/sha512-mips.pl o32   > crypto/sha/asm/sha256-mips.s
    150 
    151   # Generate x86 asm
    152   perl crypto/aes/asm/aes-586.pl      elf  > crypto/aes/asm/aes-586.s
    153   perl crypto/aes/asm/vpaes-x86.pl    elf  > crypto/aes/asm/vpaes-x86.s
    154   perl crypto/aes/asm/aesni-x86.pl    elf  > crypto/aes/asm/aesni-x86.s
    155   perl crypto/bn/asm/bn-586.pl        elf  > crypto/bn/asm/bn-586.s
    156   perl crypto/bn/asm/co-586.pl        elf  > crypto/bn/asm/co-586.s
    157   perl crypto/bn/asm/x86-mont.pl      elf  > crypto/bn/asm/x86-mont.s
    158   perl crypto/bn/asm/x86-gf2m.pl      elf  > crypto/bn/asm/x86-gf2m.s
    159   perl crypto/modes/asm/ghash-x86.pl  elf  > crypto/modes/asm/ghash-x86.s
    160   perl crypto/sha/asm/sha1-586.pl     elf  > crypto/sha/asm/sha1-586.s
    161   perl crypto/sha/asm/sha256-586.pl   elf  > crypto/sha/asm/sha256-586.s
    162   perl crypto/sha/asm/sha512-586.pl   elf  > crypto/sha/asm/sha512-586.s
    163   perl crypto/md5/asm/md5-586.pl      elf  > crypto/md5/asm/md5-586.s
    164   perl crypto/des/asm/des-586.pl      elf  > crypto/des/asm/des-586.s
    165   perl crypto/des/asm/crypt586.pl     elf  > crypto/des/asm/crypt586.s
    166   perl crypto/bf/asm/bf-586.pl        elf  > crypto/bf/asm/bf-586.s
    167 
    168   # Setup android.testssl directory
    169   mkdir android.testssl
    170   cat test/testssl | \
    171     sed 's#../util/shlib_wrap.sh ./ssltest#adb shell /system/bin/ssltest#' | \
    172     sed 's#../util/shlib_wrap.sh ../apps/openssl#adb shell /system/bin/openssl#' | \
    173     sed 's#adb shell /system/bin/openssl no-dh#[ `adb shell /system/bin/openssl no-dh` = no-dh ]#' | \
    174     sed 's#adb shell /system/bin/openssl no-rsa#[ `adb shell /system/bin/openssl no-rsa` = no-dh ]#' | \
    175     sed 's#../apps/server2.pem#/sdcard/android.testssl/server2.pem#' | \
    176     cat > \
    177     android.testssl/testssl
    178   chmod +x android.testssl/testssl
    179   cat test/Uss.cnf | sed 's#./.rnd#/sdcard/android.testssl/.rnd#' >> android.testssl/Uss.cnf
    180   cat test/CAss.cnf | sed 's#./.rnd#/sdcard/android.testssl/.rnd#' >> android.testssl/CAss.cnf
    181   cp apps/server2.pem android.testssl/
    182   cp ../patches/testssl.sh android.testssl/
    183 
    184   cd ..
    185 
    186   # Prune unnecessary sources
    187   prune
    188 
    189   NEEDED_SOURCES="$NEEDED_SOURCES android.testssl"
    190   for i in $NEEDED_SOURCES; do
    191     echo "Updating $i"
    192     rm -r $i
    193     mv $OPENSSL_DIR/$i .
    194   done
    195 
    196   cleantar
    197 }
    198 
    199 function regenerate() {
    200   declare -r patch=$1
    201 
    202   generatepatch $patch
    203 }
    204 
    205 function generate() {
    206   declare -r patch=$1
    207   declare -r OPENSSL_SOURCE=$2
    208 
    209   untar $OPENSSL_SOURCE
    210   applypatches $OPENSSL_DIR_ORIG $patch
    211   prune
    212 
    213   for i in $NEEDED_SOURCES; do
    214     echo "Restoring $i"
    215     rm -r $OPENSSL_DIR/$i
    216     cp -rf $i $OPENSSL_DIR/$i
    217   done
    218 
    219   generatepatch $patch
    220   cleantar
    221 }
    222 
    223 function untar() {
    224   declare -r OPENSSL_SOURCE=$1
    225   declare -r readonly=$2
    226 
    227   # Remove old source
    228   cleantar
    229 
    230   # Process new source
    231   tar -zxf $OPENSSL_SOURCE
    232   mv $OPENSSL_DIR $OPENSSL_DIR_ORIG
    233   if [ ! -z $readonly ]; then
    234     find $OPENSSL_DIR_ORIG -type f -print0 | xargs -0 chmod a-w
    235   fi
    236   tar -zxf $OPENSSL_SOURCE
    237 }
    238 
    239 function prune() {
    240   echo "Removing $UNNEEDED_SOURCES"
    241   (cd $OPENSSL_DIR_ORIG && rm -rf $UNNEEDED_SOURCES)
    242   (cd $OPENSSL_DIR      && rm -r  $UNNEEDED_SOURCES)
    243 }
    244 
    245 function cleantar() {
    246   rm -rf $OPENSSL_DIR_ORIG
    247   rm -rf $OPENSSL_DIR
    248 }
    249 
    250 function applypatches () {
    251   declare -r dir=$1
    252   declare -r skip_patch=$2
    253 
    254   cd $dir
    255 
    256   # Apply appropriate patches
    257   for i in $OPENSSL_PATCHES; do
    258     if [ ! "$skip_patch" = "patches/$i" ]; then
    259       echo "Applying patch $i"
    260       patch -p1 < ../patches/$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i"
    261     else
    262       echo "Skiping patch $i"
    263     fi
    264 
    265   done
    266 
    267   # Cleanup patch output
    268   find . \( -type f -o -type l \) -name "*.orig" -print0 | xargs -0 rm -f
    269 
    270   cd ..
    271 }
    272 
    273 function generatepatch() {
    274   declare -r patch=$1
    275 
    276   # Cleanup stray files before generating patch
    277   find $BOUNCYCASTLE_DIR -type f -name "*.orig" -print0 | xargs -0 rm -f
    278   find $BOUNCYCASTLE_DIR -type f -name "*~" -print0 | xargs -0 rm -f
    279 
    280   declare -r variable_name=OPENSSL_PATCHES_`basename $patch .patch | sed s/-/_/`_SOURCES
    281   # http://tldp.org/LDP/abs/html/ivr.html
    282   eval declare -r sources=\$$variable_name
    283   rm -f $patch
    284   touch $patch
    285   for i in $sources; do
    286     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"
    287   done
    288   echo "Generated patch $patch"
    289   echo "NOTE To make sure there are not unwanted changes from conflicting patches, be sure to review the generated patch."
    290 }
    291 
    292 main $@
    293