• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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
178function 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
202function 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
225function 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
233function 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
264function 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
278main $@
279