And so it begins...
[oweals/openssl.git] / fips-1.0 / fipsld
1 #!/bin/sh -e
2 #
3 # Copyright (c) 2005 The OpenSSL Project.
4 #
5 # Depending on output file name, the script either embeds fingerprint
6 # into libcrypto.so or static application. "Static" refers to static
7 # libcrypto.a, not [necessarily] application per se.
8 #
9 # Even though this script is called fipsld, it expects C compiler
10 # command line syntax and $FIPSLD_CC or $CC environment variable set
11 # and can even be used to compile source files.
12
13 #set -x
14
15 CC=${FIPSLD_CC:-${CC}}
16 [ -n "${CC}" ] || { echo '$CC is not defined'; exit 1; }
17
18 # Initially -c wasn't intended to be interpreted here, but it might
19 # make life easier for those who want to build FIPS-ified applications
20 # with minimal [if any] modifications to their Makefiles...
21 (   while [ "x$1" != "x" -a "x$1" != "x-c" ]; do shift; done;
22     [ $# -ge 1 ]
23 ) && exec ${CC} "$@"
24
25 # If using an auto-tooled (autoconf/automake/libtool) project,
26 # configure will fail when testing the compiler or even performing
27 # simple checks.  Pass-thru to compiler directly if not linking
28 # to libcrypto, allowing auto-tooled applications to utilize fipsld
29 # (e.g.  CC=/usr/local/ssl/bin/fipsld FIPSLD_CC=gcc ./configure && make )
30 # If FIPSLD_NPT is set never call the pass-thru: the standalone fips commands
31 # need this because they don't link to libcrypto
32 [ -z "$FIPSLD_NPT" -a -z "$FIPSLD_LIBFIPS" ] && {
33 case "$*" in
34         *libcrypto.a*)
35         ;;
36         *-lcrypto*)
37         ;;
38         *)
39                 exec ${CC} $*
40         ;;
41 esac
42 }
43
44 # Turn on debugging output?
45 (   while [ "x$1" != "x" -a "x$1" != "x-DDEBUG_FINGERPRINT_PREMAIN" ]; do shift; done;
46     [ $# -ge 1 ]
47 ) && set -x
48
49 TARGET=`(while [ "x$1" != "x" -a "x$1" != "x-o" ]; do shift; done; echo $2)`
50 [ -n "${TARGET}" ] || { echo 'no -o specified'; exit 1; }
51
52 THERE="`echo $0 | sed -e 's|[^/]*$||'`"..
53
54 # FIPSCANLIB is the library containing fipscanister.o by default it is
55 # libcrypto.a
56
57 FIPSCANLIB=${FIPSCANLIB:-libcrypto}
58
59 # FIPSLIBDIR is location of installed validated FIPS module
60 # if FIPSCANISTERINTERNAL="y" link against internally generated fipscanister.o
61 if [ "x$FIPSCANISTERINTERNAL" != "xy" ]; then
62         FIPSLIBDIR=${FIPSLIBDIR:-/usr/local/ssl/lib}
63 else
64         FIPSLIBDIR=${THERE}/fips-1.0
65 fi
66
67 [ -f "${FIPSLIBDIR}/fipscanister.o" ] ||
68         { echo "fipscanister.o not found"; exit 1; }
69
70 HMAC_KEY="etaonrishdlcupfm"
71
72 case "`(uname -s) 2>/dev/null`" in
73 OSF1|IRIX*)     _WL_PREMAIN="-Wl,-init,FINGERPRINT_premain"     ;;
74 HP-UX)          _WL_PREMAIN="-Wl,+init,FINGERPRINT_premain"     ;;
75 AIX)            _WL_PREMAIN="-Wl,-binitfini:FINGERPRINT_premain";;
76 Darwin)         (   while [ "x$1" != "x" -a "x$1" != "x-dynamiclib" ]; do shift; done;
77                     [ $# -ge 1 ]
78                 ) && _WL_PREMAIN="-Wl,-init,_FINGERPRINT_premain" ;;
79 esac
80
81 case "${TARGET}" in
82 [!/]*)  TARGET=./${TARGET} ;;
83 esac
84
85 case "${TARGET}" in
86 *${FIPSCANLIB}*|*.dll)  # must be linking a shared lib...
87         # Shared lib creation can be taking place in the source
88         # directory only!!!
89         FINGERTYPE="${THERE}/fips-1.0/sha/fips_standalone_sha1"
90         CANISTER_O="${FIPSLIBDIR}/fipscanister.o"
91         PREMAIN_C="${FIPSLIBDIR}/fips_premain.c"
92 echo Canister: $CANISTER_O
93
94         # verify fipspremain.c against its detached signature...
95         ${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \
96                 diff -w "${PREMAIN_C}.sha1" - || \
97         { echo "${PREMAIN_C} fingerprint mismatch"; exit 1; }
98         # Special case: if FIPSLD_LIBFIPS is asserted we are building
99         # libfips shared library and fipscanister.o is already present
100         # in libfips.a
101         if [ -n "$FIPSLD_LIBFIPS" ] ; then
102                 ${CC}  "${PREMAIN_C}" \
103                         ${_WL_PREMAIN} "$@"
104         else
105
106                 # verify fipscanister.o against its detached signature...
107                 ${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \
108                         diff -w "${CANISTER_O}.sha1" - || \
109                 { echo "${CANISTER_O} fingerprint mismatch"; exit 1; }
110
111                 # Temporarily remove fipscanister.o from library!
112                 # We are required to use the standalone copy...
113                 trap    'ar r "${THERE}/$FIPSCANLIB.a" "${CANISTER_O}";
114                          (ranlib "${THERE}/$FIPSCANLIB.a") 2>/dev/null;
115                          sleep 1;
116                          touch -c "${TARGET}"' 0
117
118                 ar d "${THERE}/$FIPSCANLIB.a" fipscanister.o 2>&1 > /dev/null || :
119                 (ranlib "${THERE}/$FIPSCANLIB.a") 2>/dev/null || :
120
121                 ${CC}   "${CANISTER_O}" \
122                         "${PREMAIN_C}" \
123                         ${_WL_PREMAIN} "$@"
124         fi
125
126         # generate signature...
127         SIG=`("${THERE}/fips-1.0/fips_premain_dso" "${TARGET}" || rm "${TARGET}")`
128         if [ -z "${SIG}" ]; then
129            echo "unable to collect signature"; exit 1
130         fi
131
132         if [ -n "$FIPSLD_LIBFIPS" ] ; then
133                 ${CC}  -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
134                         ${_WL_PREMAIN} "$@"
135         else
136
137                 # recompile with signature...
138                 ${CC}   "${CANISTER_O}" \
139                         -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
140                         ${_WL_PREMAIN} "$@"
141         fi
142         ;;
143
144 *)      # must be linking statically...
145         # Static linking can be taking place either in the source
146         # directory or off the installed binary target destination.
147         if [ -x "${THERE}/fips-1.0/sha/fips_standalone_sha1" ]; then
148                 FINGERTYPE="${THERE}/fips-1.0/sha/fips_standalone_sha1"
149         else    # Installed tree is expected to contain
150                 # lib/fipscanister.o, lib/fipscanister.o.sha1 and
151                 # lib/fips_premain.c [not to mention bin/openssl].
152                 FINGERTYPE="${THERE}/bin/openssl sha1 -hmac ${HMAC_KEY}"
153         fi
154
155         CANISTER_O="${FIPSLIBDIR}/fipscanister.o"
156         PREMAIN_C="${FIPSLIBDIR}/fips_premain.c"
157
158         # verify fipscanister.o against its detached signature...
159         ${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \
160                 diff -w "${CANISTER_O}.sha1" - || \
161         { echo "${CANISTER_O} fingerprint mismatch"; exit 1; }
162
163         # verify fips_premain.c against its detached signature...
164 #       ${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \
165 #               diff -w "${PREMAIN_C}.sha1" - || \
166 #       { echo "${PREMAIN_C} fingerprint mismatch"; exit 1; }
167
168         ${CC}   "${CANISTER_O}" \
169                 "${PREMAIN_C}" \
170                 ${_WL_PREMAIN} "$@"
171
172         # generate signature...
173         SIG=`("${TARGET}" || /bin/rm "${TARGET}")`
174         if [ -z "${SIG}" ]; then
175            echo "unable to collect signature"; exit 1
176         fi
177
178         # recompile with signature...
179         ${CC}   "${CANISTER_O}" \
180                 -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
181                 ${_WL_PREMAIN} "$@"
182         ;;
183 esac