import_bouncycastle.sh revision e6bf3e8dfa2804891a82075cb469b736321b4827
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