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