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 function die() {
     32   declare -r message=$1
     33 
     34   echo $message
     35   exit 1
     36 }
     37 
     38 function 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 
     51 function 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 
    121 function 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 
    150 function 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 
    158 function update_timestamps() {
    159   declare -r git_dir="$1"
    160   declare -r target_dir="$2"
    161 
    162   echo -n "Restoring timestamps for ${target_dir}... "
    163 
    164   find "$git_dir" -type f -print0 | while IFS= read -r -d $'\0' file; do
    165     file_rev="$(git rev-list -n 1 HEAD "$file")"
    166     if [ "$file_rev" == "" ]; then
    167       echo
    168       echo -n "WARNING: No file revision for file $file..."
    169       continue
    170     fi
    171     file_time="$(git show --pretty=format:%ai --abbrev-commit "$file_rev" | head -n 1)"
    172     touch -d "$file_time" "${target_dir}${file#$git_dir}"
    173   done
    174 
    175   echo "done."
    176 }
    177 
    178 function generate() {
    179   declare -r patch=$1
    180   declare -r bouncycastle_source=$2
    181   declare -r bouncycastle_dir=$3
    182   declare -r bouncycastle_dir_orig=$4
    183   declare -r bouncycastle_out_dir=$5
    184   declare -r bouncycastle_patches=$6
    185   declare -r needed_sources=$7
    186   declare -r unneeded_sources=$8
    187 
    188   untar $bouncycastle_source $bouncycastle_dir $bouncycastle_dir_orig "$unneeded_sources"
    189   applypatches $bouncycastle_dir "$bouncycastle_patches" "$unneeded_sources"
    190 
    191   for i in $needed_sources; do
    192     echo "Restoring $i"
    193     rm -r $bouncycastle_dir/$i
    194     cp -rf $bouncycastle_out_dir/src/main/java/$i $bouncycastle_dir/$i
    195     update_timestamps $bouncycastle_out_dir/src/main/java/$i $bouncycastle_dir/$i
    196   done
    197 
    198   generatepatch $patch $bouncycastle_dir $bouncycastle_dir_orig
    199   cleantar $bouncycastle_dir $bouncycastle_dir_orig
    200 }
    201 
    202 function untar() {
    203   declare -r bouncycastle_source=$1
    204   declare -r bouncycastle_dir=$2
    205   declare -r bouncycastle_dir_orig=$3
    206   declare -r unneeded_sources=$4
    207 
    208   # Remove old source
    209   cleantar $bouncycastle_dir $bouncycastle_dir_orig
    210 
    211   # Process new source
    212   tar -zxf $bouncycastle_source
    213   mv $bouncycastle_dir $bouncycastle_dir_orig
    214   find $bouncycastle_dir_orig -type f -print0 | xargs -0 chmod a-w
    215   (cd $bouncycastle_dir_orig && unzip -q src.zip)
    216   tar -zxf $bouncycastle_source
    217   (cd $bouncycastle_dir && unzip -q src.zip)
    218 
    219   # Prune unnecessary sources
    220   echo "Removing $unneeded_sources"
    221   (cd $bouncycastle_dir_orig && rm -rf $unneeded_sources)
    222   (cd $bouncycastle_dir      && rm -r  $unneeded_sources)
    223 }
    224 
    225 function cleantar() {
    226   declare -r bouncycastle_dir=$1
    227   declare -r bouncycastle_dir_orig=$2
    228 
    229   rm -rf $bouncycastle_dir_orig
    230   rm -rf $bouncycastle_dir
    231 }
    232 
    233 function applypatches () {
    234   declare -r bouncycastle_dir=$1
    235   declare -r bouncycastle_patches=$2
    236   declare -r unneeded_sources=$3
    237 
    238   cd $bouncycastle_dir
    239 
    240   # Apply appropriate patches
    241   for i in $bouncycastle_patches; do
    242     echo "Applying patch $i"
    243     patch -p1 --merge < ../$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate $i"
    244 
    245     # make sure no unneeded sources got into the patch
    246     problem=0
    247     for s in $unneeded_sources; do
    248       if [ -e $s ]; then
    249         echo Unneeded source $s restored by patch $i
    250         problem=1
    251       fi
    252     done
    253     if [ $problem = 1 ]; then
    254       exit 1
    255     fi
    256   done
    257 
    258   # Cleanup patch output
    259   find . -type f -name "*.orig" -print0 | xargs -0 rm -f
    260 
    261   cd ..
    262 }
    263 
    264 function generatepatch() {
    265   declare -r patch=$1
    266   declare -r bouncycastle_dir=$2
    267   declare -r bouncycastle_dir_orig=$3
    268 
    269   # Cleanup stray files before generating patch
    270   find $bouncycastle_dir -type f -name "*.orig" -print0 | xargs -0 rm -f
    271   find $bouncycastle_dir -type f -name "*~" -print0 | xargs -0 rm -f
    272 
    273   rm -f $patch
    274   LC_ALL=C TZ=UTC0 diff -Naur $bouncycastle_dir_orig $bouncycastle_dir >> $patch && die "ERROR: No diff for patch $path in file $i"
    275   echo "Generated patch $patch"
    276 }
    277 
    278 main $@
    279