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