Commit f2c6166c authored by Devon Kearns's avatar Devon Kearns

Imported Upstream version 0.4.6

parents
/*.o
/*.ot
/*.dSYM
/sslsplit
/sslsplit.test
/extra/pki/dh*.param
/extra/pki/dsa.pem
/extra/pki/dsa.crt
/extra/pki/dsa.key
/extra/pki/dsa.param
/extra/pki/ec.pem
/extra/pki/ec.crt
/extra/pki/ec.key
/extra/pki/pwd.key
/extra/pki/rsa.pem
/extra/pki/rsa.crt
/extra/pki/rsa.key
/extra/pki/server.pem
/extra/pki/server.crt
/extra/pki/server.key
/extra/pki/session.pem
/extra/pki/targets/*
USE_GNU:
@gmake $(.TARGETS)
$(.TARGETS): USE_GNU
.PHONY: USE_GNU
### OpenSSL tweaking
# Define to use dubious hacks to decrease OpenSSL memory consumption.
#FEATURES+= -DUSE_FOOTPRINT_HACKS
# Define to disable server-mode SSL session caching for SSLv2 clients.
# This is needed if SSL session resumption fails with a bufferevent error:
# "illegal padding in SSL routines SSL2_READ_INTERNAL".
FEATURES+= -DDISABLE_SSLV2_SESSION_CACHE
# Define to disable server-mode SSLv2 completely, but still use SSL23 method.
#FEATURES+= -DDISABLE_SSLV2_SERVER
# Define to make SSLsplit set a session id context in server mode.
#FEATURES+= -DUSE_SSL_SESSION_ID_CONTEXT
### Debugging
# These flags are added to CFLAGS iff building from a git repo.
DEBUG_CFLAGS?= -g
#DEBUG_CFLAGS+= -Werror
# Define to remove false positives when debugging memory allocation.
# Note that you probably want to build OpenSSL with -DPURIFY too.
#FEATURES+= -DPURIFY
# Define to add proxy state machine debugging; dump state in debug mode.
#FEATURES+= -DDEBUG_PROXY
# Define to add certificate debugging; dump all certificates in debug mode.
#FEATURES+= -DDEBUG_CERTIFICATE
# Define to add SSL session cache debugging; dump all sessions in debug mode.
#FEATURES+= -DDEBUG_SESSION_CACHE
# Define to add debugging of parsing the SNI from the SSL ClientHello.
#FEATURES+= -DDEBUG_SNI_PARSER
# Define to add thread debugging; dump thread state when choosing a thread.
#FEATURES+= -DDEBUG_THREAD
### Autodetected features
# Autodetect pf
ifneq ($(wildcard /usr/include/net/pfvar.h),)
FEATURES+= -DHAVE_PF
endif
# Autodetect ipfw
ifneq ($(wildcard /sbin/ipfw),)
FEATURES+= -DHAVE_IPFW
endif
# Autodetect ipfilter
ifneq ($(wildcard /usr/include/netinet/ip_fil.h),)
FEATURES+= -DHAVE_IPFILTER
endif
# Autodetect netfilter
ifneq ($(wildcard /usr/include/linux/netfilter.h),)
FEATURES+= -DHAVE_NETFILTER
endif
### Variables you might need to override
PREFIX?= /usr/local
OPENSSL?= openssl
PKGCONFIG?= pkg-config
BASENAME?= basename
CAT?= cat
GREP?= grep
INSTALL?= install
MKDIR?= mkdir
SED?= sed
### Variables only used for developer targets
KHASH_URL?= https://github.com/attractivechaos/klib/raw/master/khash.h
GPGSIGNKEY?= 0xB5D3397E
CPPCHECK?= cppcheck
GPG?= gpg
GIT?= git
WGET?= wget
BZIP2?= bzip2
COL?= col
LN?= ln
MAN?= man
TAR?= tar
### You should not need to touch anything below this line
TARGET:= sslsplit
PNAME:= SSLsplit
SRCS:= $(filter-out $(wildcard *.t.c),$(wildcard *.c))
HDRS:= $(wildcard *.h)
OBJS:= $(SRCS:.c=.o)
TSRCS:= $(wildcard *.t.c)
TOBJS:= $(TSRCS:.t.c=.t.o)
TOBJS+= $(filter-out main.o,$(OBJS))
VFILE:= $(wildcard VERSION)
GITDIR:= $(wildcard .git)
ifdef VFILE
VERSION:= $(shell $(CAT) VERSION)
else
ifndef GITDIR
VERSION:= $(shell $(BASENAME) $(PWD)|\
$(GREP) $(TARGET)-|\
$(SED) 's/.*$(TARGET)-\(.*\)/\1/g')
else
VERSION:= $(shell $(GIT) describe --tags --dirty --always)
endif
CFLAGS+= $(DEBUG_CFLAGS)
endif
BUILD_DATE:= $(shell date +%Y-%m-%d)
# Autodetect dependencies known to pkg-config
PKGS:=
ifndef OPENSSL_BASE
PKGS+= $(shell $(PKGCONFIG) --exists openssl && echo openssl)
endif
ifndef LIBEVENT_BASE
PKGS+= $(shell $(PKGCONFIG) --exists libevent && echo libevent)
PKGS+= $(shell $(PKGCONFIG) --exists libevent_openssl \
&& echo libevent_openssl)
PKGS+= $(shell $(PKGCONFIG) --exists libevent_pthreads \
&& echo libevent_pthreads)
endif
TPKGS:=
ifndef CHECK_BASE
TPKGS+= $(shell $(PKGCONFIG) --exists check && echo check)
endif
# Autodetect dependencies not known to pkg-config
ifeq (,$(filter openssl,$(PKGS)))
OPENSSL_PAT:= include/openssl/ssl.h
ifdef OPENSSL_BASE
OPENSSL_FIND:= $(wildcard $(OPENSSL_BASE)/$(OPENSSL_PAT))
else
OPENSSL_FIND:= $(wildcard \
/opt/local/$(OPENSSL_PAT) \
/usr/local/$(OPENSSL_PAT) \
/usr/$(OPENSSL_PAT))
endif
OPENSSL_FOUND:= $(OPENSSL_FIND:/$(OPENSSL_PAT)=)
ifndef OPENSSL_FOUND
$(error dependency 'OpenSSL' not found; \
install it or point OPENSSL_BASE to base path)
endif
endif
ifeq (,$(filter libevent,$(PKGS)))
LIBEVENT_PAT:= include/event2/event.h
ifdef LIBEVENT_BASE
LIBEVENT_FIND:= $(wildcard $(LIBEVENT_BASE)/$(LIBEVENT_PAT))
else
LIBEVENT_FIND:= $(wildcard \
/opt/local/$(LIBEVENT_PAT) \
/usr/local/$(LIBEVENT_PAT) \
/usr/$(LIBEVENT_PAT))
endif
LIBEVENT_FOUND:=$(LIBEVENT_FIND:/$(LIBEVENT_PAT)=)
ifndef LIBEVENT_FOUND
$(error dependency 'libevent 2.x' not found; \
install it or point LIBEVENT_BASE to base path)
endif
endif
ifeq (,$(filter check,$(TPKGS)))
CHECK_PAT:= include/check.h
ifdef CHECK_BASE
CHECK_FIND:= $(wildcard $(CHECK_BASE)/$(CHECK_PAT))
else
CHECK_FIND:= $(wildcard \
/opt/local/$(CHECK_PAT) \
/usr/local/$(CHECK_PAT) \
/usr/$(CHECK_PAT))
endif
CHECK_FOUND:= $(CHECK_FIND:/$(CHECK_PAT)=)
ifndef CHECK_FOUND
CHECK_MISSING:= 1
endif
endif
ifdef OPENSSL_FOUND
PKG_CPPFLAGS+= -I$(OPENSSL_FOUND)/include
PKG_LDFLAGS+= -L$(OPENSSL_FOUND)/lib
PKG_LIBS+= -lssl -lcrypto -lz
endif
ifdef LIBEVENT_FOUND
PKG_CPPFLAGS+= -I$(LIBEVENT_FOUND)/include
PKG_LDFLAGS+= -L$(LIBEVENT_FOUND)/lib
PKG_LIBS+= -levent
endif
ifeq (,$(filter libevent_openssl,$(PKGS)))
PKG_LIBS+= -levent_openssl
endif
ifeq (,$(filter libevent_pthreads,$(PKGS)))
PKG_LIBS+= -levent_pthreads
endif
ifdef CHECK_FOUND
TPKG_CPPFLAGS+= -I$(CHECK_FOUND)/include
TPKG_LDFLAGS+= -L$(CHECK_FOUND)/lib
TPKG_LIBS+= -lcheck
endif
ifneq (,$(strip $(PKGS)))
PKG_CFLAGS+= $(shell $(PKGCONFIG) --cflags-only-other $(PKGS))
PKG_CPPFLAGS+= $(shell $(PKGCONFIG) --cflags-only-I $(PKGS))
PKG_LDFLAGS+= $(shell $(PKGCONFIG) --libs-only-L --libs-only-other $(PKGS))
PKG_LIBS+= $(shell $(PKGCONFIG) --libs-only-l $(PKGS))
endif
ifneq (,$(strip $(TPKGS)))
TPKG_CFLAGS+= $(shell $(PKGCONFIG) --cflags-only-other $(TPKGS))
TPKG_CPPFLAGS+= $(shell $(PKGCONFIG) --cflags-only-I $(TPKGS))
TPKG_LDFLAGS+= $(shell $(PKGCONFIG) --libs-only-L --libs-only-other $(TPKGS))
TPKG_LIBS+= $(shell $(PKGCONFIG) --libs-only-l $(TPKGS))
endif
PKG_CPPFLAGS:= $(subst -I,-isystem,$(PKG_CPPFLAGS))
TPKG_CPPFLAGS:= $(subst -I,-isystem,$(TPKG_CPPFLAGS))
CFLAGS+= $(PKG_CFLAGS) -pthread \
-std=c99 -Wall -Wextra -pedantic -D_FORTIFY_SOURCE=2
CPPFLAGS+= -D_GNU_SOURCE $(PKG_CPPFLAGS) $(FEATURES) \
-D"BNAME=\"$(TARGET)\"" -D"PNAME=\"$(PNAME)\"" \
-D"VERSION=\"$(VERSION)\"" -D"BUILD_DATE=\"$(BUILD_DATE)\"" \
-D"FEATURES=\"$(FEATURES)\""
LDFLAGS+= $(PKG_LDFLAGS) -pthread
LIBS+= $(PKG_LIBS)
export VERSION
export OPENSSL
export MKDIR
all: version config $(TARGET)
version:
@echo "$(PNAME) $(VERSION)"
config:
@echo "via pkg-config: $(strip $(PKGS) $(TPKGS))"
ifdef OPENSSL_FOUND
@echo "OPENSSL_BASE: $(strip $(OPENSSL_FOUND))"
endif
ifdef LIBEVENT_FOUND
@echo "LIBEVENT_BASE: $(strip $(LIBEVENT_FOUND))"
endif
ifdef CHECK_FOUND
@echo "CHECK_BASE: $(strip $(CHECK_FOUND))"
endif
@echo "Build options: $(FEATURES)"
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
version.o: version.c version.h GNUmakefile $(VFILE) FORCE
%.t.o: %.t.c $(HDRS) GNUmakefile
ifdef CHECK_MISSING
$(error unit test dependency 'check' not found; \
install it or point CHECK_BASE to base path)
endif
$(CC) -c $(CPPFLAGS) $(TPKG_CPPFLAGS) $(CFLAGS) $(TPKG_CFLAGS) -o $@ \
-x c $<
%.o: %.c $(HDRS) GNUmakefile
$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<
test: $(TARGET).test
$(RM) extra/pki/session.pem
$(MAKE) -C extra/pki testreqs session
./$(TARGET).test
$(TARGET).test: $(TOBJS)
$(CC) $(LDFLAGS) $(TPKG_LDFLAGS) -o $@ $^ $(LIBS) $(TPKG_LIBS)
clean:
$(RM) -f $(TARGET) *.o $(TARGET).test *.core *~
$(RM) -rf *.dSYM
install: $(TARGET)
test -d $(PREFIX)/bin || $(MKDIR) -p $(PREFIX)/bin
test -d $(PREFIX)/share/man/man1 || \
$(MKDIR) -p $(PREFIX)/share/man/man1
$(INSTALL) -o 0 -g 0 -m 0755 $(TARGET) $(PREFIX)/bin/
$(INSTALL) -o 0 -g 0 -m 0644 $(TARGET).1 $(PREFIX)/share/man/man1/
deinstall:
$(RM) -f $(PREFIX)/bin/$(TARGET) $(PREFIX)/share/man/man1/$(TARGET).1
ifdef GITDIR
lint:
$(CPPCHECK) --force --enable=all --error-exitcode=1 .
mantest:
$(RM) -f man1
$(LN) -sf . man1
$(MAN) -M . 1 $(TARGET)
$(RM) man1
$(TARGET)-$(VERSION).1.txt: $(TARGET).1
$(RM) -f man1
$(LN) -sf . man1
$(MAN) -M . 1 $(TARGET) | $(COL) -b >$@
$(RM) man1
man: $(TARGET)-$(VERSION).1.txt
manclean:
$(RM) -f $(TARGET)-*.1.txt
fetchdeps:
$(WGET) --no-check-certificate -O- $(KHASH_URL) >khash.h
dist: $(TARGET)-$(VERSION).tar.bz2 $(TARGET)-$(VERSION).tar.bz2.asc
%.asc: %
$(GPG) -u $(GPGSIGNKEY) --armor --output $@ --detach-sig $<
$(TARGET)-$(VERSION).tar.bz2:
$(MKDIR) -p $(TARGET)-$(VERSION)
echo $(VERSION) >$(TARGET)-$(VERSION)/VERSION
$(GIT) archive --prefix=$(TARGET)-$(VERSION)/ HEAD \
>$(TARGET)-$(VERSION).tar
$(TAR) -f $(TARGET)-$(VERSION).tar -r $(TARGET)-$(VERSION)/VERSION
$(BZIP2) <$(TARGET)-$(VERSION).tar >$(TARGET)-$(VERSION).tar.bz2
$(RM) $(TARGET)-$(VERSION).tar
$(RM) -r $(TARGET)-$(VERSION)
disttest: $(TARGET)-$(VERSION).tar.bz2 $(TARGET)-$(VERSION).tar.bz2.asc
$(GPG) --verify $<.asc $<
$(BZIP2) -d < $< | $(TAR) -x -f -
cd $(TARGET)-$(VERSION) && $(MAKE) && $(MAKE) test && ./$(TARGET) -V
$(RM) -r $(TARGET)-$(VERSION)
distclean:
$(RM) -f $(TARGET)-*.tar.bz2*
realclean: distclean manclean clean
$(MAKE) -C extra/pki clean
endif
FORCE:
.PHONY: all config clean test lint install deinstall \
mantest man manclean fetchdeps dist disttest distclean realclean
SSLsplit - transparent and scalable SSL/TLS interception
Copyright (c) 2009-2013, Daniel Roethlisberger <daniel@roe.ch>
All rights reserved.
http://www.roe.ch/SSLsplit
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice unmodified, this list of conditions, and the following
disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
### SSLsplit 0.4.6 2013-06-03
- Fix fallback to passthrough (-P) when no matching certificate is found
for a connection (issue #9).
- Work around segmentation fault when loading certificates caused by a bug
in OpenSSL 1.0.0k and 1.0.1e.
- Fix binding to ports < 1024 with default settings (issue #8).
### SSLsplit 0.4.5 2012-11-07
- Add support for 2048 and 4096 bit Diffie-Hellman.
- Fix syslog error messages (issue #6).
- Fix threading issues in daemon mode (issue #5).
- Fix address family check in netfilter NAT lookup (issue #4).
- Fix build on recent glibc systems (issue #2).
- Minor code and build process improvements.
### SSLsplit 0.4.4 2012-05-11
- Improve OCSP denial for GET based OCSP requests.
- Default elliptic curve is now 'secp160r2' for better ECDH performance.
- More user-friendly handling of -c, -k and friends.
- Unit test source code renamed from *.t to *.t.c to prevent them from being
misdetected as perl instead of c by Github et al.
- Minor bugfixes.
### SSLsplit 0.4.3 2012-04-22
- Add generic OCSP denial (-O). OCSP requests transmitted over HTTP or HTTPS
are recognized and denied with OCSP tryLater(3) responses.
- Minor bugfixes.
### SSLsplit 0.4.2 2012-04-13
- First public release.
SSLsplit - transparent and scalable SSL/TLS interception
Copyright (C) 2009-2013, Daniel Roethlisberger <daniel@roe.ch>
http://www.roe.ch/SSLsplit
## Overview
SSLsplit is a tool for man-in-the-middle attacks against SSL/TLS encrypted
network connections. Connections are transparently intercepted through a
network address translation engine and redirected to SSLsplit. SSLsplit
terminates SSL/TLS and initiates a new SSL/TLS connection to the original
destination address, while logging all data transmitted. SSLsplit is intended
to be useful for network forensics and penetration testing.
SSLsplit supports plain TCP, plain SSL, HTTP and HTTPS connections over both
IPv4 and IPv6. For SSL and HTTPS connections, SSLsplit generates and signs
forged X509v3 certificates on-the-fly, based on the original server certificate
subject DN and subjectAltName extension. SSLsplit fully supports Server Name
Indication (SNI) and is able to work with RSA, DSA and ECDSA keys and DHE and
ECDHE cipher suites. SSLsplit can also use existing certificates of which the
private key is available, instead of generating forged ones. SSLsplit supports
NULL-prefix CN certificates and can deny OCSP requests in a generic way.
See the manual page sslsplit(1) for details on using SSLsplit and setting up
the various NAT engines.
## Requirements
SSLsplit depends on the OpenSSL and libevent 2.x libraries.
The build depends on GNU make and a POSIX.2 environment in `PATH`.
The (optional) unit tests depend on check.
SSLsplit currently supports the following operating systems and NAT engines:
- FreeBSD: pf rdr, ipfw fwd, ipfilter rdr
- OpenBSD: pf rdr
- Linux: netfilter REDIRECT and TPROXY
- Mac OS X: ipfw fwd
## Installation
make
make test # optional unit tests
make install # optional install
Dependencies are autoconfigured using pkg-config. If dependencies are not
picked up and fixing `PKG_CONFIG_PATH` does not help, you can specify their
respective locations manually by setting `OPENSSL_BASE`, `LIBEVENT_BASE` and/or
`CHECK_BASE` to the respective prefixes.
You can override the default install prefix (`/usr/local`) by setting `PREFIX`.
## Development
SSLsplit is being developed on Github. For bug reports, please use the Github
issue tracker. For patch submissions, please send me pull requests.
https://github.com/droe/sslsplit
## License
SSLsplit is provided under the simplified BSD license.
SSLsplit contains components licensed under the MIT license.
See the respective source file headers for details.
## Credits
SSLsplit was inspired by mitm-ssl by Claes M. Nyberg and sslsniff by Moxie
Marlinspike, but shares no source code with them.
SSLsplit includes khash.h by Attractive Chaos.
- Strip HPKP headers from responses to prevent pinning
- Rewrite header munging
- Control SSL_OP_SINGLE_ECDH_USE and other de-optimizations by a
"prefer speed to security" command line option
- Optionally add ephemeral RSA key to SSL_CTX to allow export cipher suites
http://www.openssl.org/docs/ssl/SSL_CTX_set_tmp_rsa_callback.html
- Dump cipher suites sent by the client in debug mode
- Consider memory pools for use by per-connection state
- Parse some information from HTTP responses (status, size)
- Handle renego & client cert authentication more gracefully
- Separate orig cert retrieval from actual fwd address/proto config
- CRL denial mode based on targetdir cert's CDPs or by identifying CRL ASN.1
- Browser update denial mode
- Extendable approach to broken certificate verification implementations
- Client fingerprinting: only intercept clients with headers matching regex
- Configurable and/or scriptable modification of requests and/or responses
- STARTTLS for various protocols
- Sample scripts for single file/fifo content log postprocessing
/*
* SSLsplit - transparent and scalable SSL/TLS interception
* Copyright (c) 2009-2013, Daniel Roethlisberger <daniel@roe.ch>
* All rights reserved.
* http://www.roe.ch/SSLsplit
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ATTRIB_H
#define ATTRIB_H
/*
* GCC attributes and built-ins for improved compile-time error checking
* and performance optimization.
*
* All of these are fully optional and are automatically disabled on non-GCC
* and non-LLVM/clang compilers.
*/
/*
* Attributes.
* These serve to improve the compiler warnings or optimizations.
*/
#if !defined(__GNUC__) && !defined(__clang__)
#define __attribute__(x)
#endif
#define UNUSED __attribute__((unused))
#define NORET __attribute__((noreturn))
#define PRINTF(f,a) __attribute__((format(printf,(f),(a))))
#define SCANF(f,a) __attribute__((format(scanf,(f),(a))))
#define WUNRES __attribute__((warn_unused_result))
#define MALLOC __attribute__((malloc)) WUNRES
#define NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
#define PURE __attribute__((pure))
/*
* Branch prediction macros.
* These serve to tell the compiler which of the branches is more likely.
*/
#if !defined(__GNUC__) && !defined(__clang__)
#define likely(expr) (expr)
#define unlikely(expr) (expr)
#else
#define likely(expr) __builtin_expect((expr), 1)
#define unlikely(expr) __builtin_expect((expr), 0)
#endif
#endif /* !ATTRIB_H */
/* vim: set noet ft=c: */
/*
* SSLsplit - transparent and scalable SSL/TLS interception
* Copyright (c) 2009-2013, Daniel Roethlisberger <daniel@roe.ch>
* All rights reserved.
* http://www.roe.ch/SSLsplit
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
/*
* Base64 encoding functions.
*/
/*
* Base64 decode insz bytes from in.
* Returns allocated buffer containing outsz bytes.
* The buffer is null-terminated, but the terminator is not included in outsz.
* If in does not contain valid Base64 encoded data, returns NULL.
* This is a very strict implementation. Any characters not within the
* Base64 alphabet are considered invalid, including newline and whitespace.
*/
unsigned char *
base64_dec(const char *in, size_t insz, size_t *outsz)
{
static const int revalphabet[] = {
-1, -1, -1, -1, -1, -1, -1, -1, /* 0 .. 7 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 8 .. 15 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 16 .. 23 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 24 .. 31 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 32 .. 39 */
-1, -1, -1, 62, -1, -1, -1, 63, /* 40 .. 47 */
52, 53, 54, 55, 56, 57, 58, 59, /* 48 .. 55 */
60, 61, -1, -1, -1, -1, -1, -1, /* 56 .. 63 */
-1, 0, 1, 2, 3, 4, 5, 6, /* 64 .. 71 */
7, 8, 9, 10, 11, 12, 13, 14, /* 72 .. 79 */
15, 16, 17, 18, 19, 20, 21, 22, /* 80 .. 87 */
23, 24, 25, -1, -1, -1, -1, -1, /* 88 .. 95 */
-1, 26, 27, 28, 29, 30, 31, 32, /* 96 .. 103 */
33, 34, 35, 36, 37, 38, 39, 40, /* 104 .. 111 */
41, 42, 43, 44, 45, 46, 47, 48, /* 112 .. 119 */
49, 50, 51, -1, -1, -1, -1, -1, /* 120 .. 127 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 128 .. 135 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 136 .. 143 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 144 .. 151 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 152 .. 159 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 160 .. 167 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 168 .. 175 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 176 .. 183 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 184 .. 191 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 192 .. 199 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 200 .. 207 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 208 .. 215 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 216 .. 223 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 224 .. 231 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 232 .. 239 */
-1, -1, -1, -1, -1, -1, -1, -1, /* 240 .. 247 */
-1, -1, -1, -1, -1, -1, -1, -1 }; /* 248 .. 255 */
size_t i, o;
int tmp, digit;
unsigned char *out;
if (insz % 4)
return NULL;
if (insz == 0) {
*outsz = 0;
return (unsigned char *)strdup("");
}
if (in[insz - 2] == '=')
*outsz = ((insz / 4) * 3) - 2;
else if (in[insz - 1] == '=')
*outsz = ((insz / 4) * 3) - 1;
else
*outsz = (insz / 4) * 3;
if (!(out = malloc((*outsz) + 1))) {
*outsz = 0;
return NULL;