1#!/bin/bash 2# 3# Copyright (C) 2010 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 Bouncy Castle 20# (http://bouncycastle.org) into the Android source tree. To run, (1) 21# fetch the appropriate tarballs (bcprov and bcpkix) from the Bouncy 22# Castle repository, (2) check the checksum, and then (3) run: 23# ./import_bouncycastle.sh import bcprov-jdk*-*.tar.gz 24# 25# IMPORTANT: See README.android for additional details. 26 27# turn on exit on error as well as a warning when it happens 28set -e 29trap "echo WARNING: Exiting on non-zero subprocess exit code" ERR; 30 31function die() { 32 declare -r message=$1 33 34 echo $message 35 exit 1 36} 37 38function usage() { 39 declare -r message=$1 40 41 if [ ! "$message" = "" ]; then 42 echo $message 43 fi 44 echo "Usage:" 45 echo " ./import_bouncycastle.sh import </path/to/bcprov-jdk*-*.tar.gz>" 46 echo " ./import_bouncycastle.sh regenerate <patch/*.patch>" 47 echo " ./import_bouncycastle.sh generate <patch/*.patch> </path/to/bcprov-jdk*-*.tar.gz>" 48 exit 1 49} 50 51function main() { 52 if [ ! -d patches ]; then 53 die "Bouncy Castle patch directory patches/ not found" 54 fi 55 56 if [ ! -f bouncycastle.version ]; then 57 die "bouncycastle.version not found" 58 fi 59 60 source bouncycastle.version 61 if [ "$BOUNCYCASTLE_JDK" == "" -o "$BOUNCYCASTLE_VERSION" == "" ]; then 62 die "Invalid bouncycastle.version; see README.android for more information" 63 fi 64 65 BOUNCYCASTLE_BCPROV_DIR=bcprov-jdk$BOUNCYCASTLE_JDK-$BOUNCYCASTLE_VERSION 66 BOUNCYCASTLE_BCPROV_DIR_ORIG=$BOUNCYCASTLE_BCPROV_DIR.orig 67 68 BOUNCYCASTLE_BCPKIX_DIR=bcpkix-jdk$BOUNCYCASTLE_JDK-$BOUNCYCASTLE_VERSION 69 BOUNCYCASTLE_BCPKIX_DIR_ORIG=$BOUNCYCASTLE_BCPKIX_DIR.orig 70 71 if [ ! -f bouncycastle.config ]; then 72 die "bouncycastle.config not found" 73 fi 74 75 source bouncycastle.config 76 if [ "$UNNEEDED_BCPROV_SOURCES" == "" -o "$NEEDED_BCPROV_SOURCES" == "" \ 77 -o "$UNNEEDED_BCPKIX_SOURCES" == "" -o "$NEEDED_BCPKIX_SOURCES" == "" ]; then 78 die "Invalid bouncycastle.config; see README.android for more information" 79 fi 80 81 declare -r command=$1 82 shift || usage "No command specified. Try import, regenerate, or generate." 83 if [ "$command" = "import" ]; then 84 declare -r bcprov_tar=$1 85 shift || usage "No tar file specified." 86 declare -r bcpkix_tar=`echo $bcprov_tar | sed s/bcprov/bcpkix/` 87 import $bcprov_tar $BOUNCYCASTLE_BCPROV_DIR $BOUNCYCASTLE_BCPROV_DIR_ORIG bcprov "$BOUNCYCASTLE_BCPROV_PATCHES" "$NEEDED_BCPROV_SOURCES" "$UNNEEDED_BCPROV_SOURCES" 88 import $bcpkix_tar $BOUNCYCASTLE_BCPKIX_DIR $BOUNCYCASTLE_BCPKIX_DIR_ORIG bcpkix "$BOUNCYCASTLE_BCPKIX_PATCHES" "$NEEDED_BCPKIX_SOURCES" "$UNNEEDED_BCPKIX_SOURCES" 89 elif [ "$command" = "regenerate" ]; then 90 declare -r patch=$1 91 shift || usage "No patch file specified." 92 if [[ $BOUNCYCASTLE_BCPROV_PATCHES == *$patch* ]]; then 93 [ -d $BOUNCYCASTLE_BCPROV_DIR ] || usage "$BOUNCYCASTLE_BCPROV_DIR not found, did you mean to use generate?" 94 [ -d $BOUNCYCASTLE_BCPROV_DIR_ORIG ] || usage "$BOUNCYCASTLE_BCPROV_DIR_ORIG not found, did you mean to use generate?" 95 regenerate $patch $BOUNCYCASTLE_BCPROV_DIR $BOUNCYCASTLE_BCPROV_DIR_ORIG 96 elif [[ $BOUNCYCASTLE_BCPKIX_PATCHES == *$patch* ]]; then 97 [ -d $BOUNCYCASTLE_BCPKIX_DIR ] || usage "$BOUNCYCASTLE_BCPROV_DIR not found, did you mean to use generate?" 98 [ -d $BOUNCYCASTLE_BCPKIX_DIR_ORIG ] || usage "$BOUNCYCASTLE_BCPKIX_DIR_ORIG not found, did you mean to use generate?" 99 regenerate $patch $BOUNCYCASTLE_BCPKIX_DIR $BOUNCYCASTLE_BCPKIX_DIR_ORIG 100 else 101 usage "Unknown patch file $patch specified" 102 fi 103 elif [ "$command" = "generate" ]; then 104 declare -r patch=$1 105 shift || usage "No patch file specified." 106 declare -r bcprov_tar=$1 107 shift || usage "No tar file specified." 108 declare -r bcpkix_tar=`echo $bcprov_tar | sed s/bcprov/bcpkix/` 109 if [[ $BOUNCYCASTLE_BCPROV_PATCHES == *$patch* ]]; then 110 generate $patch $bcprov_tar $BOUNCYCASTLE_BCPROV_DIR $BOUNCYCASTLE_BCPROV_DIR_ORIG bcprov "$BOUNCYCASTLE_BCPROV_PATCHES" "$NEEDED_BCPROV_SOURCES" "$UNNEEDED_BCPROV_SOURCES" 111 elif [[ $BOUNCYCASTLE_BCPKIX_PATCHES == *$patch* ]]; then 112 generate $patch $bcpkix_tar $BOUNCYCASTLE_BCPKIX_DIR $BOUNCYCASTLE_BCPKIX_DIR_ORIG bcpkix "$BOUNCYCASTLE_BCPKIX_PATCHES" "$NEEDED_BCPKIX_SOURCES" "$UNNEEDED_BCPKIX_SOURCES" 113 else 114 usage "Unknown patch file $patch specified" 115 fi 116 else 117 usage "Unknown command specified $command. Try import, regenerate, or generate." 118 fi 119} 120 121function import() { 122 declare -r bouncycastle_source=$1 123 declare -r bouncycastle_dir=$2 124 declare -r bouncycastle_dir_orig=$3 125 declare -r bouncycastle_out_dir=$4 126 declare -r bouncycastle_patches=$5 127 declare -r needed_sources=$6 128 declare -r unneeded_sources=$7 129 130 untar $bouncycastle_source $bouncycastle_dir $bouncycastle_dir_orig "$unneeded_sources" 131 applypatches $bouncycastle_dir "$bouncycastle_patches" "$unneeded_sources" 132 133 cd $bouncycastle_dir 134 135 sed 's/<p>/& <BR>/g' LICENSE.html | html2text -width 102 -nobs -ascii > ../NOTICE 136 touch ../MODULE_LICENSE_BSD_LIKE 137 138 cd .. 139 140 rm -r $bouncycastle_out_dir/src 141 mkdir -p $bouncycastle_out_dir/src/main/java/ 142 for i in $needed_sources; do 143 echo "Updating $i" 144 mv $bouncycastle_dir/$i $bouncycastle_out_dir/src/main/java/ 145 done 146 147 cleantar $bouncycastle_dir $bouncycastle_dir_orig 148} 149 150function regenerate() { 151 declare -r patch=$1 152 declare -r bouncycastle_dir=$2 153 declare -r bouncycastle_dir_orig=$3 154 155 generatepatch $patch $bouncycastle_dir $bouncycastle_dir_orig 156} 157 158function generate() { 159 declare -r patch=$1 160 declare -r bouncycastle_source=$2 161 declare -r bouncycastle_dir=$3 162 declare -r bouncycastle_dir_orig=$4 163 declare -r bouncycastle_out_dir=$5 164 declare -r bouncycastle_patches=$6 165 declare -r needed_sources=$7 166 declare -r unneeded_sources=$8 167 168 untar $bouncycastle_source $bouncycastle_dir $bouncycastle_dir_orig "$unneeded_sources" 169 applypatches $bouncycastle_dir "$bouncycastle_patches" "$unneeded_sources" 170 171 for i in $needed_sources; do 172 echo "Restoring $i" 173 rm -r $bouncycastle_dir/$i 174 cp -rf $bouncycastle_out_dir/src/main/java/$i $bouncycastle_dir/$i 175 done 176 177 generatepatch $patch $bouncycastle_dir $bouncycastle_dir_orig 178 cleantar $bouncycastle_dir $bouncycastle_dir_orig 179} 180 181function untar() { 182 declare -r bouncycastle_source=$1 183 declare -r bouncycastle_dir=$2 184 declare -r bouncycastle_dir_orig=$3 185 declare -r unneeded_sources=$4 186 187 # Remove old source 188 cleantar $bouncycastle_dir $bouncycastle_dir_orig 189 190 # Process new source 191 tar -zxf $bouncycastle_source 192 mv $bouncycastle_dir $bouncycastle_dir_orig 193 find $bouncycastle_dir_orig -type f -print0 | xargs -0 chmod a-w 194 (cd $bouncycastle_dir_orig && unzip -q src.zip) 195 tar -zxf $bouncycastle_source 196 (cd $bouncycastle_dir && unzip -q src.zip) 197 198 # Prune unnecessary sources 199 echo "Removing $unneeded_sources" 200 (cd $bouncycastle_dir_orig && rm -rf $unneeded_sources) 201 (cd $bouncycastle_dir && rm -r $unneeded_sources) 202} 203 204function cleantar() { 205 declare -r bouncycastle_dir=$1 206 declare -r bouncycastle_dir_orig=$2 207 208 rm -rf $bouncycastle_dir_orig 209 rm -rf $bouncycastle_dir 210} 211 212function applypatches () { 213 declare -r bouncycastle_dir=$1 214 declare -r bouncycastle_patches=$2 215 declare -r unneeded_sources=$3 216 217 cd $bouncycastle_dir 218 219 # Apply appropriate patches 220 for i in $bouncycastle_patches; do 221 echo "Applying patch $i" 222 patch -p1 < ../$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i" 223 224 # make sure no unneeded sources got into the patch 225 problem=0 226 for s in $unneeded_sources; do 227 if [ -e $s ]; then 228 echo Unneeded source $s restored by patch $i 229 problem=1 230 fi 231 done 232 if [ $problem = 1 ]; then 233 exit 1 234 fi 235 done 236 237 # Cleanup patch output 238 find . -type f -name "*.orig" -print0 | xargs -0 rm -f 239 240 cd .. 241} 242 243function generatepatch() { 244 declare -r patch=$1 245 declare -r bouncycastle_dir=$2 246 declare -r bouncycastle_dir_orig=$3 247 248 # Cleanup stray files before generating patch 249 find $bouncycastle_dir -type f -name "*.orig" -print0 | xargs -0 rm -f 250 find $bouncycastle_dir -type f -name "*~" -print0 | xargs -0 rm -f 251 252 rm -f $patch 253 LC_ALL=C TZ=UTC0 diff -Naur $bouncycastle_dir_orig $bouncycastle_dir >> $patch && die "ERROR: No diff for patch $path in file $i" 254 echo "Generated patch $patch" 255} 256 257main $@ 258