mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-04-24 00:00:05 +08:00
Squashed 'Sources/OpenVPN3/' content from commit 0a6e0b6e54
git-subtree-dir: Sources/OpenVPN3 git-subtree-split: 0a6e0b6e542c2d19de1f416c4caccd899d72831a
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
README.html
|
||||||
|
x64
|
||||||
|
*.vcxproj.user
|
||||||
|
*.ipch
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
dist: bionic
|
||||||
|
os: linux
|
||||||
|
language: cpp
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- secure: "dqiLqbzug/xs6F4Q9ei1pGpNf9Q6H3+iKN1W+P0TtODbCXPr/mLWdvHGVMIMqr7H7rBrIUPFPrfqd80nu3jQuQonjcHK/XyJJfmf5hUdhGAszSaixhWnGfVmn/VSV7/5+9DGAU3l9S6YZg4lvi12+cOrlblNgx8GeI5VdN/6HBSHkEqKNI56qn3Y+ugSdLeL1opmzlY58vRsCCmpBH8Ronn4tmSyi85/WZXfF43o9FGGJcygdh6QVWA1CDdNMeLTCt9ld+oToUIiFLiUrhfS1JpSvzysz2xsuEntxZaTMDYPyL4+O8Mj/scl6ejLLXzxTNa7AZOgySLBahf+F4b+yhL1deSVuu40MfxPW6XiM1jKy3KPH/GlYgM8CZQ3D1hQIq1CIUg8DgnTa06RUzevsR5DqDvz+EcPanFHE7dHGrPy9Rs/0y59dNHp3qWKjWMoSA06GerbF61XFOb4mcE29053kV8uxqIa5ZShZ/ndoLeVpQ4mZ+/XSkUybysVl0gWrKnnNNEPtqrdmKf+jlmKY0jyRPdwf425Ldn+wcbGw9ZEnkosYzqAhDBDX4OETAKLi8G0FEYECKKQcd1OX+HNvsOIyOAoLOj7H30F8UkPsjR3ysdIEmc6702ly06gDYjWmwQaCigL/1ktRKgf7ePB0HS+8fOa5SML7619kQrGrWA="
|
||||||
|
- PREFIX="${HOME}/opt"
|
||||||
|
- ASIO_VERSION="90f32660cd503494b3707840cfbd5434d8e9dabe"
|
||||||
|
- LZ4_VERSION="1.8.3"
|
||||||
|
- MBEDTLS_VERSION="2.7.5"
|
||||||
|
- MBEDTLS_CFLAGS="-I${PREFIX}/include"
|
||||||
|
- MBEDTLS_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto"
|
||||||
|
- OPENSSL_VERSION="1.0.2s"
|
||||||
|
- OPENSSL_CFLAGS="-I${PREFIX}/include"
|
||||||
|
- OPENSSL_LIBS="-lssl -lcrypto"
|
||||||
|
- COVERITY_BRANCH="master"
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- env: SSLLIB="openssl"
|
||||||
|
os: osx
|
||||||
|
osx_image: xcode10.2
|
||||||
|
compiler: clang
|
||||||
|
- env: SSLLIB="mbedtls"
|
||||||
|
os: osx
|
||||||
|
osx_image: xcode10.2
|
||||||
|
compiler: clang
|
||||||
|
- env: SSLLIB="openssl" RUN_COVERITY_SCAN="1"
|
||||||
|
os: linux
|
||||||
|
compiler: gcc
|
||||||
|
- env: SSLLIB="openssl"
|
||||||
|
os: linux
|
||||||
|
compiler: clang
|
||||||
|
- env: SSLLIB="mbedtls"
|
||||||
|
os: linux
|
||||||
|
compiler: gcc
|
||||||
|
- env: SSLLIB="mbedtls"
|
||||||
|
os: linux
|
||||||
|
compiler: clang
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libboost-all-dev
|
||||||
|
- linux-libc-dev
|
||||||
|
|
||||||
|
cache:
|
||||||
|
ccache: true
|
||||||
|
directories:
|
||||||
|
- download-cache
|
||||||
|
- ${HOME}/opt
|
||||||
|
|
||||||
|
install:
|
||||||
|
- .travis/build-deps.sh
|
||||||
|
|
||||||
|
script:
|
||||||
|
- .travis/build-check.sh
|
||||||
Executable
+75
@@ -0,0 +1,75 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
PREFIX="${PREFIX:-${HOME}/opt}"
|
||||||
|
RUN_COVERITY_SCAN="${RUN_COVERITY_SCAN:-0}"
|
||||||
|
|
||||||
|
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
|
||||||
|
export LD_LIBRARY_PATH="${PREFIX}/lib:${LD_LIBRARY_PATH:-}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
|
||||||
|
export DYLD_LIBRARY_PATH="${PREFIX}/lib:${DYLD_LIBRARY_PATH:-}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "${SSLLIB}" = "openssl" ]; then
|
||||||
|
SSL_LIBS="${OPENSSL_LIBS}"
|
||||||
|
SSL_CFLAGS="-DUSE_OPENSSL"
|
||||||
|
elif [ "${SSLLIB}" = "mbedtls" ]; then
|
||||||
|
SSL_LIBS="${MBEDTLS_LIBS}"
|
||||||
|
SSL_CFLAGS="-DUSE_MBEDTLS"
|
||||||
|
else
|
||||||
|
echo "Invalid crypto lib: ${SSLLIB}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
LIBS="${SSL_LIBS} -llz4"
|
||||||
|
CXXFLAGS="-O3 -std=c++14 -Wall -pthread \
|
||||||
|
-DOPENVPN_SHOW_SESSION_TOKEN -DHAVE_LZ4 \
|
||||||
|
-DUSE_ASIO -DASIO_STANDALONE -DASIO_NO_DEPRECATED ${SSL_CFLAGS}"
|
||||||
|
|
||||||
|
if [ "${CC}" = "gcc" ]; then
|
||||||
|
CXXFLAGS="${CXXFLAGS} -fwhole-program -flto=4"
|
||||||
|
fi
|
||||||
|
|
||||||
|
INCLUDEDIRS="-I../../asio/asio/include -I${PREFIX}/include -I../../"
|
||||||
|
LDFLAGS="-L${PREFIX}/lib"
|
||||||
|
|
||||||
|
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
|
||||||
|
LDFLAGS="${LDFLAGS} -Wl,--no-as-needed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
|
||||||
|
CXXFLAGS="${CXXFLAGS} -stdlib=libc++ -arch x86_64"
|
||||||
|
LIBS="${LIBS} -framework Security \
|
||||||
|
-framework CoreFoundation \
|
||||||
|
-framework SystemConfiguration \
|
||||||
|
-framework IOKit \
|
||||||
|
-framework ApplicationServices"
|
||||||
|
fi
|
||||||
|
|
||||||
|
(
|
||||||
|
cd test/ovpncli
|
||||||
|
${CXX} ${CXXFLAGS} ${INCLUDEDIRS} ${LDFLAGS} cli.cpp -o cli ${LIBS}
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
cd test/ssl
|
||||||
|
${CXX} ${CXXFLAGS} -DNOERR ${INCLUDEDIRS} ${LDFLAGS} proto.cpp -o proto ${LIBS}
|
||||||
|
./proto
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ "${RUN_COVERITY_SCAN}" = "1" -a "${TRAVIS_BRANCH}" = "${COVERITY_BRANCH}" ]; then
|
||||||
|
unset LD_LIBRARY_PATH #don't mess up SSL for curl/wget
|
||||||
|
|
||||||
|
export COVERITY_SCAN_PROJECT_NAME="OpenVPN/openvpn3"
|
||||||
|
export COVERITY_SCAN_BRANCH_PATTERN="${COVERITY_BRANCH}"
|
||||||
|
export COVERITY_SCAN_NOTIFICATION_EMAIL="scan-reports@openvpn.net"
|
||||||
|
export COVERITY_SCAN_BUILD_COMMAND_PREPEND="cd test/ssl"
|
||||||
|
export COVERITY_SCAN_BUILD_COMMAND="${CXX} ${CXXFLAGS} ${INCLUDEDIRS} \
|
||||||
|
${LDFLAGS} proto.cpp -o proto ${LIBS}"
|
||||||
|
|
||||||
|
# Ignore exit code, script exits with 1 if we're not on the right branch
|
||||||
|
curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash || true
|
||||||
|
fi
|
||||||
Executable
+133
@@ -0,0 +1,133 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
# Set defaults
|
||||||
|
PREFIX="${PREFIX:-${HOME}/opt}"
|
||||||
|
|
||||||
|
download_asio () {
|
||||||
|
if [ ! -d "download-cache/asio" ]; then
|
||||||
|
git clone https://github.com/chriskohlhoff/asio.git \
|
||||||
|
download-cache/asio
|
||||||
|
else
|
||||||
|
(
|
||||||
|
cd download-cache/asio
|
||||||
|
if [ "$(git log -1 --format=%H)" != "${ASIO_VERSION}" ]; then
|
||||||
|
git checkout master
|
||||||
|
git pull
|
||||||
|
git checkout ${ASIO_VERSION}
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
build_asio () {
|
||||||
|
(
|
||||||
|
if [ ! -L asio ]; then
|
||||||
|
rm -Rf asio
|
||||||
|
ln -s download-cache/asio asio
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
download_lz4 () {
|
||||||
|
if [ ! -f "download-cache/lz4-${LZ4_VERSION}.tar.gz" ]; then
|
||||||
|
wget "https://github.com/lz4/lz4/archive/v${LZ4_VERSION}.tar.gz" \
|
||||||
|
-O download-cache/lz4-${LZ4_VERSION}.tar.gz
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
build_lz4 () {
|
||||||
|
if [ "$(cat ${PREFIX}/.lz4-version)" != "${LZ4_VERSION}" ]; then
|
||||||
|
tar zxf download-cache/lz4-${LZ4_VERSION}.tar.gz
|
||||||
|
(
|
||||||
|
cd "lz4-${LZ4_VERSION}"
|
||||||
|
make default CC=$CC CXX=$CXX
|
||||||
|
make install PREFIX="${PREFIX}"
|
||||||
|
)
|
||||||
|
echo "${LZ4_VERSION}" > "${PREFIX}/.lz4-version"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
download_mbedtls () {
|
||||||
|
if [ ! -f "download-cache/mbedtls-${MBEDTLS_VERSION}-apache.tgz" ]; then
|
||||||
|
wget -P download-cache/ \
|
||||||
|
"https://tls.mbed.org/download/mbedtls-${MBEDTLS_VERSION}-apache.tgz"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
build_mbedtls () {
|
||||||
|
if [ "$(cat ${PREFIX}/.mbedtls-version)" != "${MBEDTLS_VERSION}" ]; then
|
||||||
|
tar zxf download-cache/mbedtls-${MBEDTLS_VERSION}-apache.tgz
|
||||||
|
(
|
||||||
|
cd "mbedtls-${MBEDTLS_VERSION}"
|
||||||
|
make CC=$CC CXX=$CXX
|
||||||
|
make install DESTDIR="${PREFIX}"
|
||||||
|
)
|
||||||
|
echo "${MBEDTLS_VERSION}" > "${PREFIX}/.mbedtls-version"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
download_openssl () {
|
||||||
|
if [ ! -f "download-cache/openssl-${OPENSSL_VERSION}.tar.gz" ]; then
|
||||||
|
wget -P download-cache/ \
|
||||||
|
"https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
build_openssl_linux () {
|
||||||
|
(
|
||||||
|
cd "openssl-${OPENSSL_VERSION}/"
|
||||||
|
./config shared --prefix="${PREFIX}" --openssldir="${PREFIX}" -DPURIFY
|
||||||
|
make all install_sw
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
build_openssl_osx () {
|
||||||
|
(
|
||||||
|
cd "openssl-${OPENSSL_VERSION}/"
|
||||||
|
./Configure darwin64-x86_64-cc shared \
|
||||||
|
--prefix="${PREFIX}" --openssldir="${PREFIX}" -DPURIFY
|
||||||
|
make depend all install_sw
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
build_openssl () {
|
||||||
|
if [ "$(cat ${PREFIX}/.openssl-version)" != "${OPENSSL_VERSION}" ]; then
|
||||||
|
tar zxf "download-cache/openssl-${OPENSSL_VERSION}.tar.gz"
|
||||||
|
if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
|
||||||
|
build_openssl_osx
|
||||||
|
elif [ "${TRAVIS_OS_NAME}" = "linux" ]; then
|
||||||
|
build_openssl_linux
|
||||||
|
fi
|
||||||
|
echo "${OPENSSL_VERSION}" > "${PREFIX}/.openssl-version"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enable ccache
|
||||||
|
if [ "${TRAVIS_OS_NAME}" != "osx" ] && [ -z ${CHOST+x} ]; then
|
||||||
|
# ccache not available on osx, see:
|
||||||
|
# https://github.com/travis-ci/travis-ci/issues/5567
|
||||||
|
# also ccache not enabled for cross builds
|
||||||
|
mkdir -p "${HOME}/bin"
|
||||||
|
ln -s "$(which ccache)" "${HOME}/bin/${CXX}"
|
||||||
|
ln -s "$(which ccache)" "${HOME}/bin/${CC}"
|
||||||
|
PATH="${HOME}/bin:${PATH}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Download and build crypto lib
|
||||||
|
if [ "${SSLLIB}" = "openssl" ]; then
|
||||||
|
download_openssl
|
||||||
|
build_openssl
|
||||||
|
elif [ "${SSLLIB}" = "mbedtls" ]; then
|
||||||
|
download_mbedtls
|
||||||
|
build_mbedtls
|
||||||
|
else
|
||||||
|
echo "Invalid crypto lib: ${SSLLIB}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
download_asio
|
||||||
|
build_asio
|
||||||
|
|
||||||
|
download_lz4
|
||||||
|
build_lz4
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
Contributor agreement for the OpenVPN project version 1.3 - December 2017
|
||||||
|
#########################################################################
|
||||||
|
|
||||||
|
This Contributor Agreement consists of two parts. Part I is the
|
||||||
|
Developer Certificate of Origin available at
|
||||||
|
http://developercertificate.org/.
|
||||||
|
|
||||||
|
In this contributor agreement, "This project" refers to the OpenVPN
|
||||||
|
project and
|
||||||
|
"open source license indicated in `the file <LICENSE.rst>`_" refers to
|
||||||
|
the AGPLv3 license with an additional permission that allows linking
|
||||||
|
the OpenSSL software, https://www.openssl.org/, with the OpenVPN
|
||||||
|
software.
|
||||||
|
|
||||||
|
Part I
|
||||||
|
######
|
||||||
|
|
||||||
|
Developer Certificate of Origin Version 1.1
|
||||||
|
|
||||||
|
Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 1
|
||||||
|
Letterman Drive Suite D4700 San Francisco, CA, 94129
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Developer's Certificate of Origin 1.1
|
||||||
|
|
||||||
|
By making a contribution to this project, I certify that:
|
||||||
|
|
||||||
|
(a) The contribution was created in whole or in part by me and I have
|
||||||
|
the right to submit it under the open source license indicated in the
|
||||||
|
file; or
|
||||||
|
|
||||||
|
(b) The contribution is based upon previous work that, to the best of
|
||||||
|
my knowledge, is covered under an appropriate open source license and
|
||||||
|
I have the right under that license to submit that work with
|
||||||
|
modifications, whether created in whole or in part by me, under the
|
||||||
|
same open source license (unless I am permitted to submit under a
|
||||||
|
different license), as indicated in the file; or
|
||||||
|
|
||||||
|
(c) The contribution was provided directly to me by some other person
|
||||||
|
who certified (a), (b) or (c) and I have not modified it.
|
||||||
|
|
||||||
|
(d) I understand and agree that this project and the contribution are
|
||||||
|
public and that a record of the contribution (including all personal
|
||||||
|
information I submit with it, including my sign-off) is maintained
|
||||||
|
indefinitely and may be redistributed consistent with this project or
|
||||||
|
the open source license(s) involved.
|
||||||
|
|
||||||
|
Part II
|
||||||
|
#######
|
||||||
|
|
||||||
|
Copyright (C) 2017 OpenVPN Inc.
|
||||||
|
|
||||||
|
In addition:
|
||||||
|
|
||||||
|
(e) I understand that OpenVPN Inc. may relicense this project, this
|
||||||
|
contribution, and any modification to it under any license. I certify that I,
|
||||||
|
or the person on whose behalf I am submitting the contribution, have the
|
||||||
|
right to grant and hereby grant OpenVPN Inc. a license to do so for this
|
||||||
|
contribution. My grant is made on the condition that OpenVPN Inc. will make
|
||||||
|
any modification to this contribution available to the OpenVPN project under
|
||||||
|
the open source license indicated in the file.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Cmake in OpenVPN3 core is mainly used to get Clion editior support and to run unit tests. For normal
|
||||||
|
# Build instructions see the README.rst
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
add_subdirectory(test/unittests)
|
||||||
|
add_subdirectory(test/ovpncli)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Contributing to OpenVPN 3
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Patches can be sent as GitHub pull requests.
|
||||||
|
|
||||||
|
Note that by contributing to the OpenVPN 3 project you accept the Contributor
|
||||||
|
License Agreement described in `CLA.rst <CLA.rst>`_.
|
||||||
@@ -0,0 +1,661 @@
|
|||||||
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU Affero General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works, specifically designed to ensure
|
||||||
|
cooperation with the community in the case of network server software.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
our General Public Licenses are intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
Developers that use our General Public Licenses protect your rights
|
||||||
|
with two steps: (1) assert copyright on the software, and (2) offer
|
||||||
|
you this License which gives you legal permission to copy, distribute
|
||||||
|
and/or modify the software.
|
||||||
|
|
||||||
|
A secondary benefit of defending all users' freedom is that
|
||||||
|
improvements made in alternate versions of the program, if they
|
||||||
|
receive widespread use, become available for other developers to
|
||||||
|
incorporate. Many developers of free software are heartened and
|
||||||
|
encouraged by the resulting cooperation. However, in the case of
|
||||||
|
software used on network servers, this result may fail to come about.
|
||||||
|
The GNU General Public License permits making a modified version and
|
||||||
|
letting the public access it on a server without ever releasing its
|
||||||
|
source code to the public.
|
||||||
|
|
||||||
|
The GNU Affero General Public License is designed specifically to
|
||||||
|
ensure that, in such cases, the modified source code becomes available
|
||||||
|
to the community. It requires the operator of a network server to
|
||||||
|
provide the source code of the modified version running there to the
|
||||||
|
users of that server. Therefore, public use of a modified version, on
|
||||||
|
a publicly accessible server, gives the public access to the source
|
||||||
|
code of the modified version.
|
||||||
|
|
||||||
|
An older license, called the Affero General Public License and
|
||||||
|
published by Affero, was designed to accomplish similar goals. This is
|
||||||
|
a different license, not a version of the Affero GPL, but Affero has
|
||||||
|
released a new version of the Affero GPL which permits relicensing under
|
||||||
|
this license.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, if you modify the
|
||||||
|
Program, your modified version must prominently offer all users
|
||||||
|
interacting with it remotely through a computer network (if your version
|
||||||
|
supports such interaction) an opportunity to receive the Corresponding
|
||||||
|
Source of your version by providing access to the Corresponding Source
|
||||||
|
from a network server at no charge, through some standard or customary
|
||||||
|
means of facilitating copying of software. This Corresponding Source
|
||||||
|
shall include the Corresponding Source for any work covered by version 3
|
||||||
|
of the GNU General Public License that is incorporated pursuant to the
|
||||||
|
following paragraph.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the work with which it is combined will remain governed by version
|
||||||
|
3 of the GNU General Public License.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU Affero General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU Affero General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU Affero General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU Affero General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If your software can interact with users remotely through a computer
|
||||||
|
network, you should also make sure that it provides a way for users to
|
||||||
|
get its source. For example, if your program is a web application, its
|
||||||
|
interface could display a "Source" link that leads users to an archive
|
||||||
|
of the code. There are many ways you could offer source, and different
|
||||||
|
solutions will be better for different programs; see section 13 for the
|
||||||
|
specific requirements.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
OpenVPN 3 is distributed under
|
||||||
|
`GNU Affero General Public License version 3 <COPYRIGHT.AGPLV3>`_
|
||||||
|
with a special permission to link against OpenSSL:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Additional permission under GNU AGPL version 3 section 7
|
||||||
|
|
||||||
|
If you modify this Program, or any covered work, by linking or combining
|
||||||
|
it with OpenSSL (or a modified version of that library), containing parts
|
||||||
|
covered by the terms of the OpenSSL License or the Original SSLeay License,
|
||||||
|
the licensors of this Program grant you additional permission to convey the
|
||||||
|
resulting work. Corresponding Source for a non-source form of such a
|
||||||
|
combination shall include the source code for the parts of OpenSSL used as
|
||||||
|
well as that of the covered work.
|
||||||
+617
@@ -0,0 +1,617 @@
|
|||||||
|
OpenVPN 3
|
||||||
|
=========
|
||||||
|
|
||||||
|
OpenVPN 3 is a C++ class library that implements the functionality
|
||||||
|
of an OpenVPN client, and is protocol-compatible with the OpenVPN
|
||||||
|
2.x branch.
|
||||||
|
|
||||||
|
OpenVPN 3 includes a minimal client wrapper (``cli``) that links in with
|
||||||
|
the library and provides basic command line functionality.
|
||||||
|
|
||||||
|
OpenVPN 3 is currently used in production as the core of the
|
||||||
|
OpenVPN Connect clients for iOS, Android, Linux, Windows, and Mac OS X.
|
||||||
|
|
||||||
|
NOTE: As of 2017, OpenVPN 3 is primarily of interest to developers,
|
||||||
|
as it does not yet replicate the full functionality of OpenVPN 2.x.
|
||||||
|
In particular, server functionality is not yet implemented.
|
||||||
|
|
||||||
|
.. contents:: Table of Contents
|
||||||
|
|
||||||
|
OpenVPN 3 Client API
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
OpenVPN 3 is organized as a C++ class library, and the API is defined in
|
||||||
|
`<client/ovpncli.hpp>`_.
|
||||||
|
|
||||||
|
A simple command-line wrapper for the API is provided in
|
||||||
|
`<test/ovpncli/cli.cpp>`_.
|
||||||
|
|
||||||
|
Building the OpenVPN 3 client on Linux
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
These instructions were tested on Ubuntu 16.
|
||||||
|
|
||||||
|
Get prerequisites to allow for either mbedTLS or OpenSSL linkage::
|
||||||
|
|
||||||
|
$ sudo apt-get install g++ make libmbedtls-dev libssl-dev liblz4-dev
|
||||||
|
|
||||||
|
Get Asio C++ library::
|
||||||
|
|
||||||
|
$ cd ~
|
||||||
|
$ git clone https://github.com/chriskohlhoff/asio.git
|
||||||
|
|
||||||
|
Set environmental variable used by OpenVPN 3 build scripts::
|
||||||
|
|
||||||
|
$ export O3=~/ovpn3
|
||||||
|
|
||||||
|
Clone the OpenVPN 3 source repo::
|
||||||
|
|
||||||
|
$ mkdir ~/ovpn3
|
||||||
|
$ cd ~/ovpn3
|
||||||
|
$ git clone https://github.com/OpenVPN/openvpn3.git core
|
||||||
|
|
||||||
|
Build the OpenVPN 3 client wrapper (cli) with mbedTLS crypto/ssl library
|
||||||
|
and LZ4 compression::
|
||||||
|
|
||||||
|
$ cd $O3/core/test/ovpncli
|
||||||
|
$ ECHO=1 PROF=linux ASIO_DIR=~/asio MTLS_SYS=1 LZ4_SYS=1 NOSSL=1 $O3/core/scripts/build cli
|
||||||
|
|
||||||
|
Or alternatively build with OpenSSL::
|
||||||
|
|
||||||
|
$ cd $O3/core/test/ovpncli
|
||||||
|
$ ECHO=1 PROF=linux ASIO_DIR=~/asio OPENSSL_SYS=1 LZ4_SYS=1 $O3/core/scripts/build cli
|
||||||
|
|
||||||
|
Run OpenVPN 3 client::
|
||||||
|
|
||||||
|
$ sudo ./cli -a -c yes myprofile.ovpn route-nopull
|
||||||
|
|
||||||
|
Options used::
|
||||||
|
|
||||||
|
-a : use autologin sessions, if supported
|
||||||
|
-c yes : negotiate LZ4 compression
|
||||||
|
myprofile.ovpn : OpenVPN config file (must have .ovpn extension)
|
||||||
|
route-nopull : if you are connected via ssh, prevent ssh session lockout
|
||||||
|
|
||||||
|
|
||||||
|
Building the OpenVPN 3 client on Mac OS X
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
OpenVPN 3 should be built in a non-root Mac OS X account.
|
||||||
|
Make sure that Xcode is installed with optional command-line tools.
|
||||||
|
(These instructions have been tested with Xcode 5.1.1).
|
||||||
|
|
||||||
|
Create the directories ``~/src`` and ``~/src/mac``::
|
||||||
|
|
||||||
|
$ mkdir -p ~/src/mac
|
||||||
|
|
||||||
|
Clone the OpenVPN 3 repo::
|
||||||
|
|
||||||
|
$ cd ~/src
|
||||||
|
$ mkdir ovpn3
|
||||||
|
$ cd ovpn3
|
||||||
|
$ git clone https://github.com/OpenVPN/openvpn3.git core
|
||||||
|
|
||||||
|
Export the shell variable ``O3`` to point to the OpenVPN 3 top level
|
||||||
|
directory::
|
||||||
|
|
||||||
|
export O3=~/src/ovpn3
|
||||||
|
|
||||||
|
Download source tarballs (``.tar.gz`` or ``.tgz``) for these dependency
|
||||||
|
libraries into ``~/Downloads``
|
||||||
|
|
||||||
|
See the file ``$O3/core/deps/lib-versions`` for the expected
|
||||||
|
version numbers of each dependency. If you want to use a different
|
||||||
|
version of the library than listed here, you can edit this file.
|
||||||
|
|
||||||
|
1. Asio — https://github.com/chriskohlhoff/asio
|
||||||
|
2. mbed TLS (2.3.0 or higher) — https://tls.mbed.org/
|
||||||
|
3. LZ4 — https://github.com/Cyan4973/lz4
|
||||||
|
|
||||||
|
For dependencies that are typically cloned from github vs.
|
||||||
|
provided as a .tar.gz file, tools are provided to convert
|
||||||
|
the github to a .tar.gz file. See "snapshot" scripts under
|
||||||
|
``$O3/core/deps``
|
||||||
|
|
||||||
|
Note that while OpenSSL is listed in lib-versions, it is
|
||||||
|
not required for Mac builds.
|
||||||
|
|
||||||
|
Build the dependencies::
|
||||||
|
|
||||||
|
$ DL=~/Downloads
|
||||||
|
$ OSX_ONLY=1 $O3/core/scripts/mac/build-all
|
||||||
|
|
||||||
|
Now build the OpenVPN 3 client executable::
|
||||||
|
|
||||||
|
$ cd $O3/core
|
||||||
|
$ . vars/vars-osx64
|
||||||
|
$ . vars/setpath
|
||||||
|
$ cd test/ovpncli
|
||||||
|
$ MTLS=1 LZ4=1 ASIO=1 build cli
|
||||||
|
|
||||||
|
This will build the OpenVPN 3 client library with a small client
|
||||||
|
wrapper (``cli``). It will also statically link in all external
|
||||||
|
dependencies (Asio, mbedTLS, and LZ4), so ``cli`` may be distributed
|
||||||
|
to other Macs and will run as a standalone executable.
|
||||||
|
|
||||||
|
These build scripts will create a **x86_x64** Mac OS X executable,
|
||||||
|
with a minimum deployment target of 10.8.x. The Mac OS X tuntap driver is not
|
||||||
|
required, as OpenVPN 3 can use the integrated utun interface if
|
||||||
|
available.
|
||||||
|
|
||||||
|
To view the client wrapper options::
|
||||||
|
|
||||||
|
$ ./cli -h
|
||||||
|
|
||||||
|
To connect::
|
||||||
|
|
||||||
|
$ ./cli client.ovpn
|
||||||
|
|
||||||
|
|
||||||
|
Building the OpenVPN 3 client on Windows
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
|
||||||
|
* Visual Studio 2017
|
||||||
|
* Python 2.7
|
||||||
|
* Perl (for building openssl)
|
||||||
|
|
||||||
|
Clone the OpenVPN 3 source repo::
|
||||||
|
|
||||||
|
> c:\Temp>mkdir O3
|
||||||
|
> c:\Temp>cd O3
|
||||||
|
> c:\Temp\O3>git clone https://github.com/OpenVPN/openvpn3.git core
|
||||||
|
|
||||||
|
Add environment variable ``O3`` with value ``c:\Temp\O3`` and reopen commmand prompt.
|
||||||
|
|
||||||
|
Download and build dependencies::
|
||||||
|
|
||||||
|
> c:\Temp\O3>cd core\win
|
||||||
|
> c:\Temp\O3\core\win>set STATIC=1&& set DEBUG=1&& python buildep.py
|
||||||
|
|
||||||
|
Now you can open project in Visual Studio. Project and solution files are
|
||||||
|
located in ``O3\core\win`` directory.
|
||||||
|
|
||||||
|
You can also build the test client from command prompt::
|
||||||
|
|
||||||
|
> c:\Temp\O3\core\win>set STATIC=1&& set DEBUG=1&& python build.py
|
||||||
|
|
||||||
|
Testing
|
||||||
|
-------
|
||||||
|
|
||||||
|
The OpenVPN 3 core includes a stress/performance test of
|
||||||
|
the OpenVPN protocol implementation. The test basically
|
||||||
|
creates a virtualized lossy network between two OpenVPN
|
||||||
|
protocol objects, triggers TLS negotiations between them,
|
||||||
|
passes control/data channel messages, and measures the ability
|
||||||
|
of the OpenVPN protocol objects to perform and remain in
|
||||||
|
a valid state.
|
||||||
|
|
||||||
|
The OpenVPN protocol implementation that is being tested
|
||||||
|
is here: `<openvpn/ssl/proto.hpp>`_
|
||||||
|
|
||||||
|
The test code itself is here: `<test/ssl/proto.cpp>`_
|
||||||
|
|
||||||
|
Build the test::
|
||||||
|
|
||||||
|
$ cd ovpn3/core/test/ssl
|
||||||
|
$ ECHO=1 PROF=linux ASIO_DIR=~/asio MTLS_SYS=1 NOSSL=1 $O3/core/scripts/build proto
|
||||||
|
|
||||||
|
Run the test::
|
||||||
|
|
||||||
|
$ time ./proto
|
||||||
|
*** app bytes=72777936 net_bytes=122972447 data_bytes=415892854 prog=0000216599/0000216598 D=12700/600/12700/600 N=109/109 SH=17400/15300 HE=0/0
|
||||||
|
|
||||||
|
real 0m15.813s
|
||||||
|
user 0m15.800s
|
||||||
|
sys 0m0.004s
|
||||||
|
|
||||||
|
The OpenVPN 3 core also includes unit tests, which are based on
|
||||||
|
Google Test framework. To run unit tests, you need to install
|
||||||
|
CMake and build Google Test.
|
||||||
|
|
||||||
|
Building Google Test on Linux::
|
||||||
|
|
||||||
|
$ git clone https://github.com/google/googletest.git
|
||||||
|
$ cd googletest
|
||||||
|
$ cmake . && cmake --build .
|
||||||
|
|
||||||
|
Building Google Test on Windows::
|
||||||
|
|
||||||
|
> git clone https://github.com/google/googletest.git
|
||||||
|
> cd googletest
|
||||||
|
> cmake -G "Visual Studio 14 2015 Win64" .
|
||||||
|
> cmake --build .
|
||||||
|
|
||||||
|
After Google Test is built you are ready to build and run unit tests.
|
||||||
|
|
||||||
|
Build and run tests on Linux::
|
||||||
|
|
||||||
|
$ cd ovpn3/core/test/unittests
|
||||||
|
$ GTEST_DIR=~/googletest ECHO=1 PROF=linux ASIO_DIR=~/asio MTLS_SYS=1 LZ4_SYS=1 NOSSL=1 $O3/core/scripts/build test_log
|
||||||
|
$ ./test_log
|
||||||
|
|
||||||
|
Build and run tests on Windows::
|
||||||
|
|
||||||
|
$ cd ovpn3/core/win
|
||||||
|
$ python build.py ../test/unittests/test_log.cpp unittest
|
||||||
|
$ test_log.exe
|
||||||
|
|
||||||
|
Developer Guide
|
||||||
|
---------------
|
||||||
|
|
||||||
|
OpenVPN 3 is written in C++11 and developers who are moving
|
||||||
|
from C to C++ should take some time to familiarize themselves with
|
||||||
|
key C++ design patterns such as *RAII*:
|
||||||
|
|
||||||
|
https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization
|
||||||
|
|
||||||
|
OpenVPN 3 Client Core
|
||||||
|
+++++++++++++++++++++
|
||||||
|
|
||||||
|
OpenVPN 3 is designed as a class library, with an API that
|
||||||
|
is essentially defined inside of namespace ``ClientAPI``
|
||||||
|
with headers and implementation in `<client>`_ and
|
||||||
|
header-only library files under `<openvpn>`_.
|
||||||
|
|
||||||
|
The consise definition of the client API is essentially ``class OpenVPNClient``
|
||||||
|
in `<client/ovpncli.hpp>`_ with several imporant extensions to
|
||||||
|
the API found in:
|
||||||
|
|
||||||
|
* **class TunBuilderBase** in `<openvpn/tun/builder/base.hpp>`_ —
|
||||||
|
Provides an abstraction layer defining the *tun* interface,
|
||||||
|
and is especially useful for interfacing with an OS-layer VPN API.
|
||||||
|
|
||||||
|
* **class ExternalPKIBase** in `<openvpn/pki/epkibase.hpp>`_ —
|
||||||
|
Provides a callback for external private key operations, and
|
||||||
|
is useful for interfacing with an OS-layer Keychain such as
|
||||||
|
the Keychain on iOS, Mac OS X, and Android, and the Crypto API
|
||||||
|
on Windows.
|
||||||
|
|
||||||
|
* **class LogReceiver** in `<client/ovpncli.hpp>`_ —
|
||||||
|
Provides an abstraction layer for the delivery of logging messages.
|
||||||
|
|
||||||
|
OpenVPN 3 includes a command-line reference client (``cli``) for
|
||||||
|
testing the API. See `<test/ovpncli/cli.cpp>`_.
|
||||||
|
|
||||||
|
The basic approach to building an OpenVPN 3 client is
|
||||||
|
to define a client class that derives from
|
||||||
|
``ClientAPI::OpenVPNClient``, then provide implementations
|
||||||
|
for callbacks including event and logging notifications:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
class Client : public ClientAPI::OpenVPNClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void event(const Event&) override { // events delivered here
|
||||||
|
...
|
||||||
|
}
|
||||||
|
virtual void log(const LogInfo&) override { // logging delivered here
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
To start the client, first create a ``ClientAPI::Config`` object
|
||||||
|
and initialize it with the OpenVPN config file and other options:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
ClientAPI::Config config;
|
||||||
|
config.content = <config_file_content_as_multiline_string>;
|
||||||
|
...
|
||||||
|
|
||||||
|
Next, create a client object and evaluate the configuration:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
Client client;
|
||||||
|
ClientAPI::EvalConfig eval = client.eval_config(config);
|
||||||
|
if (eval.error)
|
||||||
|
throw ...;
|
||||||
|
|
||||||
|
Finally, in a new worker thread, start the connection:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
ClientAPI::Status connect_status = client.connect();
|
||||||
|
|
||||||
|
Note that ``client.connect()`` will not return until
|
||||||
|
the session has terminated.
|
||||||
|
|
||||||
|
Top Layer
|
||||||
|
.........
|
||||||
|
|
||||||
|
The top layer of the OpenVPN 3 client is implemented
|
||||||
|
in `<test/ovpncli/cli.cpp>`_ and `<openvpn/client/cliopt.hpp>`_.
|
||||||
|
Most of what this code does is marshalling the configuration and
|
||||||
|
dispatching the higher-level objects that implement the OpenVPN
|
||||||
|
client session.
|
||||||
|
|
||||||
|
Connection
|
||||||
|
..........
|
||||||
|
|
||||||
|
``class ClientConnect`` in `<openvpn/client/cliconnect.hpp>`_
|
||||||
|
implements the top-level connection logic for an OpenVPN client
|
||||||
|
connection. It is concerned with starting, stopping, pausing, and resuming
|
||||||
|
OpenVPN client connections. It deals with retrying a connection and handles
|
||||||
|
the connection timeout. It also deals with connection exceptions and understands
|
||||||
|
the difference between an exception that should halt any further reconnection
|
||||||
|
attempts (such as ``AUTH_FAILED``), and other exceptions such as network errors
|
||||||
|
that would justify a retry.
|
||||||
|
|
||||||
|
Some of the methods in the class
|
||||||
|
(such as ``stop``, ``pause``, and ``reconnect``) are often
|
||||||
|
called by another thread that is controlling the connection, therefore
|
||||||
|
thread-safe methods are provided where the thread-safe function posts a message
|
||||||
|
to the actual connection thread.
|
||||||
|
|
||||||
|
In an OpenVPN client connection, the following object stack would be used:
|
||||||
|
|
||||||
|
1. **class ClientConnect** in `<openvpn/client/cliconnect.hpp>`_ —
|
||||||
|
The top-layer object in an OpenVPN client connection.
|
||||||
|
2. **class ClientProto::Session** in `<openvpn/client/cliproto.hpp>`_ —
|
||||||
|
The OpenVPN client protocol object that subinstantiates the transport
|
||||||
|
and tun layer objects.
|
||||||
|
3. **class ProtoContext** in `<openvpn/ssl/proto.hpp>`_ —
|
||||||
|
The core OpenVPN protocol implementation that is common to both
|
||||||
|
client and server.
|
||||||
|
4. **class ProtoStackBase<Packet>** in `<openvpn/ssl/protostack.hpp>`_ —
|
||||||
|
The bottom-layer class that implements
|
||||||
|
the basic functionality of tunneling a protocol over a reliable or
|
||||||
|
unreliable transport layer, but isn't specific to OpenVPN per-se.
|
||||||
|
|
||||||
|
Transport Layer
|
||||||
|
...............
|
||||||
|
|
||||||
|
OpenVPN 3 defines abstract base classes for Transport layer
|
||||||
|
implementations in `<openvpn/transport/client/transbase.hpp>`_.
|
||||||
|
|
||||||
|
Currently, transport layer implementations are provided for:
|
||||||
|
|
||||||
|
* **UDP** — `<openvpn/transport/client/udpcli.hpp>`_
|
||||||
|
* **TCP** — `<openvpn/transport/client/tcpcli.hpp>`_
|
||||||
|
* **HTTP Proxy** — `<openvpn/transport/client/httpcli.hpp>`_
|
||||||
|
|
||||||
|
Tun Layer
|
||||||
|
.........
|
||||||
|
|
||||||
|
OpenVPN 3 defines abstract base classes for Tun layer
|
||||||
|
implementations in `<openvpn/tun/client/tunbase.hpp>`_.
|
||||||
|
|
||||||
|
There are two possible approaches to define a Tun
|
||||||
|
layer implementation:
|
||||||
|
|
||||||
|
1. Use a VPN API-centric model (such as for Android
|
||||||
|
or iOS). These models derive from **class TunBuilderBase**
|
||||||
|
in `<openvpn/tun/builder/base.hpp>`_
|
||||||
|
|
||||||
|
2. Use an OS-specific model such as:
|
||||||
|
|
||||||
|
* **Linux** — `<openvpn/tun/linux/client/tuncli.hpp>`_
|
||||||
|
* **Windows** — `<openvpn/tun/win/client/tuncli.hpp>`_
|
||||||
|
* **Mac OS X** — `<openvpn/tun/mac/client/tuncli.hpp>`_
|
||||||
|
|
||||||
|
Protocol Layer
|
||||||
|
..............
|
||||||
|
|
||||||
|
The OpenVPN protocol is implemented in **class ProtoContext**
|
||||||
|
in `<openvpn/ssl/proto.hpp>`_.
|
||||||
|
|
||||||
|
Options Processing
|
||||||
|
..................
|
||||||
|
|
||||||
|
The parsing and query of the OpenVPN config file
|
||||||
|
is implemented by ``class OptionList`` in
|
||||||
|
`<openvpn/common/options.hpp>`_.
|
||||||
|
|
||||||
|
Note that OpenVPN 3 always assumes an *inline* style of
|
||||||
|
configuration, where all certs, keys, etc. are
|
||||||
|
defined inline rather than through an external file
|
||||||
|
reference.
|
||||||
|
|
||||||
|
For config files that do use external file references,
|
||||||
|
``class ProfileMerge`` in `<openvpn/options/merge.hpp>`_
|
||||||
|
is provided to merge those external
|
||||||
|
file references into an inline form.
|
||||||
|
|
||||||
|
Calling the Client API from other languages
|
||||||
|
...........................................
|
||||||
|
|
||||||
|
The OpenVPN 3 client API, as defined by ``class OpenVPNClient``
|
||||||
|
in `<client/ovpncli.hpp>`_, can be wrapped by the
|
||||||
|
Swig_ tool to create bindings for other languages.
|
||||||
|
|
||||||
|
.. _Swig: http://www.swig.org/
|
||||||
|
|
||||||
|
For example, OpenVPN Connect for Android creates a Java
|
||||||
|
binding of the API using `<javacli/ovpncli.i>`_.
|
||||||
|
|
||||||
|
Security
|
||||||
|
++++++++
|
||||||
|
|
||||||
|
When developing security software in C++, it's very important to
|
||||||
|
take advantage of the language and OpenVPN library code
|
||||||
|
to insulate code from the kinds of
|
||||||
|
bugs that can introduce security vulnerabilities.
|
||||||
|
|
||||||
|
Here is a brief set of guidelines:
|
||||||
|
|
||||||
|
* When dealing with strings, use a ``std::string``
|
||||||
|
rather than a ``char *``.
|
||||||
|
|
||||||
|
* When dealing with binary data or buffers, always try to use a ``Buffer``,
|
||||||
|
``ConstBuffer``, ``BufferAllocated``, or ``BufferPtr`` object to
|
||||||
|
provide managed access to the buffer, to protect against security
|
||||||
|
bugs that arise when using raw buffer pointers.
|
||||||
|
See `<openvpn/buffer/buffer.hpp>`_ for the OpenVPN ``Buffer`` classes.
|
||||||
|
|
||||||
|
* When it's necessary to have a pointer to an object, use
|
||||||
|
``std::unique_ptr<>`` for non-shared objects and reference-counted
|
||||||
|
smart pointers for shared objects. For shared-pointers,
|
||||||
|
OpenVPN code should use the smart pointer classes defined
|
||||||
|
in `<openvpn/common/rc.hpp>`_. Please see the comments in
|
||||||
|
this file for documentation.
|
||||||
|
|
||||||
|
* Never use ``malloc`` or ``free``. When allocating objects,
|
||||||
|
use the C++ ``new`` operator and then immediately construct
|
||||||
|
a smart pointer to reference the object:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
std::unique_ptr<MyObject> ptr = new MyObject();
|
||||||
|
ptr->method();
|
||||||
|
|
||||||
|
* When interfacing with C functions that deal with
|
||||||
|
raw pointers, memory allocation, etc., consider wrapping
|
||||||
|
the functionality in C++. For an example, see ``enum_dir()``
|
||||||
|
in `<openvpn/common/enumdir.hpp>`_,
|
||||||
|
a function that returns a list of files in
|
||||||
|
a directory (Unix only) via a high-level
|
||||||
|
string vector, while internally calling
|
||||||
|
the low level libc methods
|
||||||
|
``opendir``, ``readdir``, and ``closedir``.
|
||||||
|
Notice how ``unique_ptr_del`` is used to wrap the
|
||||||
|
``DIR`` struct in a smart pointer with a custom
|
||||||
|
deletion function.
|
||||||
|
|
||||||
|
* When grabbing random entropy that is to be used
|
||||||
|
for cryptographic purposes (i.e. for keys, tokens, etc.),
|
||||||
|
always ensure that the RNG is crypto-grade by calling
|
||||||
|
``assert_crypto()`` on the RNG. This will throw
|
||||||
|
an exception if the RNG is not crypto-grade:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
void set_rng(RandomAPI::Ptr rng_arg) {
|
||||||
|
rng_arg->assert_crypto();
|
||||||
|
rng = std::move(rng_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
* Any variable whose value is not expected to change should
|
||||||
|
be declared ``const``.
|
||||||
|
|
||||||
|
* Don't use non-const global or static variables unless absolutely
|
||||||
|
necessary.
|
||||||
|
|
||||||
|
* When formatting strings, don't use ``snprintf``. Instead, use
|
||||||
|
``std::ostringstream`` or build the string using the '+' ``std::string``
|
||||||
|
operator:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
std::string format_reconnecting(const int n_seconds) {
|
||||||
|
return "Reconnecting in " + openvpn::to_string(n_seconds) + " seconds.";
|
||||||
|
}
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
std::string format_reconnecting(const int n_seconds) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Reconnecting in " << n_seconds << " seconds.";
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
* OpenVPN 3 is a "header-only" library, therefore all free functions
|
||||||
|
outside of classes should have the ``inline`` attribute.
|
||||||
|
|
||||||
|
Conventions
|
||||||
|
+++++++++++
|
||||||
|
|
||||||
|
* Use the **Asio** library for I/O and timers.
|
||||||
|
Don't deal with sockets directly.
|
||||||
|
|
||||||
|
* Never block. If you need to wait for something, use **Asio** timers
|
||||||
|
or sockets.
|
||||||
|
|
||||||
|
* Use the ``OPENVPN_LOG()`` macro to log stuff. Don't use ``printf``.
|
||||||
|
|
||||||
|
* Don't call crypto/ssl libraries directly. Instead use the abstraction
|
||||||
|
layers (`<openvpn/crypto>`_ and `<openvpn/ssl>`_) that allow OpenVPN
|
||||||
|
to link with different crypto/ssl libraries (such as **OpenSSL**
|
||||||
|
or **mbed TLS**).
|
||||||
|
|
||||||
|
* Use ``RandomAPI`` as a wrapper for random number
|
||||||
|
generators (`<openvpn/random/randapi.hpp>`_).
|
||||||
|
|
||||||
|
* If you need to deal with configuration file options,
|
||||||
|
see ``class OptionList`` in `<openvpn/common/options.hpp>`_.
|
||||||
|
|
||||||
|
* If you need to deal with time or time durations, use the
|
||||||
|
classes under `<openvpn/time>`_.
|
||||||
|
|
||||||
|
* If you need to deal with IP addresses, see the comprehensive classes
|
||||||
|
under `<openvpn/addr>`_.
|
||||||
|
|
||||||
|
* In general, if you need a general-purpose library class or function,
|
||||||
|
look under `<openvpn/common>`_. Chances are good that it's already
|
||||||
|
been implemented.
|
||||||
|
|
||||||
|
* The OpenVPN 3 approach to errors is to count them, rather than
|
||||||
|
unconditionally log them. If you need to add a new error
|
||||||
|
counter, see `<openvpn/error/error.hpp>`_.
|
||||||
|
|
||||||
|
* If you need to create a new event type which can be transmitted
|
||||||
|
as a notification back to the client API user, see
|
||||||
|
`<openvpn/client/clievent.hpp>`_.
|
||||||
|
|
||||||
|
* Raw pointers or references can be okay when used by an object to
|
||||||
|
point back to its parent (or container), if you can guarantee that
|
||||||
|
the object will not outlive its parent. Backreferences to a parent
|
||||||
|
object is also a common use case for weak pointers.
|
||||||
|
|
||||||
|
* Use C++ exceptions for error handling and as an alternative
|
||||||
|
to ``goto``. See OpenVPN's general exception classes
|
||||||
|
and macros in `<openvpn/common/exception.hpp>`_.
|
||||||
|
|
||||||
|
* Use C++ destructors for automatic object cleanup, and so
|
||||||
|
that thrown exceptions will not leak objects. Alternatively,
|
||||||
|
use ``Cleanup`` in `<openvpn/common/cleanup.hpp>`_ when
|
||||||
|
you need to specify a code block to execute prior to scope
|
||||||
|
exit. For example, ensure that the file ``pid_fn`` is
|
||||||
|
deleted before scope exit:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
auto clean = Cleanup([pid_fn]() {
|
||||||
|
if (pid_fn)
|
||||||
|
::unlink(pid_fn);
|
||||||
|
});
|
||||||
|
|
||||||
|
* When calling global methods (such as libc ``fork``),
|
||||||
|
prepend "::" to the symbol name, e.g.:
|
||||||
|
|
||||||
|
.. code:: c++
|
||||||
|
|
||||||
|
struct dirent *e;
|
||||||
|
while ((e = ::readdir(dir.get())) != nullptr) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
* Use ``nullptr`` instead of ``NULL``.
|
||||||
|
|
||||||
|
Threading
|
||||||
|
+++++++++
|
||||||
|
|
||||||
|
The OpenVPN 3 client core is designed to run in a single thread, with
|
||||||
|
the UI or controller driving the OpenVPN API running in a different
|
||||||
|
thread.
|
||||||
|
|
||||||
|
It's almost never necessary to create additional threads within
|
||||||
|
the OpenVPN 3 client core.
|
||||||
|
|
||||||
|
|
||||||
|
Contributing
|
||||||
|
------------
|
||||||
|
|
||||||
|
See `<CONTRIBUTING.rst>`_.
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
See `<LICENSE.rst>`_.
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
OpenVPN 3 version numbering and release process
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
OpenVPN 3 version numbers will always be prefixed with ``3.`` which
|
||||||
|
indicates the OpenVPN generation. This library is the third
|
||||||
|
generation of the OpenVPN protocol implementation.
|
||||||
|
|
||||||
|
As of OpenVPN 3.2, we will use a single positive integer indicating a
|
||||||
|
release number as the version reference.
|
||||||
|
|
||||||
|
|
||||||
|
Git branches and versioning
|
||||||
|
---------------------------
|
||||||
|
Main development will happen on the git master branch. This will not
|
||||||
|
contain any specific version. It is will be set to ``3.git:master``.
|
||||||
|
This branch will contain both stable and unstable code, which will be
|
||||||
|
bleeding edge at any time. Do not depend on git master for production code.
|
||||||
|
|
||||||
|
Once features and fixes in git master has stabilized, they will be
|
||||||
|
merged into the ``stable`` branch. Code extracted from the stable branch
|
||||||
|
will contain the release number of the last release. The stable
|
||||||
|
branch is suitable for production code.
|
||||||
|
|
||||||
|
It is not set up a specific plan for when releases will occur. We
|
||||||
|
might want to collect up a smaller set of features before defining it
|
||||||
|
ready as a release, depending on the size of the changes. At the
|
||||||
|
release time, the version string will be updated and tagged (with
|
||||||
|
a PGP signature).
|
||||||
|
|
||||||
|
We should not pile up too many features for each release. It is
|
||||||
|
better to release often with smaller changesets.
|
||||||
|
|
||||||
|
|
||||||
|
Hot-fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
We will not do any patch number releases unless strictly needed for
|
||||||
|
older releases numbers. Such releases will be called hot-fixes and
|
||||||
|
will be handled in separate branches only when needed. These branches
|
||||||
|
will be named ``hotfix/3.X``; where X denotes the release number the
|
||||||
|
hotfix targets. Hotfixes need to update the version string as well
|
||||||
|
as attaching a git tag with the proper version number.
|
||||||
|
|
||||||
|
**Hot-fixes should be avoided as much as possible** and we should
|
||||||
|
**encourage users to base their work on the stable branch** primarily.
|
||||||
|
Hot-fixes will only be used for highly critical issues which cannot
|
||||||
|
wait for a release or the feature gap to move to a newer release is
|
||||||
|
considered too big. But it should also only occur for releases which
|
||||||
|
are still relevant.
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
git ``master`` branch: version string will be ``3.git:master``
|
||||||
|
|
||||||
|
git ``stable`` branch: version string will be ``3.2``, ``3.3``, etc
|
||||||
|
|
||||||
|
hotfix for v3.2 will be in ``hotfix/3.2`` and the version string will be
|
||||||
|
``3.2.1``
|
||||||
|
|
||||||
|
Similarly, hotfix for v3.3 will be found in ``hotfix/3.3`` and the version
|
||||||
|
string will be ``3.3.1``.
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
version: 1.0.{build}
|
||||||
|
|
||||||
|
image: Visual Studio 2019
|
||||||
|
|
||||||
|
clone_folder: c:\ovpn3\core
|
||||||
|
|
||||||
|
install:
|
||||||
|
- pip install rfc6266 requests
|
||||||
|
- if not exist "C:\strawberry" choco install strawberryperl -y
|
||||||
|
- set PATH=C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;%PATH%
|
||||||
|
|
||||||
|
environment:
|
||||||
|
MSVC_DIR: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
|
||||||
|
O3: C:\ovpn3
|
||||||
|
STATIC: 1
|
||||||
|
|
||||||
|
before_build:
|
||||||
|
- cmd: cd win && python buildep.py
|
||||||
|
|
||||||
|
after_build:
|
||||||
|
- cmd: copy c:\ovpn3\deps\amd64\openssl\out32dll\ssleay32.dll c:\ovpn3\core\win\x64\ReleaseOpenSSL\
|
||||||
|
- cmd: copy c:\ovpn3\deps\amd64\openssl\out32dll\libeay32.dll c:\ovpn3\core\win\x64\ReleaseOpenSSL\
|
||||||
|
|
||||||
|
platform: x64
|
||||||
|
|
||||||
|
configuration: ReleaseOpenSSL
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
- path: win\x64\ReleaseOpenSSL\cli.exe
|
||||||
|
- path: win\x64\ReleaseOpenSSL\*.dll
|
||||||
|
|
||||||
|
|
||||||
+1420
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,633 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// API for OpenVPN Client, may be used standalone or wrapped by swig.
|
||||||
|
// Use ovpncli.i to wrap the API for swig.
|
||||||
|
// The crux of the API is defined in OpenVPNClient (below)
|
||||||
|
// and TunBuilderBase.
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <openvpn/tun/builder/base.hpp>
|
||||||
|
#include <openvpn/tun/extern/fw.hpp>
|
||||||
|
#include <openvpn/pki/epkibase.hpp>
|
||||||
|
#include <openvpn/transport/client/extern/fw.hpp>
|
||||||
|
|
||||||
|
namespace openvpn {
|
||||||
|
class OptionList;
|
||||||
|
class ProfileMerge;
|
||||||
|
class Stop;
|
||||||
|
|
||||||
|
namespace ClientAPI {
|
||||||
|
// Represents an OpenVPN server and its friendly name
|
||||||
|
// (client reads)
|
||||||
|
struct ServerEntry
|
||||||
|
{
|
||||||
|
std::string server;
|
||||||
|
std::string friendlyName;
|
||||||
|
};
|
||||||
|
|
||||||
|
// return properties of config
|
||||||
|
// (client reads)
|
||||||
|
struct EvalConfig
|
||||||
|
{
|
||||||
|
// true if error
|
||||||
|
bool error = false;
|
||||||
|
|
||||||
|
// if error, message given here
|
||||||
|
std::string message;
|
||||||
|
|
||||||
|
// this username must be used with profile
|
||||||
|
std::string userlockedUsername;
|
||||||
|
|
||||||
|
// profile name of config
|
||||||
|
std::string profileName;
|
||||||
|
|
||||||
|
// "friendly" name of config
|
||||||
|
std::string friendlyName;
|
||||||
|
|
||||||
|
// true: no creds required, false: username/password required
|
||||||
|
bool autologin = false;
|
||||||
|
|
||||||
|
// if true, this is an External PKI profile (no cert or key directives)
|
||||||
|
bool externalPki = false;
|
||||||
|
|
||||||
|
// static challenge, may be empty, ignored if autologin
|
||||||
|
std::string staticChallenge;
|
||||||
|
|
||||||
|
// true if static challenge response should be echoed to UI, ignored if autologin
|
||||||
|
bool staticChallengeEcho = false;
|
||||||
|
|
||||||
|
// true if this profile requires a private key password
|
||||||
|
bool privateKeyPasswordRequired = false;
|
||||||
|
|
||||||
|
// true if user is allowed to save authentication password in UI
|
||||||
|
bool allowPasswordSave = false;
|
||||||
|
|
||||||
|
// information about the first remote item in config
|
||||||
|
std::string remoteHost; // will be overridden by Config::serverOverride if defined
|
||||||
|
std::string remotePort;
|
||||||
|
std::string remoteProto;
|
||||||
|
|
||||||
|
// optional list of user-selectable VPN servers
|
||||||
|
std::vector<ServerEntry> serverList;
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to pass credentials to VPN core
|
||||||
|
// (client writes)
|
||||||
|
struct ProvideCreds
|
||||||
|
{
|
||||||
|
std::string username;
|
||||||
|
std::string password;
|
||||||
|
|
||||||
|
// response to challenge
|
||||||
|
std::string response;
|
||||||
|
|
||||||
|
// Dynamic challenge/response cookie
|
||||||
|
std::string dynamicChallengeCookie;
|
||||||
|
|
||||||
|
// If true, on successful connect, we will replace the password
|
||||||
|
// with the session ID we receive from the server (if provided).
|
||||||
|
// If false, the password will be cached for future reconnects
|
||||||
|
// and will not be replaced with a session ID, even if the
|
||||||
|
// server provides one.
|
||||||
|
bool replacePasswordWithSessionID = false;
|
||||||
|
|
||||||
|
// If true, and if replacePasswordWithSessionID is true, and if
|
||||||
|
// we actually receive a session ID from the server, cache
|
||||||
|
// the user-provided password for future use before replacing
|
||||||
|
// the active password with the session ID.
|
||||||
|
bool cachePassword = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to get session token from VPN core
|
||||||
|
// (client reads)
|
||||||
|
struct SessionToken
|
||||||
|
{
|
||||||
|
std::string username;
|
||||||
|
std::string session_id; // an OpenVPN Session ID, used as a proxy for password
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to query challenge/response from user
|
||||||
|
// (client reads)
|
||||||
|
struct DynamicChallenge
|
||||||
|
{
|
||||||
|
std::string challenge;
|
||||||
|
bool echo = false;
|
||||||
|
bool responseRequired = false;
|
||||||
|
|
||||||
|
std::string stateID;
|
||||||
|
};
|
||||||
|
|
||||||
|
// a basic key/value pair, used in Config below when OpenVPN profile is
|
||||||
|
// passed as a dictionary
|
||||||
|
struct KeyValue
|
||||||
|
{
|
||||||
|
KeyValue() {}
|
||||||
|
|
||||||
|
KeyValue(std::string key_arg, std::string value_arg)
|
||||||
|
: key(std::move(key_arg)),
|
||||||
|
value(std::move(value_arg)) {}
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
std::string value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// OpenVPN config-file/profile
|
||||||
|
// (client writes)
|
||||||
|
struct Config
|
||||||
|
{
|
||||||
|
// OpenVPN profile as a string
|
||||||
|
std::string content;
|
||||||
|
|
||||||
|
// OpenVPN profile as series of key/value pairs (may be provided exclusively
|
||||||
|
// or in addition to content string above).
|
||||||
|
std::vector<KeyValue> contentList;
|
||||||
|
|
||||||
|
// Set to identity OpenVPN GUI version.
|
||||||
|
// Format should be "<gui_identifier><space><version>"
|
||||||
|
// Passed to server as IV_GUI_VER.
|
||||||
|
std::string guiVersion;
|
||||||
|
|
||||||
|
// Set to a comma seperated list of supported SSO mechanisms that may
|
||||||
|
// be signalled via INFO_PRE to the client.
|
||||||
|
// "openurl" is to continue authentication by opening an url in a browser
|
||||||
|
// "crtext" gives a challenge response in text format that needs to
|
||||||
|
// responded via control channel. (
|
||||||
|
// Passed to the server as IV_SSO
|
||||||
|
std::string ssoMethods;
|
||||||
|
|
||||||
|
// Override the string that is passed as IV_HWADDR to the server
|
||||||
|
std::string hwAddrOverride;
|
||||||
|
|
||||||
|
// Set the string that is passed to the server as IV_PLAT_VER
|
||||||
|
std::string platformVersion;
|
||||||
|
|
||||||
|
// Use a different server than that specified in "remote"
|
||||||
|
// option of profile
|
||||||
|
std::string serverOverride;
|
||||||
|
|
||||||
|
// Use a different port than that specified in "remote"
|
||||||
|
// option of profile
|
||||||
|
std::string portOverride;
|
||||||
|
|
||||||
|
// Force a given transport protocol
|
||||||
|
// Should be tcp, udp, or adaptive.
|
||||||
|
std::string protoOverride;
|
||||||
|
|
||||||
|
// IPv6 preference
|
||||||
|
// no -- disable IPv6, so tunnel will be IPv4-only
|
||||||
|
// yes -- request combined IPv4/IPv6 tunnel
|
||||||
|
// default (or empty string) -- leave decision to server
|
||||||
|
std::string ipv6;
|
||||||
|
|
||||||
|
// Connection timeout in seconds, or 0 to retry indefinitely
|
||||||
|
int connTimeout = 0;
|
||||||
|
|
||||||
|
// Keep tun interface active during pauses or reconnections
|
||||||
|
bool tunPersist = false;
|
||||||
|
|
||||||
|
// If true and a redirect-gateway profile doesn't also define
|
||||||
|
// DNS servers, use the standard Google DNS servers.
|
||||||
|
bool googleDnsFallback = false;
|
||||||
|
|
||||||
|
// if true, do synchronous DNS lookup.
|
||||||
|
bool synchronousDnsLookup = false;
|
||||||
|
|
||||||
|
// Enable autologin sessions
|
||||||
|
bool autologinSessions = true;
|
||||||
|
|
||||||
|
// If true, consider AUTH_FAILED to be a non-fatal error,
|
||||||
|
// and retry the connection after a pause.
|
||||||
|
bool retryOnAuthFailed = false;
|
||||||
|
|
||||||
|
// An ID used for get-certificate and RSA signing callbacks
|
||||||
|
// for External PKI profiles.
|
||||||
|
std::string externalPkiAlias;
|
||||||
|
|
||||||
|
// If true, don't send client cert/key to peer.
|
||||||
|
bool disableClientCert = false;
|
||||||
|
|
||||||
|
// SSL library debug level
|
||||||
|
int sslDebugLevel = 0;
|
||||||
|
|
||||||
|
// Compression mode, one of:
|
||||||
|
// yes -- allow compression on both uplink and downlink
|
||||||
|
// asym -- allow compression on downlink only (i.e. server -> client)
|
||||||
|
// no (default if empty) -- support compression stubs only
|
||||||
|
std::string compressionMode;
|
||||||
|
|
||||||
|
// private key password (optional)
|
||||||
|
std::string privateKeyPassword;
|
||||||
|
|
||||||
|
// Default key direction parameter for tls-auth (0, 1, or
|
||||||
|
// -1 (bidirectional -- default)) if no key-direction parameter
|
||||||
|
// defined in profile. Generally should be -1 (bidirectional)
|
||||||
|
// for compatibility with 2.x branch
|
||||||
|
int defaultKeyDirection = -1;
|
||||||
|
|
||||||
|
// If true, force ciphersuite to be one of:
|
||||||
|
// 1. TLS_DHE_RSA_WITH_AES_256_CBC_SHA, or
|
||||||
|
// 2. TLS_DHE_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
// and disable setting TLS minimum version.
|
||||||
|
// This is intended for compatibility with legacy systems.
|
||||||
|
bool forceAesCbcCiphersuites = false;
|
||||||
|
|
||||||
|
// Override the minimum TLS version:
|
||||||
|
// disabled -- don't specify a minimum, and disable any minimum
|
||||||
|
// specified in profile
|
||||||
|
// default or "" -- use profile minimum
|
||||||
|
// tls_1_0 -- use TLS 1.0 minimum (overrides profile)
|
||||||
|
// tls_1_1 -- use TLS 1.1 minimum (overrides profile)
|
||||||
|
// tls_1_2 -- use TLS 1.2 minimum (overrides profile)
|
||||||
|
std::string tlsVersionMinOverride;
|
||||||
|
|
||||||
|
// Override or default the tls-cert-profile setting:
|
||||||
|
// default or "" -- use profile default
|
||||||
|
// legacy -- allow 1024-bit RSA certs signed with SHA1
|
||||||
|
// preferred -- require at least 2048-bit RSA certs signed
|
||||||
|
// with SHA256 or higher
|
||||||
|
// suiteb -- require NSA Suite-B
|
||||||
|
// legacy-default -- use legacy as the default if profile
|
||||||
|
// doesn't specify tls-cert-profile
|
||||||
|
// preferred-default -- use preferred as the default if profile
|
||||||
|
// doesn't specify tls-cert-profile
|
||||||
|
std::string tlsCertProfileOverride;
|
||||||
|
|
||||||
|
// Pass custom key/value pairs to OpenVPN server.
|
||||||
|
std::vector<KeyValue> peerInfo;
|
||||||
|
|
||||||
|
// HTTP Proxy parameters (optional)
|
||||||
|
std::string proxyHost; // hostname or IP address of proxy
|
||||||
|
std::string proxyPort; // port number of proxy
|
||||||
|
std::string proxyUsername; // proxy credentials (optional)
|
||||||
|
std::string proxyPassword; // proxy credentials (optional)
|
||||||
|
bool proxyAllowCleartextAuth = false; // enables HTTP Basic auth
|
||||||
|
|
||||||
|
// Custom proxy implementation
|
||||||
|
bool altProxy = false;
|
||||||
|
|
||||||
|
// Custom Data Channel Offload implementation
|
||||||
|
bool dco = false;
|
||||||
|
|
||||||
|
// pass through pushed "echo" directives via "ECHO" event
|
||||||
|
bool echo = false;
|
||||||
|
|
||||||
|
// pass through control channel INFO notifications via "INFO" event
|
||||||
|
bool info = false;
|
||||||
|
|
||||||
|
// Allow access to local LAN. This is for platforms like
|
||||||
|
// Android that disable local LAN access by default.
|
||||||
|
bool allowLocalLanAccess = false;
|
||||||
|
|
||||||
|
// Periodic convenience clock tick in milliseconds.
|
||||||
|
// Will call clock_tick() at a frequency defined by this parameter.
|
||||||
|
// Set to 0 to disable.
|
||||||
|
unsigned int clockTickMS = 0;
|
||||||
|
|
||||||
|
// Gremlin configuration (requires that the core is built with OPENVPN_GREMLIN)
|
||||||
|
std::string gremlinConfig;
|
||||||
|
|
||||||
|
// Use wintun instead of tap-windows6 on Windows
|
||||||
|
bool wintun = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to communicate VPN events such as connect, disconnect, etc.
|
||||||
|
// (client reads)
|
||||||
|
struct Event
|
||||||
|
{
|
||||||
|
bool error = false; // true if error (fatal or nonfatal)
|
||||||
|
bool fatal = false; // true if fatal error (will disconnect)
|
||||||
|
std::string name; // event name
|
||||||
|
std::string info; // additional event info
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to communicate extra details about successful connection
|
||||||
|
// (client reads)
|
||||||
|
struct ConnectionInfo
|
||||||
|
{
|
||||||
|
bool defined = false;
|
||||||
|
std::string user;
|
||||||
|
std::string serverHost;
|
||||||
|
std::string serverPort;
|
||||||
|
std::string serverProto;
|
||||||
|
std::string serverIp;
|
||||||
|
std::string vpnIp4;
|
||||||
|
std::string vpnIp6;
|
||||||
|
std::string gw4;
|
||||||
|
std::string gw6;
|
||||||
|
std::string clientIp;
|
||||||
|
std::string tunName;
|
||||||
|
};
|
||||||
|
|
||||||
|
// returned by some methods as a status/error indication
|
||||||
|
// (client reads)
|
||||||
|
struct Status
|
||||||
|
{
|
||||||
|
bool error = false; // true if error
|
||||||
|
std::string status; // an optional short error label that identifies the error
|
||||||
|
std::string message; // if error, message given here
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to pass log lines
|
||||||
|
// (client reads)
|
||||||
|
struct LogInfo
|
||||||
|
{
|
||||||
|
LogInfo() {}
|
||||||
|
LogInfo(std::string str)
|
||||||
|
: text(std::move(str)) {}
|
||||||
|
std::string text; // log output (usually but not always one line)
|
||||||
|
};
|
||||||
|
|
||||||
|
// receives log messages
|
||||||
|
struct LogReceiver
|
||||||
|
{
|
||||||
|
virtual void log(const LogInfo&) = 0;
|
||||||
|
virtual ~LogReceiver() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to pass stats for an interface
|
||||||
|
struct InterfaceStats
|
||||||
|
{
|
||||||
|
long long bytesIn;
|
||||||
|
long long packetsIn;
|
||||||
|
long long errorsIn;
|
||||||
|
long long bytesOut;
|
||||||
|
long long packetsOut;
|
||||||
|
long long errorsOut;
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to pass basic transport stats
|
||||||
|
struct TransportStats
|
||||||
|
{
|
||||||
|
long long bytesIn;
|
||||||
|
long long bytesOut;
|
||||||
|
long long packetsIn;
|
||||||
|
long long packetsOut;
|
||||||
|
|
||||||
|
// number of binary milliseconds (1/1024th of a second) since
|
||||||
|
// last packet was received, or -1 if undefined
|
||||||
|
int lastPacketReceived;
|
||||||
|
};
|
||||||
|
|
||||||
|
// return value of merge_config methods
|
||||||
|
struct MergeConfig
|
||||||
|
{
|
||||||
|
std::string status; // ProfileMerge::Status codes rendered as string
|
||||||
|
std::string errorText; // error string (augments status)
|
||||||
|
std::string basename; // profile basename
|
||||||
|
std::string profileContent; // unified profile
|
||||||
|
std::vector<std::string> refPathList; // list of all reference paths successfully read
|
||||||
|
};
|
||||||
|
|
||||||
|
// base class for External PKI queries
|
||||||
|
struct ExternalPKIRequestBase
|
||||||
|
{
|
||||||
|
bool error = false; // true if error occurred (client writes)
|
||||||
|
std::string errorText; // text describing error (client writes)
|
||||||
|
bool invalidAlias = false; // true if the error is caused by an invalid alias (client writes)
|
||||||
|
std::string alias; // the alias string, used to query cert/key (client reads)
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to query for External PKI certificate
|
||||||
|
struct ExternalPKICertRequest : public ExternalPKIRequestBase
|
||||||
|
{
|
||||||
|
// leaf cert
|
||||||
|
std::string cert; // (client writes)
|
||||||
|
|
||||||
|
// chain of intermediates and root (optional)
|
||||||
|
std::string supportingChain; // (client writes)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used to request an RSA signature.
|
||||||
|
// algorithm will determinate what signature is expected:
|
||||||
|
// RSA_PKCS1_PADDING means that
|
||||||
|
// data will be prefixed by an optional PKCS#1 digest prefix
|
||||||
|
// per RFC 3447.
|
||||||
|
// RSA_NO_PADDING mean so no padding should be done be the callee
|
||||||
|
struct ExternalPKISignRequest : public ExternalPKIRequestBase
|
||||||
|
{
|
||||||
|
std::string data; // data rendered as base64 (client reads)
|
||||||
|
std::string sig; // RSA signature, rendered as base64 (client writes)
|
||||||
|
std::string algorithm;
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to override "remote" directives
|
||||||
|
struct RemoteOverride
|
||||||
|
{
|
||||||
|
// components of "remote" directive (client writes),
|
||||||
|
std::string host; // either one of host
|
||||||
|
std::string ip; // or ip must be defined (or both)
|
||||||
|
std::string port;
|
||||||
|
std::string proto;
|
||||||
|
std::string error; // if non-empty, indicates an error
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
class ClientState;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Top-level OpenVPN client class.
|
||||||
|
class OpenVPNClient : public TunBuilderBase, // expose tun builder virtual methods
|
||||||
|
public LogReceiver, // log message notification
|
||||||
|
public ExternalTun::Factory, // low-level tun override
|
||||||
|
public ExternalTransport::Factory,// low-level transport override
|
||||||
|
private ExternalPKIBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenVPNClient();
|
||||||
|
virtual ~OpenVPNClient();
|
||||||
|
|
||||||
|
// Call me first, before calling any other method (static or instance methods)
|
||||||
|
// in this class.
|
||||||
|
static void init_process();
|
||||||
|
|
||||||
|
// Release any resources allocated by init_process.
|
||||||
|
static void uninit_process();
|
||||||
|
|
||||||
|
// Read an OpenVPN profile that might contain external
|
||||||
|
// file references, returning a unified profile.
|
||||||
|
static MergeConfig merge_config_static(const std::string& path, bool follow_references);
|
||||||
|
|
||||||
|
// Read an OpenVPN profile that might contain external
|
||||||
|
// file references, returning a unified profile.
|
||||||
|
static MergeConfig merge_config_string_static(const std::string& config_content);
|
||||||
|
|
||||||
|
// Parse profile and determine needed credentials statically.
|
||||||
|
static EvalConfig eval_config_static(const Config& config);
|
||||||
|
|
||||||
|
// Maximum size of profile that should be allowed
|
||||||
|
static long max_profile_size();
|
||||||
|
|
||||||
|
// Parse a dynamic challenge cookie, placing the result in dc.
|
||||||
|
// Return true on success or false if parse error.
|
||||||
|
static bool parse_dynamic_challenge(const std::string& cookie, DynamicChallenge& dc);
|
||||||
|
|
||||||
|
// Parse OpenVPN configuration file.
|
||||||
|
EvalConfig eval_config(const Config&);
|
||||||
|
|
||||||
|
// Provide credentials and other options. Call before connect().
|
||||||
|
Status provide_creds(const ProvideCreds&);
|
||||||
|
|
||||||
|
// Callback to "protect" a socket from being routed through the tunnel.
|
||||||
|
// Will be called from the thread executing connect().
|
||||||
|
// The remote and ipv6 are the remote host this socket will connect to
|
||||||
|
virtual bool socket_protect(int socket, std::string remote, bool ipv6);
|
||||||
|
|
||||||
|
// Primary VPN client connect method, doesn't return until disconnect.
|
||||||
|
// Should be called by a worker thread. This method will make callbacks
|
||||||
|
// to event() and log() functions. Make sure to call eval_config()
|
||||||
|
// and possibly provide_creds() as well before this function.
|
||||||
|
Status connect();
|
||||||
|
|
||||||
|
// Return information about the most recent connection. Should be called
|
||||||
|
// after an event of type "CONNECTED".
|
||||||
|
ConnectionInfo connection_info();
|
||||||
|
|
||||||
|
// Writes current session token to tok and returns true.
|
||||||
|
// If session token is unavailable, false is returned and
|
||||||
|
// tok is unmodified.
|
||||||
|
bool session_token(SessionToken& tok);
|
||||||
|
|
||||||
|
// Stop the client. Only meaningful when connect() is running.
|
||||||
|
// May be called asynchronously from a different thread
|
||||||
|
// when connect() is running.
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
// Pause the client -- useful to avoid continuous reconnection attempts
|
||||||
|
// when network is down. May be called from a different thread
|
||||||
|
// when connect() is running.
|
||||||
|
void pause(const std::string& reason);
|
||||||
|
|
||||||
|
// Resume the client after it has been paused. May be called from a
|
||||||
|
// different thread when connect() is running.
|
||||||
|
void resume();
|
||||||
|
|
||||||
|
// Do a disconnect/reconnect cycle n seconds from now. May be called
|
||||||
|
// from a different thread when connect() is running.
|
||||||
|
void reconnect(int seconds);
|
||||||
|
|
||||||
|
// When a connection is close to timeout, the core will call this
|
||||||
|
// method. If it returns false, the core will disconnect with a
|
||||||
|
// CONNECTION_TIMEOUT event. If true, the core will enter a PAUSE
|
||||||
|
// state.
|
||||||
|
virtual bool pause_on_connection_timeout() = 0;
|
||||||
|
|
||||||
|
// Get stats/error info. May be called from a different thread
|
||||||
|
// when connect() is running.
|
||||||
|
|
||||||
|
// number of stats
|
||||||
|
static int stats_n();
|
||||||
|
|
||||||
|
// return a stats name, index should be >= 0 and < stats_n()
|
||||||
|
static std::string stats_name(int index);
|
||||||
|
|
||||||
|
// return a stats value, index should be >= 0 and < stats_n()
|
||||||
|
long long stats_value(int index) const;
|
||||||
|
|
||||||
|
// return all stats in a bundle
|
||||||
|
std::vector<long long> stats_bundle() const;
|
||||||
|
|
||||||
|
// return tun stats only
|
||||||
|
InterfaceStats tun_stats() const;
|
||||||
|
|
||||||
|
// return transport stats only
|
||||||
|
TransportStats transport_stats() const;
|
||||||
|
|
||||||
|
// post control channel message
|
||||||
|
void post_cc_msg(const std::string& msg);
|
||||||
|
|
||||||
|
// Callback for delivering events during connect() call.
|
||||||
|
// Will be called from the thread executing connect().
|
||||||
|
virtual void event(const Event&) = 0;
|
||||||
|
|
||||||
|
// Callback for logging.
|
||||||
|
// Will be called from the thread executing connect().
|
||||||
|
virtual void log(const LogInfo&) = 0;
|
||||||
|
|
||||||
|
// External PKI callbacks
|
||||||
|
// Will be called from the thread executing connect().
|
||||||
|
virtual void external_pki_cert_request(ExternalPKICertRequest&) = 0;
|
||||||
|
virtual void external_pki_sign_request(ExternalPKISignRequest&) = 0;
|
||||||
|
|
||||||
|
// Remote override callback (disabled by default).
|
||||||
|
virtual bool remote_override_enabled();
|
||||||
|
virtual void remote_override(RemoteOverride&);
|
||||||
|
|
||||||
|
// Periodic convenience clock tick, controlled by Config::clockTickMS
|
||||||
|
virtual void clock_tick();
|
||||||
|
|
||||||
|
// Do a crypto library self test
|
||||||
|
static std::string crypto_self_test();
|
||||||
|
|
||||||
|
// Returns date/time of app expiration as a unix time value
|
||||||
|
static int app_expire();
|
||||||
|
|
||||||
|
// Returns platform description string
|
||||||
|
static std::string platform();
|
||||||
|
|
||||||
|
// Returns core copyright
|
||||||
|
static std::string copyright();
|
||||||
|
|
||||||
|
// Hide protected methods/data from SWIG
|
||||||
|
#ifdef SWIGJAVA
|
||||||
|
private:
|
||||||
|
#else
|
||||||
|
protected:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Status do_connect();
|
||||||
|
|
||||||
|
virtual void connect_attach();
|
||||||
|
virtual void connect_pre_run();
|
||||||
|
virtual void connect_run();
|
||||||
|
virtual void connect_session_stop();
|
||||||
|
|
||||||
|
virtual Stop* get_async_stop();
|
||||||
|
|
||||||
|
Private::ClientState* state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void connect_setup(Status&, bool&);
|
||||||
|
void do_connect_async();
|
||||||
|
static Status status_from_exception(const std::exception&);
|
||||||
|
static void parse_config(const Config&, EvalConfig&, OptionList&);
|
||||||
|
void parse_extras(const Config&, EvalConfig&);
|
||||||
|
void external_pki_error(const ExternalPKIRequestBase&, const size_t);
|
||||||
|
void process_epki_cert_chain(const ExternalPKICertRequest&);
|
||||||
|
void check_app_expired();
|
||||||
|
static MergeConfig build_merge_config(const ProfileMerge&);
|
||||||
|
|
||||||
|
friend class MyClientEvents;
|
||||||
|
void on_disconnect();
|
||||||
|
|
||||||
|
// from ExternalPKIBase
|
||||||
|
virtual bool sign(const std::string& data, std::string& sig, const std::string& algorithm);
|
||||||
|
|
||||||
|
// disable copy and assignment
|
||||||
|
OpenVPNClient(const OpenVPNClient&) = delete;
|
||||||
|
OpenVPNClient& operator=(const OpenVPNClient&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(googletest-download NONE)
|
||||||
|
|
||||||
|
include(ExternalProject)
|
||||||
|
ExternalProject_Add(googletest
|
||||||
|
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||||
|
GIT_TAG master
|
||||||
|
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
|
||||||
|
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
TEST_COMMAND ""
|
||||||
|
)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
find_path(LZ4_INCLUDE_DIR NAMES lz4.h)
|
||||||
|
find_library(LZ4_LIBRARY NAMES lz4)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
|
||||||
|
LZ4 DEFAULT_MSG
|
||||||
|
LZ4_LIBRARY LZ4_INCLUDE_DIR)
|
||||||
|
|
||||||
|
mark_as_advanced(LZ4_INCLUDE_DIR LZ4_LIBRARY)
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# - Try to find mbedTLS
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# Read-Only variables
|
||||||
|
# MBEDTLS_FOUND - system has mbedTLS
|
||||||
|
# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory
|
||||||
|
# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory
|
||||||
|
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
|
||||||
|
# MBEDTLS_LIBRARY - path to mbedTLS library
|
||||||
|
# MBEDX509_LIBRARY - path to mbedTLS X.509 library
|
||||||
|
# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
|
||||||
|
|
||||||
|
FIND_PATH(MBEDTLS_INCLUDE_DIR mbedtls/version.h)
|
||||||
|
|
||||||
|
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES)
|
||||||
|
# Already in cache, be silent
|
||||||
|
SET(MBEDTLS_FIND_QUIETLY TRUE)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
FIND_LIBRARY(MBEDTLS_LIBRARY NAMES mbedtls libmbedtls libmbedx509)
|
||||||
|
FIND_LIBRARY(MBEDX509_LIBRARY NAMES mbedx509 libmbedx509)
|
||||||
|
FIND_LIBRARY(MBEDCRYPTO_LIBRARY NAMES mbedcrypto libmbedcrypto)
|
||||||
|
|
||||||
|
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY)
|
||||||
|
SET(MBEDTLS_FOUND TRUE)
|
||||||
|
ELSEIF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND NOT MBEDX509_LIBRARY AND NOT MBEDCRYPTO_LIBRARY)
|
||||||
|
SET(MBEDTLS_FOUND TRUE)
|
||||||
|
SET(HACKY_OVPN_MBEDTLS TRUE)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF(MBEDTLS_FOUND)
|
||||||
|
IF(HACKY_OVPN_MBEDTLS)
|
||||||
|
SET(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY})
|
||||||
|
ELSE()
|
||||||
|
SET(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
IF(NOT MBEDTLS_FIND_QUIETLY)
|
||||||
|
MESSAGE(STATUS "Found mbedTLS:")
|
||||||
|
FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
|
||||||
|
STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT})
|
||||||
|
IF (MBEDTLSMATCH)
|
||||||
|
STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH})
|
||||||
|
MESSAGE(STATUS " version ${MBEDTLS_VERSION}")
|
||||||
|
ENDIF(MBEDTLSMATCH)
|
||||||
|
MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}")
|
||||||
|
MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}")
|
||||||
|
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
|
||||||
|
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
|
||||||
|
ELSE(MBEDTLS_FOUND)
|
||||||
|
IF(mbedTLS_FIND_REQUIRED)
|
||||||
|
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
|
||||||
|
ENDIF(mbedTLS_FIND_REQUIRED)
|
||||||
|
ENDIF(MBEDTLS_FOUND)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
MBEDTLS_INCLUDE_DIR
|
||||||
|
MBEDTLS_LIBRARY_DIR
|
||||||
|
MBEDTLS_LIBRARIES
|
||||||
|
MBEDTLS_LIBRARY
|
||||||
|
MBEDX509_LIBRARY
|
||||||
|
MBEDCRYPTO_LIBRARY
|
||||||
|
)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
# Google Test Unit testing
|
||||||
|
# Download and unpack googletest at configure time
|
||||||
|
|
||||||
|
# Ensure that this only downloaded and added once
|
||||||
|
#include_guard(GLOBAL)
|
||||||
|
# Unfortunately include_guard requires cmake >= 3.10
|
||||||
|
include(mypragmaonce)
|
||||||
|
|
||||||
|
my_pragma_once()
|
||||||
|
|
||||||
|
|
||||||
|
configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt.in googletest-download/CMakeLists.txt)
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
|
||||||
|
if(result)
|
||||||
|
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
|
||||||
|
endif()
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} --build .
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
|
||||||
|
if(result)
|
||||||
|
message(FATAL_ERROR "Build step for googletest failed: ${result}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Prevent overriding the parent project's compiler/linker
|
||||||
|
# settings on Windows
|
||||||
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
# Add googletest directly to our build. This defines
|
||||||
|
# the gtest and gtest_main targets.
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
|
||||||
|
EXCLUDE_FROM_ALL)
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
|
||||||
|
#cmake_policy(SET CMP0079 NEW)
|
||||||
|
|
||||||
|
set(CORE_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||||
|
|
||||||
|
|
||||||
|
set(DEP_DIR ${CORE_DIR}/../deps CACHE PATH "Dependencies")
|
||||||
|
option(USE_MBEDTLS "Use mbed TLS instead of OpenSSL")
|
||||||
|
|
||||||
|
if (DEFINED ENV{DEP_DIR})
|
||||||
|
message(WARNING "Overriding DEP_DIR setting with environment variable")
|
||||||
|
set(DEP_DIR $ENV{DEP_DIR})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Include our DEP_DIR in path used to find libraries
|
||||||
|
|
||||||
|
|
||||||
|
function(add_core_dependencies target)
|
||||||
|
if (APPLE)
|
||||||
|
set(PLAT osx)
|
||||||
|
elseif (WIN32)
|
||||||
|
set(PLAT amd64)
|
||||||
|
else ()
|
||||||
|
set(PLAT linux)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(CORE_INCLUDES
|
||||||
|
${CORE_DIR}
|
||||||
|
${DEP_DIR}/asio/asio/include
|
||||||
|
)
|
||||||
|
set(CORE_DEFINES
|
||||||
|
-DASIO_STANDALONE
|
||||||
|
-DUSE_ASIO
|
||||||
|
-DHAVE_LZ4
|
||||||
|
-DLZ4_DISABLE_DEPRECATE_WARNINGS
|
||||||
|
-DMBEDTLS_DEPRECATED_REMOVED
|
||||||
|
)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
list(APPEND CMAKE_PREFIX_PATH
|
||||||
|
${DEP_DIR}/${PLAT}/mbedtls
|
||||||
|
${DEP_DIR}/${PLAT}/lz4/lib
|
||||||
|
)
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH
|
||||||
|
${DEP_DIR}/${PLAT}/mbedtls/library
|
||||||
|
)
|
||||||
|
list(APPEND CORE_INCLUDES
|
||||||
|
${DEP_DIR}/${PLAT}/asio/asio/include
|
||||||
|
${DEP_DIR}/${PLAT}/lz4/lz4/include
|
||||||
|
${DEP_DIR}/${PLAT}/tap-windows/src
|
||||||
|
)
|
||||||
|
list(APPEND CORE_DEFINES
|
||||||
|
-D_WIN32_WINNT=0x0600
|
||||||
|
-DTAP_WIN_COMPONENT_ID=tap0901
|
||||||
|
-D_CRT_SECURE_NO_WARNINGS
|
||||||
|
)
|
||||||
|
set(EXTRA_LIBS fwpuclnt.lib Iphlpapi.lib)
|
||||||
|
target_compile_options(${target} PRIVATE "/bigobj")
|
||||||
|
else ()
|
||||||
|
list(APPEND CMAKE_PREFIX_PATH
|
||||||
|
${DEP_DIR}/mbedtls/mbedtls-${PLAT}
|
||||||
|
${DEP_DIR}/lz4/lz4-${PLAT}
|
||||||
|
)
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH
|
||||||
|
${DEP_DIR}/mbedtls/mbedtls-${PLAT}/library
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
|
if (${USE_MBEDTLS})
|
||||||
|
find_package(mbedTLS REQUIRED)
|
||||||
|
|
||||||
|
set(SSL_LIBRARY ${MBEDTLS_LIBRARIES})
|
||||||
|
|
||||||
|
list(APPEND CORE_DEFINES -DUSE_MBEDTLS)
|
||||||
|
|
||||||
|
# The findmbedTLS does not set these automatically :(
|
||||||
|
list(APPEND CORE_INCLUDES ${MBEDTLS_INCLUDE_DIR})
|
||||||
|
|
||||||
|
else ()
|
||||||
|
find_package(OpenSSL REQUIRED)
|
||||||
|
SET(SSL_LIBRARY OpenSSL::SSL)
|
||||||
|
list(APPEND CORE_DEFINES -DUSE_OPENSSL)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
find_library(coreFoundation CoreFoundation)
|
||||||
|
find_library(iokit IOKit)
|
||||||
|
find_library(coreServices CoreServices)
|
||||||
|
find_library(systemConfiguration SystemConfiguration)
|
||||||
|
target_link_libraries(${target} ${coreFoundation} ${iokit} ${coreServices} ${systemConfiguration} ${lz4} ${SSL_LIBRARY})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
target_link_libraries(${target} pthread)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(LZ4 REQUIRED)
|
||||||
|
list(APPEND CORE_INCLUDES ${LZ4_INCLUDE_DIR})
|
||||||
|
|
||||||
|
target_include_directories(${target} PRIVATE ${CORE_INCLUDES})
|
||||||
|
target_compile_definitions(${target} PRIVATE ${CORE_DEFINES})
|
||||||
|
target_link_libraries(${target} ${SSL_LIBRARY} ${EXTRA_LIBS} ${LZ4_LIBRARY})
|
||||||
|
endfunction()
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
macro(my_pragma_once)
|
||||||
|
set(__filename "${CMAKE_CURRENT_LIST_FILE}")
|
||||||
|
get_property(already_included GLOBAL PROPERTY "pr_${__filename}")
|
||||||
|
if(already_included)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set_property(GLOBAL PROPERTY "pr_${__filename}" TRUE)
|
||||||
|
endmacro()
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$DEP_DIR" ]; then
|
||||||
|
echo DEP_DIR var must point to dependency build folder
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$DL" ]; then
|
||||||
|
echo DL var must point to the download folder
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
# source helper functions
|
||||||
|
. $O3/core/deps/functions.sh
|
||||||
|
|
||||||
|
PACKAGE=${ASIO_VERSION}
|
||||||
|
FNAME=${ASIO_VERSION}.tar.gz
|
||||||
|
URL=https://github.com/chriskohlhoff/asio/archive/${ASIO_VERSION}.tar.gz
|
||||||
|
CSUM=${ASIO_CSUM}
|
||||||
|
DIST=asio
|
||||||
|
|
||||||
|
download
|
||||||
|
|
||||||
|
if [ "$NO_WIPE" = "1" ]; then
|
||||||
|
echo RETAIN existing source
|
||||||
|
else
|
||||||
|
echo WIPE and reunzip source
|
||||||
|
cd $DEP_DIR
|
||||||
|
rm -rf $DIST asio-$ASIO_VERSION
|
||||||
|
tar xfz $DL/$FNAME
|
||||||
|
cd asio-$ASIO_VERSION
|
||||||
|
|
||||||
|
apply_patches "asio"
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cp -a asio-$ASIO_VERSION $DIST
|
||||||
|
fi
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
From 00c0b1b7076ebc24735071f587f9501c1595a02b Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Yonan <james@openvpn.net>
|
||||||
|
Date: Mon, 19 Mar 2018 11:24:10 +0800
|
||||||
|
Subject: [PATCH] Added Apple NAT64 support when both ASIO_HAS_GETADDRINFO and
|
||||||
|
ASIO_APPLE_NAT64 ar defined
|
||||||
|
|
||||||
|
* When calling getaddrinfo(), Apple recommends to set
|
||||||
|
AI_DEFAULT flags in hint.
|
||||||
|
|
||||||
|
* iOS bug workaround: sometimes iOS getaddrinfo() returns a
|
||||||
|
non-zero scope ID for non-link-local addresses.
|
||||||
|
Workaround by forcing scope ID to 0 for non-link-local
|
||||||
|
addresses.
|
||||||
|
---
|
||||||
|
asio/include/asio/detail/impl/socket_ops.ipp | 17 +++++++++++++++++
|
||||||
|
1 file changed, 17 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/asio/include/asio/detail/impl/socket_ops.ipp b/asio/include/asio/detail/impl/socket_ops.ipp
|
||||||
|
index ad203b74..b17a60ed 100644
|
||||||
|
--- a/asio/include/asio/detail/impl/socket_ops.ipp
|
||||||
|
+++ b/asio/include/asio/detail/impl/socket_ops.ipp
|
||||||
|
@@ -3339,6 +3339,23 @@ asio::error_code getaddrinfo(const char* host,
|
||||||
|
# endif
|
||||||
|
#elif !defined(ASIO_HAS_GETADDRINFO)
|
||||||
|
int error = getaddrinfo_emulation(host, service, &hints, result);
|
||||||
|
+ return ec = translate_addrinfo_error(error);
|
||||||
|
+#elif defined(ASIO_HAS_GETADDRINFO) && defined(ASIO_APPLE_NAT64)
|
||||||
|
+ // For NAT64 compatibility, Apple recommends to set AI_DEFAULT flags
|
||||||
|
+ addrinfo_type new_hints = hints;
|
||||||
|
+ new_hints.ai_flags |= AI_DEFAULT;
|
||||||
|
+ int error = ::getaddrinfo(host, service, &new_hints, result);
|
||||||
|
+
|
||||||
|
+ // iOS bug workaround: sometimes iOS getaddrinfo() returns a non-zero scope ID
|
||||||
|
+ // for non-link-local addresses. Workaround by forcing scope ID to 0 for
|
||||||
|
+ // non-link-local addresses.
|
||||||
|
+ if (!error && (*result)->ai_family == AF_INET6)
|
||||||
|
+ {
|
||||||
|
+ sockaddr_in6* a6 = (sockaddr_in6*)(*result)->ai_addr;
|
||||||
|
+ if (a6->sin6_scope_id && !(IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&a6->sin6_addr)))
|
||||||
|
+ a6->sin6_scope_id = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return ec = translate_addrinfo_error(error);
|
||||||
|
#else
|
||||||
|
int error = ::getaddrinfo(host, service, &hints, result);
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
From fe57c9127cfc95b4673c6530f86edab5e6538425 Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Yonan <james@openvpn.net>
|
||||||
|
Date: Wed, 2 Sep 2015 12:18:48 -0700
|
||||||
|
Subject: [PATCH] Added randomize() method to
|
||||||
|
asio::ip::tcp::resolver::results_type.
|
||||||
|
|
||||||
|
---
|
||||||
|
asio/include/asio/ip/basic_resolver_results.hpp | 7 +++++++
|
||||||
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/asio/include/asio/ip/basic_resolver_results.hpp b/asio/include/asio/ip/basic_resolver_results.hpp
|
||||||
|
index 3b3fad49..c070f7da 100644
|
||||||
|
--- a/asio/include/asio/ip/basic_resolver_results.hpp
|
||||||
|
+++ b/asio/include/asio/ip/basic_resolver_results.hpp
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
#include "asio/detail/config.hpp"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
+#include <algorithm>
|
||||||
|
#include "asio/detail/socket_ops.hpp"
|
||||||
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
#include "asio/ip/basic_resolver_iterator.hpp"
|
||||||
|
@@ -299,6 +300,12 @@ public:
|
||||||
|
return !a.equal(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ template <typename Random>
|
||||||
|
+ void randomize(Random& r)
|
||||||
|
+ {
|
||||||
|
+ std::shuffle(this->values_->begin(), this->values_->end(), r);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
private:
|
||||||
|
typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;
|
||||||
|
};
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
From 80485636d5140c4b45679a4664eb7fe9e09f574f Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Yonan <james@openvpn.net>
|
||||||
|
Date: Mon, 27 Feb 2017 13:01:26 -0700
|
||||||
|
Subject: [PATCH] Added user code hook async_connect_post_open() to be called
|
||||||
|
immediately after socket open in async_connect.
|
||||||
|
|
||||||
|
---
|
||||||
|
asio/include/asio/basic_socket.hpp | 7 +++++++
|
||||||
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/asio/include/asio/basic_socket.hpp b/asio/include/asio/basic_socket.hpp
|
||||||
|
index 42efbda4..4da85eb6 100644
|
||||||
|
--- a/asio/include/asio/basic_socket.hpp
|
||||||
|
+++ b/asio/include/asio/basic_socket.hpp
|
||||||
|
@@ -950,6 +950,8 @@ public:
|
||||||
|
{
|
||||||
|
const protocol_type protocol = peer_endpoint.protocol();
|
||||||
|
impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);
|
||||||
|
+ if (!open_ec)
|
||||||
|
+ async_connect_post_open(protocol, open_ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
return async_initiate<ConnectHandler, void (asio::error_code)>(
|
||||||
|
@@ -1800,6 +1802,11 @@ protected:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
+ // optional user code hook immediately after socket open in async_connect
|
||||||
|
+ virtual void async_connect_post_open(const protocol_type& protocol, asio::error_code& ec)
|
||||||
|
+ {
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// Disallow copying and assignment.
|
||||||
|
basic_socket(const basic_socket&) ASIO_DELETED;
|
||||||
|
basic_socket& operator=(const basic_socket&) ASIO_DELETED;
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
From af733fe9ce8345e06947dcf8b395d4736b1cb98c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lev Stipakov <lev@openvpn.net>
|
||||||
|
Date: Mon, 29 Apr 2019 10:26:13 +0300
|
||||||
|
Subject: [PATCH] error_code.ipp: Use English for Windows error messages
|
||||||
|
|
||||||
|
FormatMessageA doesn't work well with non-ASCII chars
|
||||||
|
so make it return error message in English.
|
||||||
|
|
||||||
|
Signed-off-by: Lev Stipakov <lev@openvpn.net>
|
||||||
|
---
|
||||||
|
asio/include/asio/impl/error_code.ipp | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/asio/include/asio/impl/error_code.ipp b/asio/include/asio/impl/error_code.ipp
|
||||||
|
index 55f5b361..3ef34fcd 100644
|
||||||
|
--- a/asio/include/asio/impl/error_code.ipp
|
||||||
|
+++ b/asio/include/asio/impl/error_code.ipp
|
||||||
|
@@ -80,7 +80,7 @@ public:
|
||||||
|
DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||||
|
| FORMAT_MESSAGE_FROM_SYSTEM
|
||||||
|
| FORMAT_MESSAGE_IGNORE_INSERTS, 0, value,
|
||||||
|
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
||||||
|
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (char*)&msg, 0, 0);
|
||||||
|
detail::local_free_on_block_exit local_free_obj(msg);
|
||||||
|
if (length && msg[length - 1] == '\n')
|
||||||
|
msg[--length] = '\0';
|
||||||
|
--
|
||||||
|
2.16.2.windows.1
|
||||||
|
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
export NAME=asio
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
$DIR/../../scripts/snapshot
|
||||||
Vendored
+87
@@ -0,0 +1,87 @@
|
|||||||
|
--- boost/atomic/detail/cas128strong.hpp
|
||||||
|
+++ boost/atomic/detail/cas128strong.hpp
|
||||||
|
@@ -196,15 +196,17 @@ class base_atomic<T, void, 16, Sign>
|
||||||
|
|
||||||
|
public:
|
||||||
|
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||||
|
- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
||||||
|
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
+ memset(&v_, 0, sizeof(v_));
|
||||||
|
memcpy(&v_, &v, sizeof(value_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
- storage_type value_s = 0;
|
||||||
|
+ storage_type value_s;
|
||||||
|
+ memset(&value_s, 0, sizeof(value_s));
|
||||||
|
memcpy(&value_s, &value, sizeof(value_type));
|
||||||
|
platform_fence_before_store(order);
|
||||||
|
platform_store128(value_s, &v_);
|
||||||
|
@@ -247,7 +249,9 @@ class base_atomic<T, void, 16, Sign>
|
||||||
|
memory_order success_order,
|
||||||
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
- storage_type expected_s = 0, desired_s = 0;
|
||||||
|
+ storage_type expected_s, desired_s;
|
||||||
|
+ memset(&expected_s, 0, sizeof(expected_s));
|
||||||
|
+ memset(&desired_s, 0, sizeof(desired_s));
|
||||||
|
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||||
|
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||||
|
|
||||||
|
--- boost/atomic/detail/gcc-atomic.hpp
|
||||||
|
+++ boost/atomic/detail/gcc-atomic.hpp
|
||||||
|
@@ -958,14 +958,16 @@ class base_atomic<T, void, 16, Sign>
|
||||||
|
|
||||||
|
public:
|
||||||
|
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||||
|
- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
||||||
|
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
+ memset(&v_, 0, sizeof(v_));
|
||||||
|
memcpy(&v_, &v, sizeof(value_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
- storage_type tmp = 0;
|
||||||
|
+ storage_type tmp;
|
||||||
|
+ memset(&tmp, 0, sizeof(tmp));
|
||||||
|
memcpy(&tmp, &v, sizeof(value_type));
|
||||||
|
__atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order));
|
||||||
|
}
|
||||||
|
@@ -980,7 +982,8 @@ class base_atomic<T, void, 16, Sign>
|
||||||
|
|
||||||
|
value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
- storage_type tmp = 0;
|
||||||
|
+ storage_type tmp;
|
||||||
|
+ memset(&tmp, 0, sizeof(tmp));
|
||||||
|
memcpy(&tmp, &v, sizeof(value_type));
|
||||||
|
tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order));
|
||||||
|
value_type res;
|
||||||
|
@@ -994,7 +997,9 @@ class base_atomic<T, void, 16, Sign>
|
||||||
|
memory_order success_order,
|
||||||
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
- storage_type expected_s = 0, desired_s = 0;
|
||||||
|
+ storage_type expected_s, desired_s;
|
||||||
|
+ memset(&expected_s, 0, sizeof(expected_s));
|
||||||
|
+ memset(&desired_s, 0, sizeof(desired_s));
|
||||||
|
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||||
|
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||||
|
const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false,
|
||||||
|
@@ -1010,7 +1015,9 @@ class base_atomic<T, void, 16, Sign>
|
||||||
|
memory_order success_order,
|
||||||
|
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
- storage_type expected_s = 0, desired_s = 0;
|
||||||
|
+ storage_type expected_s, desired_s;
|
||||||
|
+ memset(&expected_s, 0, sizeof(expected_s));
|
||||||
|
+ memset(&desired_s, 0, sizeof(desired_s));
|
||||||
|
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||||
|
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||||
|
const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true,
|
||||||
|
--
|
||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# SDK_PATH_SCRIPT -- optional script to set SDK path
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$TARGETS" ]; then
|
||||||
|
echo TARGETS var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# NOTE: in Boost 1.55 and earlier, set BCONF=tools/build/v2
|
||||||
|
BCONF=tools/build/src
|
||||||
|
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
[ -z "$DL" ] && DL=~/Downloads
|
||||||
|
[ -z "$GPP_CMD" ] && export GPP_CMD=g++
|
||||||
|
[ -z "$GCC_CMD" ] && export GCC_CMD=gcc
|
||||||
|
if [ "$NO_WIPE" != "1" ]; then
|
||||||
|
echo WIPE and reunzip source
|
||||||
|
rm -rf boost $BOOST_VERSION
|
||||||
|
mkdir boost
|
||||||
|
tar xfz $DL/$BOOST_VERSION.tar.gz
|
||||||
|
cd $BOOST_VERSION
|
||||||
|
#patch -p1 <$DL/asio-engine.patch
|
||||||
|
#patch -p0 <$O3/core/deps/boost/atomic-1.55.0.patch
|
||||||
|
patch -p1 <$O3/core/deps/boost/intrusive_ptr.patch
|
||||||
|
patch -p1 <$O3/core/deps/boost/page_size.patch
|
||||||
|
|
||||||
|
./bootstrap.sh
|
||||||
|
|
||||||
|
for T in $TARGETS ; do
|
||||||
|
TS="${T//-/}"
|
||||||
|
. $O3/core/vars/vars-$T
|
||||||
|
cat >>$BCONF/user-config.jam <<EOF
|
||||||
|
using $GCC_CMD : $TS : $GPP_CMD
|
||||||
|
:
|
||||||
|
<compileflags>"-Wno-unused-function $PLATFORM_FLAGS $CXX_COMPILER_FLAGS $OTHER_COMPILER_FLAGS $LIB_FPIC $LIB_OPT_LEVEL"
|
||||||
|
;
|
||||||
|
EOF
|
||||||
|
done
|
||||||
|
echo '********** BOOST CONFIG'
|
||||||
|
tail -30 $BCONF/user-config.jam
|
||||||
|
echo '********** END BOOST CONFIG'
|
||||||
|
else
|
||||||
|
echo RETAIN existing source
|
||||||
|
cd $BOOST_VERSION
|
||||||
|
for T in $TARGETS ; do
|
||||||
|
TS="${T//-/}"
|
||||||
|
. $O3/core/vars/vars-$T
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
[ "$SDK_PATH_SCRIPT" ] && . $SDK_PATH_SCRIPT
|
||||||
|
for T in $TARGETS ; do
|
||||||
|
. $O3/core/vars/vars-$T
|
||||||
|
target="${T//-/}"
|
||||||
|
stage=stage-$T
|
||||||
|
if [ "${target:(-3)}" == "dbg" ]; then
|
||||||
|
variant=debug
|
||||||
|
else
|
||||||
|
variant=release
|
||||||
|
fi
|
||||||
|
[ -z "$LINK_MODE" ] && LINK_MODE=static
|
||||||
|
echo "************************ $target $variant $stage"
|
||||||
|
cmd="./bjam -d2 toolset=${GCC_CMD}-${target} --stagedir=$stage --with-system --with-thread --with-atomic variant=$variant link=$LINK_MODE threading=multi runtime-link=$LINK_MODE"
|
||||||
|
echo $cmd
|
||||||
|
$cmd
|
||||||
|
done
|
||||||
|
mv stage-* ../boost/
|
||||||
|
cp -a boost ../boost/
|
||||||
|
exit 0
|
||||||
Vendored
+29
@@ -0,0 +1,29 @@
|
|||||||
|
diff -ur boost_1_56_0.orig/boost/smart_ptr/intrusive_ptr.hpp boost_1_56_0/boost/smart_ptr/intrusive_ptr.hpp
|
||||||
|
--- boost_1_56_0.orig/boost/smart_ptr/intrusive_ptr.hpp 2014-07-26 00:44:34.000000000 -0600
|
||||||
|
+++ boost_1_56_0/boost/smart_ptr/intrusive_ptr.hpp 2014-08-15 19:51:11.000000000 -0600
|
||||||
|
@@ -63,7 +63,7 @@
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- intrusive_ptr( T * p, bool add_ref = true ): px( p )
|
||||||
|
+ intrusive_ptr( T * p, bool add_ref = true ) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(intrusive_ptr_add_ref(static_cast<T*>(nullptr)))) : px( p )
|
||||||
|
{
|
||||||
|
if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
|
||||||
|
}
|
||||||
|
@@ -80,14 +80,14 @@
|
||||||
|
intrusive_ptr( intrusive_ptr<U> const & rhs )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
- : px( rhs.get() )
|
||||||
|
+ BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(intrusive_ptr_add_ref(static_cast<T*>(nullptr)))) : px( rhs.get() )
|
||||||
|
{
|
||||||
|
if( px != 0 ) intrusive_ptr_add_ref( px );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
|
||||||
|
+ intrusive_ptr(intrusive_ptr const & rhs) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(intrusive_ptr_add_ref(static_cast<T*>(nullptr)))) : px( rhs.px )
|
||||||
|
{
|
||||||
|
if( px != 0 ) intrusive_ptr_add_ref( px );
|
||||||
|
}
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
diff -ur boost_1_57_0/boost/thread/pthread/thread_data.hpp boost_1_57_0.new/boost/thread/pthread/thread_data.hpp
|
||||||
|
--- boost_1_57_0/boost/thread/pthread/thread_data.hpp 2014-10-24 10:43:26.000000000 -0600
|
||||||
|
+++ boost_1_57_0.new/boost/thread/pthread/thread_data.hpp 2015-02-26 00:43:26.000000000 -0700
|
||||||
|
@@ -24,8 +24,10 @@
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
-#if defined(__ANDROID__)
|
||||||
|
-#include <asm/page.h> // http://code.google.com/p/android/issues/detail?id=39983
|
||||||
|
+// JY modified
|
||||||
|
+#if defined(__ANDROID__) && !defined(PAGE_SIZE)
|
||||||
|
+#define PAGE_SIZE 4096
|
||||||
|
+//#include <asm/page.h> // http://code.google.com/p/android/issues/detail?id=39983
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$DEP_DIR" ]; then
|
||||||
|
echo DEP_DIR var must point to dependency build folder
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$DL" ]; then
|
||||||
|
echo DL var must point to the download folder
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo TARGET var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# source vars
|
||||||
|
. $O3/core/vars/vars-${TARGET}
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
# source helper functions
|
||||||
|
. $O3/core/deps/functions.sh
|
||||||
|
|
||||||
|
FNAME=cityhash-${CITYHASH_VERSION}.tar.gz
|
||||||
|
PN=${CITYHASH_VERSION#*-}
|
||||||
|
URL=https://codeload.github.com/google/cityhash/tar.gz/${CITYHASH_VERSION}
|
||||||
|
CSUM=${CITYHASH_CSUM}
|
||||||
|
|
||||||
|
download
|
||||||
|
|
||||||
|
CC=cc
|
||||||
|
LD=ld
|
||||||
|
AR=ar
|
||||||
|
RANLIB=ranlib
|
||||||
|
[ "$GCC_CMD" ] && CC=$GCC_CMD
|
||||||
|
[ "$LD_CMD" ] && LD=$LD_CMD
|
||||||
|
[ "$AR_CMD" ] && AR=$AR_CMD
|
||||||
|
[ "$RANLIB_CMD" ] && RANLIB=$RANLIB_CMD
|
||||||
|
|
||||||
|
if [ "$NO_WIPE" != "1" ]; then
|
||||||
|
rm -rf $CITYHASH_VERSION
|
||||||
|
tar xfz $DL/cityhash-$CITYHASH_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
DIST=$(pwd)/cityhash/cityhash-$PLATFORM
|
||||||
|
rm -rf $DIST
|
||||||
|
mkdir -p $DIST/include
|
||||||
|
mkdir $DIST/lib
|
||||||
|
cd cityhash-$CITYHASH_VERSION
|
||||||
|
CMD=./configure
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
CMD="$CC $PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC -I. -Isrc -c src/city.cc"
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
$AR rc $DIST/lib/libcityhash.a city.o
|
||||||
|
$RANLIB $DIST/lib/libcityhash.a
|
||||||
|
cp src/city.h $DIST/include/
|
||||||
|
exit 0
|
||||||
Vendored
+47
@@ -0,0 +1,47 @@
|
|||||||
|
function check_download()
|
||||||
|
{
|
||||||
|
if [ -f $DL/$FNAME ]; then
|
||||||
|
CHECK=$(shasum -a 256 $DL/$FNAME |awk '{printf $1};')
|
||||||
|
if [ "$CHECK" == "$CSUM" ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "Checksum mismatch for $FNAME. Was $CHECK, expected $CSUM"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$FNAME not found."
|
||||||
|
fi
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
function download()
|
||||||
|
{
|
||||||
|
check_download && return 0
|
||||||
|
|
||||||
|
rm -f $DL/$FNAME
|
||||||
|
if [ -n "$URL" ]; then
|
||||||
|
wget $URL -O $DL/$FNAME
|
||||||
|
else
|
||||||
|
echo URL must be specified
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
check_download || return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
function apply_patches()
|
||||||
|
{
|
||||||
|
DEP_NAME=$1
|
||||||
|
|
||||||
|
# change directory since git apply got confused when
|
||||||
|
# applying patches to files which are not found in index
|
||||||
|
DIR=$(pwd)
|
||||||
|
pushd ${DIR}
|
||||||
|
cd /tmp
|
||||||
|
# apply pre-generated patches
|
||||||
|
for file in $O3/core/deps/${DEP_NAME}/patches/*.patch; do
|
||||||
|
echo Applying patch: $file
|
||||||
|
git apply --directory ${DIR} --unsafe-path $file
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
}
|
||||||
Vendored
+24
@@ -0,0 +1,24 @@
|
|||||||
|
export ASIO_VERSION=asio-1-14-0
|
||||||
|
export ASIO_CSUM=bdb01a649c24d73ca4a836662e7af442d935313ed6deef6b07f17f3bc5f78d7a
|
||||||
|
|
||||||
|
export LZ4_VERSION=lz4-1.8.3
|
||||||
|
export LZ4_CSUM=33af5936ac06536805f9745e0b6d61da606a1f8b4cc5c04dd3cbaca3b9b4fc43
|
||||||
|
|
||||||
|
export MBEDTLS_VERSION=mbedtls-2.7.12
|
||||||
|
export MBEDTLS_CSUM=d3a36dbc9f607747daa6875c1ab2e41f49eff5fc99d3436b4f3ac90c89f3c143
|
||||||
|
|
||||||
|
export JSONCPP_VERSION=1.8.4
|
||||||
|
export JSONCPP_CSUM=c49deac9e0933bcb7044f08516861a2d560988540b23de2ac1ad443b219afdb6
|
||||||
|
|
||||||
|
export TAP_VERSION=0e30f5c13b3c7b0bdd60da915350f653e4c14d92
|
||||||
|
export TAP_CSUM=8ff65f9e741c5ecfe1af904eaa38713f05639ce9457ef92041fd8e6b2a170315
|
||||||
|
|
||||||
|
export CITYHASH_VERSION=8af9b8c2b889d80c22d6bc26ba0df1afb79a30db
|
||||||
|
export CITYHASH_CSUM=f70368facd15735dffc77fe2b27ab505bfdd05be5e9166d94149a8744c212f49
|
||||||
|
|
||||||
|
export LZO_VERSION=lzo-2.10
|
||||||
|
export LZO_CSUM=c0f892943208266f9b6543b3ae308fab6284c5c90e627931446fb49b4221a072
|
||||||
|
|
||||||
|
export OPENSSL_VERSION=openssl-1.1.1d
|
||||||
|
export OPENSSL_CSUM=1e3a91bc1f9dfce01af26026f856e064eab4c8ee0a8f457b5ae30b40b8b711f2
|
||||||
|
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$DEP_DIR" ]; then
|
||||||
|
echo DEP_DIR var must point to dependency build folder
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$DL" ]; then
|
||||||
|
echo DL var must point to the download folder
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo TARGET var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# source vars
|
||||||
|
. $O3/core/vars/vars-${TARGET}
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
# source helper functions
|
||||||
|
. $O3/core/deps/functions.sh
|
||||||
|
|
||||||
|
FNAME=${LZ4_VERSION}.tar.gz
|
||||||
|
PN=${LZ4_VERSION#*-}
|
||||||
|
URL=https://github.com/lz4/lz4/archive/v${PN}.tar.gz
|
||||||
|
CSUM=${LZ4_CSUM}
|
||||||
|
|
||||||
|
download
|
||||||
|
|
||||||
|
CC=cc
|
||||||
|
LD=ld
|
||||||
|
AR=ar
|
||||||
|
RANLIB=ranlib
|
||||||
|
[ "$GCC_CMD" ] && CC=$GCC_CMD
|
||||||
|
[ "$LD_CMD" ] && LD=$LD_CMD
|
||||||
|
[ "$AR_CMD" ] && AR=$AR_CMD
|
||||||
|
[ "$RANLIB_CMD" ] && RANLIB=$RANLIB_CMD
|
||||||
|
|
||||||
|
if [ "$NO_WIPE" != "1" ]; then
|
||||||
|
rm -rf $LZ4_VERSION
|
||||||
|
tar xfz $DL/$LZ4_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "x$NO_BUILD" == x1 ]; then
|
||||||
|
echo "Not building"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
DIST=$(pwd)/lz4/lz4-$PLATFORM
|
||||||
|
rm -rf $DIST
|
||||||
|
mkdir -p $DIST/include
|
||||||
|
mkdir $DIST/lib
|
||||||
|
cd $LZ4_VERSION/lib
|
||||||
|
CMD="$CC $PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC -c lz4.c"
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
$AR rc $DIST/lib/liblz4.a lz4.o
|
||||||
|
$RANLIB $DIST/lib/liblz4.a
|
||||||
|
cp lz4.h $DIST/include/
|
||||||
|
exit 0
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
export NAME=lz4
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
$DIR/../../scripts/snapshot
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$DEP_DIR" ]; then
|
||||||
|
echo DEP_DIR var must point to dependency build folder
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo TARGET var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$DL" ] && DL=~/Downloads
|
||||||
|
|
||||||
|
# source vars
|
||||||
|
. $O3/core/vars/vars-${TARGET}
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
# source helper functions
|
||||||
|
. $O3/core/deps/functions.sh
|
||||||
|
|
||||||
|
FNAME=${LZO_VERSION}.tar.gz
|
||||||
|
PN=${LZO_VERSION#*-}
|
||||||
|
URL=http://www.oberhumer.com/opensource/lzo/download/${LZO_VERSION}.tar.gz
|
||||||
|
CSUM=${LZO_CSUM}
|
||||||
|
|
||||||
|
download
|
||||||
|
|
||||||
|
CC=cc
|
||||||
|
LD=ld
|
||||||
|
AR=ar
|
||||||
|
RANLIB=ranlib
|
||||||
|
[ "$GCC_CMD" ] && CC=$GCC_CMD
|
||||||
|
[ "$LD_CMD" ] && LD=$LD_CMD
|
||||||
|
[ "$AR_CMD" ] && AR=$AR_CMD
|
||||||
|
[ "$RANLIB_CMD" ] && RANLIB=$RANLIB_CMD
|
||||||
|
|
||||||
|
case $PLATFORM in
|
||||||
|
android*)
|
||||||
|
echo PLATFORM android
|
||||||
|
host=arm
|
||||||
|
target=arm
|
||||||
|
;;
|
||||||
|
ios*)
|
||||||
|
echo PLATFORM ios
|
||||||
|
host="x86_64-apple-darwin"
|
||||||
|
target=arm
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
host=""
|
||||||
|
target=""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$target" ]; then
|
||||||
|
targ_opt="--target=$target"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$host" ]; then
|
||||||
|
host_opt="--host=$host"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$NO_WIPE" != "1" ]; then
|
||||||
|
rm -rf $LZO_VERSION
|
||||||
|
tar xfz $DL/$LZO_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
DIST=$(pwd)/lzo/lzo-$PLATFORM
|
||||||
|
rm -rf $DIST
|
||||||
|
mkdir -p $DIST
|
||||||
|
cd $LZO_VERSION
|
||||||
|
echo 'OPTIONS' $CC $LD $AR $RANLIB $host_opt $targ_opt
|
||||||
|
CFLAGS="$PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC" ./configure --prefix=$DIST $host_opt $targ_opt
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
exit 0
|
||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$DEP_DIR" ]; then
|
||||||
|
echo DEP_DIR var must point to dependency build folder
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$DL" ]; then
|
||||||
|
echo DL var must point to the download folder
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo TARGET var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# source vars
|
||||||
|
. $O3/core/vars/vars-${TARGET}
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
# source helper functions
|
||||||
|
. $O3/core/deps/functions.sh
|
||||||
|
|
||||||
|
FNAME=${MBEDTLS_VERSION}-apache.tgz
|
||||||
|
PN=${MBEDTLS_VERSION#*-}
|
||||||
|
URL=https://tls.mbed.org/download/$MBEDTLS_VERSION-apache.tgz
|
||||||
|
CSUM=${MBEDTLS_CSUM}
|
||||||
|
|
||||||
|
download
|
||||||
|
|
||||||
|
# put build targets here
|
||||||
|
DIST=$(pwd)/mbedtls/mbedtls-$PLATFORM
|
||||||
|
rm -rf $DIST
|
||||||
|
mkdir -p $DIST
|
||||||
|
|
||||||
|
if [ "$NO_WIPE" = "1" ]; then
|
||||||
|
echo RETAIN existing source
|
||||||
|
cd $MBEDTLS_VERSION
|
||||||
|
else
|
||||||
|
echo WIPE and reunzip source
|
||||||
|
rm -rf $MBEDTLS_VERSION
|
||||||
|
[ -z "$DL" ] && DL=~/Downloads
|
||||||
|
tar xfz $DL/$MBEDTLS_VERSION-apache.tgz
|
||||||
|
cd $MBEDTLS_VERSION
|
||||||
|
|
||||||
|
# enable MD4 (needed for NTLM auth)
|
||||||
|
perl -pi -e 's/^\/\/// if /#define MBEDTLS_MD4_C/' include/mbedtls/config.h
|
||||||
|
|
||||||
|
apply_patches "mbedtls"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "x$NO_BUILD" == x1 ]; then
|
||||||
|
echo "Not building"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "x$TARGET" == xlinux* || "x$TARGET" == xosx* ]]; then
|
||||||
|
# run unit tests and then clean
|
||||||
|
echo RUNNING CHECK
|
||||||
|
make check
|
||||||
|
echo CLEANING
|
||||||
|
make clean
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo BUILDING
|
||||||
|
|
||||||
|
# compiler vars
|
||||||
|
CC=cc
|
||||||
|
LD=ld
|
||||||
|
AR=ar
|
||||||
|
RANLIB=ranlib
|
||||||
|
[ "$GCC_CMD" ] && CC=$GCC_CMD
|
||||||
|
[ "$LD_CMD" ] && LD=$LD_CMD
|
||||||
|
[ "$AR_CMD" ] && AR=$AR_CMD
|
||||||
|
[ "$RANLIB_CMD" ] && RANLIB=$RANLIB_CMD
|
||||||
|
|
||||||
|
# build it
|
||||||
|
SRC=$(pwd)
|
||||||
|
cd library
|
||||||
|
rm -f *.o
|
||||||
|
for c in *.c ; do
|
||||||
|
CMD="$CC -I../include -DMBEDTLS_RELAXED_X509_DATE \
|
||||||
|
$PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC -c $c"
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
done
|
||||||
|
|
||||||
|
# create archive
|
||||||
|
cd $DIST
|
||||||
|
mkdir library
|
||||||
|
$AR rc library/libmbedtls.a $SRC/library/*.o
|
||||||
|
$RANLIB library/libmbedtls.a 2>&1 | grep -v "has no symbols" || true
|
||||||
|
|
||||||
|
# copy headers
|
||||||
|
mkdir -p include/mbedtls
|
||||||
|
cp $SRC/include/mbedtls/*.h include/mbedtls/
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
From 0554efae4e27b6a764def80f600394519ef1addb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Antonio Quartulli <antonio@openvpn.net>
|
||||||
|
Date: Tue, 20 Mar 2018 09:35:47 +0800
|
||||||
|
Subject: [PATCH 1/2] relax x509 date format check
|
||||||
|
|
||||||
|
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
|
||||||
|
---
|
||||||
|
library/x509.c | 18 +++++++++++++++++-
|
||||||
|
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/library/x509.c b/library/x509.c
|
||||||
|
index 264c7fb0c..9372bcb92 100644
|
||||||
|
--- a/library/x509.c
|
||||||
|
+++ b/library/x509.c
|
||||||
|
@@ -556,13 +556,20 @@ static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
|
||||||
|
/*
|
||||||
|
* Parse seconds if present
|
||||||
|
*/
|
||||||
|
- if ( len >= 2 )
|
||||||
|
+ if ( len >= 2 && **p >= '0' && **p <= '9' )
|
||||||
|
{
|
||||||
|
CHECK( x509_parse_int( p, 2, &tm->sec ) );
|
||||||
|
len -= 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
+ {
|
||||||
|
+#if defined(MBEDTLS_RELAXED_X509_DATE)
|
||||||
|
+ /* if relaxed mode, allow seconds to be absent */
|
||||||
|
+ tm->sec = 0;
|
||||||
|
+#else
|
||||||
|
return ( MBEDTLS_ERR_X509_INVALID_DATE );
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse trailing 'Z' if present
|
||||||
|
@@ -572,6 +579,15 @@ static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
|
||||||
|
(*p)++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
+#if defined(MBEDTLS_RELAXED_X509_DATE)
|
||||||
|
+ else if ( len == 5 && **p == '+' )
|
||||||
|
+ {
|
||||||
|
+ int tz; /* throwaway timezone */
|
||||||
|
+ (*p)++;
|
||||||
|
+ CHECK( x509_parse_int( p, 4, &tz ) );
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We should have parsed all characters at this point
|
||||||
|
--
|
||||||
|
2.18.0
|
||||||
|
|
||||||
+361
@@ -0,0 +1,361 @@
|
|||||||
|
From 076f1437fe82de0b1f0ecf9a7ca031cd94c0c579 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lev Stipakov <lev@openvpn.net>
|
||||||
|
Date: Fri, 23 Feb 2018 17:12:49 +0200
|
||||||
|
Subject: [PATCH] Enable allowing unsupported critical extensions in runtime
|
||||||
|
|
||||||
|
When compile time flag MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
|
||||||
|
is not set, certificate parsing fails if certificate contains unsupported critical extension.
|
||||||
|
|
||||||
|
This patch allows to modify this behavior in runtime.
|
||||||
|
|
||||||
|
Signed-off-by: Lev Stipakov <lev@openvpn.net>
|
||||||
|
---
|
||||||
|
include/mbedtls/oid.h | 13 +++-
|
||||||
|
include/mbedtls/ssl.h | 22 ++++++
|
||||||
|
include/mbedtls/x509_crt.h | 2 +
|
||||||
|
library/oid.c | 81 ++++++++++++++++++----
|
||||||
|
library/ssl_tls.c | 8 +++
|
||||||
|
library/x509_crt.c | 10 ++-
|
||||||
|
tests/data_files/test-ca-nc.crt | 20 ++++++
|
||||||
|
tests/suites/test_suite_x509parse.data | 6 ++
|
||||||
|
tests/suites/test_suite_x509parse.function | 15 ++++
|
||||||
|
9 files changed, 162 insertions(+), 15 deletions(-)
|
||||||
|
create mode 100644 tests/data_files/test-ca-nc.crt
|
||||||
|
|
||||||
|
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
|
||||||
|
index 408645ece..b116736f8 100644
|
||||||
|
--- a/include/mbedtls/oid.h
|
||||||
|
+++ b/include/mbedtls/oid.h
|
||||||
|
@@ -410,7 +410,7 @@ int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_b
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
|
||||||
|
/**
|
||||||
|
- * \brief Translate an X.509 extension OID into local values
|
||||||
|
+ * \brief Translate supported X.509 extension OID into local values
|
||||||
|
*
|
||||||
|
* \param oid OID to use
|
||||||
|
* \param ext_type place to store the extension type
|
||||||
|
@@ -418,6 +418,17 @@ int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_b
|
||||||
|
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
|
*/
|
||||||
|
int mbedtls_oid_get_x509_ext_type( const mbedtls_asn1_buf *oid, int *ext_type );
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief Translate supported and unsupported X.509 extension OID into local values
|
||||||
|
+ *
|
||||||
|
+ * \param oid OID to use
|
||||||
|
+ * \param ext_type place to store the extension type
|
||||||
|
+ * \param is_supported place to store flag if extension is supported (1 - supported, 0 otherwise)
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||||
|
+ */
|
||||||
|
+int mbedtls_oid_get_x509_ext_type_supported( const mbedtls_asn1_buf *oid, int *ext_type, int *is_supported );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
|
||||||
|
index 5fd6969da..1087ea166 100644
|
||||||
|
--- a/include/mbedtls/ssl.h
|
||||||
|
+++ b/include/mbedtls/ssl.h
|
||||||
|
@@ -696,6 +696,10 @@ struct mbedtls_ssl_config
|
||||||
|
retransmission timeout (ms) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ uint32_t allowed_unsupported_critical_exts; /*!< Bit flags which represent runtime-enabled
|
||||||
|
+ unsupported critical extensions, e.g.
|
||||||
|
+ MBEDTLS_X509_EXT_NAME_CONSTRAINTS */
|
||||||
|
+
|
||||||
|
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
||||||
|
int renego_max_records; /*!< grace period for renegotiation */
|
||||||
|
unsigned char renego_period[8]; /*!< value of the record counters
|
||||||
|
@@ -2298,6 +2302,24 @@ void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
|
||||||
|
const unsigned char period[8] );
|
||||||
|
#endif /* MBEDTLS_SSL_RENEGOTIATION */
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * \brief Allows unsupported critical extensions
|
||||||
|
+ *
|
||||||
|
+ * Without compile-time flag MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
|
||||||
|
+ * mbedTLS fails certificate verification if certificate contains
|
||||||
|
+ * unsupported critical extensions.
|
||||||
|
+ *
|
||||||
|
+ * This method allows to modify behavior in runtime by providing
|
||||||
|
+ * bit flags which represent unsupported extensions (for example MBEDTLS_X509_EXT_NAME_CONSTRAINTS)
|
||||||
|
+ * which should be allowed despite missing above mentioned compile-time flag.
|
||||||
|
+ *
|
||||||
|
+ * \param conf SSL configuration
|
||||||
|
+ * \param exts Bit flags which represent runtime-enabled unsupported critical extensions,
|
||||||
|
+ * e.g. MBEDTLS_X509_EXT_NAME_CONSTRAINTS
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+void mbedtls_ssl_conf_allow_unsupported_critical_exts( mbedtls_ssl_config *conf, uint32_t exts );
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* \brief Return the number of data bytes available to read
|
||||||
|
*
|
||||||
|
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
|
||||||
|
index e72231ee8..9df19e52c 100644
|
||||||
|
--- a/include/mbedtls/x509_crt.h
|
||||||
|
+++ b/include/mbedtls/x509_crt.h
|
||||||
|
@@ -90,6 +90,8 @@ typedef struct mbedtls_x509_crt
|
||||||
|
mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
|
||||||
|
void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
|
||||||
|
|
||||||
|
+ uint32_t allowed_unsupported_critical_exts; /**< Optional Bit flags which represent runtime-enabled unsupported critical extensions, e.g. MBEDTLS_X509_EXT_NAME_CONSTRAINTS */
|
||||||
|
+
|
||||||
|
struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */
|
||||||
|
}
|
||||||
|
mbedtls_x509_crt;
|
||||||
|
diff --git a/library/oid.c b/library/oid.c
|
||||||
|
index edea950f8..a756d2801 100644
|
||||||
|
--- a/library/oid.c
|
||||||
|
+++ b/library/oid.c
|
||||||
|
@@ -254,38 +254,95 @@ FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, oid_x520_attr_t, x520_attr, co
|
||||||
|
typedef struct {
|
||||||
|
mbedtls_oid_descriptor_t descriptor;
|
||||||
|
int ext_type;
|
||||||
|
+ int is_supported;
|
||||||
|
} oid_x509_ext_t;
|
||||||
|
|
||||||
|
static const oid_x509_ext_t oid_x509_ext[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
- { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
|
||||||
|
- MBEDTLS_X509_EXT_BASIC_CONSTRAINTS,
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), "id-ce-authorityKeyIdentifier", "Authority Key Identifier" },
|
||||||
|
+ MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER, 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
- { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
|
||||||
|
- MBEDTLS_X509_EXT_KEY_USAGE,
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ), "id-ce-subjectKeyIdentifier", "Subject Key Identifier" },
|
||||||
|
+ MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER, 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
- { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
|
||||||
|
- MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE,
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
|
||||||
|
+ MBEDTLS_X509_EXT_KEY_USAGE, 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
- { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
|
||||||
|
- MBEDTLS_X509_EXT_SUBJECT_ALT_NAME,
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_CERTIFICATE_POLICIES ), "id-ce-certificatePolicies", "Certificate Policies" },
|
||||||
|
+ MBEDTLS_X509_EXT_CERTIFICATE_POLICIES, 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
- { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
|
||||||
|
- MBEDTLS_X509_EXT_NS_CERT_TYPE,
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_POLICY_MAPPINGS ), "id-ce-policyMappings", "Policy Mapping" },
|
||||||
|
+ MBEDTLS_X509_EXT_POLICY_MAPPINGS, 0,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_ISSUER_ALT_NAME ), "id-ce-issuerAltName", "Issuer Alt Name" },
|
||||||
|
+ MBEDTLS_X509_EXT_ISSUER_ALT_NAME, 0,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS ), "id-ce-subjectDirectoryAttributes", "Subject Directory Attributes" },
|
||||||
|
+ MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS, 0,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
|
||||||
|
+ MBEDTLS_X509_EXT_BASIC_CONSTRAINTS, 1,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_NAME_CONSTRAINTS ), "id-ce-nameConstraints", "Name Constraints" },
|
||||||
|
+ MBEDTLS_X509_EXT_NAME_CONSTRAINTS, 0,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_POLICY_CONSTRAINTS ), "id-ce-policyConstraints", "Policy Constraints" },
|
||||||
|
+ MBEDTLS_X509_EXT_POLICY_CONSTRAINTS, 0,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
|
||||||
|
+ MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE, 1
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_CRL_DISTRIBUTION_POINTS ), "id-ce-cRLDistributionPoints", "CRL Distribution Points" },
|
||||||
|
+ MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS, 0,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_INIHIBIT_ANYPOLICY ), "id-ce-inhibitAnyPolicy", "Inhibit Any Policy" },
|
||||||
|
+ MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY, 0,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_FRESHEST_CRL ), "id-ce-freshestCRL", "Freshest CRL" },
|
||||||
|
+ MBEDTLS_X509_EXT_FRESHEST_CRL, 0,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
|
||||||
|
+ MBEDTLS_X509_EXT_SUBJECT_ALT_NAME, 1
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
|
||||||
|
+ MBEDTLS_X509_EXT_NS_CERT_TYPE, 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ NULL, 0, NULL, NULL },
|
||||||
|
- 0,
|
||||||
|
+ 0, 0
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext)
|
||||||
|
-FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type)
|
||||||
|
+FN_OID_GET_ATTR2(mbedtls_oid_get_x509_ext_type_supported, oid_x509_ext_t, x509_ext, int, ext_type, int, is_supported)
|
||||||
|
+
|
||||||
|
+int mbedtls_oid_get_x509_ext_type( const mbedtls_asn1_buf *oid, int *ext_type )
|
||||||
|
+{
|
||||||
|
+ int ret = 0;
|
||||||
|
+ int is_supported = 0;
|
||||||
|
+
|
||||||
|
+ ret = mbedtls_oid_get_x509_ext_type_supported(oid, ext_type, &is_supported);
|
||||||
|
+ if( is_supported == 0 )
|
||||||
|
+ ret = MBEDTLS_ERR_OID_NOT_FOUND;
|
||||||
|
+
|
||||||
|
+ return( ret );
|
||||||
|
+}
|
||||||
|
|
||||||
|
static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
|
||||||
|
{
|
||||||
|
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
|
||||||
|
index 1270ee9b8..2ce3f9b7d 100644
|
||||||
|
--- a/library/ssl_tls.c
|
||||||
|
+++ b/library/ssl_tls.c
|
||||||
|
@@ -4668,6 +4668,9 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
|
||||||
|
|
||||||
|
mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert );
|
||||||
|
|
||||||
|
+ ssl->session_negotiate->peer_cert->allowed_unsupported_critical_exts =
|
||||||
|
+ ssl->conf->allowed_unsupported_critical_exts;
|
||||||
|
+
|
||||||
|
i += 3;
|
||||||
|
|
||||||
|
while( i < ssl->in_hslen )
|
||||||
|
@@ -6626,6 +6629,11 @@ void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_SSL_RENEGOTIATION */
|
||||||
|
|
||||||
|
+void mbedtls_ssl_conf_allow_unsupported_critical_exts( mbedtls_ssl_config *conf, uint32_t exts )
|
||||||
|
+{
|
||||||
|
+ conf->allowed_unsupported_critical_exts = exts;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||||
|
#if defined(MBEDTLS_SSL_CLI_C)
|
||||||
|
void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets )
|
||||||
|
diff --git a/library/x509_crt.c b/library/x509_crt.c
|
||||||
|
index 3ad53a715..130b3ad1b 100644
|
||||||
|
--- a/library/x509_crt.c
|
||||||
|
+++ b/library/x509_crt.c
|
||||||
|
@@ -539,6 +539,7 @@ static int x509_get_crt_ext( unsigned char **p,
|
||||||
|
int ret;
|
||||||
|
size_t len;
|
||||||
|
unsigned char *end_ext_data, *end_ext_octet;
|
||||||
|
+ int is_supported;
|
||||||
|
|
||||||
|
if( *p == end )
|
||||||
|
return( 0 );
|
||||||
|
@@ -593,9 +594,9 @@ static int x509_get_crt_ext( unsigned char **p,
|
||||||
|
/*
|
||||||
|
* Detect supported extensions
|
||||||
|
*/
|
||||||
|
- ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
|
||||||
|
+ ret = mbedtls_oid_get_x509_ext_type_supported( &extn_oid, &ext_type, &is_supported );
|
||||||
|
|
||||||
|
- if( ret != 0 )
|
||||||
|
+ if( ( ret != 0 ) || ( is_supported == 0 ) )
|
||||||
|
{
|
||||||
|
/* No parser found, skip extension */
|
||||||
|
*p = end_ext_octet;
|
||||||
|
@@ -603,6 +604,10 @@ static int x509_get_crt_ext( unsigned char **p,
|
||||||
|
#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
|
||||||
|
if( is_critical )
|
||||||
|
{
|
||||||
|
+ /* Do not fail if extension is found, but unsupported and allowed in runtime */
|
||||||
|
+ if( ( ret == 0 ) && ( ext_type & crt->allowed_unsupported_critical_exts ) )
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
/* Data is marked as critical: fail */
|
||||||
|
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
|
||||||
|
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
|
||||||
|
@@ -956,6 +961,7 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *bu
|
||||||
|
|
||||||
|
prev = crt;
|
||||||
|
mbedtls_x509_crt_init( crt->next );
|
||||||
|
+ crt->next->allowed_unsupported_critical_exts = crt->allowed_unsupported_critical_exts;
|
||||||
|
crt = crt->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/tests/data_files/test-ca-nc.crt b/tests/data_files/test-ca-nc.crt
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..7e0c56134
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/data_files/test-ca-nc.crt
|
||||||
|
@@ -0,0 +1,20 @@
|
||||||
|
+-----BEGIN CERTIFICATE-----
|
||||||
|
+MIIDSzCCAjOgAwIBAgIJAJx/NjT4C4viMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNV
|
||||||
|
+BAMMCExlZXZpQ0E0MB4XDTE4MDEyNzE1MDczMloXDTI4MDEyNTE1MDczMlowEzER
|
||||||
|
+MA8GA1UEAwwITGVldmlDQTQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
|
+AQDWN79RTlyFm5o0LVMSVjc68W0+gtl95xpaaD7IS6gDYjcbGnCwSefiq7y9rtck
|
||||||
|
+OM1A5Bzhj5+iWbmZStUmeJUhSGgxP/FxuUaAV0fsBGJ5jDrzmbhzDkHsNxDMB2ks
|
||||||
|
+XFyy4LfODcBs9TXxY43KUKuq/0meiT3WAaZWHMYle9vkQJM2l0RyH4IXHCHiIRwd
|
||||||
|
+2wntin6T9QOFJOc2ietNb7KsXVne81wb7h9BVMsjCIAsbPpHa+PZQs1xFuxmRxCs
|
||||||
|
+kpavnMy+SqevHhvqtvbHppcXYtZspTnkVoXWUdx3HHXgZMQKlAWlwyx57xpZBU2g
|
||||||
|
+qksO+KCLVYOQMN9usmuMOpHHAgMBAAGjgaEwgZ4wHQYDVR0eAQH/BBMwEaAPMA2C
|
||||||
|
+C2V4YW1wbGUuY29tMB0GA1UdDgQWBBR3T9IilPeRAFfLO8ocg216OBo+6DBDBgNV
|
||||||
|
+HSMEPDA6gBR3T9IilPeRAFfLO8ocg216OBo+6KEXpBUwEzERMA8GA1UEAwwITGVl
|
||||||
|
+dmlDQTSCCQCcfzY0+AuL4jAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq
|
||||||
|
+hkiG9w0BAQsFAAOCAQEAR086ciNM3ujSQNhhguqFHYGfDRRuAgOk4l7GXIfFa9te
|
||||||
|
+B2KMLSwP367QaMwFxRrOoDvixIjzbpiiKB3cv+IXqGyfsRJw47XLwGK4FtSsXjst
|
||||||
|
+m2M8W5iXBQ94XoLj9OKb4ZJWKI930S/PF7uuxICtWttYSoylfyMkiR45+1SLj2eF
|
||||||
|
+X4EnXK3Q0H42v8LCDFqj9iNQ2WMLwA7kFPB+oOZxkFi2G0F3VuW+JZeBPQCpYdRO
|
||||||
|
+0kQQ/gIZE6KEdscKHi9y6OfGSeRlDBMADky9NiZy7I3AcspLcmMQh/191/DnooNe
|
||||||
|
+OwQ6w1HweApjB46bGyILpGUi9MZhvCnoLWg+cN3/wQ==
|
||||||
|
+-----END CERTIFICATE-----
|
||||||
|
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
|
||||||
|
index 0fe68cb06..e39f065e2 100644
|
||||||
|
--- a/tests/suites/test_suite_x509parse.data
|
||||||
|
+++ b/tests/suites/test_suite_x509parse.data
|
||||||
|
@@ -1798,6 +1798,12 @@ X509 File parse (trailing spaces, OK)
|
||||||
|
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
|
||||||
|
x509parse_crt_file:"data_files/server7_trailing_space.crt":0
|
||||||
|
|
||||||
|
+X509 File parse (unsupported critical ext Name Constraints, fail)
|
||||||
|
+x509parse_crt_file:"data_files/test-ca-nc.crt":MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
|
||||||
|
+
|
||||||
|
+X509 File parse (allowed unsupported critical ext Name Constraints, ok)
|
||||||
|
+x509parse_crt_file_allow_exts:"data_files/test-ca-nc.crt":MBEDTLS_X509_EXT_NAME_CONSTRAINTS:0
|
||||||
|
+
|
||||||
|
X509 Get time (UTC no issues)
|
||||||
|
depends_on:MBEDTLS_X509_USE_C
|
||||||
|
x509_get_time:MBEDTLS_ASN1_UTC_TIME:"500101000000Z":0:1950:1:1:0:0:0
|
||||||
|
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
|
||||||
|
index 584ee822b..c12a0e0ef 100644
|
||||||
|
--- a/tests/suites/test_suite_x509parse.function
|
||||||
|
+++ b/tests/suites/test_suite_x509parse.function
|
||||||
|
@@ -448,6 +448,21 @@ exit:
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_FS_IO */
|
||||||
|
+void x509parse_crt_file_allow_exts( char *crt_file, int exts, int result )
|
||||||
|
+{
|
||||||
|
+ mbedtls_x509_crt crt;
|
||||||
|
+
|
||||||
|
+ mbedtls_x509_crt_init( &crt );
|
||||||
|
+ crt.allowed_unsupported_critical_exts = exts;
|
||||||
|
+
|
||||||
|
+ TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == result );
|
||||||
|
+
|
||||||
|
+exit:
|
||||||
|
+ mbedtls_x509_crt_free( &crt );
|
||||||
|
+}
|
||||||
|
+/* END_CASE */
|
||||||
|
+
|
||||||
|
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
|
||||||
|
void x509parse_crt( char *crt_data, char *result_str, int result )
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.22.0.windows.1
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Only in mbedtls-2.7.5/include/mbedtls: #bn_mul.h#
|
||||||
|
diff -ur mbedtls-2.7.5/include/mbedtls/bn_mul.h mbedtls-2.7.5.patch/include/mbedtls/bn_mul.h
|
||||||
|
--- mbedtls-2.7.5/include/mbedtls/bn_mul.h 2018-07-26 15:33:14.000000000 +0200
|
||||||
|
+++ mbedtls-2.7.5.patch/include/mbedtls/bn_mul.h 2018-08-22 14:37:31.000000000 +0200
|
||||||
|
@@ -56,7 +56,7 @@
|
||||||
|
* This is done as the number of registers used in the assembly code doesn't
|
||||||
|
* work with the -O0 option.
|
||||||
|
*/
|
||||||
|
-#if defined(__i386__) && defined(__OPTIMIZE__)
|
||||||
|
+#if defined(__i386__) && defined(__OPTIMIZE__) && (!defined(__ANDROID_API__) || defined(__clang__))
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( \
|
||||||
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
--- aes-armv4.pl.orig 2012-09-03 00:16:20.000000000 -0600
|
||||||
|
+++ aes-armv4.pl 2012-09-03 00:17:22.000000000 -0600
|
||||||
|
@@ -171,7 +170,8 @@
|
||||||
|
stmdb sp!,{r1,r4-r12,lr}
|
||||||
|
mov $rounds,r0 @ inp
|
||||||
|
mov $key,r2
|
||||||
|
- sub $tbl,r3,#AES_encrypt-AES_Te @ Te
|
||||||
|
+ad1=AES_encrypt-AES_Te
|
||||||
|
+ sub $tbl,r3,#ad1 @ Te
|
||||||
|
#if __ARM_ARCH__<7
|
||||||
|
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
|
||||||
|
ldrb $t1,[$rounds,#2] @ manner...
|
||||||
|
@@ -426,7 +426,8 @@
|
||||||
|
bne .Labrt
|
||||||
|
|
||||||
|
.Lok: stmdb sp!,{r4-r12,lr}
|
||||||
|
- sub $tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4
|
||||||
|
+ad2=_armv4_AES_set_encrypt_key-AES_Te-1024
|
||||||
|
+ sub $tbl,r3,#ad2 @ Te4
|
||||||
|
|
||||||
|
mov $rounds,r0 @ inp
|
||||||
|
mov lr,r1 @ bits
|
||||||
|
@@ -887,7 +888,8 @@
|
||||||
|
stmdb sp!,{r1,r4-r12,lr}
|
||||||
|
mov $rounds,r0 @ inp
|
||||||
|
mov $key,r2
|
||||||
|
- sub $tbl,r3,#AES_decrypt-AES_Td @ Td
|
||||||
|
+ad3=AES_decrypt-AES_Td
|
||||||
|
+ sub $tbl,r3,#ad3 @ Td
|
||||||
|
#if __ARM_ARCH__<7
|
||||||
|
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
|
||||||
|
ldrb $t1,[$rounds,#2] @ manner...
|
||||||
+759
@@ -0,0 +1,759 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# arm-as-to-ios Modify ARM assembly code for the iOS assembler
|
||||||
|
#
|
||||||
|
# Copyright (c) 2012 Psellos http://psellos.com/
|
||||||
|
# Licensed under the MIT License:
|
||||||
|
# http://www.opensource.org/licenses/mit-license.php
|
||||||
|
#
|
||||||
|
# Resources for running OCaml on iOS: http://psellos.com/ocaml/
|
||||||
|
#
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
VERSION = '1.4.0'
|
||||||
|
|
||||||
|
initial_glosyms = []
|
||||||
|
initial_defsyms = []
|
||||||
|
|
||||||
|
# Character classes for expression lexing.
|
||||||
|
#
|
||||||
|
g_ccid0 = '[$.A-Z_a-z\x80-\xff]' # Beginning of id
|
||||||
|
g_ccid = '[$.0-9A-Z_a-z\x80-\xff]' # Later in id
|
||||||
|
def ccc(cc): # Complement the class
|
||||||
|
if cc[1] == '^':
|
||||||
|
return cc[0] + cc[2:]
|
||||||
|
return cc[0] + '^' + cc[1:]
|
||||||
|
def ccce(cc): # Complement the class, include EOL
|
||||||
|
return '(?:' + ccc(cc) + '|$)'
|
||||||
|
|
||||||
|
# Prefixes for pooled symbol labels and jump table base labels. They're
|
||||||
|
# in the space of Linux assembler local symbols. Later rules will
|
||||||
|
# modify them to the Loc() form.
|
||||||
|
#
|
||||||
|
g_poolpfx = '.LP'
|
||||||
|
g_basepfx = '.LB'
|
||||||
|
|
||||||
|
|
||||||
|
def exists(p, l):
|
||||||
|
for l1 in l:
|
||||||
|
if p(l1):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def forall(p, l):
|
||||||
|
for l1 in l:
|
||||||
|
if not p(l1):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def add_prefix(instrs):
|
||||||
|
# Add compatibility macros for all systems, plus hardware
|
||||||
|
# definitions and compatibility macros for iOS.
|
||||||
|
#
|
||||||
|
# All systems:
|
||||||
|
#
|
||||||
|
# Glo() cpp macro for making global symbols (xxx vs _xxx)
|
||||||
|
# Loc() cpp macro for making local symbols (.Lxxx vs Lxxx)
|
||||||
|
# .funtype Expands to .thumb_func for iOS armv7 (null for armv6)
|
||||||
|
# Expands to .type %function for others
|
||||||
|
#
|
||||||
|
# iOS:
|
||||||
|
#
|
||||||
|
# .machine armv6/armv7
|
||||||
|
# .thumb (for armv7)
|
||||||
|
# cbz Expands to cmp/beq for armv6 (Thumb-only instr)
|
||||||
|
# .type Not supported by Apple assembler
|
||||||
|
# .size Not supported by Apple assembler
|
||||||
|
#
|
||||||
|
defre = '#[ \t]*if.*def.*SYS' # Add new defs near first existing ones
|
||||||
|
skipre = '$|\.syntax[ \t]' # Skip comment lines (and .syntax)
|
||||||
|
|
||||||
|
for i in range(len(instrs)):
|
||||||
|
if re.match(defre, instrs[i][1]):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
i = 0
|
||||||
|
for i in range(i, len(instrs)):
|
||||||
|
if not re.match(skipre, instrs[i][1]):
|
||||||
|
break
|
||||||
|
instrs[i:0] = [
|
||||||
|
('', '', '\n'),
|
||||||
|
('/* Apple compatibility macros */', '', '\n'),
|
||||||
|
('', '#if defined(SYS_macosx)', '\n'),
|
||||||
|
('', '#define Glo(s) _##s', '\n'),
|
||||||
|
('', '#define Loc(s) L##s', '\n'),
|
||||||
|
('', '#if defined(MODEL_armv6)', '\n'),
|
||||||
|
(' ', '.machine armv6', '\n'),
|
||||||
|
(' ', '.macro .funtype', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
(' ', '.macro cbz', '\n'),
|
||||||
|
(' ', 'cmp $0, #0', '\n'),
|
||||||
|
(' ', 'beq $1', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
('', '#else', '\n'),
|
||||||
|
(' ', '.machine armv7', '\n'),
|
||||||
|
('', '#if !defined(NO_THUMB)', '\n'),
|
||||||
|
(' ', '.thumb', '\n'),
|
||||||
|
('', '#endif', '\n'),
|
||||||
|
(' ', '.macro .funtype', '\n'),
|
||||||
|
('', '#if !defined(NO_THUMB)', '\n'),
|
||||||
|
(' ', '.thumb_func $0', '\n'),
|
||||||
|
('', '#endif', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
('', '#endif', '\n'),
|
||||||
|
(' ', '.macro .type', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
(' ', '.macro .size', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
(' ', '.macro .skip', '\n'),
|
||||||
|
(' ', '.space $0', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
(' ', '.macro .fpu', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
(' ', '.macro .global', '\n'),
|
||||||
|
(' ', '.globl $0', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
('', '#else', '\n'),
|
||||||
|
('', '#define Glo(s) s', '\n'),
|
||||||
|
('', '#define Loc(s) .L##s', '\n'),
|
||||||
|
(' ', '.macro .funtype symbol', '\n'),
|
||||||
|
(' ', '.type \\symbol, %function', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
('', '#endif', '\n'),
|
||||||
|
('/* End Apple compatibility macros */', '', '\n'),
|
||||||
|
('', '', '\n')
|
||||||
|
]
|
||||||
|
return instrs
|
||||||
|
|
||||||
|
|
||||||
|
# Regular expression for modified ldr lines
|
||||||
|
#
|
||||||
|
g_ldre = '(ldr[ \t][^,]*,[ \t]*)=(([^ \t\n@,/]|/(?!\*))*)(.*)'
|
||||||
|
|
||||||
|
|
||||||
|
def explicit_address_loads(instrs):
|
||||||
|
# Linux assemblers allow the following:
|
||||||
|
#
|
||||||
|
# ldr rM, =symbol
|
||||||
|
#
|
||||||
|
# which loads rM with [mov] (immediately) if possible, or creates an
|
||||||
|
# entry in memory for the symbol value and loads it PC-relatively
|
||||||
|
# with [ldr].
|
||||||
|
#
|
||||||
|
# The Apple assembler doesn't seem to support this notation. If the
|
||||||
|
# value is a suitable constant, it emits a valid [mov]. Otherwise
|
||||||
|
# it seems to emit an invalid [ldr] that always generates an error.
|
||||||
|
# (At least I have not been able to make it work). So, change uses
|
||||||
|
# of =symbol to explicit PC-relative loads.
|
||||||
|
#
|
||||||
|
# This requires a pool containing the addresses to be loaded. For
|
||||||
|
# now, we just keep track of it ourselves and emit it into the text
|
||||||
|
# segment at the end of the file.
|
||||||
|
#
|
||||||
|
syms = {}
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def repl1((syms, result), (a, b, c)):
|
||||||
|
global g_poolpfx
|
||||||
|
global g_ldre
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
mo = re.match(g_ldre, b3, re.DOTALL)
|
||||||
|
if mo:
|
||||||
|
if mo.group(2) not in syms:
|
||||||
|
syms[mo.group(2)] = len(syms)
|
||||||
|
psym = mo.group(2)
|
||||||
|
if psym[0:2] == '.L':
|
||||||
|
psym = psym[2:]
|
||||||
|
newb3 = mo.group(1) + g_poolpfx + psym + mo.group(4)
|
||||||
|
result.append((a, b1 + b2 + newb3, c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (syms, result)
|
||||||
|
|
||||||
|
def pool1(result, s):
|
||||||
|
global g_poolpfx
|
||||||
|
psym = s
|
||||||
|
if psym[0:2] == '.L':
|
||||||
|
psym = psym[2:]
|
||||||
|
result.append(('', g_poolpfx + psym + ':', '\n'))
|
||||||
|
result.append((' ', '.long ' + s, '\n'))
|
||||||
|
return result
|
||||||
|
|
||||||
|
reduce(repl1, instrs, (syms, result))
|
||||||
|
if len(syms) > 0:
|
||||||
|
result.append(('', '', '\n'))
|
||||||
|
result.append(('/* Pool of addresses loaded into registers */',
|
||||||
|
'', '\n'))
|
||||||
|
result.append(('', '', '\n'))
|
||||||
|
result.append((' ', '.text', '\n'))
|
||||||
|
result.append((' ', '.align 2', '\n'))
|
||||||
|
reduce(pool1, sorted(syms, key=syms.get), result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def global_symbols(instrs):
|
||||||
|
# The form of a global symbol differs between Linux assemblers and
|
||||||
|
# the Apple assember:
|
||||||
|
#
|
||||||
|
# Linux: xxx
|
||||||
|
# Apple: _xxx
|
||||||
|
#
|
||||||
|
# Change occurrences of global symbols to use the Glo() cpp macro
|
||||||
|
# defined in our prefix.
|
||||||
|
#
|
||||||
|
# We consider a symbol to be global if:
|
||||||
|
#
|
||||||
|
# a. It appears in a .globl declaration; or
|
||||||
|
# b. It is referenced, has global form, and is not defined
|
||||||
|
#
|
||||||
|
glosyms = set(initial_glosyms)
|
||||||
|
refsyms = set()
|
||||||
|
defsyms = set(initial_defsyms)
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def findglo1 (glosyms, (a, b, c)):
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line; nothing to do
|
||||||
|
return glosyms
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
mo = re.match('(\.globa?l)' + ccce(g_ccid), b3)
|
||||||
|
if mo:
|
||||||
|
tokens = parse_expr(b3[len(mo.group(1)):])
|
||||||
|
if forall(lambda t: token_type(t) in ['space', 'id', ','], tokens):
|
||||||
|
for t in tokens:
|
||||||
|
if token_type(t) == 'id':
|
||||||
|
glosyms.add(t)
|
||||||
|
return glosyms
|
||||||
|
|
||||||
|
def findref1 ((refsyms, skipct), (a, b, c)):
|
||||||
|
|
||||||
|
def looksglobal(s):
|
||||||
|
if re.match('(r|a|v|p|c|cr|f|s|d|q|mvax|wcgr)[0-9]+$', s, re.I):
|
||||||
|
return False # numbered registers
|
||||||
|
if re.match('(wr|sb|sl|fp|ip|sp|lr|pc)$', s, re.I):
|
||||||
|
return False # named registers
|
||||||
|
if re.match('(fpsid|fpscr|fpexc|mvfr1|mvfr0)$', s, re.I):
|
||||||
|
return False # more named registers
|
||||||
|
if re.match('(mvf|mvd|mvfx|mvdx|dspsc)$', s, re.I):
|
||||||
|
return False # even more named registers
|
||||||
|
if re.match('(wcid|wcon|wcssf|wcasf|acc)$', s, re.I):
|
||||||
|
return False # even more named registers
|
||||||
|
if re.match('\.$|\.L|[0-9]|#', s):
|
||||||
|
return False # dot, local symbol, or number
|
||||||
|
if re.match('(asl|lsl|lsr|asr|ror|rrx)$', s, re.I):
|
||||||
|
return False # shift names
|
||||||
|
return True
|
||||||
|
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line; nothing to do
|
||||||
|
return (refsyms, skipct)
|
||||||
|
|
||||||
|
# Track nesting of .macro/.endm. For now, we don't look for
|
||||||
|
# global syms in macro defs. (Avoiding scoping probs etc.)
|
||||||
|
#
|
||||||
|
if skipct > 0 and re.match('\.(endm|endmacro)' + ccce(g_ccid), b):
|
||||||
|
return (refsyms, skipct - 1)
|
||||||
|
if re.match('\.macro' + ccce(g_ccid), b):
|
||||||
|
return (refsyms, skipct + 1)
|
||||||
|
if skipct > 0:
|
||||||
|
return (refsyms, skipct)
|
||||||
|
if re.match('\.(type|size|syntax|arch|fpu)' + ccce(g_ccid), b):
|
||||||
|
return (refsyms, skipct)
|
||||||
|
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
rtokens = parse_rexpr(b3)
|
||||||
|
if len(rtokens) > 1 and rtokens[1] == '.req':
|
||||||
|
# .req has atypical syntax; no symbol refs there anyway
|
||||||
|
return (refsyms, skipct)
|
||||||
|
for t in rtokens[1:]:
|
||||||
|
if token_type(t) == 'id' and looksglobal(t):
|
||||||
|
refsyms.add(t)
|
||||||
|
return (refsyms, skipct)
|
||||||
|
|
||||||
|
def finddef1(defsyms, (a, b, c)):
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line
|
||||||
|
return defsyms
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
rtokens = parse_rexpr(b3)
|
||||||
|
if b1 != '':
|
||||||
|
defsyms.add(b1)
|
||||||
|
if len(rtokens) > 1 and rtokens[1] == '.req':
|
||||||
|
defsyms.add(rtokens[0])
|
||||||
|
return defsyms
|
||||||
|
|
||||||
|
def repl1((glosyms, result), (a, b, c)):
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (glosyms, result)
|
||||||
|
toglo = lambda s: 'Glo(' + s + ')'
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
tokens = parse_expr(b3)
|
||||||
|
|
||||||
|
if b1 in glosyms:
|
||||||
|
b1 = toglo(b1)
|
||||||
|
for i in range(len(tokens)):
|
||||||
|
if token_type(tokens[i]) == 'id' and tokens[i] in glosyms:
|
||||||
|
tokens[i] = toglo(tokens[i])
|
||||||
|
result.append((a, b1 + b2 + ''.join(tokens), c))
|
||||||
|
return (glosyms, result)
|
||||||
|
|
||||||
|
reduce(findglo1, instrs, glosyms)
|
||||||
|
reduce(findref1, instrs, (refsyms, 0))
|
||||||
|
reduce(finddef1, instrs, defsyms)
|
||||||
|
glosyms |= (refsyms - defsyms)
|
||||||
|
reduce(repl1, instrs, (glosyms, result))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def local_symbols(instrs):
|
||||||
|
# The form of a local symbol differs between Linux assemblers and
|
||||||
|
# the Apple assember:
|
||||||
|
#
|
||||||
|
# Linux: .Lxxx
|
||||||
|
# Apple: Lxxx
|
||||||
|
#
|
||||||
|
# Change occurrences of local symbols to use the Loc() cpp macro
|
||||||
|
# defined in our prefix.
|
||||||
|
#
|
||||||
|
lsyms = set()
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def find1 (lsyms, (a, b, c)):
|
||||||
|
mo = re.match('(\.L[^ \t:]*)[ \t]*:', b)
|
||||||
|
if mo:
|
||||||
|
lsyms.add(mo.group(1))
|
||||||
|
return lsyms
|
||||||
|
|
||||||
|
def repl1((lsyms, result), (a, b, c)):
|
||||||
|
matches = list(re.finditer('\.L[^ \t@:,+*/\-()]+', b))
|
||||||
|
if matches != []:
|
||||||
|
matches.reverse()
|
||||||
|
newb = b
|
||||||
|
for mo in matches:
|
||||||
|
if mo.group() in lsyms:
|
||||||
|
newb = newb[0:mo.start()] + \
|
||||||
|
'Loc(' + mo.group()[2:] + ')' + \
|
||||||
|
newb[mo.end():]
|
||||||
|
result.append((a, newb, c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (lsyms, result)
|
||||||
|
|
||||||
|
reduce(find1, instrs, lsyms)
|
||||||
|
reduce(repl1, instrs, (lsyms, result))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def funtypes(instrs):
|
||||||
|
# Linux assemblers accept declarations like this:
|
||||||
|
#
|
||||||
|
# .type symbol, %function
|
||||||
|
#
|
||||||
|
# For Thumb functions, the Apple assembler wants to see:
|
||||||
|
#
|
||||||
|
# .thumb_func symbol
|
||||||
|
#
|
||||||
|
# Handle this by converting declarations to this:
|
||||||
|
#
|
||||||
|
# .funtype symbol
|
||||||
|
#
|
||||||
|
# Our prefix defines an appropriate .funtype macro for each
|
||||||
|
# environment.
|
||||||
|
#
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def repl1(result, (a, b, c)):
|
||||||
|
mo = re.match('.type[ \t]+([^ \t,]*),[ \t]*%function', b)
|
||||||
|
if mo:
|
||||||
|
result.append((a, '.funtype ' + mo.group(1), c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
return result
|
||||||
|
|
||||||
|
reduce(repl1, instrs, result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def jump_tables(instrs):
|
||||||
|
# Jump tables for Linux assemblers often look like this:
|
||||||
|
#
|
||||||
|
# tbh [pc, rM, lsl #1]
|
||||||
|
# .short (.Labc-.)/2+0
|
||||||
|
# .short (.Ldef-.)/2+1
|
||||||
|
# .short (.Lghi-.)/2+2
|
||||||
|
#
|
||||||
|
# The Apple assembler disagrees about the meaning of this code,
|
||||||
|
# producing jump tables that don't work. Convert to the following:
|
||||||
|
#
|
||||||
|
# tbh [pc, rM, lsl #1]
|
||||||
|
# .LBxxx:
|
||||||
|
# .short (.Labc-.LBxxx)/2
|
||||||
|
# .short (.Ldef-.LBxxx)/2
|
||||||
|
# .short (.Lghi-.LBxxx)/2
|
||||||
|
#
|
||||||
|
# In fact we just convert sequences of .short pseudo-ops of the
|
||||||
|
# right form. There's no requirement that they follow a tbh
|
||||||
|
# instruction.
|
||||||
|
#
|
||||||
|
baselabs = []
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def short_match(seq, op):
|
||||||
|
# Determine whether the op is a .short of the form that needs to
|
||||||
|
# be converted: .short (symbol-.)/2+k. If so, return a pair
|
||||||
|
# containing the symbol and the value of k. If not, return
|
||||||
|
# None. The short can only be converted if there were at least
|
||||||
|
# k other .shorts in sequence before the current one. A summary
|
||||||
|
# of the previous .shorts is in seq.
|
||||||
|
#
|
||||||
|
# (A real parser would do a better job, but this was quick to
|
||||||
|
# get working.)
|
||||||
|
#
|
||||||
|
sp = '([ \t]|/\*.*?\*/)*' # space
|
||||||
|
sp1 = '([ \t]|/\*.*?\*/)+' # at least 1 space
|
||||||
|
spe = '([ \t]|/\*.*?\*/|@[^\n]*)*$' # end-of-instr space
|
||||||
|
expr_re0 = (
|
||||||
|
'\.short' + sp + '\(' + sp + # .short (
|
||||||
|
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||||
|
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||||
|
'/' + sp + '2' + spe # /2 END
|
||||||
|
)
|
||||||
|
expr_re1 = (
|
||||||
|
'\.short' + sp + '\(' + sp + # .short (
|
||||||
|
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||||
|
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||||
|
'/' + sp + '2' + sp + # /2
|
||||||
|
'\+' + sp + # +
|
||||||
|
'((0[xX])?[0-9]+)' + spe # k END
|
||||||
|
)
|
||||||
|
expr_re2 = (
|
||||||
|
'\.short' + sp1 + # .short
|
||||||
|
'((0[xX])?[0-9]+)' + sp + # k
|
||||||
|
'\+' + sp + '\(' + sp + # +(
|
||||||
|
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||||
|
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||||
|
'/' + sp + '2' + spe # /2 END
|
||||||
|
)
|
||||||
|
mo = re.match(expr_re0, op)
|
||||||
|
if mo:
|
||||||
|
return(mo.group(3), 0)
|
||||||
|
mo = re.match(expr_re1, op)
|
||||||
|
if mo:
|
||||||
|
k = int(mo.group(11), 0)
|
||||||
|
if k > len(seq):
|
||||||
|
return None
|
||||||
|
return (mo.group(3), k)
|
||||||
|
mo = re.match(expr_re2, op)
|
||||||
|
if mo:
|
||||||
|
k = int(mo.group(2), 0)
|
||||||
|
if k > len(seq):
|
||||||
|
return None
|
||||||
|
return (mo.group(7), k)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def conv1 ((baselabs, shortseq, label, result), (a, b, c)):
|
||||||
|
# Convert current instr (a,b,c) if it's a .short of the right
|
||||||
|
# form that spans a previous sequence of .shorts.
|
||||||
|
#
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
|
||||||
|
if b3 == '':
|
||||||
|
# No operation: just note label if present.
|
||||||
|
result.append((a, b, c))
|
||||||
|
if re.match('\.L.', b1):
|
||||||
|
return (baselabs, shortseq, b1, result)
|
||||||
|
return (baselabs, shortseq, label, result)
|
||||||
|
|
||||||
|
if not re.match('.short[ \t]+[^ \t@]', b3):
|
||||||
|
# Not a .short: clear shortseq and label
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (baselabs, [], '', result)
|
||||||
|
|
||||||
|
# We have a .short: figure out the label if any
|
||||||
|
if re.match('\.L', b1):
|
||||||
|
sl = b1
|
||||||
|
else:
|
||||||
|
sl = label
|
||||||
|
|
||||||
|
mpair = short_match(shortseq, b3)
|
||||||
|
if not mpair:
|
||||||
|
# A .short, but not of right form
|
||||||
|
shortseq.append((len(result), sl))
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (baselabs, shortseq, '', result)
|
||||||
|
|
||||||
|
# OK, we have a .short to convert!
|
||||||
|
(sym, k) = mpair
|
||||||
|
shortseq.append((len(result), sl))
|
||||||
|
|
||||||
|
# Figure out base label (create one if necessary).
|
||||||
|
bx = len(shortseq) - 1 - k
|
||||||
|
bl = shortseq[bx][1]
|
||||||
|
if bl == '':
|
||||||
|
bl = g_basepfx + str(shortseq[bx][0])
|
||||||
|
shortseq[bx] = (shortseq[bx][0], bl)
|
||||||
|
baselabs.append(shortseq[bx])
|
||||||
|
|
||||||
|
op = '.short\t(' + sym + '-' + bl + ')/2'
|
||||||
|
|
||||||
|
result.append ((a, b1 + b2 + op, c))
|
||||||
|
return (baselabs, shortseq, '', result)
|
||||||
|
|
||||||
|
# Convert, accumulate result and new labels.
|
||||||
|
reduce(conv1, instrs, (baselabs, [], '', result))
|
||||||
|
|
||||||
|
# Add labels created here to the instruction stream.
|
||||||
|
baselabs.reverse()
|
||||||
|
for (ix, lab) in baselabs:
|
||||||
|
result[ix:0] = [('', lab + ':', '\n')]
|
||||||
|
|
||||||
|
# That does it
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def dot_relative(instrs):
|
||||||
|
# The Apple assembler (or possibly the linker) has trouble with code
|
||||||
|
# that looks like this:
|
||||||
|
#
|
||||||
|
# .word .Label - . + 0x80000000
|
||||||
|
# .word 0x1966
|
||||||
|
# .Label:
|
||||||
|
# .word 0x1967
|
||||||
|
#
|
||||||
|
# One way to describe the problem is that the assembler marks the
|
||||||
|
# first .word for relocation when in fact it's an assembly-time
|
||||||
|
# constant. Translate to the following form, which doesn't generate
|
||||||
|
# a relocation marking:
|
||||||
|
#
|
||||||
|
# DR0 = .Label - . + 0x80000000
|
||||||
|
# .word DR0
|
||||||
|
# .word 0x1966
|
||||||
|
# .Label:
|
||||||
|
# .word 0x1967
|
||||||
|
#
|
||||||
|
prefix = 'DR'
|
||||||
|
pseudos = '(\.byte|\.short|\.word|\.long|\.quad)'
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def tok_ok(t):
|
||||||
|
return t in ['.', '+', '-', '(', ')'] or \
|
||||||
|
token_type(t) in ['space', 'locid', 'number']
|
||||||
|
|
||||||
|
def dotrel_match(expr):
|
||||||
|
# Determine whether the expression is one that needs to be
|
||||||
|
# translated.
|
||||||
|
tokens = parse_expr(expr)
|
||||||
|
return forall(tok_ok, tokens) and \
|
||||||
|
exists(lambda t: token_type(t) == 'locid', tokens) and \
|
||||||
|
exists(lambda t: token_type(t) == 'number', tokens) and \
|
||||||
|
exists(lambda t: t == '-', tokens) and \
|
||||||
|
exists(lambda t: t == '.', tokens)
|
||||||
|
|
||||||
|
def conv1(result, (a, b, c)):
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line
|
||||||
|
result.append((a, b, c))
|
||||||
|
else:
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
mo = re.match(pseudos + ccce(g_ccid), b3)
|
||||||
|
if mo:
|
||||||
|
p = mo.group(1)
|
||||||
|
expr = b3[len(p):]
|
||||||
|
if dotrel_match(expr):
|
||||||
|
sym = prefix + str(len(result))
|
||||||
|
instr = sym + ' =' + expr
|
||||||
|
result.append(('', instr, '\n'))
|
||||||
|
result.append((a, b1 + b2 + p + ' ' + sym, c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
return result
|
||||||
|
|
||||||
|
reduce(conv1, instrs, result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def read_input():
|
||||||
|
# Concatenate all the input files into a string.
|
||||||
|
#
|
||||||
|
def fnl(s):
|
||||||
|
if s == '' or s[-1] == '\n':
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return s + '\n'
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
return fnl(sys.stdin.read())
|
||||||
|
else:
|
||||||
|
input = ""
|
||||||
|
for f in sys.argv[1:]:
|
||||||
|
# allow global symbols to be enabled or disabled, eg:
|
||||||
|
# --global=foo,!bar
|
||||||
|
# foo is forced to be global
|
||||||
|
# bar is forced to be non-global
|
||||||
|
if f.startswith('--global='):
|
||||||
|
glist = f[9:].split(',')
|
||||||
|
for g in glist:
|
||||||
|
if g.startswith('!'):
|
||||||
|
initial_defsyms.append(g[1:])
|
||||||
|
else:
|
||||||
|
initial_glosyms.append(g)
|
||||||
|
elif f.startswith('--stdin'):
|
||||||
|
input = input + fnl(sys.stdin.read())
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
fd = open(f)
|
||||||
|
input = input + fnl(fd.read())
|
||||||
|
fd.close()
|
||||||
|
except:
|
||||||
|
sys.stderr.write('arm-as-to-ios: cannot open ' + f + '\n')
|
||||||
|
return input
|
||||||
|
|
||||||
|
|
||||||
|
def parse_instrs(s):
|
||||||
|
# Parse the string into assembly instructions, also noting C
|
||||||
|
# preprocessor lines. Each instruction is represented as a triple:
|
||||||
|
# (space/comments, instruction, end). The end is either ';' or
|
||||||
|
# '\n'.
|
||||||
|
#
|
||||||
|
def goodmo(mo):
|
||||||
|
if mo == None:
|
||||||
|
# Should never happen
|
||||||
|
sys.stderr.write('arm-as-to-ios: internal parsing error\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
cpp_re = '([ \t]*)(#([^\n]*\\\\\n)*[^\n]*[^\\\\\n])\n'
|
||||||
|
comment_re = '[ \t]*#[^\n]*'
|
||||||
|
instr_re = (
|
||||||
|
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||||
|
'(([ \t]|/\*.*?\*/|[^;\n])*)' # "Instruction"
|
||||||
|
'([;\n])' # End
|
||||||
|
)
|
||||||
|
instrs = []
|
||||||
|
while s != '':
|
||||||
|
if re.match('[ \t]*#[ \t]*(if|ifdef|elif|else|endif|define)', s):
|
||||||
|
mo = re.match(cpp_re, s)
|
||||||
|
goodmo(mo)
|
||||||
|
instrs.append((mo.group(1), mo.group(2), '\n'))
|
||||||
|
elif re.match('[ \t]*#', s):
|
||||||
|
mo = re.match(comment_re, s)
|
||||||
|
goodmo(mo)
|
||||||
|
instrs.append((mo.group(0), '', '\n'))
|
||||||
|
else:
|
||||||
|
mo = re.match(instr_re, s, re.DOTALL)
|
||||||
|
goodmo(mo)
|
||||||
|
instrs.append((mo.group(1), mo.group(3), mo.group(5)))
|
||||||
|
s = s[len(mo.group(0)):]
|
||||||
|
return instrs
|
||||||
|
|
||||||
|
|
||||||
|
def parse_iparts(i):
|
||||||
|
# Parse an instruction into smaller parts, returning a triple of
|
||||||
|
# strings (label, colon, operation). The colon part also contains
|
||||||
|
# any surrounding spaces and comments (making the label and the
|
||||||
|
# operation cleaner to process).
|
||||||
|
#
|
||||||
|
# (Caller warrants that the given string doesn't start with space or
|
||||||
|
# a comment. This is true for strings returned by the instruction
|
||||||
|
# parser.)
|
||||||
|
#
|
||||||
|
lab_re = (
|
||||||
|
'([^ \t:/@]+)' # Label
|
||||||
|
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||||
|
':' # Colon
|
||||||
|
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||||
|
'([^\n]*)' # Operation
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(i) > 0 and i[0] == '#':
|
||||||
|
# C preprocessor line; treat as operation.
|
||||||
|
return ('', '', i)
|
||||||
|
mo = re.match(lab_re, i)
|
||||||
|
if mo:
|
||||||
|
return (mo.group(1), mo.group(2) + ':' + mo.group(4), mo.group(6))
|
||||||
|
# No label, just an operation
|
||||||
|
return ('', '', i)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_expr(s):
|
||||||
|
# Parse a string into a sequence of tokens. A segment of white
|
||||||
|
# space (including comments) is treated as a token, so that the
|
||||||
|
# tokens can be reassembled into the string again.
|
||||||
|
#
|
||||||
|
result = []
|
||||||
|
while s != '':
|
||||||
|
mo = re.match('([ \t]|/\*.*?\*/|@.*)+', s)
|
||||||
|
if not mo:
|
||||||
|
# Glo(...) and Loc(...) are single tokens
|
||||||
|
mo = re.match('(Glo|Loc)\([^()]*\)', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match('"([^\\\\"]|\\\\.)*"', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match(g_ccid0 + g_ccid + '*', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match('[0-9]+[bf]', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match('0[Xx][0-9a-fA-F]+|[0-9]+', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match('.', s)
|
||||||
|
result.append(mo.group(0))
|
||||||
|
s = s[len(mo.group(0)):]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def parse_rexpr(s):
|
||||||
|
# Like parse_expr(), but return only "real" tokens, not the
|
||||||
|
# intervening space.
|
||||||
|
#
|
||||||
|
return filter(lambda t: token_type(t) != 'space', parse_expr(s))
|
||||||
|
|
||||||
|
|
||||||
|
def token_type(t):
|
||||||
|
# Determine the type of a token. Caller warrants that it was
|
||||||
|
# returned by parse_expr() or parse_rexpr().
|
||||||
|
#
|
||||||
|
if re.match('[ \t]|/\*|@', t):
|
||||||
|
return 'space'
|
||||||
|
if re.match('Glo\(', t):
|
||||||
|
return 'gloid'
|
||||||
|
if re.match('Loc\(', t):
|
||||||
|
return 'locid'
|
||||||
|
if re.match('"', t):
|
||||||
|
return 'string'
|
||||||
|
if re.match(g_ccid0, t):
|
||||||
|
return 'id'
|
||||||
|
if re.match('[0-9]+[bf]', t):
|
||||||
|
return 'label'
|
||||||
|
if re.match('[0-9]', t):
|
||||||
|
return 'number'
|
||||||
|
return t # Sui generis
|
||||||
|
|
||||||
|
|
||||||
|
def debug_parse(a, b, c):
|
||||||
|
# Show results of instuction stream parse.
|
||||||
|
#
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
newb = '{' + b1 + '}' + '{' + b2 + '}' + '{' + b3 + '}'
|
||||||
|
sys.stdout.write('{' + a + '}' + newb + c)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
instrs = parse_instrs(read_input())
|
||||||
|
instrs = explicit_address_loads(instrs)
|
||||||
|
instrs = funtypes(instrs)
|
||||||
|
instrs = jump_tables(instrs)
|
||||||
|
instrs = global_symbols(instrs)
|
||||||
|
instrs = local_symbols(instrs)
|
||||||
|
instrs = dot_relative(instrs)
|
||||||
|
instrs = add_prefix(instrs)
|
||||||
|
for (a, b, c) in instrs:
|
||||||
|
sys.stdout.write(a + b + c)
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
||||||
+730
@@ -0,0 +1,730 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# arm-as-to-ios Modify ARM assembly code for the iOS assembler
|
||||||
|
#
|
||||||
|
# Copyright (c) 2012 Psellos http://psellos.com/
|
||||||
|
# Licensed under the MIT License:
|
||||||
|
# http://www.opensource.org/licenses/mit-license.php
|
||||||
|
#
|
||||||
|
# Resources for running OCaml on iOS: http://psellos.com/ocaml/
|
||||||
|
#
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
VERSION = '1.4.0'
|
||||||
|
|
||||||
|
# Character classes for expression lexing.
|
||||||
|
#
|
||||||
|
g_ccid0 = '[$.A-Z_a-z\x80-\xff]' # Beginning of id
|
||||||
|
g_ccid = '[$.0-9A-Z_a-z\x80-\xff]' # Later in id
|
||||||
|
def ccc(cc): # Complement the class
|
||||||
|
if cc[1] == '^':
|
||||||
|
return cc[0] + cc[2:]
|
||||||
|
return cc[0] + '^' + cc[1:]
|
||||||
|
def ccce(cc): # Complement the class, include EOL
|
||||||
|
return '(?:' + ccc(cc) + '|$)'
|
||||||
|
|
||||||
|
# Prefixes for pooled symbol labels and jump table base labels. They're
|
||||||
|
# in the space of Linux assembler local symbols. Later rules will
|
||||||
|
# modify them to the Loc() form.
|
||||||
|
#
|
||||||
|
g_poolpfx = '.LP'
|
||||||
|
g_basepfx = '.LB'
|
||||||
|
|
||||||
|
|
||||||
|
def exists(p, l):
|
||||||
|
for l1 in l:
|
||||||
|
if p(l1):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def forall(p, l):
|
||||||
|
for l1 in l:
|
||||||
|
if not p(l1):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def add_prefix(instrs):
|
||||||
|
# Add compatibility macros for all systems, plus hardware
|
||||||
|
# definitions and compatibility macros for iOS.
|
||||||
|
#
|
||||||
|
# All systems:
|
||||||
|
#
|
||||||
|
# Glo() cpp macro for making global symbols (xxx vs _xxx)
|
||||||
|
# Loc() cpp macro for making local symbols (.Lxxx vs Lxxx)
|
||||||
|
# .funtype Expands to .thumb_func for iOS armv7 (null for armv6)
|
||||||
|
# Expands to .type %function for others
|
||||||
|
#
|
||||||
|
# iOS:
|
||||||
|
#
|
||||||
|
# .machine armv6/armv7
|
||||||
|
# .thumb (for armv7)
|
||||||
|
# cbz Expands to cmp/beq for armv6 (Thumb-only instr)
|
||||||
|
# .type Not supported by Apple assembler
|
||||||
|
# .size Not supported by Apple assembler
|
||||||
|
#
|
||||||
|
defre = '#[ \t]*if.*def.*SYS' # Add new defs near first existing ones
|
||||||
|
skipre = '$|\.syntax[ \t]' # Skip comment lines (and .syntax)
|
||||||
|
|
||||||
|
for i in range(len(instrs)):
|
||||||
|
if re.match(defre, instrs[i][1]):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
i = 0
|
||||||
|
for i in range(i, len(instrs)):
|
||||||
|
if not re.match(skipre, instrs[i][1]):
|
||||||
|
break
|
||||||
|
instrs[i:0] = [
|
||||||
|
('', '', '\n'),
|
||||||
|
('/* Apple compatibility macros */', '', '\n'),
|
||||||
|
('', '#if defined(SYS_macosx)', '\n'),
|
||||||
|
('', '#define Glo(s) _##s', '\n'),
|
||||||
|
('', '#define Loc(s) L##s', '\n'),
|
||||||
|
('', '#if defined(MODEL_armv6)', '\n'),
|
||||||
|
(' ', '.machine armv6', '\n'),
|
||||||
|
(' ', '.macro .funtype', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
(' ', '.macro cbz', '\n'),
|
||||||
|
(' ', 'cmp $0, #0', '\n'),
|
||||||
|
(' ', 'beq $1', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
('', '#else', '\n'),
|
||||||
|
(' ', '.machine armv7', '\n'),
|
||||||
|
(' ', '.thumb', '\n'),
|
||||||
|
(' ', '.macro .funtype', '\n'),
|
||||||
|
(' ', '.thumb_func $0', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
('', '#endif', '\n'),
|
||||||
|
(' ', '.macro .type', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
(' ', '.macro .size', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
('', '#else', '\n'),
|
||||||
|
('', '#define Glo(s) s', '\n'),
|
||||||
|
('', '#define Loc(s) .L##s', '\n'),
|
||||||
|
(' ', '.macro .funtype symbol', '\n'),
|
||||||
|
(' ', '.type \\symbol, %function', '\n'),
|
||||||
|
(' ', '.endm', '\n'),
|
||||||
|
('', '#endif', '\n'),
|
||||||
|
('/* End Apple compatibility macros */', '', '\n'),
|
||||||
|
('', '', '\n')
|
||||||
|
]
|
||||||
|
return instrs
|
||||||
|
|
||||||
|
|
||||||
|
# Regular expression for modified ldr lines
|
||||||
|
#
|
||||||
|
g_ldre = '(ldr[ \t][^,]*,[ \t]*)=(([^ \t\n@,/]|/(?!\*))*)(.*)'
|
||||||
|
|
||||||
|
|
||||||
|
def explicit_address_loads(instrs):
|
||||||
|
# Linux assemblers allow the following:
|
||||||
|
#
|
||||||
|
# ldr rM, =symbol
|
||||||
|
#
|
||||||
|
# which loads rM with [mov] (immediately) if possible, or creates an
|
||||||
|
# entry in memory for the symbol value and loads it PC-relatively
|
||||||
|
# with [ldr].
|
||||||
|
#
|
||||||
|
# The Apple assembler doesn't seem to support this notation. If the
|
||||||
|
# value is a suitable constant, it emits a valid [mov]. Otherwise
|
||||||
|
# it seems to emit an invalid [ldr] that always generates an error.
|
||||||
|
# (At least I have not been able to make it work). So, change uses
|
||||||
|
# of =symbol to explicit PC-relative loads.
|
||||||
|
#
|
||||||
|
# This requires a pool containing the addresses to be loaded. For
|
||||||
|
# now, we just keep track of it ourselves and emit it into the text
|
||||||
|
# segment at the end of the file.
|
||||||
|
#
|
||||||
|
syms = {}
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def repl1((syms, result), (a, b, c)):
|
||||||
|
global g_poolpfx
|
||||||
|
global g_ldre
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
mo = re.match(g_ldre, b3, re.DOTALL)
|
||||||
|
if mo:
|
||||||
|
if mo.group(2) not in syms:
|
||||||
|
syms[mo.group(2)] = len(syms)
|
||||||
|
psym = mo.group(2)
|
||||||
|
if psym[0:2] == '.L':
|
||||||
|
psym = psym[2:]
|
||||||
|
newb3 = mo.group(1) + g_poolpfx + psym + mo.group(4)
|
||||||
|
result.append((a, b1 + b2 + newb3, c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (syms, result)
|
||||||
|
|
||||||
|
def pool1(result, s):
|
||||||
|
global g_poolpfx
|
||||||
|
psym = s
|
||||||
|
if psym[0:2] == '.L':
|
||||||
|
psym = psym[2:]
|
||||||
|
result.append(('', g_poolpfx + psym + ':', '\n'))
|
||||||
|
result.append((' ', '.long ' + s, '\n'))
|
||||||
|
return result
|
||||||
|
|
||||||
|
reduce(repl1, instrs, (syms, result))
|
||||||
|
if len(syms) > 0:
|
||||||
|
result.append(('', '', '\n'))
|
||||||
|
result.append(('/* Pool of addresses loaded into registers */',
|
||||||
|
'', '\n'))
|
||||||
|
result.append(('', '', '\n'))
|
||||||
|
result.append((' ', '.text', '\n'))
|
||||||
|
result.append((' ', '.align 2', '\n'))
|
||||||
|
reduce(pool1, sorted(syms, key=syms.get), result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def global_symbols(instrs):
|
||||||
|
# The form of a global symbol differs between Linux assemblers and
|
||||||
|
# the Apple assember:
|
||||||
|
#
|
||||||
|
# Linux: xxx
|
||||||
|
# Apple: _xxx
|
||||||
|
#
|
||||||
|
# Change occurrences of global symbols to use the Glo() cpp macro
|
||||||
|
# defined in our prefix.
|
||||||
|
#
|
||||||
|
# We consider a symbol to be global if:
|
||||||
|
#
|
||||||
|
# a. It appears in a .globl declaration; or
|
||||||
|
# b. It is referenced, has global form, and is not defined
|
||||||
|
#
|
||||||
|
glosyms = set()
|
||||||
|
refsyms = set()
|
||||||
|
defsyms = set()
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def findglo1 (glosyms, (a, b, c)):
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line; nothing to do
|
||||||
|
return glosyms
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
mo = re.match('(\.globl)' + ccce(g_ccid), b3)
|
||||||
|
if mo:
|
||||||
|
tokens = parse_expr(b3[len(mo.group(1)):])
|
||||||
|
if forall(lambda t: token_type(t) in ['space', 'id', ','], tokens):
|
||||||
|
for t in tokens:
|
||||||
|
if token_type(t) == 'id':
|
||||||
|
glosyms.add(t)
|
||||||
|
return glosyms
|
||||||
|
|
||||||
|
def findref1 ((refsyms, skipct), (a, b, c)):
|
||||||
|
|
||||||
|
def looksglobal(s):
|
||||||
|
if re.match('(r|a|v|p|c|cr|f|s|d|q|mvax|wcgr)[0-9]+$', s, re.I):
|
||||||
|
return False # numbered registers
|
||||||
|
if re.match('(wr|sb|sl|fp|ip|sp|lr|pc)$', s, re.I):
|
||||||
|
return False # named registers
|
||||||
|
if re.match('(fpsid|fpscr|fpexc|mvfr1|mvfr0)$', s, re.I):
|
||||||
|
return False # more named registers
|
||||||
|
if re.match('(mvf|mvd|mvfx|mvdx|dspsc)$', s, re.I):
|
||||||
|
return False # even more named registers
|
||||||
|
if re.match('(wcid|wcon|wcssf|wcasf|acc)$', s, re.I):
|
||||||
|
return False # even more named registers
|
||||||
|
if re.match('\.$|\.L|[0-9]|#', s):
|
||||||
|
return False # dot, local symbol, or number
|
||||||
|
if re.match('(asl|lsl|lsr|asr|ror|rrx)$', s, re.I):
|
||||||
|
return False # shift names
|
||||||
|
return True
|
||||||
|
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line; nothing to do
|
||||||
|
return (refsyms, skipct)
|
||||||
|
|
||||||
|
# Track nesting of .macro/.endm. For now, we don't look for
|
||||||
|
# global syms in macro defs. (Avoiding scoping probs etc.)
|
||||||
|
#
|
||||||
|
if skipct > 0 and re.match('\.(endm|endmacro)' + ccce(g_ccid), b):
|
||||||
|
return (refsyms, skipct - 1)
|
||||||
|
if re.match('\.macro' + ccce(g_ccid), b):
|
||||||
|
return (refsyms, skipct + 1)
|
||||||
|
if skipct > 0:
|
||||||
|
return (refsyms, skipct)
|
||||||
|
if re.match('\.(type|size|syntax|arch|fpu)' + ccce(g_ccid), b):
|
||||||
|
return (refsyms, skipct)
|
||||||
|
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
rtokens = parse_rexpr(b3)
|
||||||
|
if len(rtokens) > 1 and rtokens[1] == '.req':
|
||||||
|
# .req has atypical syntax; no symbol refs there anyway
|
||||||
|
return (refsyms, skipct)
|
||||||
|
for t in rtokens[1:]:
|
||||||
|
if token_type(t) == 'id' and looksglobal(t):
|
||||||
|
refsyms.add(t)
|
||||||
|
return (refsyms, skipct)
|
||||||
|
|
||||||
|
def finddef1(defsyms, (a, b, c)):
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line
|
||||||
|
return defsyms
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
rtokens = parse_rexpr(b3)
|
||||||
|
if b1 != '':
|
||||||
|
defsyms.add(b1)
|
||||||
|
if len(rtokens) > 1 and rtokens[1] == '.req':
|
||||||
|
defsyms.add(rtokens[0])
|
||||||
|
return defsyms
|
||||||
|
|
||||||
|
def repl1((glosyms, result), (a, b, c)):
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (glosyms, result)
|
||||||
|
toglo = lambda s: 'Glo(' + s + ')'
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
tokens = parse_expr(b3)
|
||||||
|
|
||||||
|
if b1 in glosyms:
|
||||||
|
b1 = toglo(b1)
|
||||||
|
for i in range(len(tokens)):
|
||||||
|
if token_type(tokens[i]) == 'id' and tokens[i] in glosyms:
|
||||||
|
tokens[i] = toglo(tokens[i])
|
||||||
|
result.append((a, b1 + b2 + ''.join(tokens), c))
|
||||||
|
return (glosyms, result)
|
||||||
|
|
||||||
|
reduce(findglo1, instrs, glosyms)
|
||||||
|
reduce(findref1, instrs, (refsyms, 0))
|
||||||
|
reduce(finddef1, instrs, defsyms)
|
||||||
|
glosyms |= (refsyms - defsyms)
|
||||||
|
reduce(repl1, instrs, (glosyms, result))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def local_symbols(instrs):
|
||||||
|
# The form of a local symbol differs between Linux assemblers and
|
||||||
|
# the Apple assember:
|
||||||
|
#
|
||||||
|
# Linux: .Lxxx
|
||||||
|
# Apple: Lxxx
|
||||||
|
#
|
||||||
|
# Change occurrences of local symbols to use the Loc() cpp macro
|
||||||
|
# defined in our prefix.
|
||||||
|
#
|
||||||
|
lsyms = set()
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def find1 (lsyms, (a, b, c)):
|
||||||
|
mo = re.match('(\.L[^ \t:]*)[ \t]*:', b)
|
||||||
|
if mo:
|
||||||
|
lsyms.add(mo.group(1))
|
||||||
|
return lsyms
|
||||||
|
|
||||||
|
def repl1((lsyms, result), (a, b, c)):
|
||||||
|
matches = list(re.finditer('\.L[^ \t@:,+*/\-()]+', b))
|
||||||
|
if matches != []:
|
||||||
|
matches.reverse()
|
||||||
|
newb = b
|
||||||
|
for mo in matches:
|
||||||
|
if mo.group() in lsyms:
|
||||||
|
newb = newb[0:mo.start()] + \
|
||||||
|
'Loc(' + mo.group()[2:] + ')' + \
|
||||||
|
newb[mo.end():]
|
||||||
|
result.append((a, newb, c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (lsyms, result)
|
||||||
|
|
||||||
|
reduce(find1, instrs, lsyms)
|
||||||
|
reduce(repl1, instrs, (lsyms, result))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def funtypes(instrs):
|
||||||
|
# Linux assemblers accept declarations like this:
|
||||||
|
#
|
||||||
|
# .type symbol, %function
|
||||||
|
#
|
||||||
|
# For Thumb functions, the Apple assembler wants to see:
|
||||||
|
#
|
||||||
|
# .thumb_func symbol
|
||||||
|
#
|
||||||
|
# Handle this by converting declarations to this:
|
||||||
|
#
|
||||||
|
# .funtype symbol
|
||||||
|
#
|
||||||
|
# Our prefix defines an appropriate .funtype macro for each
|
||||||
|
# environment.
|
||||||
|
#
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def repl1(result, (a, b, c)):
|
||||||
|
mo = re.match('.type[ \t]+([^ \t,]*),[ \t]*%function', b)
|
||||||
|
if mo:
|
||||||
|
result.append((a, '.funtype ' + mo.group(1), c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
return result
|
||||||
|
|
||||||
|
reduce(repl1, instrs, result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def jump_tables(instrs):
|
||||||
|
# Jump tables for Linux assemblers often look like this:
|
||||||
|
#
|
||||||
|
# tbh [pc, rM, lsl #1]
|
||||||
|
# .short (.Labc-.)/2+0
|
||||||
|
# .short (.Ldef-.)/2+1
|
||||||
|
# .short (.Lghi-.)/2+2
|
||||||
|
#
|
||||||
|
# The Apple assembler disagrees about the meaning of this code,
|
||||||
|
# producing jump tables that don't work. Convert to the following:
|
||||||
|
#
|
||||||
|
# tbh [pc, rM, lsl #1]
|
||||||
|
# .LBxxx:
|
||||||
|
# .short (.Labc-.LBxxx)/2
|
||||||
|
# .short (.Ldef-.LBxxx)/2
|
||||||
|
# .short (.Lghi-.LBxxx)/2
|
||||||
|
#
|
||||||
|
# In fact we just convert sequences of .short pseudo-ops of the
|
||||||
|
# right form. There's no requirement that they follow a tbh
|
||||||
|
# instruction.
|
||||||
|
#
|
||||||
|
baselabs = []
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def short_match(seq, op):
|
||||||
|
# Determine whether the op is a .short of the form that needs to
|
||||||
|
# be converted: .short (symbol-.)/2+k. If so, return a pair
|
||||||
|
# containing the symbol and the value of k. If not, return
|
||||||
|
# None. The short can only be converted if there were at least
|
||||||
|
# k other .shorts in sequence before the current one. A summary
|
||||||
|
# of the previous .shorts is in seq.
|
||||||
|
#
|
||||||
|
# (A real parser would do a better job, but this was quick to
|
||||||
|
# get working.)
|
||||||
|
#
|
||||||
|
sp = '([ \t]|/\*.*?\*/)*' # space
|
||||||
|
sp1 = '([ \t]|/\*.*?\*/)+' # at least 1 space
|
||||||
|
spe = '([ \t]|/\*.*?\*/|@[^\n]*)*$' # end-of-instr space
|
||||||
|
expr_re0 = (
|
||||||
|
'\.short' + sp + '\(' + sp + # .short (
|
||||||
|
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||||
|
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||||
|
'/' + sp + '2' + spe # /2 END
|
||||||
|
)
|
||||||
|
expr_re1 = (
|
||||||
|
'\.short' + sp + '\(' + sp + # .short (
|
||||||
|
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||||
|
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||||
|
'/' + sp + '2' + sp + # /2
|
||||||
|
'\+' + sp + # +
|
||||||
|
'((0[xX])?[0-9]+)' + spe # k END
|
||||||
|
)
|
||||||
|
expr_re2 = (
|
||||||
|
'\.short' + sp1 + # .short
|
||||||
|
'((0[xX])?[0-9]+)' + sp + # k
|
||||||
|
'\+' + sp + '\(' + sp + # +(
|
||||||
|
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||||
|
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||||
|
'/' + sp + '2' + spe # /2 END
|
||||||
|
)
|
||||||
|
mo = re.match(expr_re0, op)
|
||||||
|
if mo:
|
||||||
|
return(mo.group(3), 0)
|
||||||
|
mo = re.match(expr_re1, op)
|
||||||
|
if mo:
|
||||||
|
k = int(mo.group(11), 0)
|
||||||
|
if k > len(seq):
|
||||||
|
return None
|
||||||
|
return (mo.group(3), k)
|
||||||
|
mo = re.match(expr_re2, op)
|
||||||
|
if mo:
|
||||||
|
k = int(mo.group(2), 0)
|
||||||
|
if k > len(seq):
|
||||||
|
return None
|
||||||
|
return (mo.group(7), k)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def conv1 ((baselabs, shortseq, label, result), (a, b, c)):
|
||||||
|
# Convert current instr (a,b,c) if it's a .short of the right
|
||||||
|
# form that spans a previous sequence of .shorts.
|
||||||
|
#
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
|
||||||
|
if b3 == '':
|
||||||
|
# No operation: just note label if present.
|
||||||
|
result.append((a, b, c))
|
||||||
|
if re.match('\.L.', b1):
|
||||||
|
return (baselabs, shortseq, b1, result)
|
||||||
|
return (baselabs, shortseq, label, result)
|
||||||
|
|
||||||
|
if not re.match('.short[ \t]+[^ \t@]', b3):
|
||||||
|
# Not a .short: clear shortseq and label
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (baselabs, [], '', result)
|
||||||
|
|
||||||
|
# We have a .short: figure out the label if any
|
||||||
|
if re.match('\.L', b1):
|
||||||
|
sl = b1
|
||||||
|
else:
|
||||||
|
sl = label
|
||||||
|
|
||||||
|
mpair = short_match(shortseq, b3)
|
||||||
|
if not mpair:
|
||||||
|
# A .short, but not of right form
|
||||||
|
shortseq.append((len(result), sl))
|
||||||
|
result.append((a, b, c))
|
||||||
|
return (baselabs, shortseq, '', result)
|
||||||
|
|
||||||
|
# OK, we have a .short to convert!
|
||||||
|
(sym, k) = mpair
|
||||||
|
shortseq.append((len(result), sl))
|
||||||
|
|
||||||
|
# Figure out base label (create one if necessary).
|
||||||
|
bx = len(shortseq) - 1 - k
|
||||||
|
bl = shortseq[bx][1]
|
||||||
|
if bl == '':
|
||||||
|
bl = g_basepfx + str(shortseq[bx][0])
|
||||||
|
shortseq[bx] = (shortseq[bx][0], bl)
|
||||||
|
baselabs.append(shortseq[bx])
|
||||||
|
|
||||||
|
op = '.short\t(' + sym + '-' + bl + ')/2'
|
||||||
|
|
||||||
|
result.append ((a, b1 + b2 + op, c))
|
||||||
|
return (baselabs, shortseq, '', result)
|
||||||
|
|
||||||
|
# Convert, accumulate result and new labels.
|
||||||
|
reduce(conv1, instrs, (baselabs, [], '', result))
|
||||||
|
|
||||||
|
# Add labels created here to the instruction stream.
|
||||||
|
baselabs.reverse()
|
||||||
|
for (ix, lab) in baselabs:
|
||||||
|
result[ix:0] = [('', lab + ':', '\n')]
|
||||||
|
|
||||||
|
# That does it
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def dot_relative(instrs):
|
||||||
|
# The Apple assembler (or possibly the linker) has trouble with code
|
||||||
|
# that looks like this:
|
||||||
|
#
|
||||||
|
# .word .Label - . + 0x80000000
|
||||||
|
# .word 0x1966
|
||||||
|
# .Label:
|
||||||
|
# .word 0x1967
|
||||||
|
#
|
||||||
|
# One way to describe the problem is that the assembler marks the
|
||||||
|
# first .word for relocation when in fact it's an assembly-time
|
||||||
|
# constant. Translate to the following form, which doesn't generate
|
||||||
|
# a relocation marking:
|
||||||
|
#
|
||||||
|
# DR0 = .Label - . + 0x80000000
|
||||||
|
# .word DR0
|
||||||
|
# .word 0x1966
|
||||||
|
# .Label:
|
||||||
|
# .word 0x1967
|
||||||
|
#
|
||||||
|
prefix = 'DR'
|
||||||
|
pseudos = '(\.byte|\.short|\.word|\.long|\.quad)'
|
||||||
|
result = []
|
||||||
|
|
||||||
|
def tok_ok(t):
|
||||||
|
return t in ['.', '+', '-', '(', ')'] or \
|
||||||
|
token_type(t) in ['space', 'locid', 'number']
|
||||||
|
|
||||||
|
def dotrel_match(expr):
|
||||||
|
# Determine whether the expression is one that needs to be
|
||||||
|
# translated.
|
||||||
|
tokens = parse_expr(expr)
|
||||||
|
return forall(tok_ok, tokens) and \
|
||||||
|
exists(lambda t: token_type(t) == 'locid', tokens) and \
|
||||||
|
exists(lambda t: token_type(t) == 'number', tokens) and \
|
||||||
|
exists(lambda t: t == '-', tokens) and \
|
||||||
|
exists(lambda t: t == '.', tokens)
|
||||||
|
|
||||||
|
def conv1(result, (a, b, c)):
|
||||||
|
if re.match('#', b):
|
||||||
|
# Preprocessor line
|
||||||
|
result.append((a, b, c))
|
||||||
|
else:
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
mo = re.match(pseudos + ccce(g_ccid), b3)
|
||||||
|
if mo:
|
||||||
|
p = mo.group(1)
|
||||||
|
expr = b3[len(p):]
|
||||||
|
if dotrel_match(expr):
|
||||||
|
sym = prefix + str(len(result))
|
||||||
|
instr = sym + ' =' + expr
|
||||||
|
result.append(('', instr, '\n'))
|
||||||
|
result.append((a, b1 + b2 + p + ' ' + sym, c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
else:
|
||||||
|
result.append((a, b, c))
|
||||||
|
return result
|
||||||
|
|
||||||
|
reduce(conv1, instrs, result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def read_input():
|
||||||
|
# Concatenate all the input files into a string.
|
||||||
|
#
|
||||||
|
def fnl(s):
|
||||||
|
if s == '' or s[-1] == '\n':
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return s + '\n'
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
return fnl(sys.stdin.read())
|
||||||
|
else:
|
||||||
|
input = ""
|
||||||
|
for f in sys.argv[1:]:
|
||||||
|
try:
|
||||||
|
fd = open(f)
|
||||||
|
input = input + fnl(fd.read())
|
||||||
|
fd.close()
|
||||||
|
except:
|
||||||
|
sys.stderr.write('arm-as-to-ios: cannot open ' + f + '\n')
|
||||||
|
return input
|
||||||
|
|
||||||
|
|
||||||
|
def parse_instrs(s):
|
||||||
|
# Parse the string into assembly instructions, also noting C
|
||||||
|
# preprocessor lines. Each instruction is represented as a triple:
|
||||||
|
# (space/comments, instruction, end). The end is either ';' or
|
||||||
|
# '\n'.
|
||||||
|
#
|
||||||
|
def goodmo(mo):
|
||||||
|
if mo == None:
|
||||||
|
# Should never happen
|
||||||
|
sys.stderr.write('arm-as-to-ios: internal parsing error\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
cpp_re = '([ \t]*)(#([^\n]*\\\\\n)*[^\n]*[^\\\\\n])\n'
|
||||||
|
comment_re = '[ \t]*#[^\n]*'
|
||||||
|
instr_re = (
|
||||||
|
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||||
|
'(([ \t]|/\*.*?\*/|[^;\n])*)' # "Instruction"
|
||||||
|
'([;\n])' # End
|
||||||
|
)
|
||||||
|
instrs = []
|
||||||
|
while s != '':
|
||||||
|
if re.match('[ \t]*#[ \t]*(if|ifdef|elif|else|endif|define)', s):
|
||||||
|
mo = re.match(cpp_re, s)
|
||||||
|
goodmo(mo)
|
||||||
|
instrs.append((mo.group(1), mo.group(2), '\n'))
|
||||||
|
elif re.match('[ \t]*#', s):
|
||||||
|
mo = re.match(comment_re, s)
|
||||||
|
goodmo(mo)
|
||||||
|
instrs.append((mo.group(0), '', '\n'))
|
||||||
|
else:
|
||||||
|
mo = re.match(instr_re, s, re.DOTALL)
|
||||||
|
goodmo(mo)
|
||||||
|
instrs.append((mo.group(1), mo.group(3), mo.group(5)))
|
||||||
|
s = s[len(mo.group(0)):]
|
||||||
|
return instrs
|
||||||
|
|
||||||
|
|
||||||
|
def parse_iparts(i):
|
||||||
|
# Parse an instruction into smaller parts, returning a triple of
|
||||||
|
# strings (label, colon, operation). The colon part also contains
|
||||||
|
# any surrounding spaces and comments (making the label and the
|
||||||
|
# operation cleaner to process).
|
||||||
|
#
|
||||||
|
# (Caller warrants that the given string doesn't start with space or
|
||||||
|
# a comment. This is true for strings returned by the instruction
|
||||||
|
# parser.)
|
||||||
|
#
|
||||||
|
lab_re = (
|
||||||
|
'([^ \t:/@]+)' # Label
|
||||||
|
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||||
|
':' # Colon
|
||||||
|
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||||
|
'([^\n]*)' # Operation
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(i) > 0 and i[0] == '#':
|
||||||
|
# C preprocessor line; treat as operation.
|
||||||
|
return ('', '', i)
|
||||||
|
mo = re.match(lab_re, i)
|
||||||
|
if mo:
|
||||||
|
return (mo.group(1), mo.group(2) + ':' + mo.group(4), mo.group(6))
|
||||||
|
# No label, just an operation
|
||||||
|
return ('', '', i)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_expr(s):
|
||||||
|
# Parse a string into a sequence of tokens. A segment of white
|
||||||
|
# space (including comments) is treated as a token, so that the
|
||||||
|
# tokens can be reassembled into the string again.
|
||||||
|
#
|
||||||
|
result = []
|
||||||
|
while s != '':
|
||||||
|
mo = re.match('([ \t]|/\*.*?\*/|@.*)+', s)
|
||||||
|
if not mo:
|
||||||
|
# Glo(...) and Loc(...) are single tokens
|
||||||
|
mo = re.match('(Glo|Loc)\([^()]*\)', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match('"([^\\\\"]|\\\\.)*"', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match(g_ccid0 + g_ccid + '*', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match('[0-9]+[bf]', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match('0[Xx][0-9a-fA-F]+|[0-9]+', s)
|
||||||
|
if not mo:
|
||||||
|
mo = re.match('.', s)
|
||||||
|
result.append(mo.group(0))
|
||||||
|
s = s[len(mo.group(0)):]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def parse_rexpr(s):
|
||||||
|
# Like parse_expr(), but return only "real" tokens, not the
|
||||||
|
# intervening space.
|
||||||
|
#
|
||||||
|
return filter(lambda t: token_type(t) != 'space', parse_expr(s))
|
||||||
|
|
||||||
|
|
||||||
|
def token_type(t):
|
||||||
|
# Determine the type of a token. Caller warrants that it was
|
||||||
|
# returned by parse_expr() or parse_rexpr().
|
||||||
|
#
|
||||||
|
if re.match('[ \t]|/\*|@', t):
|
||||||
|
return 'space'
|
||||||
|
if re.match('Glo\(', t):
|
||||||
|
return 'gloid'
|
||||||
|
if re.match('Loc\(', t):
|
||||||
|
return 'locid'
|
||||||
|
if re.match('"', t):
|
||||||
|
return 'string'
|
||||||
|
if re.match(g_ccid0, t):
|
||||||
|
return 'id'
|
||||||
|
if re.match('[0-9]+[bf]', t):
|
||||||
|
return 'label'
|
||||||
|
if re.match('[0-9]', t):
|
||||||
|
return 'number'
|
||||||
|
return t # Sui generis
|
||||||
|
|
||||||
|
|
||||||
|
def debug_parse(a, b, c):
|
||||||
|
# Show results of instuction stream parse.
|
||||||
|
#
|
||||||
|
(b1, b2, b3) = parse_iparts(b)
|
||||||
|
newb = '{' + b1 + '}' + '{' + b2 + '}' + '{' + b3 + '}'
|
||||||
|
sys.stdout.write('{' + a + '}' + newb + c)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
instrs = parse_instrs(read_input())
|
||||||
|
instrs = explicit_address_loads(instrs)
|
||||||
|
instrs = funtypes(instrs)
|
||||||
|
instrs = jump_tables(instrs)
|
||||||
|
instrs = global_symbols(instrs)
|
||||||
|
instrs = local_symbols(instrs)
|
||||||
|
instrs = dot_relative(instrs)
|
||||||
|
instrs = add_prefix(instrs)
|
||||||
|
for (a, b, c) in instrs:
|
||||||
|
sys.stdout.write(a + b + c)
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
||||||
+137
@@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo TARGET var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$DL" ] && DL=~/Downloads
|
||||||
|
|
||||||
|
. $O3/core/vars/vars-$TARGET
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
# Build ASM files with clang 3.0
|
||||||
|
if [ "$APPLE_FAMILY" = "1" ]; then
|
||||||
|
GCC_AS_CMD=$HOME/clang3/clang
|
||||||
|
if ! [ -f "$GCC_AS_CMD" ]; then
|
||||||
|
echo "clang 3.0 binary must be present in $GCC_AS_CMD to assemble ARM crypto algorithms"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEST=minicrypto/minicrypto-$PLATFORM
|
||||||
|
|
||||||
|
GLOBAL_COMPILE_FLAGS="$PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC -DSHA1_ASM -DBF_PTR -DOPENSSL_VERSION_PTEXT= -D__LP32__"
|
||||||
|
|
||||||
|
[ -z "$GCC_CMD" ] && GCC_CMD=gcc
|
||||||
|
[ -z "$GCC_AS_CMD" ] && GCC_AS_CMD="$GCC_CMD"
|
||||||
|
[ -z "$AR_CMD" ] && AR_CMD=ar
|
||||||
|
# the directory where this script lives
|
||||||
|
H=$O3/core/deps/minicrypto
|
||||||
|
|
||||||
|
if [ "$NO_WIPE" != "1" ]; then
|
||||||
|
# unzip OpenSSL
|
||||||
|
rm -rf $OPENSSL_VERSION
|
||||||
|
tar xfz $DL/$OPENSSL_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
OPENSSL_DIR=$(pwd)/$OPENSSL_VERSION
|
||||||
|
|
||||||
|
# make build directory
|
||||||
|
mkdir -p minicrypto
|
||||||
|
rm -rf minicrypto/minicrypto-$PLATFORM
|
||||||
|
mkdir -p minicrypto/minicrypto-$PLATFORM/build.tmp
|
||||||
|
cd minicrypto/minicrypto-$PLATFORM/build.tmp
|
||||||
|
mkdir openssl
|
||||||
|
|
||||||
|
# copy files from OpenSSL tree
|
||||||
|
|
||||||
|
# ARM
|
||||||
|
cp $OPENSSL_DIR/crypto/arm_arch.h .
|
||||||
|
|
||||||
|
# SHA general
|
||||||
|
cp $OPENSSL_DIR/crypto/md32_common.h .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha.h openssl
|
||||||
|
|
||||||
|
# AES
|
||||||
|
cp $OPENSSL_DIR/crypto/aes/asm/aes-armv4.pl .
|
||||||
|
|
||||||
|
# SHA1
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/asm/sha1-armv4-large.pl .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha_locl.h .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha1dgst.c .
|
||||||
|
|
||||||
|
# SHA2
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha256.c .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/asm/sha256-armv4.pl .
|
||||||
|
|
||||||
|
# SHA4
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha512.c .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/asm/sha512-armv4.pl .
|
||||||
|
|
||||||
|
# note that OPENSSL_cleanse is not used by any
|
||||||
|
# of the functions we are interested in
|
||||||
|
cat >openssl/crypto.h <<EOF
|
||||||
|
#define fips_md_init(alg) fips_md_init_ctx(alg, alg)
|
||||||
|
#define fips_md_init_ctx(alg, cx) int alg##_Init(cx##_CTX *c)
|
||||||
|
#define OPENSSL_cleanse(ptr, len) memset((ptr), 0, (len))
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# irrelevant headers
|
||||||
|
touch openssl/e_os2.h
|
||||||
|
touch openssl/opensslconf.h
|
||||||
|
touch openssl/opensslv.h
|
||||||
|
touch aes_locl.h
|
||||||
|
touch cryptlib.h
|
||||||
|
touch crypto.h
|
||||||
|
|
||||||
|
# patches
|
||||||
|
patch <$H/aes-armv4.pl.patch
|
||||||
|
patch <$H/sha512-armv4.pl.patch
|
||||||
|
perl -pi -e 's/private_//g' aes-armv4.pl
|
||||||
|
for f in aes-armv4.pl sha256-armv4.pl sha512-armv4.pl ; do # armv4cpuid.pre
|
||||||
|
perl -pi -e 's/^(\.code.*)$/\/* \1 *\//' $f
|
||||||
|
done
|
||||||
|
|
||||||
|
# build C files
|
||||||
|
for f in *.c ; do
|
||||||
|
COMPILE_FLAGS="-Wno-unused-value"
|
||||||
|
CMD="$GCC_CMD $GLOBAL_COMPILE_FLAGS $COMPILE_FLAGS -I. -c $f"
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
done
|
||||||
|
|
||||||
|
# build armv4cpuid.S
|
||||||
|
#$O3/core/deps/minicrypto/arm-as-to-ios <armv4cpuid.pre >armv4cpuid.S
|
||||||
|
#CMD="$GCC_AS_CMD $GLOBAL_COMPILE_FLAGS -DSYS_macosx -DNO_THUMB -c armv4cpuid.S"
|
||||||
|
#echo $CMD
|
||||||
|
#$CMD
|
||||||
|
|
||||||
|
# build the ASM files given as perl source
|
||||||
|
for f in *.pl ; do
|
||||||
|
bn=${f%%.pl}
|
||||||
|
S=$bn.S
|
||||||
|
COMPILE_FLAGS=""
|
||||||
|
CVT_FLAGS=""
|
||||||
|
if [ "$APPLE_FAMILY" = "1" ]; then
|
||||||
|
COMPILE_FLAGS="$COMPILE_FLAGS -DNO_THUMB"
|
||||||
|
[ "$bn" = "aes-armv4" ] && CVT_FLAGS="$CVT_FLAGS --global=!ad1,!ad2,!ad3"
|
||||||
|
[ "$bn" = "sha512-armv4" ] && CVT_FLAGS="$CVT_FLAGS --global=!HI,!LO"
|
||||||
|
perl $f | $O3/core/deps/minicrypto/arm-as-to-ios --stdin $CVT_FLAGS >$S
|
||||||
|
else
|
||||||
|
perl $f >$S
|
||||||
|
fi
|
||||||
|
CMD="$GCC_AS_CMD $GLOBAL_COMPILE_FLAGS $COMPILE_FLAGS -DSYS_macosx -c $S"
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
done
|
||||||
|
|
||||||
|
CMD="$AR_CMD crs ../libminicrypto.a *.o"
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
exit 0
|
||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo TARGET var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$ARCH" ]; then
|
||||||
|
echo "ARCH var must be defined (x86_64|i386)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$DL" ] && DL=~/Downloads
|
||||||
|
|
||||||
|
. $O3/core/vars-$TARGET
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
DEST=minicrypto/minicrypto-$PLATFORM
|
||||||
|
|
||||||
|
GLOBAL_COMPILE_FLAGS="$MIN_DEPLOY_TARGET $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC"
|
||||||
|
|
||||||
|
[ -z "$GCC_CMD" ] && GCC_CMD=gcc
|
||||||
|
[ -z "$GCC_AS_CMD" ] && GCC_AS_CMD="$GCC_CMD"
|
||||||
|
[ -z "$AR_CMD" ] && AR_CMD=ar
|
||||||
|
|
||||||
|
# the directory where this script lives
|
||||||
|
H=$O3/core/deps/minicrypto
|
||||||
|
|
||||||
|
if [ "$NO_WIPE" != "1" ]; then
|
||||||
|
# unzip OpenSSL
|
||||||
|
rm -rf $OPENSSL_VERSION
|
||||||
|
tar xfz $DL/$OPENSSL_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
OPENSSL_DIR=$(pwd)/$OPENSSL_VERSION
|
||||||
|
|
||||||
|
# make build directory
|
||||||
|
mkdir -p minicrypto
|
||||||
|
rm -rf minicrypto/minicrypto-$PLATFORM/$ARCH
|
||||||
|
mkdir -p minicrypto/minicrypto-$PLATFORM/$ARCH/build.tmp
|
||||||
|
cd minicrypto/minicrypto-$PLATFORM/$ARCH/build.tmp
|
||||||
|
mkdir openssl
|
||||||
|
|
||||||
|
# copy files from OpenSSL tree
|
||||||
|
|
||||||
|
# AES (not necessary now that PolarSSL has AES optimizations)
|
||||||
|
#cp $OPENSSL_DIR/crypto/aes/asm/aesni-x86_64.pl .
|
||||||
|
|
||||||
|
if [ "$ARCH" = "x86_64" ]; then
|
||||||
|
# General
|
||||||
|
cp $O3/core/deps/polarssl/intel_cpu.c .
|
||||||
|
cp $OPENSSL_DIR/crypto/perlasm/x86_64-xlate.pl .
|
||||||
|
cp $OPENSSL_DIR/crypto/x86_64cpuid.pl .
|
||||||
|
|
||||||
|
# SHA general
|
||||||
|
cp $OPENSSL_DIR/crypto/md32_common.h .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha.h openssl
|
||||||
|
|
||||||
|
# SHA1
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha_locl.h .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha1dgst.c .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/asm/sha1-x86_64.pl .
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha256.c .
|
||||||
|
|
||||||
|
# SHA512
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha512.c .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/asm/sha512-x86_64.pl .
|
||||||
|
|
||||||
|
# convert perl ASM to .s
|
||||||
|
for f in x86_64cpuid sha1-x86_64 ; do
|
||||||
|
perl $f.pl macosx >$f.s
|
||||||
|
done
|
||||||
|
perl sha512-x86_64.pl macosx sha512-x86_64.s
|
||||||
|
perl sha512-x86_64.pl macosx sha256-x86_64.s
|
||||||
|
elif [ "$ARCH" = "i386" ]; then
|
||||||
|
# General
|
||||||
|
cp $O3/core/deps/polarssl/intel_cpu.c .
|
||||||
|
cp $OPENSSL_DIR/crypto/perlasm/x86asm.pl .
|
||||||
|
cp $OPENSSL_DIR/crypto/perlasm/x86gas.pl .
|
||||||
|
cp $OPENSSL_DIR/crypto/x86cpuid.pl .
|
||||||
|
|
||||||
|
# SHA general
|
||||||
|
cp $OPENSSL_DIR/crypto/md32_common.h .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha.h openssl
|
||||||
|
|
||||||
|
# SHA1
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha_locl.h .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha1dgst.c .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/asm/sha1-586.pl .
|
||||||
|
|
||||||
|
# SHA256
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha256.c .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/asm/sha256-586.pl .
|
||||||
|
|
||||||
|
# SHA512
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/sha512.c .
|
||||||
|
cp $OPENSSL_DIR/crypto/sha/asm/sha512-586.pl .
|
||||||
|
|
||||||
|
# convert perl ASM to .s
|
||||||
|
for f in x86cpuid sha1-586 sha256-586 sha512-586 ; do
|
||||||
|
perl $f.pl macosx >$f.s
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >openssl/crypto.h <<EOF
|
||||||
|
#define fips_md_init(alg) fips_md_init_ctx(alg, alg)
|
||||||
|
#define fips_md_init_ctx(alg, cx) int alg##_Init(cx##_CTX *c)
|
||||||
|
void OPENSSL_cleanse(void *ptr, unsigned long len);
|
||||||
|
#define OPENSSL_VERSION_PTEXT " minicrypto"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# irrelevant headers
|
||||||
|
touch openssl/e_os2.h
|
||||||
|
touch openssl/opensslconf.h
|
||||||
|
touch openssl/opensslv.h
|
||||||
|
touch aes_locl.h
|
||||||
|
touch cryptlib.h
|
||||||
|
touch crypto.h
|
||||||
|
|
||||||
|
# build C/ASM files
|
||||||
|
for f in *.c *.s ; do
|
||||||
|
COMPILE_FLAGS="-arch $ARCH -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM"
|
||||||
|
CMD="$GCC_CMD $GLOBAL_COMPILE_FLAGS $COMPILE_FLAGS -I. -c $f"
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
done
|
||||||
|
|
||||||
|
CMD="$AR_CMD crs ../libminicrypto.a *.o"
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
echo SYMBOLS
|
||||||
|
nm ../libminicrypto.a
|
||||||
|
exit 0
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
--- sha512-armv4.pl.orig 2012-09-03 13:21:35.000000000 -0600
|
||||||
|
+++ sha512-armv4.pl 2012-09-03 13:50:08.000000000 -0600
|
||||||
|
@@ -220,9 +220,6 @@
|
||||||
|
WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a)
|
||||||
|
WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817)
|
||||||
|
.size K512,.-K512
|
||||||
|
-.LOPENSSL_armcap:
|
||||||
|
-.word OPENSSL_armcap_P-sha512_block_data_order
|
||||||
|
-.skip 32-4
|
||||||
|
|
||||||
|
.global sha512_block_data_order
|
||||||
|
.type sha512_block_data_order,%function
|
||||||
|
@@ -230,10 +227,7 @@
|
||||||
|
sub r3,pc,#8 @ sha512_block_data_order
|
||||||
|
add $len,$inp,$len,lsl#7 @ len to point at the end of inp
|
||||||
|
#if __ARM_ARCH__>=7
|
||||||
|
- ldr r12,.LOPENSSL_armcap
|
||||||
|
- ldr r12,[r3,r12] @ OPENSSL_armcap_P
|
||||||
|
- tst r12,#1
|
||||||
|
- bne .LNEON
|
||||||
|
+ b .LNEON @ JY -- assume ARM v7 always supports NEON
|
||||||
|
#endif
|
||||||
|
stmdb sp!,{r4-r12,lr}
|
||||||
|
sub $Ktbl,r3,#672 @ K512
|
||||||
|
@@ -573,7 +567,6 @@
|
||||||
|
.size sha512_block_data_order,.-sha512_block_data_order
|
||||||
|
.asciz "SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
|
||||||
|
.align 2
|
||||||
|
-.comm OPENSSL_armcap_P,4,4
|
||||||
|
___
|
||||||
|
|
||||||
|
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo TARGET var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$OPENSSL_TARGET" ]; then
|
||||||
|
echo "OPENSSL_TARGET var must be defined"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# GNU sed differs from BSD sed
|
||||||
|
if sed --version 2>&1 | grep -q GNU ; then
|
||||||
|
mysed='sed -i'
|
||||||
|
else
|
||||||
|
mysed='sed -i ""'
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$GCC_CMD" ] && GCC_CMD=gcc
|
||||||
|
|
||||||
|
[ -z "$LINK_MODE" ] && LINK_MODE=static
|
||||||
|
[ "$LINK_MODE" = "static" ] && LINK_MODE=no-shared
|
||||||
|
|
||||||
|
[ -z "$DL" ] && DL=~/Downloads
|
||||||
|
|
||||||
|
. $O3/core/vars/vars-$TARGET
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
|
||||||
|
# source vars
|
||||||
|
. $O3/core/vars/vars-${TARGET}
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
# source helper functions
|
||||||
|
. $O3/core/deps/functions.sh
|
||||||
|
|
||||||
|
FNAME=openssl-${OPNESSL_VERSION}.tar.gz
|
||||||
|
URL=https://www.openssl.org/source/${OPENSSL_VERSION}.tar.gz
|
||||||
|
CSUM=${OPENSSL_CSUM}
|
||||||
|
|
||||||
|
download
|
||||||
|
|
||||||
|
AR=ar
|
||||||
|
RANLIB=ranlib
|
||||||
|
[ "$AR_CMD" ] && AR=$AR_CMD
|
||||||
|
[ "$RANLIB_CMD" ] && RANLIB=$RANLIB_CMD
|
||||||
|
|
||||||
|
# special hack because OpenSSL build system doesn't use rc options for ar
|
||||||
|
[ "$AR" = "gcc-ar" ] && AR="gcc-ar rc"
|
||||||
|
[ "$AR" = "gcc-ar-5" ] && AR="gcc-ar-5 rc"
|
||||||
|
|
||||||
|
OPENSSL=$OPENSSL_VERSION
|
||||||
|
DIST=$(pwd)/openssl/openssl-$PLATFORM
|
||||||
|
[ "$ARCH" ] && DIST=$DIST/$ARCH
|
||||||
|
rm -rf $OPENSSL $DIST
|
||||||
|
mkdir -p $DIST
|
||||||
|
tar xfz $DL/$FNAME
|
||||||
|
pushd $OPENSSL
|
||||||
|
CMD="./Configure $OPENSSL_TARGET $LINK_MODE threads no-idea no-mdc2 no-rc5 --prefix=$DIST"
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
$mysed -e "s|-O3|$LIB_OPT_LEVEL $MIN_DEPLOY_TARGET $OTHER_COMPILER_FLAGS $LIB_FPIC|" Makefile
|
||||||
|
#$mysed -e "s|ERR_load_COMP_strings()|//ERR_load_COMP_strings()|" crypto/err/err_all.c
|
||||||
|
make depend
|
||||||
|
make CC="$GCC_CMD" AR="$AR" RANLIB="$RANLIB" -j ${MAKE_JOBS:-1} build_libs
|
||||||
|
touch apps/openssl
|
||||||
|
touch openssl.pc
|
||||||
|
touch libcrypto.pc
|
||||||
|
touch libssl.pc
|
||||||
|
make install_sw
|
||||||
|
popd
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
polartmp
|
||||||
Vendored
+86
@@ -0,0 +1,86 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
project(POLARSSL C)
|
||||||
|
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
# JY Added
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "")
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
|
||||||
|
set(CMAKE_OSX_SYSROOT "")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $ENV{LIB_FPIC} $ENV{LIB_OPT_LEVEL} $ENV{PLATFORM_FLAGS} $ENV{OTHER_COMPILER_FLAGS} -Wall -W -Wdeclaration-after-statement")
|
||||||
|
if (NOT "$ENV{GCC_CMD}" STREQUAL "")
|
||||||
|
set(CMAKE_C_COMPILER "$ENV{GCC_CMD}")
|
||||||
|
endif()
|
||||||
|
if (NOT "$ENV{GPP_CMD}" STREQUAL "")
|
||||||
|
set(CMAKE_CXX_COMPILER "$ENV{GPP_CMD}")
|
||||||
|
endif()
|
||||||
|
if (NOT "$ENV{AR_CMD}" STREQUAL "")
|
||||||
|
set(CMAKE_AR "$ENV{AR_CMD}")
|
||||||
|
endif()
|
||||||
|
if (NOT "$ENV{RANLIB_CMD}" STREQUAL "")
|
||||||
|
set(CMAKE_RANLIB "$ENV{RANLIB_CMD}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# JY Commented out
|
||||||
|
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -Wall -Wextra -W -Wdeclaration-after-statement")
|
||||||
|
#set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
|
||||||
|
#set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 -fprofile-arcs -ftest-coverage -lgcov")
|
||||||
|
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")
|
||||||
|
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
|
||||||
|
|
||||||
|
option(USE_PKCS11_HELPER_LIBRARY "Build PolarSSL with the pkcs11-helper library." OFF)
|
||||||
|
|
||||||
|
option(ENABLE_ZLIB_SUPPORT "Build PolarSSL with zlib library." OFF)
|
||||||
|
|
||||||
|
# JY added
|
||||||
|
if(MINICRYPTO)
|
||||||
|
if(MINICRYPTO_DIR)
|
||||||
|
add_library(minicrypto STATIC IMPORTED)
|
||||||
|
set_property(TARGET minicrypto PROPERTY IMPORTED_LOCATION "${MINICRYPTO_DIR}/libminicrypto.a")
|
||||||
|
endif()
|
||||||
|
if(OSSLCRYPTO_DIR)
|
||||||
|
add_library(crypto STATIC IMPORTED)
|
||||||
|
set_property(TARGET crypto PROPERTY IMPORTED_LOCATION "${OSSLCRYPTO_DIR}/libcrypto.a")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# include full testing infrastructure (JY added)
|
||||||
|
if(ENABLE_TESTING)
|
||||||
|
enable_testing()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(LIB_INSTALL_DIR)
|
||||||
|
else()
|
||||||
|
set(LIB_INSTALL_DIR lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include_directories(include/)
|
||||||
|
|
||||||
|
if(ENABLE_ZLIB_SUPPORT)
|
||||||
|
find_package(ZLIB)
|
||||||
|
|
||||||
|
if(ZLIB_FOUND)
|
||||||
|
include_directories(ZLIB_INCLUDE_DIR)
|
||||||
|
endif(ZLIB_FOUND)
|
||||||
|
endif(ENABLE_ZLIB_SUPPORT)
|
||||||
|
|
||||||
|
add_subdirectory(library)
|
||||||
|
add_subdirectory(include)
|
||||||
|
|
||||||
|
# include full testing infrastructure (JY modified)
|
||||||
|
if(ENABLE_TESTING)
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
add_subdirectory(programs)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ADD_CUSTOM_TARGET(apidoc
|
||||||
|
COMMAND doxygen doxygen/polarssl.doxyfile
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
Building PolarSSL for android.
|
||||||
|
|
||||||
|
First, build static OpenSSL for PolarSSL/OpenSSL bridge
|
||||||
|
(the build-openssl-small script may be used).
|
||||||
|
|
||||||
|
Next build libminicrypto.a from libcrypto.a :
|
||||||
|
|
||||||
|
$O3/polarssl/build-mini-openssl ref
|
||||||
|
|
||||||
|
Finally, build PolarSSL:
|
||||||
|
|
||||||
|
TARGET=android $O3/polarssl/build-polarssl
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
# this one is important
|
||||||
|
SET(CMAKE_SYSTEM_NAME Linux)
|
||||||
|
#this one not so much
|
||||||
|
SET(CMAKE_SYSTEM_VERSION 1)
|
||||||
|
|
||||||
|
# specify the cross compiler (assumes that PATH already points to android toolchain)
|
||||||
|
SET(CMAKE_C_COMPILER gcc)
|
||||||
|
SET(CMAKE_CXX_COMPILER g++)
|
||||||
|
|
||||||
|
# where is the target environment
|
||||||
|
#SET(CMAKE_FIND_ROOT_PATH /opt/eldk-2007-01-19/ppc_74xx /home/alex/eldk-ppc74xx-inst)
|
||||||
|
|
||||||
|
# search for programs in the build host directories
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
# for libraries and headers in the target directories
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
# specify the cross compiler
|
||||||
|
SET(CMAKE_C_COMPILER clang)
|
||||||
|
SET(CMAKE_CXX_COMPILER clang++)
|
||||||
|
SET(CMAKE_COMPILER_IS_GNUCC 1)
|
||||||
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/bn_mul.h polarssl-1.2.7.new/include/polarssl/bn_mul.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/bn_mul.h 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl-1.2.7.new/include/polarssl/bn_mul.h 2013-06-13 16:30:35.000000000 -0600
|
||||||
|
@@ -548,7 +548,7 @@
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
|
||||||
|
-#if defined(__thumb__)
|
||||||
|
+#if defined(__thumb__) && !defined(__thumb2__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( \
|
||||||
|
diff -uNr polarssl-1.2.7/library/bignum.c polarssl-1.2.7.new/library/bignum.c
|
||||||
|
--- polarssl-1.2.7/library/bignum.c 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl-1.2.7.new/library/bignum.c 2013-06-13 16:30:35.000000000 -0600
|
||||||
|
@@ -935,7 +935,15 @@
|
||||||
|
/*
|
||||||
|
* Helper for mpi multiplication
|
||||||
|
*/
|
||||||
|
-static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
|
||||||
|
+static
|
||||||
|
+#if defined(__APPLE__) && defined(__arm__)
|
||||||
|
+/*
|
||||||
|
+ * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
|
||||||
|
+ * appears to need this to prevent bad ARM code generation at -O3.
|
||||||
|
+ */
|
||||||
|
+__attribute__ ((noinline))
|
||||||
|
+#endif
|
||||||
|
+void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
|
||||||
|
{
|
||||||
|
t_uint c = 0, t = 0;
|
||||||
|
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
POLARSSL_SRC=$HOME/src/mac/$POLARSSL_VERSION
|
||||||
|
PD=$O3/core/deps/polarssl
|
||||||
|
PB=$(basename $POLARSSL_SRC)
|
||||||
|
|
||||||
|
rm -rf polartmp
|
||||||
|
mkdir polartmp
|
||||||
|
cd polartmp
|
||||||
|
cp -a $POLARSSL_SRC polarssl.new
|
||||||
|
|
||||||
|
# extract the PolarSSL source
|
||||||
|
tar xfz $DL/$PB-gpl.tgz
|
||||||
|
|
||||||
|
cd $PB
|
||||||
|
rm $(find . -type f | grep -E 'Makefile|\.orig$|\.rej$')
|
||||||
|
rm -f CMakeLists.txt include/polarssl/config.h include/polarssl/openvpn-polarssl.h
|
||||||
|
|
||||||
|
cd ../polarssl.new
|
||||||
|
rm -f CMakeLists.txt include/polarssl/config.h include/polarssl/openvpn-polarssl.h
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
diff -ur $PB polarssl.new | grep -v '^Only in'
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Examples:
|
||||||
|
# $O3/core/deps/polarssl/build-mini-openssl ref
|
||||||
|
# $O3/core/deps/polarssl/build-mini-openssl ref-aesni
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "usage: build-mini-openssl <ref|ref-aesni>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$OPENSSL_DIR" ]; then
|
||||||
|
echo OPENSSL_DIR must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$APPLE_FAMILY" = "1" ] && [ -z "$GCC_CMD" ]; then
|
||||||
|
GCC_CMD=clang
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$APPLE_FAMILY" = "1" ]; then
|
||||||
|
NM_FLAGS=-P
|
||||||
|
BSD_SYMBOLS="1"
|
||||||
|
VISIBILITY="-fvisibility=hidden"
|
||||||
|
else
|
||||||
|
NM_FLAGS="-f posix"
|
||||||
|
BSD_SYMBOLS="0"
|
||||||
|
VISIBILITY=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$NM_CMD" ] && NM_CMD=nm
|
||||||
|
[ -z "$AR_CMD" ] && AR_CMD=ar
|
||||||
|
[ -z "$GCC_CMD" ] && GCC_CMD=gcc
|
||||||
|
PD=$O3/core/deps/polarssl
|
||||||
|
cd $OPENSSL_DIR
|
||||||
|
cd lib
|
||||||
|
rm -rf tmp
|
||||||
|
mkdir tmp
|
||||||
|
$NM_CMD $NM_FLAGS libcrypto.a >tmp/nm-file
|
||||||
|
echo "NOTE: on BSD systems, don't worry about any 'no name list' errors above"
|
||||||
|
cd tmp
|
||||||
|
python $O3/common/scripts/sym.py $PD/$1 nm-file $AR_CMD ../libcrypto.a libminicrypto.a buildmini ../mini-undef.sh $BSD_SYMBOLS
|
||||||
|
. buildmini
|
||||||
|
|
||||||
|
# need any special initialization?
|
||||||
|
. ../mini-undef.sh
|
||||||
|
if [ "$SYM_UNDEF_OPENSSL_ia32cap_P" ] && [ "$SYM_UNDEF_OPENSSL_cpuid_setup" ]; then
|
||||||
|
echo BUILDING STUB intel_cpu.c
|
||||||
|
$GCC_CMD $VISIBILITY $LIB_OPT_LEVEL $LIB_FPIC -c $PD/intel_cpu.c
|
||||||
|
$AR_CMD rs libminicrypto.a intel_cpu.o
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv libminicrypto.a ..
|
||||||
+167
@@ -0,0 +1,167 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# CMAKE_TARGET -- use $CMAKE_TARGET.cmake as toolchain file
|
||||||
|
# AES_NI=1 -- enable AES_NI processor optimization
|
||||||
|
# EXTERNAL_RNG=1 -- disable all internal RNG implementations (caller must provide)
|
||||||
|
# ENABLE_TESTING=1 -- run PolarSSL test scripts after build
|
||||||
|
# DEBUG_BUILD=1 or SELF_TEST=1 -- enable minimal testing on target
|
||||||
|
# ENABLE_SERVER=1 -- enable SSL/TLS server code
|
||||||
|
# ENABLE_FS_IO=1 -- enable PolarSSL file I/O
|
||||||
|
# VERBOSE=1 -- see build commands
|
||||||
|
# USE_MINICRYPTO=1 -- use minicrypto library
|
||||||
|
# NO_WIPE=1 -- don't wipe source tree and reunzip tarball
|
||||||
|
# STOCK_CONFIG=1 -- use stock PolarSSL config.h
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo TARGET var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# source vars
|
||||||
|
. $O3/core/vars/vars-${TARGET}
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
# extract the PolarSSL source
|
||||||
|
PD=$O3/core/deps/polarssl
|
||||||
|
DIST=polarssl-$PLATFORM
|
||||||
|
|
||||||
|
rm -rf $DIST
|
||||||
|
mkdir $DIST
|
||||||
|
|
||||||
|
if [ "$NO_WIPE" = "1" ]; then
|
||||||
|
echo RETAIN existing source
|
||||||
|
cd $POLARSSL_VERSION
|
||||||
|
elif [ "$NO_WIPE" = "partial" ]; then
|
||||||
|
echo RETAIN existing source but copy config.h and CMakeLists.txt
|
||||||
|
cd $POLARSSL_VERSION
|
||||||
|
|
||||||
|
# define configs
|
||||||
|
if [ "$STOCK_CONFIG" != "1" ]; then
|
||||||
|
cp $PD/config.h include/polarssl/
|
||||||
|
fi
|
||||||
|
cp $PD/CMakeLists.txt .
|
||||||
|
else
|
||||||
|
echo WIPE and reunzip source
|
||||||
|
rm -rf $POLARSSL_VERSION $POLARSSL_VERSION-prerelease
|
||||||
|
[ -z "$DL" ] && DL=~/Downloads
|
||||||
|
tar xfz $DL/$POLARSSL_VERSION-gpl.tgz
|
||||||
|
|
||||||
|
[ -d $POLARSSL_VERSION-prerelease ] && mv $POLARSSL_VERSION-prerelease $POLARSSL_VERSION
|
||||||
|
cd $POLARSSL_VERSION
|
||||||
|
|
||||||
|
# delete makefiles (apparently not needed)
|
||||||
|
rm $(find . -type f | grep Makefile)
|
||||||
|
|
||||||
|
patch -p1 <$PD/relaxed-x509-date.patch
|
||||||
|
#patch -p1 <$PD/dhm.patch
|
||||||
|
#patch -p1 <$PD/entropy-printf.patch
|
||||||
|
|
||||||
|
if [ "$USE_MINICRYPTO" = "1" ]; then
|
||||||
|
# do the big polar-openssl patch
|
||||||
|
echo MERGING polarssl-minicrypto.patch
|
||||||
|
patch -p1 <$PD/polarssl-minicrypto.patch
|
||||||
|
fi
|
||||||
|
|
||||||
|
# define configs
|
||||||
|
cp include/polarssl/config.h include/polarssl/config.h.orig
|
||||||
|
cp CMakeLists.txt CMakeLists.txt.orig
|
||||||
|
cp $PD/config.h include/polarssl/
|
||||||
|
cp $PD/CMakeLists.txt .
|
||||||
|
fi
|
||||||
|
|
||||||
|
# dynamically generated header file with options,
|
||||||
|
# included by config.h
|
||||||
|
OPC=include/polarssl/openvpn-polarssl.h
|
||||||
|
echo '/* Automatically generated by ovpn3/core/deps/polarssl/build-polarssl, do not edit */' >$OPC
|
||||||
|
|
||||||
|
# set options
|
||||||
|
OPT=""
|
||||||
|
|
||||||
|
# relaxed cert checking
|
||||||
|
echo "#define POLARSSL_RELAXED_X509_DATE" >>$OPC
|
||||||
|
|
||||||
|
# RNG
|
||||||
|
if [ "$EXTERNAL_RNG" = "1" ]; then
|
||||||
|
echo "#define EXTERNAL_RNG" >>$OPC
|
||||||
|
fi
|
||||||
|
|
||||||
|
# enable full testing infrastructure
|
||||||
|
if [ "$ENABLE_TESTING" = "1" ]; then
|
||||||
|
OPT="$OPT -DENABLE_TESTING=1"
|
||||||
|
echo "#define ENABLE_TESTING" >>$OPC
|
||||||
|
fi
|
||||||
|
|
||||||
|
# enable minimal testing on target
|
||||||
|
if [ "$DEBUG_BUILD" = "1" ] || [ "$SELF_TEST" = "1" ]; then
|
||||||
|
echo "#define POLARSSL_SELF_TEST" >>$OPC
|
||||||
|
fi
|
||||||
|
|
||||||
|
# configure target
|
||||||
|
if [ "$CMAKE_TARGET" ]; then
|
||||||
|
OPT="$OPT -DCMAKE_TOOLCHAIN_FILE=$PD/$CMAKE_TARGET.cmake"
|
||||||
|
elif [ "$APPLE_FAMILY" = "1" ]; then
|
||||||
|
OPT="$OPT -DCMAKE_TOOLCHAIN_FILE=$PD/apple.cmake"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Minicrypto
|
||||||
|
if [ "$USE_MINICRYPTO" = "1" ]; then
|
||||||
|
OPT="$OPT -DMINICRYPTO=1"
|
||||||
|
if [ "$MINICRYPTO_DIR" ]; then
|
||||||
|
OPT="$OPT -DMINICRYPTO_DIR=$MINICRYPTO_DIR"
|
||||||
|
fi
|
||||||
|
if [ "$OSSLCRYPTO_DIR" ]; then
|
||||||
|
OPT="$OPT -DOSSLCRYPTO_DIR=$OSSLCRYPTO_DIR"
|
||||||
|
fi
|
||||||
|
if [ "$MINICRYPTO_NO_AES" != "1" ]; then
|
||||||
|
echo "#define POLARSSL_AES_ALT" >>$OPC
|
||||||
|
fi
|
||||||
|
echo "#define POLARSSL_SHA1_ALT" >>$OPC
|
||||||
|
echo "#define POLARSSL_SHA256_ALT" >>$OPC
|
||||||
|
echo "#define POLARSSL_SHA512_ALT" >>$OPC
|
||||||
|
if [ "$AES_NI" = "1" ] && [ "$MINICRYPTO_NO_AES" != "1" ]; then
|
||||||
|
echo "#define POLARSSL_USE_OPENSSL_AES_NI" >>$OPC
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable SSL/TLS server
|
||||||
|
if [ "$ENABLE_SERVER" = "1" ]; then
|
||||||
|
echo "#define POLARSSL_SSL_SRV_C" >>$OPC
|
||||||
|
fi
|
||||||
|
|
||||||
|
# enable PolarSSL file I/O
|
||||||
|
if [ "$ENABLE_FS_IO" = "1" ]; then
|
||||||
|
echo "#define POLARSSL_FS_IO" >>$OPC
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build shared library
|
||||||
|
if [ "$SHARED" = "1" ]; then
|
||||||
|
OPT="$OPT -DUSE_SHARED_POLARSSL_LIBRARY=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# echo options
|
||||||
|
echo OPTIONS $OPT
|
||||||
|
|
||||||
|
# build it
|
||||||
|
pwd
|
||||||
|
cd ../$DIST
|
||||||
|
cmake $OPT ../$POLARSSL_VERSION
|
||||||
|
if [ "$VERBOSE" = "1" ]; then
|
||||||
|
make VERBOSE=1
|
||||||
|
else
|
||||||
|
make
|
||||||
|
fi
|
||||||
|
|
||||||
|
# test it
|
||||||
|
if [ "$ENABLE_TESTING" = "1" ]; then
|
||||||
|
make test
|
||||||
|
fi
|
||||||
|
|
||||||
|
# copy headers
|
||||||
|
cp -a ../$POLARSSL_VERSION/include/polarssl include/
|
||||||
|
exit 0
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
POLARSSL_SRC=$HOME/src/mac/$POLARSSL_VERSION
|
||||||
|
PD=$O3/core/deps/polarssl
|
||||||
|
PB=$(basename $POLARSSL_SRC)
|
||||||
|
|
||||||
|
rm -rf polartmp
|
||||||
|
mkdir polartmp
|
||||||
|
cd polartmp
|
||||||
|
cp -a $POLARSSL_SRC polarssl.new
|
||||||
|
|
||||||
|
# extract the PolarSSL source
|
||||||
|
tar xfz $DL/$PB-gpl.tgz
|
||||||
|
|
||||||
|
cd $PB
|
||||||
|
rm $(find . -type f | grep -E 'Makefile|\.orig$|\.rej$')
|
||||||
|
rm -f CMakeLists.txt include/polarssl/config.h include/polarssl/openvpn-polarssl.h
|
||||||
|
|
||||||
|
cd ../polarssl.new
|
||||||
|
rm -f CMakeLists.txt include/polarssl/config.h include/polarssl/openvpn-polarssl.h
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
if [ "$CRYPTO_ALT_PATCH" = "1" ]; then
|
||||||
|
diff -uNr $PB polarssl.new >$PD/polar-openssl.patch
|
||||||
|
cp $PD/crypto-alt.txt $PD/polarssl-crypto-alt.patch
|
||||||
|
diff -ur $PB polarssl.new | grep -v '^Only in' >>$PD/polarssl-crypto-alt.patch
|
||||||
|
else
|
||||||
|
diff -ur $PB polarssl.new | grep -v '^Only in'
|
||||||
|
fi
|
||||||
Vendored
+2227
File diff suppressed because it is too large
Load Diff
Vendored
+2180
File diff suppressed because it is too large
Load Diff
Vendored
+959
@@ -0,0 +1,959 @@
|
|||||||
|
/**
|
||||||
|
* \file config.h
|
||||||
|
*
|
||||||
|
* \brief Configuration options (set of defines)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2012, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* This set of compile-time options may be used to enable
|
||||||
|
* or disable features selectively, and reduce the global
|
||||||
|
* memory footprint.
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_CONFIG_H
|
||||||
|
#define POLARSSL_CONFIG_H
|
||||||
|
|
||||||
|
#include <polarssl/openvpn-polarssl.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name SECTION: System support
|
||||||
|
*
|
||||||
|
* This section sets system specific settings.
|
||||||
|
* \{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_HAVE_INT8
|
||||||
|
*
|
||||||
|
* The system uses 8-bit wide native integers.
|
||||||
|
*
|
||||||
|
* Uncomment if native integers are 8-bit wide.
|
||||||
|
#define POLARSSL_HAVE_INT8
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_HAVE_INT16
|
||||||
|
*
|
||||||
|
* The system uses 16-bit wide native integers.
|
||||||
|
*
|
||||||
|
* Uncomment if native integers are 16-bit wide.
|
||||||
|
#define POLARSSL_HAVE_INT16
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_HAVE_LONGLONG
|
||||||
|
*
|
||||||
|
* The compiler supports the 'long long' type.
|
||||||
|
* (Only used on 32-bit platforms)
|
||||||
|
*/
|
||||||
|
#define POLARSSL_HAVE_LONGLONG
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_HAVE_ASM
|
||||||
|
*
|
||||||
|
* The compiler has support for asm()
|
||||||
|
*
|
||||||
|
* Uncomment to enable the use of assembly code.
|
||||||
|
*
|
||||||
|
* Requires support for asm() in compiler.
|
||||||
|
*
|
||||||
|
* Used in:
|
||||||
|
* library/timing.c
|
||||||
|
* library/padlock.c
|
||||||
|
* include/polarssl/bn_mul.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define POLARSSL_HAVE_ASM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_HAVE_SSE2
|
||||||
|
*
|
||||||
|
* CPU supports SSE2 instruction set.
|
||||||
|
*
|
||||||
|
* Uncomment if the CPU supports SSE2 (IA-32 specific).
|
||||||
|
*
|
||||||
|
#define POLARSSL_HAVE_SSE2
|
||||||
|
*/
|
||||||
|
/* \} name */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name SECTION: PolarSSL feature support
|
||||||
|
*
|
||||||
|
* This section sets support for features that are or are not needed
|
||||||
|
* within the modules that are enabled.
|
||||||
|
* \{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_AES_ROM_TABLES
|
||||||
|
*
|
||||||
|
* Store the AES tables in ROM.
|
||||||
|
*
|
||||||
|
* Uncomment this macro to store the AES tables in ROM.
|
||||||
|
*
|
||||||
|
#define POLARSSL_AES_ROM_TABLES
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_CIPHER_MODE_CFB
|
||||||
|
*
|
||||||
|
* Enable Cipher Feedback mode (CFB) for symmetric ciphers.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_CIPHER_MODE_CFB
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_CIPHER_MODE_CTR
|
||||||
|
*
|
||||||
|
* Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_CIPHER_MODE_CTR
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_CIPHER_NULL_CIPHER
|
||||||
|
*
|
||||||
|
* Enable NULL cipher.
|
||||||
|
* Warning: Only do so when you know what you are doing. This allows for
|
||||||
|
* encryption or channels without any security!
|
||||||
|
*
|
||||||
|
* Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable
|
||||||
|
* the following ciphersuites:
|
||||||
|
* TLS_RSA_WITH_NULL_MD5
|
||||||
|
* TLS_RSA_WITH_NULL_SHA
|
||||||
|
* TLS_RSA_WITH_NULL_SHA256
|
||||||
|
*
|
||||||
|
* Uncomment this macro to enable the NULL cipher and ciphersuites
|
||||||
|
#define POLARSSL_CIPHER_NULL_CIPHER
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_ENABLE_WEAK_CIPHERSUITES
|
||||||
|
*
|
||||||
|
* Enable weak ciphersuites in SSL / TLS
|
||||||
|
* Warning: Only do so when you know what you are doing. This allows for
|
||||||
|
* channels with virtually no security at all!
|
||||||
|
*
|
||||||
|
* This enables the following ciphersuites:
|
||||||
|
* TLS_RSA_WITH_DES_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_DES_CBC_SHA
|
||||||
|
*
|
||||||
|
* Uncomment this macro to enable weak ciphersuites
|
||||||
|
#define POLARSSL_ENABLE_WEAK_CIPHERSUITES
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_ERROR_STRERROR_DUMMY
|
||||||
|
*
|
||||||
|
* Enable a dummy error function to make use of error_strerror() in
|
||||||
|
* third party libraries easier.
|
||||||
|
*
|
||||||
|
* Disable if you run into name conflicts and want to really remove the
|
||||||
|
* error_strerror()
|
||||||
|
*/
|
||||||
|
#define POLARSSL_ERROR_STRERROR_DUMMY
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_GENPRIME
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C
|
||||||
|
*
|
||||||
|
* Enable the RSA prime-number generation code.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_GENPRIME
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_FS_IO
|
||||||
|
*
|
||||||
|
* Enable functions that use the filesystem.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_FS_IO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
|
||||||
|
*
|
||||||
|
* Do not add default entropy sources. These are the platform specific,
|
||||||
|
* hardclock and HAVEGE based poll functions.
|
||||||
|
*
|
||||||
|
* This is useful to have more control over the added entropy sources in an
|
||||||
|
* application.
|
||||||
|
*
|
||||||
|
* Uncomment this macro to prevent loading of default entropy functions.
|
||||||
|
#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_NO_PLATFORM_ENTROPY
|
||||||
|
*
|
||||||
|
* Do not use built-in platform entropy functions.
|
||||||
|
* This is useful if your platform does not support
|
||||||
|
* standards like the /dev/urandom or Windows CryptoAPI.
|
||||||
|
*
|
||||||
|
* Uncomment this macro to disable the built-in platform entropy functions.
|
||||||
|
#define POLARSSL_NO_PLATFORM_ENTROPY
|
||||||
|
*/
|
||||||
|
|
||||||
|
// JY added
|
||||||
|
#ifdef EXTERNAL_RNG
|
||||||
|
#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
|
||||||
|
#define POLARSSL_NO_PLATFORM_ENTROPY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_PKCS1_V21
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_MD_C, POLARSSL_RSA_C
|
||||||
|
*
|
||||||
|
* Enable support for PKCS#1 v2.1 encoding.
|
||||||
|
* This enables support for RSAES-OAEP and RSASSA-PSS operations.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_PKCS1_V21
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_RSA_NO_CRT
|
||||||
|
*
|
||||||
|
* Do not use the Chinese Remainder Theorem for the RSA private operation.
|
||||||
|
*
|
||||||
|
* Uncomment this macro to disable the use of CRT in RSA.
|
||||||
|
*
|
||||||
|
#define POLARSSL_RSA_NO_CRT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SELF_TEST
|
||||||
|
*
|
||||||
|
* Enable the checkup functions (*_self_test).
|
||||||
|
*/
|
||||||
|
// JY changed
|
||||||
|
#if defined(ENABLE_TESTING) && !defined(POLARSSL_SELF_TEST)
|
||||||
|
#define POLARSSL_SELF_TEST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SSL_ALL_ALERT_MESSAGES
|
||||||
|
*
|
||||||
|
* Enable sending of alert messages in case of encountered errors as per RFC.
|
||||||
|
* If you choose not to send the alert messages, PolarSSL can still communicate
|
||||||
|
* with other servers, only debugging of failures is harder.
|
||||||
|
*
|
||||||
|
* The advantage of not sending alert messages, is that no information is given
|
||||||
|
* about reasons for failures thus preventing adversaries of gaining intel.
|
||||||
|
*
|
||||||
|
* Enable sending of all alert messages
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_ALERT_MESSAGES
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SSL_DEBUG_ALL
|
||||||
|
*
|
||||||
|
* Enable the debug messages in SSL module for all issues.
|
||||||
|
* Debug messages have been disabled in some places to prevent timing
|
||||||
|
* attacks due to (unbalanced) debugging function calls.
|
||||||
|
*
|
||||||
|
* If you need all error reporting you should enable this during debugging,
|
||||||
|
* but remove this for production servers that should log as well.
|
||||||
|
*
|
||||||
|
* Uncomment this macro to report all debug messages on errors introducing
|
||||||
|
* a timing side-channel.
|
||||||
|
*
|
||||||
|
#define POLARSSL_SSL_DEBUG_ALL
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SSL_HW_RECORD_ACCEL
|
||||||
|
*
|
||||||
|
* Enable hooking functions in SSL module for hardware acceleration of
|
||||||
|
* individual records.
|
||||||
|
*
|
||||||
|
* Uncomment this macro to enable hooking functions.
|
||||||
|
#define POLARSSL_SSL_HW_RECORD_ACCEL
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
|
||||||
|
*
|
||||||
|
* Enable support for receiving and parsing SSLv2 Client Hello messages for the
|
||||||
|
* SSL Server module (POLARSSL_SSL_SRV_C)
|
||||||
|
*
|
||||||
|
* Comment this macro to disable support for SSLv2 Client Hello messages.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
|
||||||
|
*
|
||||||
|
* If set, the X509 parser will not break-off when parsing an X509 certificate
|
||||||
|
* and encountering an unknown critical extension.
|
||||||
|
*
|
||||||
|
* Uncomment to prevent an error.
|
||||||
|
*
|
||||||
|
#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_ZLIB_SUPPORT
|
||||||
|
*
|
||||||
|
* If set, the SSL/TLS module uses ZLIB to support compression and
|
||||||
|
* decompression of packet data.
|
||||||
|
*
|
||||||
|
* Used in: library/ssl_tls.c
|
||||||
|
* library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
*
|
||||||
|
* This feature requires zlib library and headers to be present.
|
||||||
|
*
|
||||||
|
* Uncomment to enable use of ZLIB
|
||||||
|
#define POLARSSL_ZLIB_SUPPORT
|
||||||
|
*/
|
||||||
|
/* \} name */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name SECTION: PolarSSL modules
|
||||||
|
*
|
||||||
|
* This section enables or disables entire modules in PolarSSL
|
||||||
|
* \{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_AES_C
|
||||||
|
*
|
||||||
|
* Enable the AES block cipher.
|
||||||
|
*
|
||||||
|
* Module: library/aes.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
* library/pem.c
|
||||||
|
* library/ctr_drbg.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites (if other requisites are
|
||||||
|
* enabled as well):
|
||||||
|
* TLS_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
* TLS_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
* TLS_RSA_WITH_AES_128_CBC_SHA256
|
||||||
|
* TLS_RSA_WITH_AES_256_CBC_SHA256
|
||||||
|
* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
|
||||||
|
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
|
||||||
|
* TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
* TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
*
|
||||||
|
* PEM uses AES for decrypting encrypted keys.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_AES_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_ARC4_C
|
||||||
|
*
|
||||||
|
* Enable the ARCFOUR stream cipher.
|
||||||
|
*
|
||||||
|
* Module: library/arc4.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites:
|
||||||
|
* TLS_RSA_WITH_RC4_128_MD5
|
||||||
|
* TLS_RSA_WITH_RC4_128_SHA
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_ARC4_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_ASN1_PARSE_C
|
||||||
|
*
|
||||||
|
* Enable the generic ASN1 parser.
|
||||||
|
*
|
||||||
|
* Module: library/asn1.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*/
|
||||||
|
#define POLARSSL_ASN1_PARSE_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_ASN1_WRITE_C
|
||||||
|
*
|
||||||
|
* Enable the generic ASN1 writer.
|
||||||
|
*
|
||||||
|
* Module: library/asn1write.c
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_ASN1_WRITE_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_BASE64_C
|
||||||
|
*
|
||||||
|
* Enable the Base64 module.
|
||||||
|
*
|
||||||
|
* Module: library/base64.c
|
||||||
|
* Caller: library/pem.c
|
||||||
|
*
|
||||||
|
* This module is required for PEM support (required by X.509).
|
||||||
|
*/
|
||||||
|
#define POLARSSL_BASE64_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_BIGNUM_C
|
||||||
|
*
|
||||||
|
* Enable the multi-precision integer library.
|
||||||
|
*
|
||||||
|
* Module: library/bignum.c
|
||||||
|
* Caller: library/dhm.c
|
||||||
|
* library/rsa.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for RSA and DHM support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_BIGNUM_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_BLOWFISH_C
|
||||||
|
*
|
||||||
|
* Enable the Blowfish block cipher.
|
||||||
|
*
|
||||||
|
* Module: library/blowfish.c
|
||||||
|
*/
|
||||||
|
#define POLARSSL_BLOWFISH_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_CAMELLIA_C
|
||||||
|
*
|
||||||
|
* Enable the Camellia block cipher.
|
||||||
|
*
|
||||||
|
* Module: library/camellia.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites (if other requisites are
|
||||||
|
* enabled as well):
|
||||||
|
* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
|
||||||
|
* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
|
||||||
|
* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
|
||||||
|
* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
|
||||||
|
* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
|
||||||
|
* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_CAMELLIA_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_CERTS_C
|
||||||
|
*
|
||||||
|
* Enable the test certificates.
|
||||||
|
*
|
||||||
|
* Module: library/certs.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module is used for testing (ssl_client/server).
|
||||||
|
*/
|
||||||
|
// JY changed
|
||||||
|
#ifdef ENABLE_TESTING
|
||||||
|
#define POLARSSL_CERTS_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_CIPHER_C
|
||||||
|
*
|
||||||
|
* Enable the generic cipher layer.
|
||||||
|
*
|
||||||
|
* Module: library/cipher.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* Uncomment to enable generic cipher wrappers.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_CIPHER_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_CTR_DRBG_C
|
||||||
|
*
|
||||||
|
* Enable the CTR_DRBG AES-256-based random generator
|
||||||
|
*
|
||||||
|
* Module: library/ctr_drbg.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_AES_C
|
||||||
|
*
|
||||||
|
* This module provides the CTR_DRBG AES-256 random number generator.
|
||||||
|
*/
|
||||||
|
// JY added
|
||||||
|
#ifndef EXTERNAL_RNG
|
||||||
|
#define POLARSSL_CTR_DRBG_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_DEBUG_C
|
||||||
|
*
|
||||||
|
* Enable the debug functions.
|
||||||
|
*
|
||||||
|
* Module: library/debug.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module provides debugging functions.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DEBUG_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_DES_C
|
||||||
|
*
|
||||||
|
* Enable the DES block cipher.
|
||||||
|
*
|
||||||
|
* Module: library/des.c
|
||||||
|
* Caller: library/pem.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites (if other requisites are
|
||||||
|
* enabled as well):
|
||||||
|
* TLS_RSA_WITH_3DES_EDE_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
|
||||||
|
*
|
||||||
|
* PEM uses DES/3DES for decrypting encrypted keys.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DES_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_DHM_C
|
||||||
|
*
|
||||||
|
* Enable the Diffie-Hellman-Merkle key exchange.
|
||||||
|
*
|
||||||
|
* Module: library/dhm.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites (if other requisites are
|
||||||
|
* enabled as well):
|
||||||
|
* TLS_DHE_RSA_WITH_DES_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
|
||||||
|
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
|
||||||
|
* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
|
||||||
|
* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
|
||||||
|
* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
|
||||||
|
* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
* TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DHM_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_ENTROPY_C
|
||||||
|
*
|
||||||
|
* Enable the platform-specific entropy code.
|
||||||
|
*
|
||||||
|
* Module: library/entropy.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_SHA4_C
|
||||||
|
*
|
||||||
|
* This module provides a generic entropy pool
|
||||||
|
*/
|
||||||
|
#define POLARSSL_ENTROPY_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_ERROR_C
|
||||||
|
*
|
||||||
|
* Enable error code to error string conversion.
|
||||||
|
*
|
||||||
|
* Module: library/error.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module enables err_strerror().
|
||||||
|
*/
|
||||||
|
#define POLARSSL_ERROR_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_GCM_C
|
||||||
|
*
|
||||||
|
* Enable the Galois/Counter Mode (GCM) for AES
|
||||||
|
*
|
||||||
|
* Module: library/gcm.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_AES_C
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites (if other requisites are
|
||||||
|
* enabled as well):
|
||||||
|
* TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
* TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
*/
|
||||||
|
#define POLARSSL_GCM_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_HAVEGE_C
|
||||||
|
*
|
||||||
|
* Enable the HAVEGE random generator.
|
||||||
|
*
|
||||||
|
* Module: library/havege.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_TIMING_C
|
||||||
|
*
|
||||||
|
* This module enables the HAVEGE random number generator.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_HAVEGE_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_MD_C
|
||||||
|
*
|
||||||
|
* Enable the generic message digest layer.
|
||||||
|
*
|
||||||
|
* Module: library/md.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* Uncomment to enable generic message digest wrappers.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_MD_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_MD2_C
|
||||||
|
*
|
||||||
|
* Enable the MD2 hash algorithm
|
||||||
|
*
|
||||||
|
* Module: library/md2.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* Uncomment to enable support for (rare) MD2-signed X.509 certs.
|
||||||
|
*
|
||||||
|
#define POLARSSL_MD2_C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_MD4_C
|
||||||
|
*
|
||||||
|
* Enable the MD4 hash algorithm
|
||||||
|
*
|
||||||
|
* Module: library/md4.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* Uncomment to enable support for (rare) MD4-signed X.509 certs.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// JY Added for NTLM proxy auth
|
||||||
|
#define POLARSSL_MD4_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_MD5_C
|
||||||
|
*
|
||||||
|
* Enable the MD5 hash algorithm
|
||||||
|
*
|
||||||
|
* Module: library/md5.c
|
||||||
|
* Caller: library/pem.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS and X.509.
|
||||||
|
* PEM uses MD5 for decrypting encrypted keys.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_MD5_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_NET_C
|
||||||
|
*
|
||||||
|
* Enable the TCP/IP networking routines.
|
||||||
|
*
|
||||||
|
* Module: library/net.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module provides TCP/IP networking routines.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_NET_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_PADLOCK_C
|
||||||
|
*
|
||||||
|
* Enable VIA Padlock support on x86.
|
||||||
|
*
|
||||||
|
* Module: library/padlock.c
|
||||||
|
* Caller: library/aes.c
|
||||||
|
*
|
||||||
|
* This modules adds support for the VIA PadLock on x86.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_PADLOCK_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_PBKDF2_C
|
||||||
|
*
|
||||||
|
* Enable PKCS#5 PBKDF2 key derivation function
|
||||||
|
* DEPRECATED: Use POLARSSL_PKCS5_C instead
|
||||||
|
*
|
||||||
|
* Module: library/pbkdf2.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_PKCS5_C
|
||||||
|
*
|
||||||
|
* This module adds support for the PKCS#5 PBKDF2 key derivation function.
|
||||||
|
#define POLARSSL_PBKDF2_C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_PEM_C
|
||||||
|
*
|
||||||
|
* Enable PEM decoding
|
||||||
|
*
|
||||||
|
* Module: library/pem.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_BASE64_C
|
||||||
|
*
|
||||||
|
* This modules adds support for decoding PEM files.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_PEM_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_PKCS5_C
|
||||||
|
*
|
||||||
|
* Enable PKCS#5 functions
|
||||||
|
*
|
||||||
|
* Module: library/pkcs5.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_MD_C
|
||||||
|
*
|
||||||
|
* This module adds support for the PKCS#5 functions.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_PKCS5_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_PKCS11_C
|
||||||
|
*
|
||||||
|
* Enable wrapper for PKCS#11 smartcard support.
|
||||||
|
*
|
||||||
|
* Module: library/ssl_srv.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_SSL_TLS_C
|
||||||
|
*
|
||||||
|
* This module enables SSL/TLS PKCS #11 smartcard support.
|
||||||
|
* Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
|
||||||
|
#define POLARSSL_PKCS11_C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_PKCS12_C
|
||||||
|
*
|
||||||
|
* Enable PKCS#12 PBE functions
|
||||||
|
* Adds algorithms for parsing PKCS#8 encrypted private keys
|
||||||
|
*
|
||||||
|
* Module: library/pkcs12.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_ASN1_PARSE_C
|
||||||
|
* Can use: POLARSSL_SHA1_C, POLARSSL_DES_C, POLARSSL_ARC4_C
|
||||||
|
*
|
||||||
|
* This module enables PKCS#12 functions.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_PKCS12_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_RSA_C
|
||||||
|
*
|
||||||
|
* Enable the RSA public-key cryptosystem.
|
||||||
|
*
|
||||||
|
* Module: library/rsa.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_BIGNUM_C
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS and MD5-signed certificates.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_RSA_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SHA1_C
|
||||||
|
*
|
||||||
|
* Enable the SHA1 cryptographic hash algorithm.
|
||||||
|
*
|
||||||
|
* Module: library/sha1.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS and SHA1-signed certificates.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SHA1_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SHA2_C
|
||||||
|
*
|
||||||
|
* Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
|
||||||
|
*
|
||||||
|
* Module: library/sha2.c
|
||||||
|
* Caller: library/md_wrap.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module adds support for SHA-224 and SHA-256.
|
||||||
|
* This module is required for the SSL/TLS 1.2 PRF function.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SHA2_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SHA4_C
|
||||||
|
*
|
||||||
|
* Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
|
||||||
|
*
|
||||||
|
* Module: library/sha4.c
|
||||||
|
* Caller: library/md_wrap.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module adds support for SHA-384 and SHA-512.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SHA4_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SSL_CACHE_C
|
||||||
|
*
|
||||||
|
* Enable simple SSL cache implementation.
|
||||||
|
*
|
||||||
|
* Module: library/ssl_cache.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_SSL_CACHE_C
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_SSL_CACHE_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SSL_CLI_C
|
||||||
|
*
|
||||||
|
* Enable the SSL/TLS client code.
|
||||||
|
*
|
||||||
|
* Module: library/ssl_cli.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_SSL_TLS_C
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS client support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_CLI_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SSL_SRV_C
|
||||||
|
*
|
||||||
|
* Enable the SSL/TLS server code.
|
||||||
|
*
|
||||||
|
* Module: library/ssl_srv.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_SSL_TLS_C
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS server support.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_SSL_SRV_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_SSL_TLS_C
|
||||||
|
*
|
||||||
|
* Enable the generic SSL/TLS code.
|
||||||
|
*
|
||||||
|
* Module: library/ssl_tls.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_MD5_C, POLARSSL_SHA1_C, POLARSSL_X509_PARSE_C
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_TLS_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_TIMING_C
|
||||||
|
*
|
||||||
|
* Enable the portable timing interface.
|
||||||
|
*
|
||||||
|
* Module: library/timing.c
|
||||||
|
* Caller: library/havege.c
|
||||||
|
*
|
||||||
|
* This module is used by the HAVEGE random number generator.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_TIMING_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_VERSION_C
|
||||||
|
*
|
||||||
|
* Enable run-time version information.
|
||||||
|
*
|
||||||
|
* Module: library/version.c
|
||||||
|
*
|
||||||
|
* This module provides run-time version information.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_VERSION_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_X509_PARSE_C
|
||||||
|
*
|
||||||
|
* Enable X.509 certificate parsing.
|
||||||
|
*
|
||||||
|
* Module: library/x509parse.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_RSA_C
|
||||||
|
*
|
||||||
|
* This module is required for X.509 certificate parsing.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_X509_PARSE_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_X509_WRITE_C
|
||||||
|
*
|
||||||
|
* Enable X.509 buffer writing.
|
||||||
|
*
|
||||||
|
* Module: library/x509write.c
|
||||||
|
*
|
||||||
|
* Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C
|
||||||
|
*
|
||||||
|
* This module is required for X.509 certificate request writing.
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_X509_WRITE_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_XTEA_C
|
||||||
|
*
|
||||||
|
* Enable the XTEA block cipher.
|
||||||
|
*
|
||||||
|
* Module: library/xtea.c
|
||||||
|
* Caller:
|
||||||
|
*/
|
||||||
|
// JY removed
|
||||||
|
//#define POLARSSL_XTEA_C
|
||||||
|
/* \} name */
|
||||||
|
|
||||||
|
// JY added
|
||||||
|
#define POLARSSL_BLOWFISH_NAME "BF"
|
||||||
|
#define POLARSSL_BLOWFISH_DEFAULT_KEY_LEN 128
|
||||||
|
|
||||||
|
#endif /* config.h */
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
This patch (against PolarSSL 1.2.7) allows alternative crypto
|
||||||
|
implementations to be compiled, without actually defining
|
||||||
|
such implementations.
|
||||||
|
|
||||||
|
* define POLARSSL_AES_ALT to include alternative AES implementation
|
||||||
|
from polarssl/aes_alt.h
|
||||||
|
|
||||||
|
* define POLARSSL_SHA1_ALT to include alternative SHA1 implementation
|
||||||
|
from polarssl/sha1_alt.h
|
||||||
|
|
||||||
|
* define POLARSSL_SHA2_ALT to include alternative SHA2 implementation
|
||||||
|
from polarssl/sha2_alt.h
|
||||||
|
|
||||||
|
* define POLARSSL_SHA4_ALT to include alternative SHA4 implementation
|
||||||
|
from polarssl/sha4_alt.h
|
||||||
|
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
diff -ur polarssl-1.3.4/library/dhm.c polarssl.new/library/dhm.c
|
||||||
|
--- polarssl-1.3.4/library/dhm.c 2014-01-27 05:36:23.000000000 -0700
|
||||||
|
+++ polarssl.new/library/dhm.c 2014-03-02 14:47:02.000000000 -0700
|
||||||
|
@@ -32,6 +32,8 @@
|
||||||
|
|
||||||
|
#if defined(POLARSSL_DHM_C)
|
||||||
|
|
||||||
|
+#include "polarssl/x509.h" // for POLARSSL_ERR_X509_FEATURE_UNAVAILABLE
|
||||||
|
+
|
||||||
|
#include "polarssl/dhm.h"
|
||||||
|
|
||||||
|
#if defined(POLARSSL_PEM_PARSE_C)
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
diff -ur polarssl-1.3.8.orig/library/entropy.c polarssl-1.3.8/library/entropy.c
|
||||||
|
--- polarssl-1.3.8.orig/library/entropy.c 2014-07-09 03:34:48.000000000 -0600
|
||||||
|
+++ polarssl-1.3.8/library/entropy.c 2014-07-09 16:27:06.000000000 -0600
|
||||||
|
@@ -34,7 +34,7 @@
|
||||||
|
#include "polarssl/entropy.h"
|
||||||
|
#include "polarssl/entropy_poll.h"
|
||||||
|
|
||||||
|
-#if defined(POLARSSL_FS_IO)
|
||||||
|
+#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
rm -rf gitar.tmp
|
||||||
|
mkdir gitar.tmp
|
||||||
|
cd gitar.tmp
|
||||||
|
git clone https://github.com/polarssl/polarssl.git -b $POLARSSL_VERSION $POLARSSL_VERSION
|
||||||
|
tar cfz $DL/$POLARSSL_VERSION-gpl.tgz $POLARSSL_VERSION
|
||||||
|
cd ..
|
||||||
|
rm -rf gitar.tmp
|
||||||
Vendored
+22
@@ -0,0 +1,22 @@
|
|||||||
|
#if defined(_WIN32)
|
||||||
|
typedef unsigned __int64 IA32CAP;
|
||||||
|
#else
|
||||||
|
typedef unsigned long long IA32CAP;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IA32CAP OPENSSL_ia32_cpuid(void);
|
||||||
|
|
||||||
|
unsigned int OPENSSL_ia32cap_P[2]; // GLOBAL
|
||||||
|
|
||||||
|
void OPENSSL_cpuid_setup(void)
|
||||||
|
{
|
||||||
|
const IA32CAP vec = OPENSSL_ia32_cpuid();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* |(1<<10) sets a reserved bit to signal that variable
|
||||||
|
* was initialized already... This is to avoid interference
|
||||||
|
* with cpuid snippets in ELF .init segment.
|
||||||
|
*/
|
||||||
|
OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10);
|
||||||
|
OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32);
|
||||||
|
}
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
# this one is important
|
||||||
|
SET(CMAKE_SYSTEM_NAME Linux)
|
||||||
|
#this one not so much
|
||||||
|
SET(CMAKE_SYSTEM_VERSION 1)
|
||||||
|
|
||||||
|
# specify the cross compiler
|
||||||
|
SET(CMAKE_C_COMPILER arm-linux-gnueabi-gcc-4.6)
|
||||||
|
SET(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++-4.6)
|
||||||
|
|
||||||
|
# where is the target environment
|
||||||
|
#SET(CMAKE_FIND_ROOT_PATH /opt/eldk-2007-01-19/ppc_74xx /home/alex/eldk-ppc74xx-inst)
|
||||||
|
|
||||||
|
# search for programs in the build host directories
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
# for libraries and headers in the target directories
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
Vendored
+782
@@ -0,0 +1,782 @@
|
|||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/aes.h polarssl.new/include/polarssl/aes.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/aes.h 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/include/polarssl/aes.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -29,6 +29,8 @@
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "config.h"
|
||||||
|
+
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <basetsd.h>
|
||||||
|
typedef UINT32 uint32_t;
|
||||||
|
@@ -42,6 +44,12 @@
|
||||||
|
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||||
|
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||||
|
|
||||||
|
+#ifdef POLARSSL_AES_ALT
|
||||||
|
+
|
||||||
|
+#include "polarssl/aes_alt.h"
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* \brief AES context structure
|
||||||
|
*/
|
||||||
|
@@ -169,6 +177,17 @@
|
||||||
|
unsigned char stream_block[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* POLARSSL_AES_ALT */
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/aes_alt.h polarssl.new/include/polarssl/aes_alt.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/aes_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/aes_alt.h 2013-06-07 18:18:37.000000000 -0600
|
||||||
|
@@ -0,0 +1,183 @@
|
||||||
|
+/*
|
||||||
|
+ * Use OpenSSL implementation of AES methods to get asm and hardware acceleration.
|
||||||
|
+ * Don't include this file directly, it is included by aes.h when
|
||||||
|
+ * POLARSSL_AES_ALT is defined.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifdef _MSC_VER
|
||||||
|
+#include <basetsd.h>
|
||||||
|
+typedef UINT32 uint32_t;
|
||||||
|
+#else
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define OPENSSL_AES_BLOCK_SIZE 16
|
||||||
|
+#define OPENSSL_AES_MAXNR 14
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES context structure
|
||||||
|
+ */
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ uint32_t rd_key[4 * (OPENSSL_AES_MAXNR + 1)];
|
||||||
|
+ int rounds;
|
||||||
|
+}
|
||||||
|
+aes_context;
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined(POLARSSL_USE_OPENSSL_AES_NI)
|
||||||
|
+
|
||||||
|
+int aesni_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||||
|
+ aes_context *key);
|
||||||
|
+int aesni_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||||
|
+ aes_context *key);
|
||||||
|
+void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||||
|
+ size_t length, const aes_context *key, const int enc);
|
||||||
|
+void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||||
|
+ size_t length, const aes_context *key,
|
||||||
|
+ unsigned char *ivec, const int enc);
|
||||||
|
+
|
||||||
|
+#define OPENSSL_AES_SET_ENCRYPT_KEY(k,b,c) aesni_set_encrypt_key(k,b,c)
|
||||||
|
+#define OPENSSL_AES_SET_DECRYPT_KEY(k,b,c) aesni_set_decrypt_key(k,b,c)
|
||||||
|
+#define OPENSSL_AES_ECB_ENCRYPT(i,o,k) aesni_ecb_encrypt(i,o,16,k,AES_ENCRYPT)
|
||||||
|
+#define OPENSSL_AES_ECB_DECRYPT(i,o,k) aesni_ecb_encrypt(i,o,16,k,AES_DECRYPT)
|
||||||
|
+#define OPENSSL_AES_CBC_ENCRYPT(i,o,l,k,iv,e) aesni_cbc_encrypt(i,o,l,k,iv,e)
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||||
|
+ aes_context *key);
|
||||||
|
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||||
|
+ aes_context *key);
|
||||||
|
+
|
||||||
|
+void AES_encrypt(const unsigned char *in, unsigned char *out, const aes_context *key);
|
||||||
|
+void AES_decrypt(const unsigned char *in, unsigned char *out, const aes_context *key);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#define OPENSSL_AES_SET_ENCRYPT_KEY(k,b,c) AES_set_encrypt_key(k,b,c)
|
||||||
|
+#define OPENSSL_AES_SET_DECRYPT_KEY(k,b,c) AES_set_decrypt_key(k,b,c)
|
||||||
|
+#define OPENSSL_AES_ECB_ENCRYPT(i,o,k) AES_encrypt(i,o,k)
|
||||||
|
+#define OPENSSL_AES_ECB_DECRYPT(i,o,k) AES_decrypt(i,o,k)
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES key schedule (encryption)
|
||||||
|
+ *
|
||||||
|
+ * \param ctx AES context to be initialized
|
||||||
|
+ * \param key encryption key
|
||||||
|
+ * \param keysize must be 128, 192 or 256
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||||
|
+ */
|
||||||
|
+static inline int aes_setkey_enc( aes_context *ctx, const unsigned char *key, const unsigned int keysize )
|
||||||
|
+{
|
||||||
|
+ const int status = OPENSSL_AES_SET_ENCRYPT_KEY(key, keysize, ctx);
|
||||||
|
+ return status ? POLARSSL_ERR_AES_INVALID_KEY_LENGTH : 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES key schedule (decryption)
|
||||||
|
+ *
|
||||||
|
+ * \param ctx AES context to be initialized
|
||||||
|
+ * \param key decryption key
|
||||||
|
+ * \param keysize must be 128, 192 or 256
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||||
|
+ */
|
||||||
|
+static inline int aes_setkey_dec( aes_context *ctx, const unsigned char *key, const unsigned int keysize )
|
||||||
|
+{
|
||||||
|
+ const int status = OPENSSL_AES_SET_DECRYPT_KEY(key, keysize, ctx);
|
||||||
|
+ return status ? POLARSSL_ERR_AES_INVALID_KEY_LENGTH : 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES-ECB block encryption/decryption
|
||||||
|
+ *
|
||||||
|
+ * \param ctx AES context
|
||||||
|
+ * \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
+ * \param input 16-byte input block
|
||||||
|
+ * \param output 16-byte output block
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful
|
||||||
|
+ */
|
||||||
|
+static inline int aes_crypt_ecb( aes_context *ctx,
|
||||||
|
+ const int mode,
|
||||||
|
+ const unsigned char input[16],
|
||||||
|
+ unsigned char output[16] )
|
||||||
|
+{
|
||||||
|
+ if (mode == AES_DECRYPT)
|
||||||
|
+ OPENSSL_AES_ECB_DECRYPT(input, output, ctx);
|
||||||
|
+ else
|
||||||
|
+ OPENSSL_AES_ECB_ENCRYPT(input, output, ctx);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES-CBC buffer encryption/decryption
|
||||||
|
+ * Length should be a multiple of the block
|
||||||
|
+ * size (16 bytes)
|
||||||
|
+ *
|
||||||
|
+ * \param ctx AES context
|
||||||
|
+ * \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
+ * \param length length of the input data
|
||||||
|
+ * \param iv initialization vector (updated after use)
|
||||||
|
+ * \param input buffer holding the input data
|
||||||
|
+ * \param output buffer holding the output data
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||||
|
+ */
|
||||||
|
+static inline int aes_crypt_cbc( aes_context *ctx,
|
||||||
|
+ const int mode,
|
||||||
|
+ size_t length,
|
||||||
|
+ unsigned char iv[16],
|
||||||
|
+ const unsigned char *input,
|
||||||
|
+ unsigned char *output )
|
||||||
|
+{
|
||||||
|
+#ifdef OPENSSL_AES_CBC_ENCRYPT
|
||||||
|
+ if (length & (OPENSSL_AES_BLOCK_SIZE-1))
|
||||||
|
+ return POLARSSL_ERR_AES_INVALID_INPUT_LENGTH;
|
||||||
|
+ OPENSSL_AES_CBC_ENCRYPT(input, output, length, ctx, iv, mode);
|
||||||
|
+ return 0;
|
||||||
|
+#else
|
||||||
|
+ int i;
|
||||||
|
+ unsigned char temp[16];
|
||||||
|
+ if (length & (OPENSSL_AES_BLOCK_SIZE-1))
|
||||||
|
+ return POLARSSL_ERR_AES_INVALID_INPUT_LENGTH;
|
||||||
|
+ if( mode == AES_DECRYPT )
|
||||||
|
+ {
|
||||||
|
+ while( length > 0 )
|
||||||
|
+ {
|
||||||
|
+ memcpy( temp, input, 16 );
|
||||||
|
+ OPENSSL_AES_ECB_DECRYPT(input, output, ctx);
|
||||||
|
+ for( i = 0; i < 16; i++ )
|
||||||
|
+ output[i] = (unsigned char)( output[i] ^ iv[i] );
|
||||||
|
+ memcpy( iv, temp, 16 );
|
||||||
|
+ input += 16;
|
||||||
|
+ output += 16;
|
||||||
|
+ length -= 16;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ while( length > 0 )
|
||||||
|
+ {
|
||||||
|
+ for( i = 0; i < 16; i++ )
|
||||||
|
+ output[i] = (unsigned char)( input[i] ^ iv[i] );
|
||||||
|
+ OPENSSL_AES_ECB_ENCRYPT(output, output, ctx);
|
||||||
|
+ memcpy( iv, output, 16 );
|
||||||
|
+ input += 16;
|
||||||
|
+ output += 16;
|
||||||
|
+ length -= 16;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return( 0 );
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha1.h polarssl.new/include/polarssl/sha1.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha1.h 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/include/polarssl/sha1.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -29,6 +29,8 @@
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "config.h"
|
||||||
|
+
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <basetsd.h>
|
||||||
|
typedef UINT32 uint32_t;
|
||||||
|
@@ -38,6 +40,12 @@
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_SHA1_FILE_IO_ERROR -0x0076 /**< Read/write error in file. */
|
||||||
|
|
||||||
|
+#ifdef POLARSSL_SHA1_ALT
|
||||||
|
+
|
||||||
|
+#include "polarssl/sha1_alt.h"
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* \brief SHA-1 context structure
|
||||||
|
*/
|
||||||
|
@@ -80,6 +88,19 @@
|
||||||
|
*/
|
||||||
|
void sha1_finish( sha1_context *ctx, unsigned char output[20] );
|
||||||
|
|
||||||
|
+/* Internal use */
|
||||||
|
+void sha1_process( sha1_context *ctx, const unsigned char data[64] );
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* POLARSSL_SHA1_ALT */
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* \brief Output = SHA-1( input buffer )
|
||||||
|
*
|
||||||
|
@@ -152,9 +173,6 @@
|
||||||
|
*/
|
||||||
|
int sha1_self_test( int verbose );
|
||||||
|
|
||||||
|
-/* Internal use */
|
||||||
|
-void sha1_process( sha1_context *ctx, const unsigned char data[64] );
|
||||||
|
-
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha1_alt.h polarssl.new/include/polarssl/sha1_alt.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha1_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/sha1_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -0,0 +1,56 @@
|
||||||
|
+/*
|
||||||
|
+ * Use OpenSSL implementation of SHA1 methods to get asm and hardware acceleration.
|
||||||
|
+ * Don't include this file directly, it is included by sha1.h when
|
||||||
|
+ * POLARSSL_SHA1_ALT is defined.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "polarssl/sha_openssl.h"
|
||||||
|
+
|
||||||
|
+struct openssl_sha_context {
|
||||||
|
+ SHA_LONG h0,h1,h2,h3,h4;
|
||||||
|
+ SHA_LONG Nl,Nh;
|
||||||
|
+ SHA_LONG data[SHA_LBLOCK];
|
||||||
|
+ unsigned int num;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ struct openssl_sha_context octx;
|
||||||
|
+
|
||||||
|
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||||
|
+ unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||||
|
+}
|
||||||
|
+sha1_context;
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+int SHA1_Init(struct openssl_sha_context *c);
|
||||||
|
+int SHA1_Update(struct openssl_sha_context *c, const void *data, size_t len);
|
||||||
|
+int SHA1_Final(unsigned char *md, struct openssl_sha_context *c);
|
||||||
|
+void sha1_block_data_order(struct openssl_sha_context *c, const void *p, size_t num);
|
||||||
|
+
|
||||||
|
+static inline void sha1_starts( sha1_context *ctx )
|
||||||
|
+{
|
||||||
|
+ SHA1_Init(&ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen )
|
||||||
|
+{
|
||||||
|
+ SHA1_Update(&ctx->octx, input, ilen);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha1_finish( sha1_context *ctx, unsigned char output[20] )
|
||||||
|
+{
|
||||||
|
+ SHA1_Final(output, &ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha1_process( sha1_context *ctx, const unsigned char data[64] )
|
||||||
|
+{
|
||||||
|
+ sha1_block_data_order(&ctx->octx, data, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha2.h polarssl.new/include/polarssl/sha2.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha2.h 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/include/polarssl/sha2.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -29,6 +29,8 @@
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "config.h"
|
||||||
|
+
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <basetsd.h>
|
||||||
|
typedef UINT32 uint32_t;
|
||||||
|
@@ -38,6 +40,12 @@
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_SHA2_FILE_IO_ERROR -0x0078 /**< Read/write error in file. */
|
||||||
|
|
||||||
|
+#ifdef POLARSSL_SHA2_ALT
|
||||||
|
+
|
||||||
|
+#include "polarssl/sha2_alt.h"
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 context structure
|
||||||
|
*/
|
||||||
|
@@ -82,6 +90,19 @@
|
||||||
|
*/
|
||||||
|
void sha2_finish( sha2_context *ctx, unsigned char output[32] );
|
||||||
|
|
||||||
|
+/* Internal use */
|
||||||
|
+void sha2_process( sha2_context *ctx, const unsigned char data[64] );
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* POLARSSL_SHA2_ALT */
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* \brief Output = SHA-256( input buffer )
|
||||||
|
*
|
||||||
|
@@ -160,9 +181,6 @@
|
||||||
|
*/
|
||||||
|
int sha2_self_test( int verbose );
|
||||||
|
|
||||||
|
-/* Internal use */
|
||||||
|
-void sha2_process( sha2_context *ctx, const unsigned char data[64] );
|
||||||
|
-
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha2_alt.h polarssl.new/include/polarssl/sha2_alt.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha2_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/sha2_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -0,0 +1,71 @@
|
||||||
|
+/*
|
||||||
|
+ * Use OpenSSL implementation of SHA2 methods to get asm and hardware acceleration.
|
||||||
|
+ * Don't include this file directly, it is included by sha2.h when
|
||||||
|
+ * POLARSSL_SHA2_ALT is defined.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "polarssl/sha_openssl.h"
|
||||||
|
+
|
||||||
|
+struct openssl_sha2_context {
|
||||||
|
+ SHA_LONG h[8];
|
||||||
|
+ SHA_LONG Nl,Nh;
|
||||||
|
+ SHA_LONG data[SHA_LBLOCK];
|
||||||
|
+ unsigned int num,md_len;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ struct openssl_sha2_context octx;
|
||||||
|
+
|
||||||
|
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||||
|
+ unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||||
|
+ int is224; /*!< 0 => SHA-256, else SHA-224 */
|
||||||
|
+}
|
||||||
|
+sha2_context;
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+int SHA224_Init(struct openssl_sha2_context *c);
|
||||||
|
+int SHA224_Update(struct openssl_sha2_context *c, const void *data, size_t len);
|
||||||
|
+int SHA224_Final(unsigned char *md, struct openssl_sha2_context *c);
|
||||||
|
+
|
||||||
|
+int SHA256_Init(struct openssl_sha2_context *c);
|
||||||
|
+int SHA256_Update(struct openssl_sha2_context *c, const void *data, size_t len);
|
||||||
|
+int SHA256_Final(unsigned char *md, struct openssl_sha2_context *c);
|
||||||
|
+
|
||||||
|
+void sha256_block_data_order(struct openssl_sha2_context *c, const void *p, size_t num);
|
||||||
|
+
|
||||||
|
+static inline void sha2_starts( sha2_context *ctx, int is224 )
|
||||||
|
+{
|
||||||
|
+ if ((ctx->is224 = is224))
|
||||||
|
+ SHA224_Init(&ctx->octx);
|
||||||
|
+ else
|
||||||
|
+ SHA256_Init(&ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha2_update( sha2_context *ctx, const unsigned char *input, size_t ilen )
|
||||||
|
+{
|
||||||
|
+ if (ctx->is224)
|
||||||
|
+ SHA224_Update(&ctx->octx, input, ilen);
|
||||||
|
+ else
|
||||||
|
+ SHA256_Update(&ctx->octx, input, ilen);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha2_finish( sha2_context *ctx, unsigned char output[32] )
|
||||||
|
+{
|
||||||
|
+ if (ctx->is224)
|
||||||
|
+ SHA224_Final(output, &ctx->octx);
|
||||||
|
+ else
|
||||||
|
+ SHA256_Final(output, &ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha2_process( sha2_context *ctx, const unsigned char data[64] )
|
||||||
|
+{
|
||||||
|
+ sha256_block_data_order(&ctx->octx, data, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha4.h polarssl.new/include/polarssl/sha4.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha4.h 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/include/polarssl/sha4.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -29,6 +29,8 @@
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "config.h"
|
||||||
|
+
|
||||||
|
#if defined(_MSC_VER) || defined(__WATCOMC__)
|
||||||
|
#define UL64(x) x##ui64
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
@@ -39,6 +41,12 @@
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_SHA4_FILE_IO_ERROR -0x007A /**< Read/write error in file. */
|
||||||
|
|
||||||
|
+#ifdef POLARSSL_SHA4_ALT
|
||||||
|
+
|
||||||
|
+#include "polarssl/sha4_alt.h"
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* \brief SHA-512 context structure
|
||||||
|
*/
|
||||||
|
@@ -83,6 +91,16 @@
|
||||||
|
*/
|
||||||
|
void sha4_finish( sha4_context *ctx, unsigned char output[64] );
|
||||||
|
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* POLARSSL_SHA4_ALT */
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* \brief Output = SHA-512( input buffer )
|
||||||
|
*
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha4_alt.h polarssl.new/include/polarssl/sha4_alt.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha4_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/sha4_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -0,0 +1,67 @@
|
||||||
|
+/*
|
||||||
|
+ * Use OpenSSL implementation of SHA4 methods to get asm and hardware acceleration.
|
||||||
|
+ * Don't include this file directly, it is included by sha4.h when
|
||||||
|
+ * POLARSSL_SHA4_ALT is defined.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "polarssl/sha_openssl.h"
|
||||||
|
+
|
||||||
|
+struct openssl_sha4_context {
|
||||||
|
+ SHA_LONG64 h[8];
|
||||||
|
+ SHA_LONG64 Nl,Nh;
|
||||||
|
+ union {
|
||||||
|
+ SHA_LONG64 d[SHA_LBLOCK];
|
||||||
|
+ unsigned char p[SHA512_CBLOCK];
|
||||||
|
+ } u;
|
||||||
|
+ unsigned int num,md_len;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ struct openssl_sha4_context octx;
|
||||||
|
+
|
||||||
|
+ unsigned char ipad[128]; /*!< HMAC: inner padding */
|
||||||
|
+ unsigned char opad[128]; /*!< HMAC: outer padding */
|
||||||
|
+ int is384; /*!< 0 => SHA-512, else SHA-384 */
|
||||||
|
+}
|
||||||
|
+sha4_context;
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+int SHA384_Init(struct openssl_sha4_context *c);
|
||||||
|
+int SHA384_Update(struct openssl_sha4_context *c, const void *data, size_t len);
|
||||||
|
+int SHA384_Final(unsigned char *md, struct openssl_sha4_context *c);
|
||||||
|
+
|
||||||
|
+int SHA512_Init(struct openssl_sha4_context *c);
|
||||||
|
+int SHA512_Update(struct openssl_sha4_context *c, const void *data, size_t len);
|
||||||
|
+int SHA512_Final(unsigned char *md, struct openssl_sha4_context *c);
|
||||||
|
+
|
||||||
|
+static inline void sha4_starts( sha4_context *ctx, int is384 )
|
||||||
|
+{
|
||||||
|
+ if ((ctx->is384 = is384))
|
||||||
|
+ SHA384_Init(&ctx->octx);
|
||||||
|
+ else
|
||||||
|
+ SHA512_Init(&ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha4_update( sha4_context *ctx, const unsigned char *input, size_t ilen )
|
||||||
|
+{
|
||||||
|
+ if (ctx->is384)
|
||||||
|
+ SHA384_Update(&ctx->octx, input, ilen);
|
||||||
|
+ else
|
||||||
|
+ SHA512_Update(&ctx->octx, input, ilen);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha4_finish( sha4_context *ctx, unsigned char output[64] )
|
||||||
|
+{
|
||||||
|
+ if (ctx->is384)
|
||||||
|
+ SHA384_Final(output, &ctx->octx);
|
||||||
|
+ else
|
||||||
|
+ SHA512_Final(output, &ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha_openssl.h polarssl.new/include/polarssl/sha_openssl.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha_openssl.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/sha_openssl.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -0,0 +1,42 @@
|
||||||
|
+/*
|
||||||
|
+ * Common header file for all OpenSSL-imported SHA methods
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef POLARSSL_SHA_OPENSSL_H
|
||||||
|
+#define POLARSSL_SHA_OPENSSL_H
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
|
||||||
|
+ * ! SHA_LONG_LOG2 has to be defined along. !
|
||||||
|
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#if defined(__LP32__)
|
||||||
|
+#define SHA_LONG unsigned long
|
||||||
|
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
|
||||||
|
+#define SHA_LONG unsigned long
|
||||||
|
+#define SHA_LONG_LOG2 3
|
||||||
|
+#else
|
||||||
|
+#define SHA_LONG unsigned int
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define SHA_LBLOCK 16
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
|
||||||
|
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
|
||||||
|
+ * for further details.
|
||||||
|
+ */
|
||||||
|
+#define SHA512_CBLOCK (SHA_LBLOCK*8) /* SHA-512 treats input data as a
|
||||||
|
+ * contiguous array of 64 bit
|
||||||
|
+ * wide big-endian values. */
|
||||||
|
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
|
||||||
|
+#define SHA_LONG64 unsigned __int64
|
||||||
|
+#elif defined(__arch64__)
|
||||||
|
+#define SHA_LONG64 unsigned long
|
||||||
|
+#else
|
||||||
|
+#define SHA_LONG64 unsigned long long
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff -uNr polarssl-1.2.7/library/aes.c polarssl.new/library/aes.c
|
||||||
|
--- polarssl-1.2.7/library/aes.c 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/library/aes.c 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -38,6 +38,8 @@
|
||||||
|
#include "polarssl/padlock.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef POLARSSL_AES_ALT
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* 32-bit integer manipulation macros (little endian)
|
||||||
|
*/
|
||||||
|
@@ -914,6 +916,7 @@
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||||
|
+#endif /* !POLARSSL_AES_ALT */
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SELF_TEST)
|
||||||
|
|
||||||
|
diff -uNr polarssl-1.2.7/library/sha1.c polarssl.new/library/sha1.c
|
||||||
|
--- polarssl-1.2.7/library/sha1.c 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/library/sha1.c 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -38,6 +38,8 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef POLARSSL_SHA1_ALT
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* 32-bit integer manipulation macros (big endian)
|
||||||
|
*/
|
||||||
|
@@ -313,6 +315,8 @@
|
||||||
|
PUT_UINT32_BE( ctx->state[4], output, 16 );
|
||||||
|
}
|
||||||
|
|
||||||
|
+#endif /* !POLARSSL_SHA1_ALT */
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* output = SHA-1( input buffer )
|
||||||
|
*/
|
||||||
|
diff -uNr polarssl-1.2.7/library/sha2.c polarssl.new/library/sha2.c
|
||||||
|
--- polarssl-1.2.7/library/sha2.c 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/library/sha2.c 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -38,6 +38,8 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef POLARSSL_SHA2_ALT
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* 32-bit integer manipulation macros (big endian)
|
||||||
|
*/
|
||||||
|
@@ -314,6 +316,8 @@
|
||||||
|
PUT_UINT32_BE( ctx->state[7], output, 28 );
|
||||||
|
}
|
||||||
|
|
||||||
|
+#endif /* !POLARSSL_SHA2_ALT */
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* output = SHA-256( input buffer )
|
||||||
|
*/
|
||||||
|
diff -uNr polarssl-1.2.7/library/sha4.c polarssl.new/library/sha4.c
|
||||||
|
--- polarssl-1.2.7/library/sha4.c 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/library/sha4.c 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -38,6 +38,8 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef POLARSSL_SHA4_ALT
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* 64-bit integer manipulation macros (big endian)
|
||||||
|
*/
|
||||||
|
@@ -312,6 +314,8 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+#endif /* !POLARSSL_SHA4_ALT */
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* output = SHA-512( input buffer )
|
||||||
|
*/
|
||||||
|
diff -uNr polarssl-1.2.7/library/ssl_tls.c polarssl.new/library/ssl_tls.c
|
||||||
|
--- polarssl-1.2.7/library/ssl_tls.c 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/library/ssl_tls.c 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -2550,8 +2550,10 @@
|
||||||
|
SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
|
||||||
|
md5.state, sizeof( md5.state ) );
|
||||||
|
|
||||||
|
+#ifndef POLARSSL_SHA1_ALT
|
||||||
|
SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
|
||||||
|
sha1.state, sizeof( sha1.state ) );
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
sender = ( from == SSL_IS_CLIENT ) ? (char *) "CLNT"
|
||||||
|
: (char *) "SRVR";
|
||||||
|
@@ -2621,8 +2623,10 @@
|
||||||
|
SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
|
||||||
|
md5.state, sizeof( md5.state ) );
|
||||||
|
|
||||||
|
+#ifndef POLARSSL_SHA1_ALT
|
||||||
|
SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
|
||||||
|
sha1.state, sizeof( sha1.state ) );
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
sender = ( from == SSL_IS_CLIENT )
|
||||||
|
? (char *) "client finished"
|
||||||
|
@@ -2666,8 +2670,10 @@
|
||||||
|
* Hash( handshake ) )[0.11]
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#ifndef POLARSSL_SHA2_ALT
|
||||||
|
SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
|
||||||
|
sha2.state, sizeof( sha2.state ) );
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
sender = ( from == SSL_IS_CLIENT )
|
||||||
|
? (char *) "client finished"
|
||||||
|
@@ -2710,8 +2716,10 @@
|
||||||
|
* Hash( handshake ) )[0.11]
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#ifndef POLARSSL_SHA4_ALT
|
||||||
|
SSL_DEBUG_BUF( 4, "finished sha4 state", (unsigned char *)
|
||||||
|
sha4.state, sizeof( sha4.state ) );
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
sender = ( from == SSL_IS_CLIENT )
|
||||||
|
? (char *) "client finished"
|
||||||
|
diff -uNr polarssl-1.2.7/tests/suites/test_suite_aes.function polarssl.new/tests/suites/test_suite_aes.function
|
||||||
|
--- polarssl-1.2.7/tests/suites/test_suite_aes.function 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/tests/suites/test_suite_aes.function 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -1,4 +1,5 @@
|
||||||
|
BEGIN_HEADER
|
||||||
|
+#include <polarssl/config.h>
|
||||||
|
#include <polarssl/aes.h>
|
||||||
|
END_HEADER
|
||||||
|
|
||||||
|
diff -uNr polarssl-1.2.7/tests/suites/test_suite_ctr_drbg.function polarssl.new/tests/suites/test_suite_ctr_drbg.function
|
||||||
|
--- polarssl-1.2.7/tests/suites/test_suite_ctr_drbg.function 2013-04-13 03:56:17.000000000 -0600
|
||||||
|
+++ polarssl.new/tests/suites/test_suite_ctr_drbg.function 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -1,4 +1,5 @@
|
||||||
|
BEGIN_HEADER
|
||||||
|
+#include <polarssl/config.h>
|
||||||
|
#include <polarssl/ctr_drbg.h>
|
||||||
|
|
||||||
|
int test_offset;
|
||||||
+446
@@ -0,0 +1,446 @@
|
|||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/aes_alt.h polarssl.new/include/polarssl/aes_alt.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/aes_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/aes_alt.h 2013-06-07 18:18:37.000000000 -0600
|
||||||
|
@@ -0,0 +1,183 @@
|
||||||
|
+/*
|
||||||
|
+ * Use OpenSSL implementation of AES methods to get asm and hardware acceleration.
|
||||||
|
+ * Don't include this file directly, it is included by aes.h when
|
||||||
|
+ * POLARSSL_AES_ALT is defined.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifdef _MSC_VER
|
||||||
|
+#include <basetsd.h>
|
||||||
|
+typedef UINT32 uint32_t;
|
||||||
|
+#else
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define OPENSSL_AES_BLOCK_SIZE 16
|
||||||
|
+#define OPENSSL_AES_MAXNR 14
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES context structure
|
||||||
|
+ */
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ uint32_t rd_key[4 * (OPENSSL_AES_MAXNR + 1)];
|
||||||
|
+ int rounds;
|
||||||
|
+}
|
||||||
|
+aes_context;
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined(POLARSSL_USE_OPENSSL_AES_NI)
|
||||||
|
+
|
||||||
|
+int aesni_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||||
|
+ aes_context *key);
|
||||||
|
+int aesni_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||||
|
+ aes_context *key);
|
||||||
|
+void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||||
|
+ size_t length, const aes_context *key, const int enc);
|
||||||
|
+void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||||
|
+ size_t length, const aes_context *key,
|
||||||
|
+ unsigned char *ivec, const int enc);
|
||||||
|
+
|
||||||
|
+#define OPENSSL_AES_SET_ENCRYPT_KEY(k,b,c) aesni_set_encrypt_key(k,b,c)
|
||||||
|
+#define OPENSSL_AES_SET_DECRYPT_KEY(k,b,c) aesni_set_decrypt_key(k,b,c)
|
||||||
|
+#define OPENSSL_AES_ECB_ENCRYPT(i,o,k) aesni_ecb_encrypt(i,o,16,k,AES_ENCRYPT)
|
||||||
|
+#define OPENSSL_AES_ECB_DECRYPT(i,o,k) aesni_ecb_encrypt(i,o,16,k,AES_DECRYPT)
|
||||||
|
+#define OPENSSL_AES_CBC_ENCRYPT(i,o,l,k,iv,e) aesni_cbc_encrypt(i,o,l,k,iv,e)
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||||
|
+ aes_context *key);
|
||||||
|
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||||
|
+ aes_context *key);
|
||||||
|
+
|
||||||
|
+void AES_encrypt(const unsigned char *in, unsigned char *out, const aes_context *key);
|
||||||
|
+void AES_decrypt(const unsigned char *in, unsigned char *out, const aes_context *key);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#define OPENSSL_AES_SET_ENCRYPT_KEY(k,b,c) AES_set_encrypt_key(k,b,c)
|
||||||
|
+#define OPENSSL_AES_SET_DECRYPT_KEY(k,b,c) AES_set_decrypt_key(k,b,c)
|
||||||
|
+#define OPENSSL_AES_ECB_ENCRYPT(i,o,k) AES_encrypt(i,o,k)
|
||||||
|
+#define OPENSSL_AES_ECB_DECRYPT(i,o,k) AES_decrypt(i,o,k)
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES key schedule (encryption)
|
||||||
|
+ *
|
||||||
|
+ * \param ctx AES context to be initialized
|
||||||
|
+ * \param key encryption key
|
||||||
|
+ * \param keysize must be 128, 192 or 256
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||||
|
+ */
|
||||||
|
+static inline int aes_setkey_enc( aes_context *ctx, const unsigned char *key, const unsigned int keysize )
|
||||||
|
+{
|
||||||
|
+ const int status = OPENSSL_AES_SET_ENCRYPT_KEY(key, keysize, ctx);
|
||||||
|
+ return status ? POLARSSL_ERR_AES_INVALID_KEY_LENGTH : 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES key schedule (decryption)
|
||||||
|
+ *
|
||||||
|
+ * \param ctx AES context to be initialized
|
||||||
|
+ * \param key decryption key
|
||||||
|
+ * \param keysize must be 128, 192 or 256
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||||
|
+ */
|
||||||
|
+static inline int aes_setkey_dec( aes_context *ctx, const unsigned char *key, const unsigned int keysize )
|
||||||
|
+{
|
||||||
|
+ const int status = OPENSSL_AES_SET_DECRYPT_KEY(key, keysize, ctx);
|
||||||
|
+ return status ? POLARSSL_ERR_AES_INVALID_KEY_LENGTH : 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES-ECB block encryption/decryption
|
||||||
|
+ *
|
||||||
|
+ * \param ctx AES context
|
||||||
|
+ * \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
+ * \param input 16-byte input block
|
||||||
|
+ * \param output 16-byte output block
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful
|
||||||
|
+ */
|
||||||
|
+static inline int aes_crypt_ecb( aes_context *ctx,
|
||||||
|
+ const int mode,
|
||||||
|
+ const unsigned char input[16],
|
||||||
|
+ unsigned char output[16] )
|
||||||
|
+{
|
||||||
|
+ if (mode == AES_DECRYPT)
|
||||||
|
+ OPENSSL_AES_ECB_DECRYPT(input, output, ctx);
|
||||||
|
+ else
|
||||||
|
+ OPENSSL_AES_ECB_ENCRYPT(input, output, ctx);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief AES-CBC buffer encryption/decryption
|
||||||
|
+ * Length should be a multiple of the block
|
||||||
|
+ * size (16 bytes)
|
||||||
|
+ *
|
||||||
|
+ * \param ctx AES context
|
||||||
|
+ * \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
+ * \param length length of the input data
|
||||||
|
+ * \param iv initialization vector (updated after use)
|
||||||
|
+ * \param input buffer holding the input data
|
||||||
|
+ * \param output buffer holding the output data
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||||
|
+ */
|
||||||
|
+static inline int aes_crypt_cbc( aes_context *ctx,
|
||||||
|
+ const int mode,
|
||||||
|
+ size_t length,
|
||||||
|
+ unsigned char iv[16],
|
||||||
|
+ const unsigned char *input,
|
||||||
|
+ unsigned char *output )
|
||||||
|
+{
|
||||||
|
+#ifdef OPENSSL_AES_CBC_ENCRYPT
|
||||||
|
+ if (length & (OPENSSL_AES_BLOCK_SIZE-1))
|
||||||
|
+ return POLARSSL_ERR_AES_INVALID_INPUT_LENGTH;
|
||||||
|
+ OPENSSL_AES_CBC_ENCRYPT(input, output, length, ctx, iv, mode);
|
||||||
|
+ return 0;
|
||||||
|
+#else
|
||||||
|
+ int i;
|
||||||
|
+ unsigned char temp[16];
|
||||||
|
+ if (length & (OPENSSL_AES_BLOCK_SIZE-1))
|
||||||
|
+ return POLARSSL_ERR_AES_INVALID_INPUT_LENGTH;
|
||||||
|
+ if( mode == AES_DECRYPT )
|
||||||
|
+ {
|
||||||
|
+ while( length > 0 )
|
||||||
|
+ {
|
||||||
|
+ memcpy( temp, input, 16 );
|
||||||
|
+ OPENSSL_AES_ECB_DECRYPT(input, output, ctx);
|
||||||
|
+ for( i = 0; i < 16; i++ )
|
||||||
|
+ output[i] = (unsigned char)( output[i] ^ iv[i] );
|
||||||
|
+ memcpy( iv, temp, 16 );
|
||||||
|
+ input += 16;
|
||||||
|
+ output += 16;
|
||||||
|
+ length -= 16;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ while( length > 0 )
|
||||||
|
+ {
|
||||||
|
+ for( i = 0; i < 16; i++ )
|
||||||
|
+ output[i] = (unsigned char)( input[i] ^ iv[i] );
|
||||||
|
+ OPENSSL_AES_ECB_ENCRYPT(output, output, ctx);
|
||||||
|
+ memcpy( iv, output, 16 );
|
||||||
|
+ input += 16;
|
||||||
|
+ output += 16;
|
||||||
|
+ length -= 16;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return( 0 );
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha1_alt.h polarssl.new/include/polarssl/sha1_alt.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha1_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/sha1_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -0,0 +1,56 @@
|
||||||
|
+/*
|
||||||
|
+ * Use OpenSSL implementation of SHA1 methods to get asm and hardware acceleration.
|
||||||
|
+ * Don't include this file directly, it is included by sha1.h when
|
||||||
|
+ * POLARSSL_SHA1_ALT is defined.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "polarssl/sha_openssl.h"
|
||||||
|
+
|
||||||
|
+struct openssl_sha_context {
|
||||||
|
+ SHA_LONG h0,h1,h2,h3,h4;
|
||||||
|
+ SHA_LONG Nl,Nh;
|
||||||
|
+ SHA_LONG data[SHA_LBLOCK];
|
||||||
|
+ unsigned int num;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ struct openssl_sha_context octx;
|
||||||
|
+
|
||||||
|
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||||
|
+ unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||||
|
+}
|
||||||
|
+sha1_context;
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+int SHA1_Init(struct openssl_sha_context *c);
|
||||||
|
+int SHA1_Update(struct openssl_sha_context *c, const void *data, size_t len);
|
||||||
|
+int SHA1_Final(unsigned char *md, struct openssl_sha_context *c);
|
||||||
|
+void sha1_block_data_order(struct openssl_sha_context *c, const void *p, size_t num);
|
||||||
|
+
|
||||||
|
+static inline void sha1_starts( sha1_context *ctx )
|
||||||
|
+{
|
||||||
|
+ SHA1_Init(&ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen )
|
||||||
|
+{
|
||||||
|
+ SHA1_Update(&ctx->octx, input, ilen);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha1_finish( sha1_context *ctx, unsigned char output[20] )
|
||||||
|
+{
|
||||||
|
+ SHA1_Final(output, &ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha1_process( sha1_context *ctx, const unsigned char data[64] )
|
||||||
|
+{
|
||||||
|
+ sha1_block_data_order(&ctx->octx, data, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha256_alt.h polarssl.new/include/polarssl/sha256_alt.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha256_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/sha256_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -0,0 +1,71 @@
|
||||||
|
+/*
|
||||||
|
+ * Use OpenSSL implementation of SHA256 methods to get asm and hardware acceleration.
|
||||||
|
+ * Don't include this file directly, it is included by sha256.h when
|
||||||
|
+ * POLARSSL_SHA256_ALT is defined.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "polarssl/sha_openssl.h"
|
||||||
|
+
|
||||||
|
+struct openssl_sha256_context {
|
||||||
|
+ SHA_LONG h[8];
|
||||||
|
+ SHA_LONG Nl,Nh;
|
||||||
|
+ SHA_LONG data[SHA_LBLOCK];
|
||||||
|
+ unsigned int num,md_len;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ struct openssl_sha256_context octx;
|
||||||
|
+
|
||||||
|
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||||
|
+ unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||||
|
+ int is224; /*!< 0 => SHA-256, else SHA-224 */
|
||||||
|
+}
|
||||||
|
+sha256_context;
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+int SHA224_Init(struct openssl_sha256_context *c);
|
||||||
|
+int SHA224_Update(struct openssl_sha256_context *c, const void *data, size_t len);
|
||||||
|
+int SHA224_Final(unsigned char *md, struct openssl_sha256_context *c);
|
||||||
|
+
|
||||||
|
+int SHA256_Init(struct openssl_sha256_context *c);
|
||||||
|
+int SHA256_Update(struct openssl_sha256_context *c, const void *data, size_t len);
|
||||||
|
+int SHA256_Final(unsigned char *md, struct openssl_sha256_context *c);
|
||||||
|
+
|
||||||
|
+void sha256_block_data_order(struct openssl_sha256_context *c, const void *p, size_t num);
|
||||||
|
+
|
||||||
|
+static inline void sha256_starts( sha256_context *ctx, int is224 )
|
||||||
|
+{
|
||||||
|
+ if ((ctx->is224 = is224))
|
||||||
|
+ SHA224_Init(&ctx->octx);
|
||||||
|
+ else
|
||||||
|
+ SHA256_Init(&ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha256_update( sha256_context *ctx, const unsigned char *input, size_t ilen )
|
||||||
|
+{
|
||||||
|
+ if (ctx->is224)
|
||||||
|
+ SHA224_Update(&ctx->octx, input, ilen);
|
||||||
|
+ else
|
||||||
|
+ SHA256_Update(&ctx->octx, input, ilen);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha256_finish( sha256_context *ctx, unsigned char output[32] )
|
||||||
|
+{
|
||||||
|
+ if (ctx->is224)
|
||||||
|
+ SHA224_Final(output, &ctx->octx);
|
||||||
|
+ else
|
||||||
|
+ SHA256_Final(output, &ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha256_process( sha256_context *ctx, const unsigned char data[64] )
|
||||||
|
+{
|
||||||
|
+ sha256_block_data_order(&ctx->octx, data, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha512_alt.h polarssl.new/include/polarssl/sha512_alt.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha512_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/sha512_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -0,0 +1,74 @@
|
||||||
|
+/*
|
||||||
|
+ * Use OpenSSL implementation of SHA512 methods to get asm and hardware acceleration.
|
||||||
|
+ * Don't include this file directly, it is included by sha512.h when
|
||||||
|
+ * POLARSSL_SHA512_ALT is defined.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "polarssl/sha_openssl.h"
|
||||||
|
+
|
||||||
|
+struct openssl_sha512_context {
|
||||||
|
+ SHA_LONG64 h[8];
|
||||||
|
+ SHA_LONG64 Nl,Nh;
|
||||||
|
+ union {
|
||||||
|
+ SHA_LONG64 d[SHA_LBLOCK];
|
||||||
|
+ unsigned char p[SHA512_CBLOCK];
|
||||||
|
+ } u;
|
||||||
|
+ unsigned int num,md_len;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ struct openssl_sha512_context octx;
|
||||||
|
+
|
||||||
|
+ unsigned char ipad[128]; /*!< HMAC: inner padding */
|
||||||
|
+ unsigned char opad[128]; /*!< HMAC: outer padding */
|
||||||
|
+ int is384; /*!< 0 => SHA-512, else SHA-384 */
|
||||||
|
+}
|
||||||
|
+sha512_context;
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+int SHA384_Init(struct openssl_sha512_context *c);
|
||||||
|
+int SHA384_Update(struct openssl_sha512_context *c, const void *data, size_t len);
|
||||||
|
+int SHA384_Final(unsigned char *md, struct openssl_sha512_context *c);
|
||||||
|
+
|
||||||
|
+int SHA512_Init(struct openssl_sha512_context *c);
|
||||||
|
+int SHA512_Update(struct openssl_sha512_context *c, const void *data, size_t len);
|
||||||
|
+int SHA512_Final(unsigned char *md, struct openssl_sha512_context *c);
|
||||||
|
+
|
||||||
|
+void sha512_block_data_order(struct openssl_sha512_context *c, const void *p, size_t num);
|
||||||
|
+
|
||||||
|
+static inline void sha512_starts( sha512_context *ctx, int is384 )
|
||||||
|
+{
|
||||||
|
+ if ((ctx->is384 = is384))
|
||||||
|
+ SHA384_Init(&ctx->octx);
|
||||||
|
+ else
|
||||||
|
+ SHA512_Init(&ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha512_update( sha512_context *ctx, const unsigned char *input, size_t ilen )
|
||||||
|
+{
|
||||||
|
+ if (ctx->is384)
|
||||||
|
+ SHA384_Update(&ctx->octx, input, ilen);
|
||||||
|
+ else
|
||||||
|
+ SHA512_Update(&ctx->octx, input, ilen);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha512_finish( sha512_context *ctx, unsigned char output[64] )
|
||||||
|
+{
|
||||||
|
+ if (ctx->is384)
|
||||||
|
+ SHA384_Final(output, &ctx->octx);
|
||||||
|
+ else
|
||||||
|
+ SHA512_Final(output, &ctx->octx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void sha512_process( sha512_context *ctx, const unsigned char data[128] )
|
||||||
|
+{
|
||||||
|
+ sha512_block_data_order(&ctx->octx, data, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff -uNr polarssl-1.2.7/include/polarssl/sha_openssl.h polarssl.new/include/polarssl/sha_openssl.h
|
||||||
|
--- polarssl-1.2.7/include/polarssl/sha_openssl.h 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ polarssl.new/include/polarssl/sha_openssl.h 2013-06-07 17:43:56.000000000 -0600
|
||||||
|
@@ -0,0 +1,42 @@
|
||||||
|
+/*
|
||||||
|
+ * Common header file for all OpenSSL-imported SHA methods
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef POLARSSL_SHA_OPENSSL_H
|
||||||
|
+#define POLARSSL_SHA_OPENSSL_H
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
|
||||||
|
+ * ! SHA_LONG_LOG2 has to be defined along. !
|
||||||
|
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#if defined(__LP32__)
|
||||||
|
+#define SHA_LONG unsigned long
|
||||||
|
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
|
||||||
|
+#define SHA_LONG unsigned long
|
||||||
|
+#define SHA_LONG_LOG2 3
|
||||||
|
+#else
|
||||||
|
+#define SHA_LONG unsigned int
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define SHA_LBLOCK 16
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
|
||||||
|
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
|
||||||
|
+ * for further details.
|
||||||
|
+ */
|
||||||
|
+#define SHA512_CBLOCK (SHA_LBLOCK*8) /* SHA-512 treats input data as a
|
||||||
|
+ * contiguous array of 64 bit
|
||||||
|
+ * wide big-endian values. */
|
||||||
|
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
|
||||||
|
+#define SHA_LONG64 unsigned __int64
|
||||||
|
+#elif defined(__arch64__)
|
||||||
|
+#define SHA_LONG64 unsigned long
|
||||||
|
+#else
|
||||||
|
+#define SHA_LONG64 unsigned long long
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
Vendored
+24
@@ -0,0 +1,24 @@
|
|||||||
|
AES_set_encrypt_key
|
||||||
|
AES_set_decrypt_key
|
||||||
|
AES_ecb_encrypt
|
||||||
|
AES_cbc_encrypt
|
||||||
|
BF_set_key
|
||||||
|
BF_ecb_encrypt
|
||||||
|
BF_cbc_encrypt
|
||||||
|
SHA1_Init
|
||||||
|
SHA1_Update
|
||||||
|
SHA1_Final
|
||||||
|
SHA224_Init
|
||||||
|
SHA224_Update
|
||||||
|
SHA224_Final
|
||||||
|
SHA256_Init
|
||||||
|
SHA256_Update
|
||||||
|
SHA256_Final
|
||||||
|
SHA384_Init
|
||||||
|
SHA384_Update
|
||||||
|
SHA384_Final
|
||||||
|
SHA512_Init
|
||||||
|
SHA512_Update
|
||||||
|
SHA512_Final
|
||||||
|
OPENSSL_ia32_cpuid
|
||||||
|
-OPENSSL_cpuid_setup
|
||||||
Vendored
+24
@@ -0,0 +1,24 @@
|
|||||||
|
aesni_set_encrypt_key
|
||||||
|
aesni_set_decrypt_key
|
||||||
|
aesni_ecb_encrypt
|
||||||
|
aesni_cbc_encrypt
|
||||||
|
BF_set_key
|
||||||
|
BF_ecb_encrypt
|
||||||
|
BF_cbc_encrypt
|
||||||
|
SHA1_Init
|
||||||
|
SHA1_Update
|
||||||
|
SHA1_Final
|
||||||
|
SHA224_Init
|
||||||
|
SHA224_Update
|
||||||
|
SHA224_Final
|
||||||
|
SHA256_Init
|
||||||
|
SHA256_Update
|
||||||
|
SHA256_Final
|
||||||
|
SHA384_Init
|
||||||
|
SHA384_Update
|
||||||
|
SHA384_Final
|
||||||
|
SHA512_Init
|
||||||
|
SHA512_Update
|
||||||
|
SHA512_Final
|
||||||
|
OPENSSL_ia32_cpuid
|
||||||
|
-OPENSSL_cpuid_setup
|
||||||
+118
@@ -0,0 +1,118 @@
|
|||||||
|
diff -ur mbedtls-1.3.17/library/x509.c polarssl.new/library/x509.c
|
||||||
|
--- mbedtls-1.3.17/library/x509.c 2016-06-27 13:00:26.000000000 -0600
|
||||||
|
+++ polarssl.new/library/x509.c 2016-08-04 17:21:52.000000000 -0600
|
||||||
|
@@ -490,6 +490,73 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) field.
|
||||||
|
+ */
|
||||||
|
+static int x509_parse_time(unsigned char **p, size_t len, unsigned int yearlen, x509_time *time)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* minimum length is 10 or 12 depending on yearlen */
|
||||||
|
+ if (len < yearlen + 8)
|
||||||
|
+ return POLARSSL_ERR_X509_INVALID_DATE;
|
||||||
|
+ len -= yearlen + 8;
|
||||||
|
+
|
||||||
|
+ /* parse year, month, day, hour, minute */
|
||||||
|
+ CHECK( x509_parse_int( p, yearlen, &time->year ) );
|
||||||
|
+ if (yearlen == 2)
|
||||||
|
+ {
|
||||||
|
+ if (time->year < 50)
|
||||||
|
+ time->year += 100;
|
||||||
|
+ time->year += 1900;
|
||||||
|
+ }
|
||||||
|
+ CHECK( x509_parse_int( p, 2, &time->mon ) );
|
||||||
|
+ CHECK( x509_parse_int( p, 2, &time->day ) );
|
||||||
|
+ CHECK( x509_parse_int( p, 2, &time->hour ) );
|
||||||
|
+ CHECK( x509_parse_int( p, 2, &time->min ) );
|
||||||
|
+
|
||||||
|
+ /* parse seconds if present */
|
||||||
|
+ if (len >= 2 && **p >= '0' && **p <= '9')
|
||||||
|
+ {
|
||||||
|
+ CHECK( x509_parse_int( p, 2, &time->sec ) );
|
||||||
|
+ len -= 2;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+#if defined(POLARSSL_RELAXED_X509_DATE)
|
||||||
|
+ /* if relaxed mode, allow seconds to be absent */
|
||||||
|
+ time->sec = 0;
|
||||||
|
+#else
|
||||||
|
+ return POLARSSL_ERR_X509_INVALID_DATE;
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* parse trailing 'Z' if present */
|
||||||
|
+ if (len == 1 && **p == 'Z')
|
||||||
|
+ {
|
||||||
|
+ (*p)++;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#if defined(POLARSSL_RELAXED_X509_DATE)
|
||||||
|
+ /* if relaxed mode, allow timezone to be present */
|
||||||
|
+ else if (len == 5 && **p == '+')
|
||||||
|
+ {
|
||||||
|
+ int tz; /* throwaway timezone */
|
||||||
|
+ (*p)++;
|
||||||
|
+ CHECK( x509_parse_int( p, 4, &tz ) );
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* okay if no trailing 'Z' or timezone specified */
|
||||||
|
+ else if (len == 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ else
|
||||||
|
+ return POLARSSL_ERR_X509_INVALID_DATE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
* Time ::= CHOICE {
|
||||||
|
* utcTime UTCTime,
|
||||||
|
* generalTime GeneralizedTime }
|
||||||
|
@@ -515,20 +582,7 @@
|
||||||
|
if( ret != 0 )
|
||||||
|
return( POLARSSL_ERR_X509_INVALID_DATE + ret );
|
||||||
|
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->year ) );
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->mon ) );
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->day ) );
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->hour ) );
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->min ) );
|
||||||
|
- if( len > 10 )
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->sec ) );
|
||||||
|
- if( len > 12 && *(*p)++ != 'Z' )
|
||||||
|
- return( POLARSSL_ERR_X509_INVALID_DATE );
|
||||||
|
-
|
||||||
|
- time->year += 100 * ( time->year < 50 );
|
||||||
|
- time->year += 1900;
|
||||||
|
-
|
||||||
|
- return( 0 );
|
||||||
|
+ return x509_parse_time(p, len, 2, time);
|
||||||
|
}
|
||||||
|
else if( tag == ASN1_GENERALIZED_TIME )
|
||||||
|
{
|
||||||
|
@@ -538,17 +592,7 @@
|
||||||
|
if( ret != 0 )
|
||||||
|
return( POLARSSL_ERR_X509_INVALID_DATE + ret );
|
||||||
|
|
||||||
|
- CHECK( x509_parse_int( p, 4, &time->year ) );
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->mon ) );
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->day ) );
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->hour ) );
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->min ) );
|
||||||
|
- if( len > 12 )
|
||||||
|
- CHECK( x509_parse_int( p, 2, &time->sec ) );
|
||||||
|
- if( len > 14 && *(*p)++ != 'Z' )
|
||||||
|
- return( POLARSSL_ERR_X509_INVALID_DATE );
|
||||||
|
-
|
||||||
|
- return( 0 );
|
||||||
|
+ return x509_parse_time(p, len, 4, time);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return( POLARSSL_ERR_X509_INVALID_DATE +
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
ver=1.2.7
|
||||||
|
src=~/src/mac/polarssl-$ver
|
||||||
|
rm -rf polarssl-$ver polarssl-$ver.new
|
||||||
|
tar xfz $DL/polarssl-$ver-gpl.tgz
|
||||||
|
cp -a polarssl-$ver polarssl-$ver.new
|
||||||
|
cd polarssl-$ver.new
|
||||||
|
cp $src/include/polarssl/bn_mul.h include/polarssl/
|
||||||
|
cp $src/library/bignum.c library/
|
||||||
|
#cp $src/library/mpi_mul_hlp.c library/
|
||||||
|
#cp $src/library/CMakeLists.txt library/
|
||||||
|
cd ..
|
||||||
|
diff -uNr polarssl-$ver polarssl-$ver.new
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
Make the ciphersuites array argument to ssl_set_ciphersuites const.
|
||||||
|
This should be done to assure callers that PolarSSL doesn't intend
|
||||||
|
to modify this array (which it apparently doesn't).
|
||||||
|
|
||||||
|
diff -ur polarssl-1.1.1/include/polarssl/ssl.h polarssl-1.1.1.new/include/polarssl/ssl.h
|
||||||
|
--- polarssl-1.1.1/include/polarssl/ssl.h 2012-01-23 02:57:38.000000000 -0700
|
||||||
|
+++ polarssl-1.1.1.new/include/polarssl/ssl.h 2012-03-14 02:46:30.315215130 -0600
|
||||||
|
@@ -306,7 +306,7 @@
|
||||||
|
sha1_context fin_sha1; /*!< Finished SHA-1 checksum */
|
||||||
|
|
||||||
|
int do_crypt; /*!< en(de)cryption flag */
|
||||||
|
- int *ciphersuites; /*!< allowed ciphersuites */
|
||||||
|
+ const int *ciphersuites; /*!< allowed ciphersuites */
|
||||||
|
size_t pmslen; /*!< premaster length */
|
||||||
|
unsigned int keylen; /*!< symmetric key length */
|
||||||
|
size_t minlen; /*!< min. ciphertext length */
|
||||||
|
@@ -495,7 +495,7 @@
|
||||||
|
* \param ssl SSL context
|
||||||
|
* \param ciphersuites 0-terminated list of allowed ciphersuites
|
||||||
|
*/
|
||||||
|
-void ssl_set_ciphersuites( ssl_context *ssl, int *ciphersuites );
|
||||||
|
+void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the data required to verify peer certificate
|
||||||
|
diff -ur polarssl-1.1.1/library/ssl_tls.c polarssl-1.1.1.new/library/ssl_tls.c
|
||||||
|
--- polarssl-1.1.1/library/ssl_tls.c 2012-01-23 02:57:38.000000000 -0700
|
||||||
|
+++ polarssl-1.1.1.new/library/ssl_tls.c 2012-03-14 02:47:10.830001668 -0600
|
||||||
|
@@ -1838,7 +1838,7 @@
|
||||||
|
ssl->session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
-void ssl_set_ciphersuites( ssl_context *ssl, int *ciphersuites )
|
||||||
|
+void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites )
|
||||||
|
{
|
||||||
|
ssl->ciphersuites = ciphersuites;
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
This fixes an issue where the cipher.h header doesn't compile when included
|
||||||
|
by C++ code, as C++ is more strict than C about implicit enum casts.
|
||||||
|
|
||||||
|
diff -ur polarssl-1.1.1/include/polarssl/cipher.h /home/james/polarssl-1.1.1/include/polarssl/cipher.h
|
||||||
|
--- polarssl-1.1.1/include/polarssl/cipher.h 2011-11-15 08:38:45.000000000 -0700
|
||||||
|
+++ /home/james/polarssl-1.1.1/include/polarssl/cipher.h 2012-03-12 17:31:12.279631469 -0600
|
||||||
|
@@ -313,7 +313,7 @@
|
||||||
|
static inline cipher_type_t cipher_get_type( const cipher_context_t *ctx )
|
||||||
|
{
|
||||||
|
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||||
|
- return 0;
|
||||||
|
+ return POLARSSL_CIPHER_NONE;
|
||||||
|
|
||||||
|
return ctx->cipher_info->type;
|
||||||
|
}
|
||||||
+181
@@ -0,0 +1,181 @@
|
|||||||
|
This patch allows the caller to create a proxy object that can be used
|
||||||
|
in place of a private key. The proxy object must define sign and
|
||||||
|
decrypt methods. This functionality is similar to that provided by
|
||||||
|
POLARSSL_PKCS11_C except that it can accomodate any arbitrary
|
||||||
|
implementation of external private keys, not only that provided by
|
||||||
|
the PKCS#11 helper library.
|
||||||
|
|
||||||
|
This is necessary to allow PolarSSL to interact with certificate/key
|
||||||
|
stores on many different platforms that don't natively support
|
||||||
|
PKCS#11 such as Mac (uses Keychain API), Windows (uses CryptoAPI),
|
||||||
|
and Android (android.security.KeyChain).
|
||||||
|
|
||||||
|
In the basic usage model, the library is built with POLARSSL_PKCS11_C
|
||||||
|
and POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY. Doing this causes the
|
||||||
|
pkcs11_context object to become an interface to any arbitrary
|
||||||
|
external private key implementation that defines sign and decrypt
|
||||||
|
methods. Note that in this configuration, the PKCS#11 helper library
|
||||||
|
(libpkcs11-helper) is not used.
|
||||||
|
|
||||||
|
When POLARSSL_PKCS11_C is defined in the absence of
|
||||||
|
POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY, the pkcs11_context object
|
||||||
|
reverts to its previous implementation, where it becomes a
|
||||||
|
connector to a certificate/private-key context in the PKCS#11 helper
|
||||||
|
library.
|
||||||
|
|
||||||
|
diff -ur polarssl-1.1.1.orig/include/polarssl/config.h polarssl-1.1.1/include/polarssl/config.h
|
||||||
|
--- polarssl-1.1.1.orig/include/polarssl/config.h 2011-12-22 03:06:27.000000000 -0700
|
||||||
|
+++ polarssl-1.1.1/include/polarssl/config.h 2012-03-14 02:31:04.000000000 -0600
|
||||||
|
@@ -531,10 +531,26 @@
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS PKCS #11 smartcard support.
|
||||||
|
* Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
|
||||||
|
+ * unless POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY is also defined.
|
||||||
|
+ *
|
||||||
|
#define POLARSSL_PKCS11_C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * \def POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY
|
||||||
|
+ *
|
||||||
|
+ * Enable support for generic external private key implementations.
|
||||||
|
+ *
|
||||||
|
+ * Module: library/ssl_srv.c
|
||||||
|
+ * Caller: library/ssl_cli.c
|
||||||
|
+ * library/ssl_srv.c
|
||||||
|
+ *
|
||||||
|
+ * Requires: POLARSSL_PKCS11_C
|
||||||
|
+ *
|
||||||
|
+#define POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
* \def POLARSSL_RSA_C
|
||||||
|
*
|
||||||
|
* Enable the RSA public-key cryptosystem.
|
||||||
|
diff -ur polarssl-1.1.1.orig/include/polarssl/pkcs11.h polarssl-1.1.1/include/polarssl/pkcs11.h
|
||||||
|
--- polarssl-1.1.1.orig/include/polarssl/pkcs11.h 2011-11-18 07:26:47.000000000 -0700
|
||||||
|
+++ polarssl-1.1.1/include/polarssl/pkcs11.h 2012-03-14 02:28:34.000000000 -0600
|
||||||
|
@@ -35,6 +35,95 @@
|
||||||
|
|
||||||
|
#include "x509.h"
|
||||||
|
|
||||||
|
+#if defined(POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY)
|
||||||
|
+
|
||||||
|
+/* inline preamble */
|
||||||
|
+#if defined(_MSC_VER) && !defined(inline)
|
||||||
|
+#define inline _inline
|
||||||
|
+#else
|
||||||
|
+#if defined(__ARMCC_VERSION) && !defined(inline)
|
||||||
|
+#define inline __inline
|
||||||
|
+#endif /* __ARMCC_VERSION */
|
||||||
|
+#endif /*_MSC_VER */
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * This object is a reference to an external private key,
|
||||||
|
+ * and can be used in place of a concrete private key.
|
||||||
|
+ */
|
||||||
|
+typedef struct _pkcs11_context {
|
||||||
|
+ void *parameter; /** user-defined parameter */
|
||||||
|
+ int len; /** private key length in bytes */
|
||||||
|
+
|
||||||
|
+ /** user-defined decrypt method, see pkcs11_decrypt doc below */
|
||||||
|
+ int (*f_decrypt)( struct _pkcs11_context *ctx,
|
||||||
|
+ int mode, size_t *olen,
|
||||||
|
+ const unsigned char *input,
|
||||||
|
+ unsigned char *output,
|
||||||
|
+ unsigned int output_max_len );
|
||||||
|
+
|
||||||
|
+ /** user-defined sign method, see pkcs11_sign doc below */
|
||||||
|
+ int (*f_sign)( struct _pkcs11_context *ctx,
|
||||||
|
+ int mode,
|
||||||
|
+ int hash_id,
|
||||||
|
+ unsigned int hashlen,
|
||||||
|
+ const unsigned char *hash,
|
||||||
|
+ unsigned char *sig );
|
||||||
|
+
|
||||||
|
+} pkcs11_context;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief Do an RSA private key decrypt, then remove the message padding
|
||||||
|
+ *
|
||||||
|
+ * \param ctx PKCS #11 context
|
||||||
|
+ * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature
|
||||||
|
+ * \param input buffer holding the encrypted data
|
||||||
|
+ * \param output buffer that will hold the plaintext
|
||||||
|
+ * \param olen will contain the plaintext length
|
||||||
|
+ * \param output_max_len maximum length of the output buffer
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
+ *
|
||||||
|
+ * \note The output buffer must be as large as the size
|
||||||
|
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
|
||||||
|
+ * an error is thrown.
|
||||||
|
+ */
|
||||||
|
+static inline int pkcs11_decrypt( pkcs11_context *ctx,
|
||||||
|
+ int mode, size_t *olen,
|
||||||
|
+ const unsigned char *input,
|
||||||
|
+ unsigned char *output,
|
||||||
|
+ unsigned int output_max_len )
|
||||||
|
+{
|
||||||
|
+ return (*ctx->f_decrypt)(ctx, mode, olen, input, output, output_max_len);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \brief Do a private RSA to sign a message digest
|
||||||
|
+ *
|
||||||
|
+ * \param ctx PKCS #11 context
|
||||||
|
+ * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature
|
||||||
|
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||||
|
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||||
|
+ * \param hash buffer holding the message digest
|
||||||
|
+ * \param sig buffer that will hold the ciphertext
|
||||||
|
+ *
|
||||||
|
+ * \return 0 if the signing operation was successful,
|
||||||
|
+ * or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
+ *
|
||||||
|
+ * \note The "sig" buffer must be as large as the size
|
||||||
|
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||||
|
+ */
|
||||||
|
+static inline int pkcs11_sign( pkcs11_context *ctx,
|
||||||
|
+ int mode,
|
||||||
|
+ int hash_id,
|
||||||
|
+ unsigned int hashlen,
|
||||||
|
+ const unsigned char *hash,
|
||||||
|
+ unsigned char *sig )
|
||||||
|
+{
|
||||||
|
+ return (*ctx->f_sign)(ctx, mode, hash_id, hashlen, hash, sig);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -121,6 +210,8 @@
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned char *sig );
|
||||||
|
|
||||||
|
+#endif /* POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY */
|
||||||
|
+
|
||||||
|
#endif /* POLARSSL_PKCS11_C */
|
||||||
|
|
||||||
|
#endif /* POLARSSL_PKCS11_H */
|
||||||
|
diff -ur polarssl-1.1.1.orig/library/pkcs11.c polarssl-1.1.1/library/pkcs11.c
|
||||||
|
--- polarssl-1.1.1.orig/library/pkcs11.c 2011-04-24 02:57:21.000000000 -0600
|
||||||
|
+++ polarssl-1.1.1/library/pkcs11.c 2012-03-14 02:28:22.000000000 -0600
|
||||||
|
@@ -29,7 +29,7 @@
|
||||||
|
|
||||||
|
#include "polarssl/pkcs11.h"
|
||||||
|
|
||||||
|
-#if defined(POLARSSL_PKCS11_C)
|
||||||
|
+#if defined(POLARSSL_PKCS11_C) && !defined(POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY)
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@@ -235,4 +235,4 @@
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
-#endif /* defined(POLARSSL_PKCS11_C) */
|
||||||
|
+#endif /* defined(POLARSSL_PKCS11_C) && !defined(POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY) */
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
diff -ur polarssl-1.1.3/library/ssl_tls.c polarssl-1.1.3.jy/library/ssl_tls.c
|
||||||
|
--- polarssl-1.1.3/library/ssl_tls.c 2012-04-20 07:33:14.000000000 -0600
|
||||||
|
+++ polarssl-1.1.3.jy/library/ssl_tls.c 2012-05-29 09:12:11.687371794 -0600
|
||||||
|
@@ -785,7 +785,7 @@
|
||||||
|
/*
|
||||||
|
* Always compute the MAC (RFC4346, CBCTIME).
|
||||||
|
*/
|
||||||
|
- if( ssl->in_msglen <= ssl->maclen + padlen )
|
||||||
|
+ if( ssl->in_msglen < ssl->maclen + padlen )
|
||||||
|
{
|
||||||
|
SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
|
||||||
|
ssl->in_msglen, ssl->maclen, padlen ) );
|
||||||
Vendored
+44
@@ -0,0 +1,44 @@
|
|||||||
|
Patch to 1.1.4 to allow X509 v3 trust extensions.
|
||||||
|
--------------------------------------------------
|
||||||
|
Index: x509parse.c
|
||||||
|
===================================================================
|
||||||
|
--- x509parse.c (revision 1322)
|
||||||
|
+++ x509parse.c (working copy)
|
||||||
|
@@ -1134,7 +1134,7 @@
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t len;
|
||||||
|
- unsigned char *p, *end;
|
||||||
|
+ unsigned char *p, *end, *crt_end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for valid input
|
||||||
|
@@ -1168,13 +1168,14 @@
|
||||||
|
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
|
||||||
|
}
|
||||||
|
|
||||||
|
- if( len != (size_t) ( end - p ) )
|
||||||
|
+ if( len > (size_t) ( end - p ) )
|
||||||
|
{
|
||||||
|
x509_free( crt );
|
||||||
|
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
|
||||||
|
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+ crt_end = p + len;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* TBSCertificate ::= SEQUENCE {
|
||||||
|
*/
|
||||||
|
@@ -1344,7 +1345,7 @@
|
||||||
|
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||||
|
}
|
||||||
|
|
||||||
|
- end = crt->raw.p + crt->raw.len;
|
||||||
|
+ end = crt_end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* signatureAlgorithm AlgorithmIdentifier,
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
End of patch file
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo TARGET var must be defined
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$DL" ] && DL=~/Downloads
|
||||||
|
|
||||||
|
# source vars
|
||||||
|
. $O3/core/vars/vars-${TARGET}
|
||||||
|
. $O3/core/deps/lib-versions
|
||||||
|
|
||||||
|
[ "$GCC_CMD" ] && export CC=$GCC_CMD
|
||||||
|
[ "$GPP_CMD" ] && export CXX=$GPP_CMD
|
||||||
|
[ "$LD_CMD" ] && export LD=$LD_CMD
|
||||||
|
[ "$AR_CMD" ] && export AR=$AR_CMD
|
||||||
|
[ "$RANLIB_CMD" ] && export RANLIB=$RANLIB_CMD
|
||||||
|
|
||||||
|
case $PLATFORM in
|
||||||
|
android*)
|
||||||
|
echo PLATFORM android
|
||||||
|
host=arm
|
||||||
|
target=arm
|
||||||
|
;;
|
||||||
|
ios*)
|
||||||
|
echo PLATFORM ios
|
||||||
|
host="x86_64-apple-darwin"
|
||||||
|
target=arm
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
host=""
|
||||||
|
target=""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$target" ]; then
|
||||||
|
targ_opt="--target=$target"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$host" ]; then
|
||||||
|
host_opt="--host=$host"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$NO_WIPE" != "1" ]; then
|
||||||
|
rm -rf $SNAPPY_VERSION
|
||||||
|
tar xfz $DL/$SNAPPY_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
DIST=$(pwd)/snappy/snappy-$PLATFORM
|
||||||
|
rm -rf $DIST
|
||||||
|
mkdir -p $DIST
|
||||||
|
cd $SNAPPY_VERSION
|
||||||
|
echo 'OPTIONS' CC=$CC LD=$LD AR=$AR RANLIB=$RANLIB host_opt=$host_opt targ_opt=$targ_opt
|
||||||
|
export CFLAGS="$PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC"
|
||||||
|
echo 'CFLAGS' $CFLAGS
|
||||||
|
export CXXFLAGS="$CFLAGS $CXX_COMPILER_FLAGS"
|
||||||
|
./configure --prefix=$DIST $host_opt $targ_opt --enable-static --disable-shared
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
OpenVPN Protocol extensions
|
||||||
|
2015-01-06
|
||||||
|
|
||||||
|
1. DATA_V2 opcode with 24-bit peer ID
|
||||||
|
|
||||||
|
* The DATA_V2 opcode is 9.
|
||||||
|
* The DATA_V2 opcode/key_id byte is followed by 3 additional
|
||||||
|
(network endian) bytes indicating the peer ID.
|
||||||
|
* If a 4-byte DATA_V2 header is passed through ntohl,
|
||||||
|
the resulting high 8 bits will be the DATA_V2 opcode/key_id,
|
||||||
|
and the lower 24 bits will be the peer ID.
|
||||||
|
* A disabled peer ID is denoted by 0xFFFFFF.
|
||||||
|
* Server tells the client to use DATA_V2/peer_id by pushing
|
||||||
|
the directive "peer-id ID" where ID is a decimal integer
|
||||||
|
in the range [-1, 16777215]. Setting the peer ID to -1
|
||||||
|
transmits DATA_V2 packets with the peer ID field set to
|
||||||
|
0xFFFFFF. Setting the peer_id to -1 is the same as
|
||||||
|
setting it to 16777215 (i.e. 0xFFFFFF).
|
||||||
|
* Client never transmits DATA_V2 packets unless the server
|
||||||
|
has pushed a "peer-id" directive.
|
||||||
|
* Server never pushes a "peer-id" directive unless the
|
||||||
|
client has indicated its support for DATA_V2 by
|
||||||
|
including "IV_PROTO=2" in the peer info data.
|
||||||
|
* When DATA_V2 is used for "float" functionality, the server
|
||||||
|
must perform the following checks before allowing
|
||||||
|
a client to float, i.e. to assume a new source address.
|
||||||
|
(a) verify integrity (HMAC or GCM auth tag, replay
|
||||||
|
protection, etc.) of the DATA_V2 packet, and
|
||||||
|
(b) ensure that the float doesn't clobber a pre-existing
|
||||||
|
client (i.e. if the address floated to is already
|
||||||
|
owned by another client) unless it can be verified
|
||||||
|
that the pre-existing client is a previous instance
|
||||||
|
of the floating client.
|
||||||
|
|
||||||
|
2. AEAD mode
|
||||||
|
|
||||||
|
To support AEAD crypto modes such as AES-GCM, some protocol
|
||||||
|
changes are in order. AES-GCM, for example, requires a 12
|
||||||
|
byte unique nonce for every packet. I would propose that 4
|
||||||
|
bytes be taken from the Packet ID which increments for every
|
||||||
|
packet and therefore provides uniqueness. The remaining 8
|
||||||
|
bytes would be derived from the random key material that would
|
||||||
|
normally be used to key the HMAC key. This is possible since
|
||||||
|
AEAD modes use a combined key for encryption and integrity
|
||||||
|
checking, therefore the random key material for HMAC is
|
||||||
|
unused and can be repurposed as an AEAD nonce source. The 8
|
||||||
|
byte nonce component derived from the HMAC keying material
|
||||||
|
would remain constant for a given Key State. Only the 4 byte
|
||||||
|
Packet ID would increment for each packet. Because AEAD
|
||||||
|
encryption can be compromised if the nonce ever repeats for
|
||||||
|
a given key, the implementation MUST disable encryption
|
||||||
|
for a key if the 32-bit packet ID wraps. In practical usage,
|
||||||
|
renegotiation usually preempts wrapping, so the
|
||||||
|
disable-encryption-on-wrap feature is a failsafe.
|
||||||
|
|
||||||
|
AEAD Nonce:
|
||||||
|
|
||||||
|
[ Packet ID ] [ HMAC keying material ]
|
||||||
|
[ 4 bytes ] [ 8 bytes ]
|
||||||
|
[ AEAD nonce total: 12 bytes ]
|
||||||
|
|
||||||
|
TLS wire protocol:
|
||||||
|
|
||||||
|
[ DATA_V2 opcode ] [ Packet ID ] [ AEAD Auth tag ] [ ciphertext ]
|
||||||
|
[ 4 bytes ] [ 4 bytes ] [ 16 bytes ]
|
||||||
|
[ AEAD additional data (AD) ]
|
||||||
|
|
||||||
|
Static Key wire protocol:
|
||||||
|
|
||||||
|
[ DATA_V2 opcode ] [ Packet ID ] [ Nonce tail (random) ] [ AEAD Auth tag ] [ ciphertext ]
|
||||||
|
[ AEAD nonce ]
|
||||||
|
[ 4 bytes ] [ 8 bytes ] [ 4 bytes ] [ 16 bytes ]
|
||||||
|
[ AEAD additional data (AD) ]
|
||||||
|
|
||||||
|
Note that the AEAD additional data (AD) includes all data
|
||||||
|
preceding the AEAD Auth tag including the DATA_V2/peer_id
|
||||||
|
opcode and packet ID.
|
||||||
|
|
||||||
|
Also, note that because the HMAC keying material used to derive
|
||||||
|
the last 8 bytes of the AEAD nonce is negotiated once per key
|
||||||
|
as part of the control channel handshake, we can omit it from the
|
||||||
|
data channel packets, thereby saving 8 bytes per packet. So
|
||||||
|
only the 4-byte Packet ID component of the nonce must be
|
||||||
|
transmitted with every packet.
|
||||||
|
|
||||||
|
When negotiating AEAD mode, the client indicates its support
|
||||||
|
of AES-128-GCM, AES-192-GCM, and AES-192-GCM by including:
|
||||||
|
|
||||||
|
IV_NCP=2
|
||||||
|
|
||||||
|
in the peer info string (NCP stands for Negotiable Crypto
|
||||||
|
Parameters).
|
||||||
|
|
||||||
|
When the IV_NCP value is 2 or higher, it indicates that
|
||||||
|
the server may push an AEAD "cipher" directive, e.g.:
|
||||||
|
|
||||||
|
push "cipher AES-128-GCM"
|
||||||
|
|
||||||
|
In the future, the IV_NCP value (2 in the current
|
||||||
|
implementation) may be increased to indicate the
|
||||||
|
availability of additional negotiable ciphers.
|
||||||
|
|
||||||
|
3. Compression V2
|
||||||
|
|
||||||
|
I have observed that compression in many cases, even when
|
||||||
|
enabled, often does not produce packet size reduction
|
||||||
|
because much of the packet data typically generated by web
|
||||||
|
sessions is already compressed. Further, the single byte that
|
||||||
|
precedes the packet and indicates whether or not compression
|
||||||
|
occurred has the unfortunate side effect of misaligning the IP
|
||||||
|
packet in cases where compression did not occur. To remedy this,
|
||||||
|
I propose a Compression V2 header that is optimized for the
|
||||||
|
case where compression does not occur.
|
||||||
|
|
||||||
|
a. No compression occurred and first byte of IP/Ethernet packet
|
||||||
|
is NOT 0x50 (0 bytes of overhead and maintains alignment):
|
||||||
|
|
||||||
|
[ uncompressed IP/Ethernet packet ]
|
||||||
|
|
||||||
|
b. No compression occurred and first byte of IP/Ethernet packet
|
||||||
|
is 0x50 (2 bytes of overhead but unlikely since no known
|
||||||
|
IP packet can begin with 0x50):
|
||||||
|
|
||||||
|
[ 0x50 ] [ 0x00 ] [ uncompressed IP/Ethernet packet ]
|
||||||
|
|
||||||
|
c. Compression occurred (2 bytes of overhead):
|
||||||
|
|
||||||
|
[ 0x50 ] [ compression Alg ID byte ] [ compressed IP/Ethernet packet ]
|
||||||
|
|
||||||
|
Compression Alg ID is one-byte algorithm identifier
|
||||||
|
for LZ4 (0x1), LZO (0x2), or Snappy (0x3).
|
||||||
|
|
||||||
|
This approach has several beneficial effects:
|
||||||
|
|
||||||
|
1. In the common case where compression does not occur, no
|
||||||
|
compression op is required, therefore there is zero overhead.
|
||||||
|
|
||||||
|
2. When compression does not occur, the IP/Ethernet packet
|
||||||
|
alignment is retained.
|
||||||
|
|
||||||
|
3. This technique does not require any byte swapping with
|
||||||
|
the tail of the packet which can potentially incur an
|
||||||
|
expensive cache miss.
|
||||||
|
|
||||||
|
When negotiating Compression V2 mode, the client indicates its
|
||||||
|
support by including the following in the peer info string:
|
||||||
|
|
||||||
|
IV_LZ4v2=1 -> LZ4 compression available in V2 format
|
||||||
|
IV_COMP_STUBv2=1 -> stub compression available in V2 format
|
||||||
|
(i.e. disable compression but still
|
||||||
|
retain compression framing)
|
||||||
|
|
||||||
|
In response, the server can push to the client:
|
||||||
|
|
||||||
|
push "compress lz4-v2" -> enable LZ4 compression in V2 format
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
push "compress stub-v2" -> disable compression but retain
|
||||||
|
compression framing in V2 format
|
||||||
|
|
||||||
|
4. TCP nonlinear mode
|
||||||
|
|
||||||
|
The OpenVPN 2.x packet ID and replay protection code, when running
|
||||||
|
in TCP mode, requires that the packet ID follows a linearly
|
||||||
|
incrementing sequence, i.e. 1, 2, 2, 3, ... This was a reasonable
|
||||||
|
requirement, since the reliable nature of TCP guaranteed that a
|
||||||
|
linear sequence of packet IDs transmitted by the sender would be
|
||||||
|
received in the same order by the receiver.
|
||||||
|
|
||||||
|
However, recent work has shown that multithreaded OpenVPN servers
|
||||||
|
may not be able to guarantee TCP packet ID linearity (on the
|
||||||
|
transmit side) without incurring a performance penalty. This
|
||||||
|
is because the packet ID for transmitted packets must be allocated
|
||||||
|
before the packet is encrypted, while a multithreaded OpenVPN server
|
||||||
|
might be concurrently encrypting and transmitting multiple packets
|
||||||
|
using different threads, where the order that the threads complete
|
||||||
|
encryption and transmit the packet is non-deterministic. This
|
||||||
|
non-deterministic ordering of packets over the TCP session means
|
||||||
|
that the client might see out-of-order packets and a non-linear
|
||||||
|
packet ID progression, just as clients now see with UDP.
|
||||||
|
|
||||||
|
My proposed solution to the issue is to relax the Packet ID
|
||||||
|
validation on the receiver side to allow non-linear packet ID
|
||||||
|
sequences, even in TCP mode. This essentially means that the
|
||||||
|
packet ID validation logic is now the same for both UDP and TCP.
|
||||||
|
|
||||||
|
The client indicates its ability to process non-linear packet
|
||||||
|
ID sequences in TCP mode by including the following in the
|
||||||
|
peer info string:
|
||||||
|
|
||||||
|
IV_TCPNL=1 -> TCP non-linear receiver supported
|
||||||
|
|
||||||
|
When the server receives a IV_TCPNL setting of 1 from the
|
||||||
|
client, it may transmit out-of-order packets in TCP mode.
|
||||||
|
Otherwise, servers must use other means (such as using thread
|
||||||
|
synchronization primitives) to ensure strictly linear packet
|
||||||
|
ID ordering in TCP mode.
|
||||||
Executable
+12
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# build ovpn3-core with system-provided mbedtls and lz4 on various linux distros
|
||||||
|
|
||||||
|
docker build -f dockerfiles/Dockerfile.debian -t deb .
|
||||||
|
docker run -it deb
|
||||||
|
|
||||||
|
docker build -f dockerfiles/Dockerfile.ubu -t ubu .
|
||||||
|
docker run -it ubu
|
||||||
|
|
||||||
|
docker build -f dockerfiles/Dockerfile.centos -t cnt .
|
||||||
|
docker run -it cnt
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
FROM centos/devtoolset-7-toolchain-centos7
|
||||||
|
|
||||||
|
USER 0
|
||||||
|
RUN yum -y update && yum -y install epel-release && \
|
||||||
|
yum -y install -y mbedtls-devel lz4-devel git wget perl-Digest-SHA make
|
||||||
|
|
||||||
|
ADD . /ovpn3/core
|
||||||
|
|
||||||
|
ENV O3 /ovpn3/
|
||||||
|
ENV DEP_DIR /ovpn3/deps
|
||||||
|
ENV DL /ovpn3/dl
|
||||||
|
|
||||||
|
CMD mkdir $DEP_DIR && mkdir $DL && \
|
||||||
|
/ovpn3/core/scripts/linux/build-all && \
|
||||||
|
cd $O3/core/test/ovpncli && \
|
||||||
|
ECHO=1 PROF=linux ASIO=1 MTLS_SYS=1 LZ4_SYS=1 NOSSL=1 $O3/core/scripts/build cli && \
|
||||||
|
cd $O3/core/test/ssl && \
|
||||||
|
ECHO=1 PROF=linux ASIO=1 MTLS_SYS=1 LZ4_SYS=1 NOSSL=1 $O3/core/scripts/build proto && \
|
||||||
|
./proto
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
FROM debian:9
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y autoconf build-essential wget git liblz4-dev libmbedtls-dev
|
||||||
|
|
||||||
|
ADD . /ovpn3/core
|
||||||
|
|
||||||
|
ENV O3 /ovpn3/
|
||||||
|
ENV DEP_DIR /ovpn3/deps
|
||||||
|
ENV DL /ovpn3/dl
|
||||||
|
|
||||||
|
CMD mkdir $DEP_DIR && mkdir $DL && \
|
||||||
|
/ovpn3/core/scripts/linux/build-all && \
|
||||||
|
cd $O3/core/test/ovpncli && \
|
||||||
|
ECHO=1 PROF=linux ASIO=1 MTLS_SYS=1 LZ4_SYS=1 NOSSL=1 $O3/core/scripts/build cli && \
|
||||||
|
cd $O3/core/test/ssl && \
|
||||||
|
ECHO=1 PROF=linux ASIO=1 MTLS_SYS=1 LZ4_SYS=1 NOSSL=1 $O3/core/scripts/build proto && \
|
||||||
|
./proto
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y autoconf build-essential wget git liblz4-dev libmbedtls-dev
|
||||||
|
|
||||||
|
ADD . /ovpn3/core
|
||||||
|
|
||||||
|
ENV O3 /ovpn3/
|
||||||
|
ENV DEP_DIR /ovpn3/deps
|
||||||
|
ENV DL /ovpn3/dl
|
||||||
|
|
||||||
|
CMD mkdir $DEP_DIR && mkdir $DL && \
|
||||||
|
/ovpn3/core/scripts/linux/build-all && \
|
||||||
|
cd $O3/core/test/ovpncli && \
|
||||||
|
ECHO=1 PROF=linux ASIO=1 MTLS_SYS=1 LZ4_SYS=1 NOSSL=1 $O3/core/scripts/build cli && \
|
||||||
|
cd $O3/core/test/ssl && \
|
||||||
|
ECHO=1 PROF=linux ASIO=1 MTLS_SYS=1 LZ4_SYS=1 NOSSL=1 $O3/core/scripts/build proto && \
|
||||||
|
./proto
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
build
|
||||||
|
ovpncli_wrap.cxx
|
||||||
|
ovpncli_wrap.h
|
||||||
|
ovpncli.java
|
||||||
|
ovpncliJNI.java
|
||||||
|
ClientAPI_*.java
|
||||||
|
SWIGTYPE_*.java
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// TESTING_ONLY
|
||||||
|
|
||||||
|
public class Client implements OpenVPNClientThread.EventReceiver {
|
||||||
|
private OpenVPNClientThread client_thread;
|
||||||
|
|
||||||
|
public static class ConfigError extends Exception {
|
||||||
|
public ConfigError(String msg) { super(msg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CredsUnspecifiedError extends Exception {
|
||||||
|
public CredsUnspecifiedError(String msg) { super(msg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load OpenVPN core (implements ClientAPI_OpenVPNClient) from shared library
|
||||||
|
static {
|
||||||
|
System.loadLibrary("ovpncli");
|
||||||
|
ClientAPI_OpenVPNClient.init_process();
|
||||||
|
String test = ClientAPI_OpenVPNClient.crypto_self_test();
|
||||||
|
System.out.format("CRYPTO SELF TEST: %s", test);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Client(String config_text, String username, String password) throws ConfigError, CredsUnspecifiedError {
|
||||||
|
// init client implementation object
|
||||||
|
client_thread = new OpenVPNClientThread();
|
||||||
|
|
||||||
|
// load/eval config
|
||||||
|
ClientAPI_Config config = new ClientAPI_Config();
|
||||||
|
config.setContent(config_text);
|
||||||
|
config.setCompressionMode("yes");
|
||||||
|
ClientAPI_EvalConfig ec = client_thread.eval_config(config);
|
||||||
|
if (ec.getError())
|
||||||
|
throw new ConfigError("OpenVPN config file parse error: " + ec.getMessage());
|
||||||
|
|
||||||
|
// handle creds
|
||||||
|
ClientAPI_ProvideCreds creds = new ClientAPI_ProvideCreds();
|
||||||
|
if (!ec.getAutologin())
|
||||||
|
{
|
||||||
|
if (username.length() > 0)
|
||||||
|
{
|
||||||
|
creds.setUsername(username);
|
||||||
|
creds.setPassword(password);
|
||||||
|
creds.setReplacePasswordWithSessionID(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new CredsUnspecifiedError("OpenVPN config file requires username/password but none provided");
|
||||||
|
}
|
||||||
|
client_thread.provide_creds(creds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect() {
|
||||||
|
// connect
|
||||||
|
client_thread.connect(this);
|
||||||
|
|
||||||
|
// wait for worker thread to exit
|
||||||
|
client_thread.wait_thread_long();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
client_thread.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show_stats() {
|
||||||
|
int n = client_thread.stats_n();
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
String name = client_thread.stats_name(i);
|
||||||
|
long value = client_thread.stats_value(i);
|
||||||
|
if (value > 0)
|
||||||
|
System.out.format("STAT %s=%s%n", name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void event(ClientAPI_Event event) {
|
||||||
|
boolean error = event.getError();
|
||||||
|
String name = event.getName();
|
||||||
|
String info = event.getInfo();
|
||||||
|
System.out.format("EVENT: err=%b name=%s info='%s'%n", error, name, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback to get a certificate
|
||||||
|
@Override
|
||||||
|
public void external_pki_cert_request(ClientAPI_ExternalPKICertRequest req) {
|
||||||
|
req.setError(true);
|
||||||
|
req.setErrorText("cert request failed: external PKI not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback to sign data
|
||||||
|
@Override
|
||||||
|
public void external_pki_sign_request(ClientAPI_ExternalPKISignRequest req) {
|
||||||
|
req.setError(true);
|
||||||
|
req.setErrorText("sign request failed: external PKI not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(ClientAPI_LogInfo loginfo) {
|
||||||
|
String text = loginfo.getText();
|
||||||
|
System.out.format("LOG: %s", text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void done(ClientAPI_Status status) {
|
||||||
|
System.out.format("DONE ClientAPI_Status: err=%b msg='%s'%n", status.getError(), status.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean socket_protect(int socket)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean pause_on_connection_timeout()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OpenVPNClientThread.TunBuilder tun_builder_new()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// TESTING_ONLY
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
// utility method to read a file and return as a String
|
||||||
|
public static String readFile(String filename) throws IOException {
|
||||||
|
return readStream(new FileInputStream(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String readStream(InputStream stream) throws IOException {
|
||||||
|
// No real need to close the BufferedReader/InputStreamReader
|
||||||
|
// as they're only wrapping the stream
|
||||||
|
try {
|
||||||
|
Reader reader = new BufferedReader(new InputStreamReader(stream));
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
char[] buffer = new char[4096];
|
||||||
|
int read;
|
||||||
|
while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
|
||||||
|
builder.append(buffer, 0, read);
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
} finally {
|
||||||
|
// Potential issue here: if this throws an IOException,
|
||||||
|
// it will mask any others. Normally I'd use a utility
|
||||||
|
// method which would log exceptions and swallow them
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, Client.ConfigError, Client.CredsUnspecifiedError {
|
||||||
|
if (args.length >= 1)
|
||||||
|
{
|
||||||
|
// load config file
|
||||||
|
String config = readFile(args[0]);
|
||||||
|
|
||||||
|
// get creds
|
||||||
|
String username = "";
|
||||||
|
String password = "";
|
||||||
|
if (args.length >= 3)
|
||||||
|
{
|
||||||
|
username = args[1];
|
||||||
|
password = args[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// instantiate client object
|
||||||
|
final Client client = new Client(config, username, password);
|
||||||
|
|
||||||
|
// catch signals
|
||||||
|
final Thread mainThread = Thread.currentThread();
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||||
|
public void run() {
|
||||||
|
client.stop();
|
||||||
|
try {
|
||||||
|
mainThread.join();
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// execute client session
|
||||||
|
client.connect();
|
||||||
|
|
||||||
|
// show stats before exit
|
||||||
|
client.show_stats();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("OpenVPN Java client");
|
||||||
|
System.err.println("Usage: java Client <client.ovpn> [username] [password]");
|
||||||
|
System.exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,359 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// package OPENVPN_PACKAGE
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
public class OpenVPNClientThread extends ClientAPI_OpenVPNClient implements Runnable {
|
||||||
|
private EventReceiver parent;
|
||||||
|
private TunBuilder tun_builder;
|
||||||
|
private Thread thread;
|
||||||
|
private ClientAPI_Status m_connect_status;
|
||||||
|
private boolean connect_called = false;
|
||||||
|
|
||||||
|
private int bytes_in_index = -1;
|
||||||
|
private int bytes_out_index = -1;
|
||||||
|
|
||||||
|
// thrown if instantiator attempts to call connect more than once
|
||||||
|
public static class ConnectCalledTwice extends RuntimeException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface EventReceiver {
|
||||||
|
// Called with events from core
|
||||||
|
void event(ClientAPI_Event event);
|
||||||
|
|
||||||
|
// Called with log text from core
|
||||||
|
void log(ClientAPI_LogInfo loginfo);
|
||||||
|
|
||||||
|
// Called when connect() thread exits
|
||||||
|
void done(ClientAPI_Status status);
|
||||||
|
|
||||||
|
// Called to "protect" a socket from being routed through the tunnel
|
||||||
|
boolean socket_protect(int socket);
|
||||||
|
|
||||||
|
// When a connection is close to timeout, the core will call this
|
||||||
|
// method. If it returns false, the core will disconnect with a
|
||||||
|
// CONNECTION_TIMEOUT event. If true, the core will enter a PAUSE
|
||||||
|
// state.
|
||||||
|
boolean pause_on_connection_timeout();
|
||||||
|
|
||||||
|
// Callback to construct a new tun builder
|
||||||
|
TunBuilder tun_builder_new();
|
||||||
|
|
||||||
|
// Callback to get a certificate
|
||||||
|
void external_pki_cert_request(ClientAPI_ExternalPKICertRequest req);
|
||||||
|
|
||||||
|
// Callback to sign data
|
||||||
|
void external_pki_sign_request(ClientAPI_ExternalPKISignRequest req);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface TunBuilder {
|
||||||
|
// Tun builder methods.
|
||||||
|
// Methods documented in openvpn/tun/builder/base.hpp
|
||||||
|
|
||||||
|
boolean tun_builder_set_remote_address(String address, boolean ipv6);
|
||||||
|
boolean tun_builder_add_address(String address, int prefix_length, String gateway, boolean ipv6, boolean net30);
|
||||||
|
boolean tun_builder_reroute_gw(boolean ipv4, boolean ipv6, long flags);
|
||||||
|
boolean tun_builder_add_route(String address, int prefix_length, boolean ipv6);
|
||||||
|
boolean tun_builder_exclude_route(String address, int prefix_length, boolean ipv6);
|
||||||
|
boolean tun_builder_add_dns_server(String address, boolean ipv6);
|
||||||
|
boolean tun_builder_add_search_domain(String domain);
|
||||||
|
boolean tun_builder_set_mtu(int mtu);
|
||||||
|
boolean tun_builder_set_session_name(String name);
|
||||||
|
int tun_builder_establish();
|
||||||
|
void tun_builder_teardown(boolean disconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenVPNClientThread() {
|
||||||
|
final int n = stats_n();
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
String name = stats_name(i);
|
||||||
|
if (name.equals("BYTES_IN"))
|
||||||
|
bytes_in_index = i;
|
||||||
|
if (name.equals("BYTES_OUT"))
|
||||||
|
bytes_out_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start connect session in worker thread
|
||||||
|
public void connect(EventReceiver parent_arg) {
|
||||||
|
if (connect_called)
|
||||||
|
throw new ConnectCalledTwice();
|
||||||
|
connect_called = true;
|
||||||
|
|
||||||
|
// direct client callbacks to parent
|
||||||
|
parent = parent_arg;
|
||||||
|
|
||||||
|
// clear status
|
||||||
|
m_connect_status = null;
|
||||||
|
|
||||||
|
// execute client in a worker thread
|
||||||
|
thread = new Thread(this, "OpenVPNClientThread");
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for worker thread to complete; to stop thread,
|
||||||
|
// first call super stop() method then wait_thread().
|
||||||
|
// This method will give the thread one second to
|
||||||
|
// exit and will abandon it after this time.
|
||||||
|
public void wait_thread_short() {
|
||||||
|
final int wait_millisecs = 5000; // max time that we will wait for thread to exit
|
||||||
|
Thread th = thread;
|
||||||
|
if (th != null) {
|
||||||
|
try {
|
||||||
|
th.join(wait_millisecs);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// thread failed to stop?
|
||||||
|
if (th.isAlive()) {
|
||||||
|
// abandon thread and deliver our own status object to instantiator.
|
||||||
|
ClientAPI_Status status = new ClientAPI_Status();
|
||||||
|
status.setError(true);
|
||||||
|
status.setMessage("CORE_THREAD_ABANDONED");
|
||||||
|
call_done(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for worker thread to complete; to stop thread,
|
||||||
|
// first call super stop() method then wait_thread().
|
||||||
|
// This method will wait forever for the thread to exit.
|
||||||
|
public void wait_thread_long() {
|
||||||
|
if (thread != null) {
|
||||||
|
boolean interrupted;
|
||||||
|
do {
|
||||||
|
interrupted = false;
|
||||||
|
try {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
interrupted = true;
|
||||||
|
super.stop(); // send thread a stop message
|
||||||
|
}
|
||||||
|
} while (interrupted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long bytes_in()
|
||||||
|
{
|
||||||
|
return super.stats_value(bytes_in_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long bytes_out()
|
||||||
|
{
|
||||||
|
return super.stats_value(bytes_out_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void call_done(ClientAPI_Status status)
|
||||||
|
{
|
||||||
|
EventReceiver p = finalize_thread(status);
|
||||||
|
if (p != null)
|
||||||
|
p.done(m_connect_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized EventReceiver finalize_thread(ClientAPI_Status connect_status)
|
||||||
|
{
|
||||||
|
EventReceiver p = parent;
|
||||||
|
if (p != null) {
|
||||||
|
// save thread connection status
|
||||||
|
m_connect_status = connect_status;
|
||||||
|
|
||||||
|
// disassociate client callbacks from parent
|
||||||
|
parent = null;
|
||||||
|
tun_builder = null;
|
||||||
|
thread = null;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runnable overrides
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Call out to core to start connection.
|
||||||
|
// Doesn't return until connection has terminated.
|
||||||
|
ClientAPI_Status status = super.connect();
|
||||||
|
call_done(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientAPI_OpenVPNClient (C++ class) overrides
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean socket_protect(int socket) {
|
||||||
|
EventReceiver p = parent;
|
||||||
|
if (p != null)
|
||||||
|
return p.socket_protect(socket);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean pause_on_connection_timeout() {
|
||||||
|
EventReceiver p = parent;
|
||||||
|
if (p != null)
|
||||||
|
return p.pause_on_connection_timeout();
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void event(ClientAPI_Event event) {
|
||||||
|
EventReceiver p = parent;
|
||||||
|
if (p != null)
|
||||||
|
p.event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(ClientAPI_LogInfo loginfo) {
|
||||||
|
EventReceiver p = parent;
|
||||||
|
if (p != null)
|
||||||
|
p.log(loginfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void external_pki_cert_request(ClientAPI_ExternalPKICertRequest req) {
|
||||||
|
EventReceiver p = parent;
|
||||||
|
if (p != null)
|
||||||
|
p.external_pki_cert_request(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void external_pki_sign_request(ClientAPI_ExternalPKISignRequest req) {
|
||||||
|
EventReceiver p = parent;
|
||||||
|
if (p != null)
|
||||||
|
p.external_pki_sign_request(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TunBuilderBase (C++ class) overrides
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_new() {
|
||||||
|
EventReceiver p = parent;
|
||||||
|
if (p != null) {
|
||||||
|
tun_builder = p.tun_builder_new();
|
||||||
|
return tun_builder != null;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_set_remote_address(String address, boolean ipv6) {
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_set_remote_address(address, ipv6);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_add_address(String address, int prefix_length, String gateway, boolean ipv6, boolean net30) {
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_add_address(address, prefix_length, gateway, ipv6, net30);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_reroute_gw(boolean ipv4, boolean ipv6, long flags) {
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_reroute_gw(ipv4, ipv6, flags);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_add_route(String address, int prefix_length, int metric, boolean ipv6) {
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_add_route(address, prefix_length, ipv6);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_exclude_route(String address, int prefix_length, int metric, boolean ipv6) {
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_exclude_route(address, prefix_length, ipv6);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_add_dns_server(String address, boolean ipv6) {
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_add_dns_server(address, ipv6);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_add_search_domain(String domain)
|
||||||
|
{
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_add_search_domain(domain);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_set_mtu(int mtu) {
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_set_mtu(mtu);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tun_builder_set_session_name(String name)
|
||||||
|
{
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_set_session_name(name);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int tun_builder_establish() {
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
return tb.tun_builder_establish();
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tun_builder_teardown(boolean disconnect) {
|
||||||
|
TunBuilder tb = tun_builder;
|
||||||
|
if (tb != null)
|
||||||
|
tb.tun_builder_teardown(disconnect);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#ifdef SWIGEXPORT
|
||||||
|
#define EXPORT SWIGEXPORT
|
||||||
|
#else
|
||||||
|
#define EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef OPENVPN_PACKAGE_ID
|
||||||
|
#error OPENVPN_PACKAGE_ID must be defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAKE_SYM2(pkg_id, suffix) Java_ ## pkg_id ## _CPUUsage_ ## suffix
|
||||||
|
#define MAKE_SYM(pkg_id, suffix) MAKE_SYM2(pkg_id, suffix)
|
||||||
|
|
||||||
|
#define CPU_USAGE MAKE_SYM(OPENVPN_PACKAGE_ID, cpu_1usage)
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
jdouble CPU_USAGE(JNIEnv* env, jclass);
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPORT jdouble CPU_USAGE(JNIEnv* env, jclass)
|
||||||
|
{
|
||||||
|
char fnbuf[64];
|
||||||
|
const pid_t pid = getpid();
|
||||||
|
double ret = 0.0;
|
||||||
|
|
||||||
|
snprintf(fnbuf, sizeof(fnbuf), "/proc/%u/stat", (unsigned int)pid);
|
||||||
|
FILE *fp = fopen(fnbuf, "r");
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
double user = 0.0;
|
||||||
|
double system = 0.0;
|
||||||
|
if (fscanf(fp, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %lf %lf", &user, &system) == 2)
|
||||||
|
ret = (user + system) / sysconf(_SC_CLK_TCK);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Native companion code for JellyBeanHack.java
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#ifdef SWIGEXPORT
|
||||||
|
#define EXPORT SWIGEXPORT
|
||||||
|
#else
|
||||||
|
#define EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef OPENVPN_PACKAGE_ID
|
||||||
|
#error OPENVPN_PACKAGE_ID must be defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAKE_SYM2(pkg_id, suffix) Java_ ## pkg_id ## _JellyBeanHack_ ## suffix
|
||||||
|
#define MAKE_SYM(pkg_id, suffix) MAKE_SYM2(pkg_id, suffix)
|
||||||
|
|
||||||
|
#define RSA_SIGN_INIT MAKE_SYM(OPENVPN_PACKAGE_ID, rsa_1sign_1init)
|
||||||
|
#define RSA_SIGN MAKE_SYM(OPENVPN_PACKAGE_ID, rsa_1sign)
|
||||||
|
#define PKEY_RETAIN MAKE_SYM(OPENVPN_PACKAGE_ID, pkey_1retain)
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
jint RSA_SIGN_INIT(JNIEnv* env, jclass);
|
||||||
|
jbyteArray RSA_SIGN(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef);
|
||||||
|
void PKEY_RETAIN(JNIEnv* env, jclass, jint pkeyRef);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void *RSA;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NID_md5_sha1=114,
|
||||||
|
CRYPTO_LOCK_EVP_PKEY=10,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EVP_PKEY
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
int save_type;
|
||||||
|
int references;
|
||||||
|
void *ameth;
|
||||||
|
void *engine;
|
||||||
|
union {
|
||||||
|
RSA *rsa;
|
||||||
|
} pkey;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*RSA_size_func_t)(const RSA *);
|
||||||
|
|
||||||
|
typedef int (*RSA_sign_func_t)(int type, const unsigned char *m, unsigned int m_length,
|
||||||
|
unsigned char *sigret, unsigned int *siglen, RSA *rsa);
|
||||||
|
|
||||||
|
typedef void (*ERR_print_errors_fp_func_t)(FILE *fp);
|
||||||
|
|
||||||
|
typedef int (*CRYPTO_add_lock_func_t)(int *pointer, int amount, int type, const char *file, int line);
|
||||||
|
|
||||||
|
static bool initialized;
|
||||||
|
static RSA_size_func_t RSA_size;
|
||||||
|
static RSA_sign_func_t RSA_sign;
|
||||||
|
static ERR_print_errors_fp_func_t ERR_print_errors_fp;
|
||||||
|
static CRYPTO_add_lock_func_t CRYPTO_add_lock;
|
||||||
|
|
||||||
|
inline bool callbacks_defined()
|
||||||
|
{
|
||||||
|
return RSA_size != NULL
|
||||||
|
&& RSA_sign != NULL
|
||||||
|
&& ERR_print_errors_fp != NULL
|
||||||
|
&& CRYPTO_add_lock != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT jint RSA_SIGN_INIT(JNIEnv* env, jclass)
|
||||||
|
{
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
void *handle = dlopen("libcrypto.so", RTLD_NOW);
|
||||||
|
if (handle)
|
||||||
|
{
|
||||||
|
RSA_size = (RSA_size_func_t) dlsym(handle, "RSA_size");
|
||||||
|
RSA_sign = (RSA_sign_func_t) dlsym(handle, "RSA_sign");
|
||||||
|
ERR_print_errors_fp = (ERR_print_errors_fp_func_t) dlsym(handle, "ERR_print_errors_fp");
|
||||||
|
CRYPTO_add_lock = (CRYPTO_add_lock_func_t) dlsym(handle, "CRYPTO_add_lock");
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
return callbacks_defined();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jni_throw(JNIEnv* env, const char* className, const char* msg)
|
||||||
|
{
|
||||||
|
jclass exceptionClass = env->FindClass(className);
|
||||||
|
|
||||||
|
if (exceptionClass == NULL) {
|
||||||
|
// ClassNotFoundException now pending
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env->ThrowNew( exceptionClass, msg) != JNI_OK) {
|
||||||
|
// an exception, most likely OOM, will now be pending
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
env->DeleteLocalRef(exceptionClass);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT jbyteArray RSA_SIGN(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef)
|
||||||
|
{
|
||||||
|
if (!callbacks_defined())
|
||||||
|
{
|
||||||
|
jni_throw(env, "java/lang/NullPointerException", "rsa_sign: OpenSSL callbacks undefined");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
|
||||||
|
if (pkey == NULL || from == NULL)
|
||||||
|
{
|
||||||
|
jni_throw(env, "java/lang/NullPointerException", "rsa_sign: from/pkey is NULL");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jbyte* data = env->GetByteArrayElements(from, NULL);
|
||||||
|
if (data == NULL)
|
||||||
|
{
|
||||||
|
jni_throw(env, "java/lang/NullPointerException", "rsa_sign: data is NULL");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int datalen = env->GetArrayLength(from);
|
||||||
|
|
||||||
|
unsigned int siglen;
|
||||||
|
unsigned char* sigret = new unsigned char[(*RSA_size)(pkey->pkey.rsa)];
|
||||||
|
|
||||||
|
if ((*RSA_sign)(NID_md5_sha1, (unsigned char*) data, datalen,
|
||||||
|
sigret, &siglen, pkey->pkey.rsa) <= 0)
|
||||||
|
{
|
||||||
|
jni_throw(env, "java/security/InvalidKeyException", "OpenSSL RSA_sign failed");
|
||||||
|
(*ERR_print_errors_fp)(stderr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jbyteArray jb = env->NewByteArray(siglen);
|
||||||
|
env->SetByteArrayRegion(jb, 0, siglen, (jbyte *)sigret);
|
||||||
|
delete [] sigret;
|
||||||
|
return jb;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT void PKEY_RETAIN(JNIEnv* env, jclass, jint pkeyRef)
|
||||||
|
{
|
||||||
|
EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
|
||||||
|
if (pkey && CRYPTO_add_lock)
|
||||||
|
{
|
||||||
|
const int newref = (*CRYPTO_add_lock)(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY, __FILE__, __LINE__);
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, "openvpn", "pkey_retain ref=%d", newref);
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+126
@@ -0,0 +1,126 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# generate expire time in python: time.mktime((2012, 5, 1, 0, 0, 0, 0, 0, -1))
|
||||||
|
# -DAPP_EXPIRE_TIME=1364796000 \
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $O3/core
|
||||||
|
. vars/android-sdk-path
|
||||||
|
cd javacli
|
||||||
|
git clean -q -fXd .
|
||||||
|
|
||||||
|
if [ "$PKG" ]; then
|
||||||
|
pkg=$PKG
|
||||||
|
pkg_id_def="-DOPENVPN_PACKAGE_ID=${PKG//./_}"
|
||||||
|
else
|
||||||
|
pkg=net.openvpn.openvpn
|
||||||
|
pkg_id_def="-DOPENVPN_PACKAGE_ID=net_openvpn_openvpn"
|
||||||
|
fi
|
||||||
|
echo PACKAGE $PKG
|
||||||
|
|
||||||
|
if [ "$PT_PROXY" = "1" ] && [ -d "$O3/common" ]; then
|
||||||
|
common="-I$O3/common -DPRIVATE_TUNNEL_PROXY"
|
||||||
|
else
|
||||||
|
common=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo SWIG
|
||||||
|
swig -c++ -java -package $pkg -I$O3/core/client -I$O3/core ovpncli.i
|
||||||
|
|
||||||
|
TARGETS=${TARGETS:-android-a7a android-a8a android-x86}
|
||||||
|
|
||||||
|
for TARGET in $TARGETS; do
|
||||||
|
|
||||||
|
if [ "$DEBUG_BUILD" = "1" ]; then
|
||||||
|
. ../vars/vars-${TARGET}-dbg
|
||||||
|
vis1=""
|
||||||
|
vis2=""
|
||||||
|
opt2="$pkg_id_def $LIB_OPT_LEVEL"
|
||||||
|
else
|
||||||
|
. ../vars/vars-${TARGET}
|
||||||
|
vis1="-fvisibility=hidden"
|
||||||
|
vis2='-DSWIGEXPORT=__attribute__((visibility("default")))'
|
||||||
|
opt2="$pkg_id_def -Os"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$OPENSSL" = "1" ]; then
|
||||||
|
ssl_def="-DUSE_OPENSSL"
|
||||||
|
ssl_inc="-I$DEP_DIR/openssl/openssl-$PLATFORM/include"
|
||||||
|
ssl_lib="-lssl -lcrypto"
|
||||||
|
ssl_libdir="-L$DEP_DIR/openssl/openssl-$PLATFORM/lib"
|
||||||
|
else
|
||||||
|
ssl_def="-DUSE_MBEDTLS"
|
||||||
|
ssl_inc="-I$DEP_DIR/mbedtls/mbedtls-$PLATFORM/include"
|
||||||
|
ssl_lib="-lmbedtls"
|
||||||
|
ssl_libdir="-L$DEP_DIR/mbedtls/mbedtls-$PLATFORM/library"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$GPP_CMD" ] && GPP_CMD=g++
|
||||||
|
|
||||||
|
echo CORE $ABI
|
||||||
|
$GPP_CMD \
|
||||||
|
$CXX_COMPILER_FLAGS \
|
||||||
|
$PLATFORM_FLAGS \
|
||||||
|
$OTHER_COMPILER_FLAGS \
|
||||||
|
$LIB_OPT_LEVEL $LIB_FPIC \
|
||||||
|
-Wall -Wno-sign-compare -Wno-unused-parameter \
|
||||||
|
-Wno-unused-local-typedefs \
|
||||||
|
$vis1 \
|
||||||
|
$ssl_def \
|
||||||
|
-DUSE_ASIO \
|
||||||
|
-DASIO_STANDALONE \
|
||||||
|
-DASIO_NO_DEPRECATED \
|
||||||
|
-DHAVE_LZ4 \
|
||||||
|
-DOPENVPN_USE_TLS_MD5 \
|
||||||
|
-DASIO_HAS_STD_STRING_VIEW \
|
||||||
|
-I$O3/core/client \
|
||||||
|
-I$O3/core \
|
||||||
|
$common \
|
||||||
|
-I$DEP_DIR/asio/asio/include \
|
||||||
|
$ssl_inc \
|
||||||
|
-I$DEP_DIR/lz4/lz4-$PLATFORM/include \
|
||||||
|
-c $O3/core/client/ovpncli.cpp
|
||||||
|
|
||||||
|
echo WRAP $ABI
|
||||||
|
$GPP_CMD \
|
||||||
|
$CXX_COMPILER_FLAGS \
|
||||||
|
$PLATFORM_FLAGS \
|
||||||
|
$OTHER_COMPILER_FLAGS \
|
||||||
|
$opt2 $LIB_FPIC \
|
||||||
|
-fno-strict-aliasing \
|
||||||
|
-Wall \
|
||||||
|
$vis1 $vis2 \
|
||||||
|
-I$O3/core/client \
|
||||||
|
-I$O3/core \
|
||||||
|
$common \
|
||||||
|
$ssl_libdir \
|
||||||
|
-L$DEP_DIR/lz4/lz4-$PLATFORM/lib \
|
||||||
|
ovpncli_wrap.cxx \
|
||||||
|
android/jellybean_hack.cpp \
|
||||||
|
android/cpu.cpp \
|
||||||
|
ovpncli.o \
|
||||||
|
-o libovpncli.so \
|
||||||
|
-shared -Wl,-soname,libovpncli.so \
|
||||||
|
$ssl_lib \
|
||||||
|
-llz4 \
|
||||||
|
-llog
|
||||||
|
|
||||||
|
if [ "$DEBUG_BUILD" != "1" ]; then
|
||||||
|
echo STRIP $ABI
|
||||||
|
strip libovpncli.so
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p build/libs/$ABI
|
||||||
|
mv libovpncli.so build/libs/$ABI/
|
||||||
|
rm ovpncli.o
|
||||||
|
done
|
||||||
|
|
||||||
|
mv ovpncli_wrap.cxx ovpncli_wrap.h ovpncli.java ovpncliJNI.java SWIGTYPE_*.java ClientAPI_*.java build/
|
||||||
|
git clean -q -fX .
|
||||||
|
|
||||||
|
tar -czf android-core-build.tgz build
|
||||||
|
mv android-core-build.tgz $O3/
|
||||||
Executable
+95
@@ -0,0 +1,95 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Build OpenVPN 3 core on Linux as a callable module from Java:
|
||||||
|
#
|
||||||
|
# ./build-linux
|
||||||
|
# java -Djava.library.path=. Main profile.ovpn
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -z "$O3" ]; then
|
||||||
|
echo O3 var must point to ovpn3 tree
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET=linux
|
||||||
|
JINC="-I/usr/local/java/jdk1.7.0_55/include -I/usr/local/java/jdk1.7.0_55/include/linux"
|
||||||
|
|
||||||
|
cd $O3/core/javacli
|
||||||
|
git clean -q -fXd .
|
||||||
|
git clean -q -fd .
|
||||||
|
|
||||||
|
if [ "$DEBUG_BUILD" = "1" ]; then
|
||||||
|
. $O3/core/vars/vars-${TARGET}-dbg
|
||||||
|
vis1=""
|
||||||
|
vis2=""
|
||||||
|
opt2="$pkg_id_def $LIB_OPT_LEVEL"
|
||||||
|
else
|
||||||
|
. $O3/core/vars/vars-${TARGET}
|
||||||
|
vis1="-fvisibility=hidden"
|
||||||
|
vis2='-DSWIGEXPORT=__attribute__((visibility("default")))'
|
||||||
|
opt2="$pkg_id_def -Os"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$OPENSSL" = "1" ]; then
|
||||||
|
ssl_def="-DUSE_OPENSSL"
|
||||||
|
ssl_inc="-I$DEP_DIR/openssl/openssl-$PLATFORM/include"
|
||||||
|
ssl_lib="-lssl -lcrypto"
|
||||||
|
ssl_libdir="-L$DEP_DIR/openssl/openssl-$PLATFORM/lib"
|
||||||
|
else
|
||||||
|
ssl_def="-DUSE_MBEDTLS"
|
||||||
|
ssl_inc="-I$DEP_DIR/mbedtls/mbedtls-$PLATFORM/include"
|
||||||
|
ssl_lib="-lmbedtls"
|
||||||
|
ssl_libdir="-L$DEP_DIR/mbedtls/mbedtls-$PLATFORM/library"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo SWIG
|
||||||
|
swig -c++ -java -I$O3/core/client -I$O3/core ovpncli.i
|
||||||
|
|
||||||
|
echo JAVA
|
||||||
|
javac *.java
|
||||||
|
|
||||||
|
echo CORE
|
||||||
|
g++ \
|
||||||
|
$CXX_COMPILER_FLAGS \
|
||||||
|
$PLATFORM_FLAGS \
|
||||||
|
$LIB_OPT_LEVEL $LIB_FPIC \
|
||||||
|
-Wall -Werror -Wno-sign-compare -Wno-unused-parameter \
|
||||||
|
-Wno-unused-local-typedefs \
|
||||||
|
$vis1 \
|
||||||
|
$ssl_def \
|
||||||
|
-DUSE_ASIO \
|
||||||
|
-DASIO_STANDALONE \
|
||||||
|
-DASIO_NO_DEPRECATED \
|
||||||
|
-DHAVE_LZ4 \
|
||||||
|
-I$O3/core/client \
|
||||||
|
-I$O3/core \
|
||||||
|
-I$DEP_DIR/asio/asio/include \
|
||||||
|
$ssl_inc \
|
||||||
|
-I$DEP_DIR/lz4/lz4-$PLATFORM/include \
|
||||||
|
-c $O3/core/client/ovpncli.cpp
|
||||||
|
|
||||||
|
echo WRAP
|
||||||
|
g++ \
|
||||||
|
$CXX_COMPILER_FLAGS \
|
||||||
|
$PLATFORM_FLAGS \
|
||||||
|
$opt2 $LIB_FPIC \
|
||||||
|
-fno-strict-aliasing \
|
||||||
|
-Wall -Werror \
|
||||||
|
$vis1 $vis2 \
|
||||||
|
-I$O3/core/client \
|
||||||
|
-I$O3/core \
|
||||||
|
$JINC \
|
||||||
|
$ssl_libdir \
|
||||||
|
-L$DEP_DIR/lz4/lz4-$PLATFORM/lib \
|
||||||
|
ovpncli_wrap.cxx \
|
||||||
|
ovpncli.o \
|
||||||
|
-o libovpncli.so \
|
||||||
|
-shared -Wl,-soname,libovpncli.so \
|
||||||
|
$ssl_lib \
|
||||||
|
-llz4
|
||||||
|
|
||||||
|
if [ "$DEBUG_BUILD" != "1" ]; then
|
||||||
|
echo STRIP $ABI
|
||||||
|
strip libovpncli.so
|
||||||
|
fi
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// SWIG interface file for OpenVPN client
|
||||||
|
|
||||||
|
// enable director feature for OpenVPNClientBase virtual method callbacks
|
||||||
|
%module(directors="1") ovpncli
|
||||||
|
%feature("director") OpenVPNClient;
|
||||||
|
|
||||||
|
%include "std_string.i" // for std::string typemaps
|
||||||
|
%include "std_vector.i"
|
||||||
|
|
||||||
|
// top-level C++ implementation file
|
||||||
|
%{
|
||||||
|
#include "ovpncli.hpp"
|
||||||
|
%}
|
||||||
|
|
||||||
|
// ignore these ClientAPI::OpenVPNClient bases
|
||||||
|
%ignore openvpn::ClientAPI::LogReceiver;
|
||||||
|
%ignore openvpn::ExternalTun::Factory;
|
||||||
|
%ignore openvpn::ExternalTransport::Factory;
|
||||||
|
|
||||||
|
// modify exported C++ class names to incorporate their enclosing namespace
|
||||||
|
%rename(ClientAPI_OpenVPNClient) OpenVPNClient;
|
||||||
|
%rename(ClientAPI_TunBuilderBase) TunBuilderBase;
|
||||||
|
%rename(ClientAPI_ExternalPKIBase) ExternalPKIBase;
|
||||||
|
%rename(ClientAPI_ServerEntry) ServerEntry;
|
||||||
|
%rename(ClientAPI_EvalConfig) EvalConfig;
|
||||||
|
%rename(ClientAPI_ProvideCreds) ProvideCreds;
|
||||||
|
%rename(ClientAPI_SessionToken) SessionToken;
|
||||||
|
%rename(ClientAPI_DynamicChallenge) DynamicChallenge;
|
||||||
|
%rename(ClientAPI_KeyValue) KeyValue;
|
||||||
|
%rename(ClientAPI_Config) Config;
|
||||||
|
%rename(ClientAPI_Event) Event;
|
||||||
|
%rename(ClientAPI_ConnectionInfo) ConnectionInfo;
|
||||||
|
%rename(ClientAPI_Status) Status;
|
||||||
|
%rename(ClientAPI_LogInfo) LogInfo;
|
||||||
|
%rename(ClientAPI_InterfaceStats) InterfaceStats;
|
||||||
|
%rename(ClientAPI_TransportStats) TransportStats;
|
||||||
|
%rename(ClientAPI_MergeConfig) MergeConfig;
|
||||||
|
%rename(ClientAPI_ExternalPKIRequestBase) ExternalPKIRequestBase;
|
||||||
|
%rename(ClientAPI_ExternalPKICertRequest) ExternalPKICertRequest;
|
||||||
|
%rename(ClientAPI_ExternalPKISignRequest) ExternalPKISignRequest;
|
||||||
|
%rename(ClientAPI_RemoteOverride) RemoteOverride;
|
||||||
|
|
||||||
|
// declare vectors
|
||||||
|
namespace std {
|
||||||
|
%template(ClientAPI_ServerEntryVector) vector<openvpn::ClientAPI::ServerEntry>;
|
||||||
|
%template(ClientAPI_LLVector) vector<long long>;
|
||||||
|
%template(ClientAPI_StringVec) vector<string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// interface to be bridged between C++ and target language
|
||||||
|
%include "openvpn/pki/epkibase.hpp"
|
||||||
|
%include "openvpn/tun/builder/base.hpp"
|
||||||
|
%import "openvpn/tun/extern/fw.hpp" // ignored
|
||||||
|
%import "openvpn/transport/client/extern/fw.hpp" // ignored
|
||||||
|
%include "ovpncli.hpp"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
**/xcuserdata/
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 48;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
DF380AE2201F0A2F0003272D /* cli.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF380AE1201F0A2F0003272D /* cli.cpp */; };
|
||||||
|
DF380AE5201F0D4F0003272D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF380AE4201F0D4F0003272D /* CoreFoundation.framework */; };
|
||||||
|
DF380AE7201F0D910003272D /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF380AE6201F0D910003272D /* SystemConfiguration.framework */; };
|
||||||
|
DF380AE9201F0DB80003272D /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF380AE8201F0DB80003272D /* IOKit.framework */; };
|
||||||
|
DF380AEB201F0DDC0003272D /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF380AEA201F0DDC0003272D /* CoreServices.framework */; };
|
||||||
|
DF380AED201F0E0E0003272D /* libmbedtls.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DF380AEC201F0E0E0003272D /* libmbedtls.a */; };
|
||||||
|
DF838B412090AC2F00B68F90 /* liblz4.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DF838B402090AC2F00B68F90 /* liblz4.a */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
DF380AD4201F07AE0003272D /* CopyFiles */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = /usr/share/man/man1/;
|
||||||
|
dstSubfolderSpec = 0;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 1;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
DF380AD6201F07AE0003272D /* ovpn3-core */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "ovpn3-core"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
DF380AE0201F09B70003272D /* openvpn */ = {isa = PBXFileReference; lastKnownFileType = folder; name = openvpn; path = ../../../openvpn; sourceTree = "<group>"; };
|
||||||
|
DF380AE1201F0A2F0003272D /* cli.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cli.cpp; path = ../../../test/ovpncli/cli.cpp; sourceTree = "<group>"; };
|
||||||
|
DF380AE4201F0D4F0003272D /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
|
||||||
|
DF380AE6201F0D910003272D /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
|
||||||
|
DF380AE8201F0DB80003272D /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||||
|
DF380AEA201F0DDC0003272D /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
|
||||||
|
DF380AEC201F0E0E0003272D /* libmbedtls.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmbedtls.a; path = "../../../deps/mbedtls/mbedtls-osx/library/libmbedtls.a"; sourceTree = "<group>"; };
|
||||||
|
DF838B402090AC2F00B68F90 /* liblz4.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblz4.a; path = "../../../deps/lz4/lz4-osx/lib/liblz4.a"; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
DF380AD3201F07AE0003272D /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
DF838B412090AC2F00B68F90 /* liblz4.a in Frameworks */,
|
||||||
|
DF380AED201F0E0E0003272D /* libmbedtls.a in Frameworks */,
|
||||||
|
DF380AEB201F0DDC0003272D /* CoreServices.framework in Frameworks */,
|
||||||
|
DF380AE9201F0DB80003272D /* IOKit.framework in Frameworks */,
|
||||||
|
DF380AE7201F0D910003272D /* SystemConfiguration.framework in Frameworks */,
|
||||||
|
DF380AE5201F0D4F0003272D /* CoreFoundation.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
DF380ACD201F07AE0003272D = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DF380AD8201F07AE0003272D /* ovpn3-core */,
|
||||||
|
DF380AD7201F07AE0003272D /* Products */,
|
||||||
|
DF380AE3201F0D4F0003272D /* Frameworks */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
DF380AD7201F07AE0003272D /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DF380AD6201F07AE0003272D /* ovpn3-core */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
DF380AD8201F07AE0003272D /* ovpn3-core */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DF380AE1201F0A2F0003272D /* cli.cpp */,
|
||||||
|
DF380AE0201F09B70003272D /* openvpn */,
|
||||||
|
);
|
||||||
|
path = "ovpn3-core";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
DF380AE3201F0D4F0003272D /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DF838B402090AC2F00B68F90 /* liblz4.a */,
|
||||||
|
DF380AEC201F0E0E0003272D /* libmbedtls.a */,
|
||||||
|
DF380AEA201F0DDC0003272D /* CoreServices.framework */,
|
||||||
|
DF380AE8201F0DB80003272D /* IOKit.framework */,
|
||||||
|
DF380AE6201F0D910003272D /* SystemConfiguration.framework */,
|
||||||
|
DF380AE4201F0D4F0003272D /* CoreFoundation.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
DF380AD5201F07AE0003272D /* ovpn3-core */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = DF380ADD201F07AE0003272D /* Build configuration list for PBXNativeTarget "ovpn3-core" */;
|
||||||
|
buildPhases = (
|
||||||
|
DF380AD2201F07AE0003272D /* Sources */,
|
||||||
|
DF380AD3201F07AE0003272D /* Frameworks */,
|
||||||
|
DF380AD4201F07AE0003272D /* CopyFiles */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = "ovpn3-core";
|
||||||
|
productName = "ovpn3-core";
|
||||||
|
productReference = DF380AD6201F07AE0003272D /* ovpn3-core */;
|
||||||
|
productType = "com.apple.product-type.tool";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
DF380ACE201F07AE0003272D /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 0920;
|
||||||
|
ORGANIZATIONNAME = "Lev Stipakov";
|
||||||
|
TargetAttributes = {
|
||||||
|
DF380AD5201F07AE0003272D = {
|
||||||
|
CreatedOnToolsVersion = 9.2;
|
||||||
|
ProvisioningStyle = Automatic;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = DF380AD1201F07AE0003272D /* Build configuration list for PBXProject "ovpn3-core" */;
|
||||||
|
compatibilityVersion = "Xcode 8.0";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
);
|
||||||
|
mainGroup = DF380ACD201F07AE0003272D;
|
||||||
|
productRefGroup = DF380AD7201F07AE0003272D /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
DF380AD5201F07AE0003272D /* ovpn3-core */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
DF380AD2201F07AE0003272D /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
DF380AE2201F0A2F0003272D /* cli.cpp in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
DF380ADB201F07AE0003272D /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
DF380ADC201F07AE0003272D /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
DF380ADE201F07AE0003272D /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
USE_ASIO,
|
||||||
|
ASIO_STANDALONE,
|
||||||
|
USE_MBEDTLS,
|
||||||
|
HAVE_LZ4,
|
||||||
|
LZ4_DISABLE_DEPRECATE_WARNINGS,
|
||||||
|
);
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"\"$(SRCROOT)/../..\"",
|
||||||
|
"\"$(SRCROOT)/../../../deps/asio/asio/include\"",
|
||||||
|
"\"$(SRCROOT)/../../../deps/mbedtls/mbedtls-osx/include\"",
|
||||||
|
"\"$(SRCROOT)/../../../deps/lz4/lz4-osx/include\"",
|
||||||
|
);
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"\"$(SRCROOT)/../../../deps/mbedtls/mbedtls-osx/library\"",
|
||||||
|
"\"$(SRCROOT)/../../../deps/lz4/lz4-osx/lib\"",
|
||||||
|
);
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
STRINGS_FILE_OUTPUT_ENCODING = "UTF-8";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
DF380ADF201F07AE0003272D /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
USE_ASIO,
|
||||||
|
ASIO_STANDALONE,
|
||||||
|
USE_MBEDTLS,
|
||||||
|
HAVE_LZ4,
|
||||||
|
LZ4_DISABLE_DEPRECATE_WARNINGS,
|
||||||
|
);
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"\"$(SRCROOT)/../..\"",
|
||||||
|
"\"$(SRCROOT)/../../../deps/asio/asio/include\"",
|
||||||
|
"\"$(SRCROOT)/../../../deps/mbedtls/mbedtls-osx/include\"",
|
||||||
|
"\"$(SRCROOT)/../../../deps/lz4/lz4-osx/include\"",
|
||||||
|
);
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"\"$(SRCROOT)/../../../deps/mbedtls/mbedtls-osx/library\"",
|
||||||
|
"\"$(SRCROOT)/../../../deps/lz4/lz4-osx/lib\"",
|
||||||
|
);
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
STRINGS_FILE_OUTPUT_ENCODING = "UTF-8";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
DF380AD1201F07AE0003272D /* Build configuration list for PBXProject "ovpn3-core" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
DF380ADB201F07AE0003272D /* Debug */,
|
||||||
|
DF380ADC201F07AE0003272D /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
DF380ADD201F07AE0003272D /* Build configuration list for PBXNativeTarget "ovpn3-core" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
DF380ADE201F07AE0003272D /* Debug */,
|
||||||
|
DF380ADF201F07AE0003272D /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = DF380ACE201F07AE0003272D /* Project object */;
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:ovpn3-core.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef OPENVPN_ADDR_ADDRLIST_H
|
||||||
|
#define OPENVPN_ADDR_ADDRLIST_H
|
||||||
|
|
||||||
|
#include <openvpn/common/rc.hpp>
|
||||||
|
#include <openvpn/addr/ip.hpp>
|
||||||
|
|
||||||
|
namespace openvpn {
|
||||||
|
namespace IP {
|
||||||
|
|
||||||
|
// A list of unique IP addresses
|
||||||
|
class AddrList : public std::vector<IP::Addr>, public RC<thread_unsafe_refcount>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef RCPtr<AddrList> Ptr;
|
||||||
|
|
||||||
|
void add(const IP::Addr& a)
|
||||||
|
{
|
||||||
|
if (!exists(a))
|
||||||
|
push_back(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exists(const IP::Addr& a) const
|
||||||
|
{
|
||||||
|
for (const_iterator i = begin(); i != end(); ++i)
|
||||||
|
{
|
||||||
|
if (a == *i)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void dump() const
|
||||||
|
{
|
||||||
|
OPENVPN_LOG("******* AddrList::dump");
|
||||||
|
for (const_iterator i = begin(); i != end(); ++i)
|
||||||
|
OPENVPN_LOG(i->to_string());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef OPENVPN_ADDR_ADDRPAIR_H
|
||||||
|
#define OPENVPN_ADDR_ADDRPAIR_H
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <openvpn/common/exception.hpp>
|
||||||
|
#include <openvpn/common/number.hpp>
|
||||||
|
#include <openvpn/common/split.hpp>
|
||||||
|
#include <openvpn/addr/ip.hpp>
|
||||||
|
|
||||||
|
namespace openvpn {
|
||||||
|
namespace IP {
|
||||||
|
|
||||||
|
// AddrMaskPair is basically an object that combines an IP address (v4 or v6)
|
||||||
|
// with a netmask or prefix length.
|
||||||
|
struct AddrMaskPair
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OPENVPN_EXCEPTION(addr_pair_mask_parse_error);
|
||||||
|
|
||||||
|
class StringPair {
|
||||||
|
public:
|
||||||
|
OPENVPN_SIMPLE_EXCEPTION(addr_pair_string_error);
|
||||||
|
|
||||||
|
StringPair()
|
||||||
|
: size_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit StringPair(const std::string& s1)
|
||||||
|
: size_(1)
|
||||||
|
{
|
||||||
|
data[0] = s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit StringPair(const std::string& s1, const std::string& s2)
|
||||||
|
: size_(2)
|
||||||
|
{
|
||||||
|
data[0] = s1;
|
||||||
|
data[1] = s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(const std::string& s)
|
||||||
|
{
|
||||||
|
if (size_ < 2)
|
||||||
|
data[size_++] = s;
|
||||||
|
else
|
||||||
|
throw addr_pair_string_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& operator[](const size_t i) const
|
||||||
|
{
|
||||||
|
if (i >= 2)
|
||||||
|
throw addr_pair_string_error();
|
||||||
|
return data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string& operator[](const size_t i)
|
||||||
|
{
|
||||||
|
if (i >= 2)
|
||||||
|
throw addr_pair_string_error();
|
||||||
|
return data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const { return size_; }
|
||||||
|
|
||||||
|
std::string render() const
|
||||||
|
{
|
||||||
|
switch (size_)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return data[0];
|
||||||
|
case 2:
|
||||||
|
return data[0] + "/" + data[1];
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string data[2];
|
||||||
|
unsigned int size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
static AddrMaskPair from_string(const std::string& s1, const std::string& s2, const char *title = nullptr)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (s2.empty())
|
||||||
|
{
|
||||||
|
const StringPair pair = Split::by_char<StringPair, NullLex, Split::NullLimit>(s1, '/');
|
||||||
|
return from_string_impl(pair, title);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const StringPair pair(s1, s2);
|
||||||
|
return from_string_impl(pair, title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
const StringPair pair(s1, s2);
|
||||||
|
error(e, pair.render(), title);
|
||||||
|
}
|
||||||
|
return AddrMaskPair(); // NOTREACHED
|
||||||
|
}
|
||||||
|
|
||||||
|
static AddrMaskPair from_string(const std::string& s, const char *title = nullptr)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
const StringPair pair = Split::by_char<StringPair, NullLex, Split::NullLimit>(s, '/');
|
||||||
|
return from_string_impl(pair, title);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
error(e, s, title);
|
||||||
|
}
|
||||||
|
return AddrMaskPair(); // NOTREACHED
|
||||||
|
}
|
||||||
|
|
||||||
|
static AddrMaskPair from_string(const StringPair& pair, const char *title = nullptr)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return from_string_impl(pair, title);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
error(e, pair.render(), title);
|
||||||
|
}
|
||||||
|
return AddrMaskPair(); // NOTREACHED
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(const bool netmask_form=false) const
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
if (netmask_form)
|
||||||
|
os << addr.to_string() << '/' << netmask.to_string();
|
||||||
|
else
|
||||||
|
os << addr.to_string() << '/' << netmask.prefix_len();
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_canonical() const
|
||||||
|
{
|
||||||
|
return (addr & netmask) == addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr::Version version() const
|
||||||
|
{
|
||||||
|
const Addr::Version v1 = addr.version();
|
||||||
|
const Addr::Version v2 = netmask.version();
|
||||||
|
if (v1 == v2)
|
||||||
|
return v1;
|
||||||
|
else
|
||||||
|
return Addr::UNSPEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr addr;
|
||||||
|
Addr netmask;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void error(const std::exception& e, const std::string& s, const char *title)
|
||||||
|
{
|
||||||
|
if (!title)
|
||||||
|
title = "";
|
||||||
|
OPENVPN_THROW(addr_pair_mask_parse_error, "AddrMaskPair parse error '" << title << "': " << s << " : " << e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
static AddrMaskPair from_string_impl(const StringPair& pair, const char *title = nullptr)
|
||||||
|
{
|
||||||
|
AddrMaskPair ret;
|
||||||
|
if (pair.size() == 1 || pair.size() == 2)
|
||||||
|
{
|
||||||
|
ret.addr = Addr::from_string(pair[0], title);
|
||||||
|
if (pair.size() == 2 && !pair[1].empty())
|
||||||
|
{
|
||||||
|
if (is_number(pair[1].c_str()))
|
||||||
|
ret.netmask = Addr::netmask_from_prefix_len(ret.addr.version(),
|
||||||
|
parse_number_throw<unsigned int>(pair[1], "prefix length"));
|
||||||
|
else
|
||||||
|
ret.netmask = Addr::from_string(pair[1]);
|
||||||
|
ret.netmask.prefix_len(); // verify that netmask is ok
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret.netmask = Addr::from_zero_complement(ret.addr.version());
|
||||||
|
ret.addr.verify_version_consistency(ret.netmask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw addr_pair_mask_parse_error("only one or two address terms allowed");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
OPENVPN_OSTREAM(AddrMaskPair, to_string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Invert a route list. Used to support excluded routes on platforms that
|
||||||
|
// don't support them natively.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <openvpn/common/exception.hpp>
|
||||||
|
#include <openvpn/addr/route.hpp>
|
||||||
|
|
||||||
|
namespace openvpn {
|
||||||
|
namespace IP {
|
||||||
|
class AddressSpaceSplitter : public RouteList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OPENVPN_EXCEPTION(address_space_splitter);
|
||||||
|
|
||||||
|
AddressSpaceSplitter() {}
|
||||||
|
|
||||||
|
// NOTE: when passing AddressSpaceSplitter to this constructor, make sure
|
||||||
|
// to static_cast it to RouteList& so as to avoid matching the
|
||||||
|
// default copy constructor.
|
||||||
|
explicit AddressSpaceSplitter(const RouteList& in)
|
||||||
|
: AddressSpaceSplitter(in, in.version_mask())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressSpaceSplitter(const RouteList& in, const Addr::VersionMask vermask)
|
||||||
|
{
|
||||||
|
in.verify_canonical();
|
||||||
|
if (vermask & Addr::V4_MASK)
|
||||||
|
descend(in, Route(Addr::from_zero(Addr::V4), 0));
|
||||||
|
if (vermask & Addr::V6_MASK)
|
||||||
|
descend(in, Route(Addr::from_zero(Addr::V6), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum Type {
|
||||||
|
EQUAL,
|
||||||
|
SUBROUTE,
|
||||||
|
LEAF,
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* This method construct a non-overlapping list of routes spanning the address
|
||||||
|
* space in @param route. The routes are constructed in a way that each
|
||||||
|
* route in the returned list is smaller or equalto each route in
|
||||||
|
* parameter @param in
|
||||||
|
*
|
||||||
|
* @param route The route we currently are looking at and split if it does
|
||||||
|
* not meet the requirements
|
||||||
|
*/
|
||||||
|
void descend(const RouteList& in, const Route& route)
|
||||||
|
{
|
||||||
|
switch (find(in, route))
|
||||||
|
{
|
||||||
|
case SUBROUTE:
|
||||||
|
{
|
||||||
|
Route r1, r2;
|
||||||
|
if (route.split(r1, r2))
|
||||||
|
{
|
||||||
|
descend(in, r1);
|
||||||
|
descend(in, r2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
push_back(route);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EQUAL:
|
||||||
|
case LEAF:
|
||||||
|
push_back(route);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Type find(const RouteList& in, const Route& route)
|
||||||
|
{
|
||||||
|
Type type = LEAF;
|
||||||
|
for (RouteList::const_iterator i = in.begin(); i != in.end(); ++i)
|
||||||
|
{
|
||||||
|
const Route& r = *i;
|
||||||
|
if (route == r)
|
||||||
|
type = EQUAL;
|
||||||
|
else if (route.contains(r))
|
||||||
|
return SUBROUTE;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,992 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef OPENVPN_ADDR_IP_H
|
||||||
|
#define OPENVPN_ADDR_IP_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cstring> // for std::memset
|
||||||
|
|
||||||
|
#include <openvpn/io/io.hpp>
|
||||||
|
|
||||||
|
#include <openvpn/common/size.hpp>
|
||||||
|
#include <openvpn/common/exception.hpp>
|
||||||
|
#include <openvpn/common/ostream.hpp>
|
||||||
|
#include <openvpn/common/hash.hpp>
|
||||||
|
#include <openvpn/addr/ipv4.hpp>
|
||||||
|
#include <openvpn/addr/ipv6.hpp>
|
||||||
|
#include <openvpn/addr/iperr.hpp>
|
||||||
|
|
||||||
|
namespace openvpn {
|
||||||
|
// This is our fundamental IP address class that handles IPv4 or IPv6
|
||||||
|
// IP addresses. It is implemented as a discriminated union of IPv4::Addr
|
||||||
|
// and IPv6::Addr.
|
||||||
|
namespace IP {
|
||||||
|
|
||||||
|
OPENVPN_EXCEPTION(ip_exception);
|
||||||
|
|
||||||
|
class Addr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Version { UNSPEC, V4, V6 };
|
||||||
|
|
||||||
|
enum { V4_MASK=(1<<0), V6_MASK=(1<<1) };
|
||||||
|
typedef unsigned int VersionMask;
|
||||||
|
|
||||||
|
enum VersionSize {
|
||||||
|
V4_SIZE = IPv4::Addr::SIZE,
|
||||||
|
V6_SIZE = IPv6::Addr::SIZE,
|
||||||
|
};
|
||||||
|
|
||||||
|
Addr(const Addr& other, const char *title = nullptr, Version required_version = UNSPEC)
|
||||||
|
: ver(other.ver)
|
||||||
|
{
|
||||||
|
other.validate_version(title, required_version);
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
u.v4 = other.u.v4;
|
||||||
|
break;
|
||||||
|
case V6:
|
||||||
|
u.v6 = other.u.v6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr(const std::string& ipstr, const char *title = nullptr, Version required_version = UNSPEC)
|
||||||
|
: Addr(from_string(ipstr, title, required_version))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SWIGPYTHON
|
||||||
|
// When calling IP:Addr with None as the second parameter, Swig will
|
||||||
|
// always pick this function and complain about not being able to convert
|
||||||
|
// a null pointer to a const std::string reference. Hide this function, so
|
||||||
|
// swig is forced to take the const char* variant of this function instead
|
||||||
|
Addr(const std::string& ipstr, const std::string& title, Version required_version = UNSPEC)
|
||||||
|
: Addr(from_string(ipstr, title.c_str(), required_version))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void validate_version(const char *title, Version required_version) const
|
||||||
|
{
|
||||||
|
if (required_version != UNSPEC && required_version != ver)
|
||||||
|
throw ip_exception(internal::format_error(to_string(), title, version_string_static(required_version), "wrong IP version"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SWIGPYTHON
|
||||||
|
void validate_version(const std::string& title, Version required_version) const
|
||||||
|
{
|
||||||
|
validate_version(title.c_str(), required_version);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static std::string validate(const std::string& ipstr, const char *title = nullptr, Version required_version = UNSPEC)
|
||||||
|
{
|
||||||
|
Addr a = from_string(ipstr, title, required_version);
|
||||||
|
return a.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SWIGPYTHON
|
||||||
|
static std::string validate(const std::string& ipstr, const std::string& title, Version required_version = UNSPEC)
|
||||||
|
{
|
||||||
|
return validate(ipstr, title.c_str(), required_version);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool is_valid(const std::string& ipstr)
|
||||||
|
{
|
||||||
|
// fast path -- rule out validity if invalid chars
|
||||||
|
for (size_t i = 0; i < ipstr.length(); ++i)
|
||||||
|
{
|
||||||
|
const char c = ipstr[i];
|
||||||
|
if (!((c >= '0' && c <= '9')
|
||||||
|
|| (c >= 'a' && c <= 'f')
|
||||||
|
|| (c >= 'A' && c <= 'F')
|
||||||
|
|| (c == '.' || c == ':' || c == '%')))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// slow path
|
||||||
|
{
|
||||||
|
openvpn_io::error_code ec;
|
||||||
|
openvpn_io::ip::make_address(ipstr, ec);
|
||||||
|
return !ec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Addr from_string(const std::string& ipstr, const char *title = nullptr, Version required_version = UNSPEC)
|
||||||
|
{
|
||||||
|
openvpn_io::error_code ec;
|
||||||
|
openvpn_io::ip::address a = openvpn_io::ip::make_address(ipstr, ec);
|
||||||
|
if (ec)
|
||||||
|
throw ip_exception(internal::format_error(ipstr, title, "", ec));
|
||||||
|
const Addr ret = from_asio(a);
|
||||||
|
if (required_version != UNSPEC && required_version != ret.ver)
|
||||||
|
throw ip_exception(internal::format_error(ipstr, title, version_string_static(required_version), "wrong IP version"));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Addr from_hex(Version v, const std::string& s)
|
||||||
|
{
|
||||||
|
if (v == V4)
|
||||||
|
return from_ipv4(IPv4::Addr::from_hex(s));
|
||||||
|
else if (v == V6)
|
||||||
|
return from_ipv6(IPv6::Addr::from_hex(s));
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
static Addr from_ipv4(IPv4::Addr addr)
|
||||||
|
{
|
||||||
|
Addr a;
|
||||||
|
a.ver = V4;
|
||||||
|
a.u.v4 = std::move(addr);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Addr from_ipv6(IPv6::Addr addr)
|
||||||
|
{
|
||||||
|
Addr a;
|
||||||
|
a.ver = V6;
|
||||||
|
a.u.v6 = std::move(addr);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IPv4::Addr& to_ipv4() const
|
||||||
|
{
|
||||||
|
if (ver == V4)
|
||||||
|
return u.v4;
|
||||||
|
else
|
||||||
|
throw ip_exception("address is not IPv4");
|
||||||
|
}
|
||||||
|
|
||||||
|
const IPv6::Addr& to_ipv6() const
|
||||||
|
{
|
||||||
|
if (ver == V6)
|
||||||
|
return u.v6;
|
||||||
|
else
|
||||||
|
throw ip_exception("address is not IPv6");
|
||||||
|
}
|
||||||
|
|
||||||
|
const IPv4::Addr& to_ipv4_nocheck() const
|
||||||
|
{
|
||||||
|
return u.v4;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IPv6::Addr& to_ipv6_nocheck() const
|
||||||
|
{
|
||||||
|
return u.v6;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Addr from_sockaddr(const struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
if (sa->sa_family == AF_INET)
|
||||||
|
return from_ipv4(IPv4::Addr::from_sockaddr((struct sockaddr_in *)sa));
|
||||||
|
else if (sa->sa_family == AF_INET6)
|
||||||
|
return from_ipv6(IPv6::Addr::from_sockaddr((struct sockaddr_in6 *)sa));
|
||||||
|
else
|
||||||
|
return Addr();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool sockaddr_defined(const struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
return sa && (sa->sa_family == AF_INET || sa->sa_family == AF_INET6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Addr from_ulong(Version v, unsigned long ul)
|
||||||
|
{
|
||||||
|
if (v == V4)
|
||||||
|
return from_ipv4(IPv4::Addr::from_ulong(ul));
|
||||||
|
else if (v == V6)
|
||||||
|
return from_ipv6(IPv6::Addr::from_ulong(ul));
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// return *this as a ulong, will raise exception on overflow
|
||||||
|
unsigned long to_ulong() const
|
||||||
|
{
|
||||||
|
if (ver == V4)
|
||||||
|
return u.v4.to_ulong();
|
||||||
|
else if (ver == V6)
|
||||||
|
return u.v6.to_ulong();
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
static Addr from_long(Version v, long ul)
|
||||||
|
{
|
||||||
|
if (v == V4)
|
||||||
|
return from_ipv4(IPv4::Addr::from_long(ul));
|
||||||
|
else if (v == V6)
|
||||||
|
return from_ipv6(IPv6::Addr::from_long(ul));
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// return *this as a long, will raise exception on overflow
|
||||||
|
long to_long() const
|
||||||
|
{
|
||||||
|
if (ver == V4)
|
||||||
|
return u.v4.to_long();
|
||||||
|
else if (ver == V6)
|
||||||
|
return u.v6.to_long();
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// return Addr from 16 byte binary string
|
||||||
|
static Addr from_byte_string(const unsigned char *bytestr)
|
||||||
|
{
|
||||||
|
Addr a;
|
||||||
|
if (IPv6::Addr::byte_string_is_v4(bytestr))
|
||||||
|
{
|
||||||
|
a.ver = V4;
|
||||||
|
a.u.v4 = IPv4::Addr::from_uint32_net(IPv6::Addr::v4_from_byte_string(bytestr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a.ver = V6;
|
||||||
|
a.u.v6 = IPv6::Addr::from_byte_string(bytestr);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert Addr to 16 byte binary string
|
||||||
|
void to_byte_string(unsigned char *bytestr) const
|
||||||
|
{
|
||||||
|
if (ver == V4)
|
||||||
|
IPv6::Addr::v4_to_byte_string(bytestr, u.v4.to_uint32_net());
|
||||||
|
else if (ver == V6)
|
||||||
|
u.v6.to_byte_string(bytestr);
|
||||||
|
else
|
||||||
|
std::memset(bytestr, 0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert Addr to variable length byte string
|
||||||
|
void to_byte_string_variable(unsigned char *bytestr) const
|
||||||
|
{
|
||||||
|
if (ver == V4)
|
||||||
|
u.v4.to_byte_string(bytestr);
|
||||||
|
else if (ver == V6)
|
||||||
|
u.v6.to_byte_string(bytestr);
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t to_uint32_net() const // return value in net byte order
|
||||||
|
{
|
||||||
|
if (ver == V4)
|
||||||
|
return u.v4.to_uint32_net();
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct an address where all bits are zero
|
||||||
|
static Addr from_zero(Version v)
|
||||||
|
{
|
||||||
|
if (v == V4)
|
||||||
|
return from_ipv4(IPv4::Addr::from_zero());
|
||||||
|
else if (v == V6)
|
||||||
|
return from_ipv6(IPv6::Addr::from_zero());
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct an address where all bits are zero
|
||||||
|
static Addr from_one(Version v)
|
||||||
|
{
|
||||||
|
if (v == V4)
|
||||||
|
return from_ipv4(IPv4::Addr::from_one());
|
||||||
|
else if (v == V6)
|
||||||
|
return from_ipv6(IPv6::Addr::from_one());
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct an address where all bits are one
|
||||||
|
static Addr from_zero_complement(Version v)
|
||||||
|
{
|
||||||
|
if (v == V4)
|
||||||
|
return from_ipv4(IPv4::Addr::from_zero_complement());
|
||||||
|
else if (v == V6)
|
||||||
|
return from_ipv6(IPv6::Addr::from_zero_complement());
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate the prefix length for the IP version
|
||||||
|
static bool validate_prefix_len(Version v, const unsigned int prefix_len)
|
||||||
|
{
|
||||||
|
if (v == V4)
|
||||||
|
{
|
||||||
|
if (prefix_len <= V4_SIZE)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (v == V6)
|
||||||
|
{
|
||||||
|
if (prefix_len <= V6_SIZE)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build a netmask using given prefix_len
|
||||||
|
static Addr netmask_from_prefix_len(Version v, const unsigned int prefix_len)
|
||||||
|
{
|
||||||
|
if (v == V4)
|
||||||
|
return from_ipv4(IPv4::Addr::netmask_from_prefix_len(prefix_len));
|
||||||
|
else if (v == V6)
|
||||||
|
return from_ipv6(IPv6::Addr::netmask_from_prefix_len(prefix_len));
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// build a netmask using *this as extent
|
||||||
|
Addr netmask_from_extent() const
|
||||||
|
{
|
||||||
|
if (ver == V4)
|
||||||
|
return from_ipv4(u.v4.netmask_from_extent());
|
||||||
|
else if (ver == V6)
|
||||||
|
return from_ipv6(u.v6.netmask_from_extent());
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string() const
|
||||||
|
{
|
||||||
|
if (ver != UNSPEC)
|
||||||
|
{
|
||||||
|
const openvpn_io::ip::address a = to_asio();
|
||||||
|
std::string ret = a.to_string();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "UNSPEC";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string_bracket_ipv6() const
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
if (ver == V6)
|
||||||
|
ret += '[';
|
||||||
|
ret += to_string();
|
||||||
|
if (ver == V6)
|
||||||
|
ret += ']';
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_hex() const
|
||||||
|
{
|
||||||
|
if (ver == V4)
|
||||||
|
return u.v4.to_hex();
|
||||||
|
else if (ver == V6)
|
||||||
|
return u.v6.to_hex();
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string arpa() const
|
||||||
|
{
|
||||||
|
if (ver == V4)
|
||||||
|
return u.v4.arpa();
|
||||||
|
else if (ver == V6)
|
||||||
|
return u.v6.arpa();
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
static Addr from_asio(const openvpn_io::ip::address& addr)
|
||||||
|
{
|
||||||
|
if (addr.is_v4())
|
||||||
|
{
|
||||||
|
Addr a;
|
||||||
|
a.ver = V4;
|
||||||
|
a.u.v4 = IPv4::Addr::from_asio(addr.to_v4());
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
else if (addr.is_v6())
|
||||||
|
{
|
||||||
|
Addr a;
|
||||||
|
a.ver = V6;
|
||||||
|
a.u.v6 = IPv6::Addr::from_asio(addr.to_v6());
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
openvpn_io::ip::address to_asio() const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return openvpn_io::ip::address_v4(u.v4.to_asio());
|
||||||
|
case V6:
|
||||||
|
return openvpn_io::ip::address_v6(u.v6.to_asio());
|
||||||
|
default:
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr operator+(const long delta) const {
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V4;
|
||||||
|
ret.u.v4 = u.v4 + delta;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case V6:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V6;
|
||||||
|
ret.u.v6 = u.v6 + delta;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr operator-(const long delta) const {
|
||||||
|
return operator+(-delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OPENVPN_IP_OPERATOR_BINOP(OP) \
|
||||||
|
Addr operator OP (const Addr& other) const { \
|
||||||
|
if (ver != other.ver) \
|
||||||
|
throw ip_exception("version inconsistency"); \
|
||||||
|
switch (ver) \
|
||||||
|
{ \
|
||||||
|
case V4: \
|
||||||
|
{ \
|
||||||
|
Addr ret; \
|
||||||
|
ret.ver = V4; \
|
||||||
|
ret.u.v4 = u.v4 OP other.u.v4; \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
case V6: \
|
||||||
|
{ \
|
||||||
|
Addr ret; \
|
||||||
|
ret.ver = V6; \
|
||||||
|
ret.u.v6 = u.v6 OP other.u.v6; \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
default: \
|
||||||
|
throw ip_exception("address unspecified"); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
OPENVPN_IP_OPERATOR_BINOP(+)
|
||||||
|
OPENVPN_IP_OPERATOR_BINOP(-)
|
||||||
|
OPENVPN_IP_OPERATOR_BINOP(*)
|
||||||
|
OPENVPN_IP_OPERATOR_BINOP(/)
|
||||||
|
OPENVPN_IP_OPERATOR_BINOP(%)
|
||||||
|
OPENVPN_IP_OPERATOR_BINOP(&)
|
||||||
|
OPENVPN_IP_OPERATOR_BINOP(|)
|
||||||
|
|
||||||
|
#undef OPENVPN_IP_OPERATOR_BINOP
|
||||||
|
|
||||||
|
Addr operator<<(const unsigned int shift) const {
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V4;
|
||||||
|
ret.u.v4 = u.v4 << shift;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case V6:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V6;
|
||||||
|
ret.u.v6 = u.v6 << shift;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr operator>>(const unsigned int shift) const {
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V4;
|
||||||
|
ret.u.v4 = u.v4 >> shift;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case V6:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V6;
|
||||||
|
ret.u.v6 = u.v6 >> shift;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr operator~() const {
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V4;
|
||||||
|
ret.u.v4 = ~u.v4;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case V6:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V6;
|
||||||
|
ret.u.v6 = ~u.v6;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr network_addr(const unsigned int prefix_len) const {
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V4;
|
||||||
|
ret.u.v4 = u.v4.network_addr(prefix_len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case V6:
|
||||||
|
{
|
||||||
|
Addr ret;
|
||||||
|
ret.ver = V6;
|
||||||
|
ret.u.v6 = u.v6.network_addr(prefix_len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const Addr& other) const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case UNSPEC:
|
||||||
|
return other.ver == UNSPEC;
|
||||||
|
case V4:
|
||||||
|
if (ver == other.ver)
|
||||||
|
return u.v4 == other.u.v4;
|
||||||
|
break;
|
||||||
|
case V6:
|
||||||
|
if (ver == other.ver)
|
||||||
|
return u.v6 == other.u.v6;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Addr& other) const
|
||||||
|
{
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OPENVPN_IP_OPERATOR_REL(OP) \
|
||||||
|
bool operator OP(const Addr& other) const \
|
||||||
|
{ \
|
||||||
|
if (ver == other.ver) \
|
||||||
|
{ \
|
||||||
|
switch (ver) \
|
||||||
|
{ \
|
||||||
|
case V4: \
|
||||||
|
return u.v4 OP other.u.v4; \
|
||||||
|
case V6: \
|
||||||
|
return u.v6 OP other.u.v6; \
|
||||||
|
default: \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else if (ver OP other.ver) \
|
||||||
|
return true; \
|
||||||
|
else \
|
||||||
|
return false; \
|
||||||
|
}
|
||||||
|
|
||||||
|
OPENVPN_IP_OPERATOR_REL(<)
|
||||||
|
OPENVPN_IP_OPERATOR_REL(>)
|
||||||
|
OPENVPN_IP_OPERATOR_REL(<=)
|
||||||
|
OPENVPN_IP_OPERATOR_REL(>=)
|
||||||
|
|
||||||
|
#undef OPENVPN_IP_OPERATOR_REL
|
||||||
|
|
||||||
|
bool unspecified() const
|
||||||
|
{
|
||||||
|
return all_zeros();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool specified() const
|
||||||
|
{
|
||||||
|
return !unspecified();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool all_zeros() const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return u.v4.all_zeros();
|
||||||
|
case V6:
|
||||||
|
return u.v6.all_zeros();
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool all_ones() const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return u.v4.all_ones();
|
||||||
|
case V6:
|
||||||
|
return u.v6.all_ones();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_loopback() const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return u.v4.is_loopback();
|
||||||
|
case V6:
|
||||||
|
return u.v6.is_loopback();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool defined() const
|
||||||
|
{
|
||||||
|
return ver != UNSPEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *version_string() const
|
||||||
|
{
|
||||||
|
return version_string_static(ver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *version_string_static(Version ver)
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return "v4";
|
||||||
|
case V6:
|
||||||
|
return "v6";
|
||||||
|
default:
|
||||||
|
return "v?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Version version() const { return ver; }
|
||||||
|
|
||||||
|
static VersionMask version_mask(const Version ver)
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return V4_MASK;
|
||||||
|
case V6:
|
||||||
|
return V6_MASK;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VersionMask version_mask() const
|
||||||
|
{
|
||||||
|
return version_mask(ver);
|
||||||
|
}
|
||||||
|
|
||||||
|
int version_index() const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return 0;
|
||||||
|
case V6:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
throw ip_exception("version index undefined");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int family() const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return AF_INET;
|
||||||
|
case V6:
|
||||||
|
return AF_INET6;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_compatible(const Addr& other) const
|
||||||
|
{
|
||||||
|
return ver == other.ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_ipv6() const
|
||||||
|
{
|
||||||
|
return ver == V6;
|
||||||
|
}
|
||||||
|
|
||||||
|
void verify_version_consistency(const Addr& other) const
|
||||||
|
{
|
||||||
|
if (!is_compatible(other))
|
||||||
|
throw ip_exception("version inconsistency");
|
||||||
|
}
|
||||||
|
|
||||||
|
// throw exception if address is not a valid netmask
|
||||||
|
void validate_netmask()
|
||||||
|
{
|
||||||
|
prefix_len();
|
||||||
|
}
|
||||||
|
|
||||||
|
// number of network bits in netmask,
|
||||||
|
// throws exception if addr is not a netmask
|
||||||
|
unsigned int prefix_len() const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return u.v4.prefix_len();
|
||||||
|
case V6:
|
||||||
|
return u.v6.prefix_len();
|
||||||
|
default:
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv6 scope ID or -1 if not IPv6
|
||||||
|
int scope_id() const
|
||||||
|
{
|
||||||
|
return ver == V6 ? u.v6.scope_id() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// number of host bits in netmask
|
||||||
|
unsigned int host_len() const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return u.v4.host_len();
|
||||||
|
case V6:
|
||||||
|
return u.v6.host_len();
|
||||||
|
default:
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the number of host addresses contained within netmask
|
||||||
|
Addr extent_from_netmask() const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
return from_ipv4(u.v4.extent_from_netmask());
|
||||||
|
case V6:
|
||||||
|
return from_ipv6(u.v6.extent_from_netmask());
|
||||||
|
default:
|
||||||
|
throw ip_exception("address unspecified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// address size in bits
|
||||||
|
unsigned int size() const
|
||||||
|
{
|
||||||
|
return version_size(ver);
|
||||||
|
}
|
||||||
|
|
||||||
|
// address size in bytes
|
||||||
|
unsigned int size_bytes() const
|
||||||
|
{
|
||||||
|
return size() / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// address size in bits of particular IP version
|
||||||
|
static unsigned int version_size(Version v)
|
||||||
|
{
|
||||||
|
if (v == V4)
|
||||||
|
return IPv4::Addr::SIZE;
|
||||||
|
else if (v == V6)
|
||||||
|
return IPv6::Addr::SIZE;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename HASH>
|
||||||
|
void hash(HASH& h) const
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case Addr::V4:
|
||||||
|
u.v4.hash(h);
|
||||||
|
break;
|
||||||
|
case Addr::V6:
|
||||||
|
u.v6.hash(h);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_CITYHASH
|
||||||
|
std::size_t hashval() const
|
||||||
|
{
|
||||||
|
HashSizeT h;
|
||||||
|
hash(h);
|
||||||
|
return h.value();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENVPN_IP_IMMUTABLE
|
||||||
|
private:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Addr()
|
||||||
|
: ver(UNSPEC)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
ver = UNSPEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr& operator=(const Addr& other)
|
||||||
|
{
|
||||||
|
switch (ver = other.ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
u.v4 = other.u.v4;
|
||||||
|
break;
|
||||||
|
case V6:
|
||||||
|
u.v6 = other.u.v6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr& operator++()
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
++u.v4;
|
||||||
|
break;
|
||||||
|
case V6:
|
||||||
|
++u.v6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr& operator+=(const long delta)
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
u.v4 += delta;
|
||||||
|
break;
|
||||||
|
case V6:
|
||||||
|
u.v6 += delta;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr& operator-=(const long delta)
|
||||||
|
{
|
||||||
|
switch (ver)
|
||||||
|
{
|
||||||
|
case V4:
|
||||||
|
u.v4 -= delta;
|
||||||
|
break;
|
||||||
|
case V6:
|
||||||
|
u.v6 -= delta;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_ipv4_from_uint32(const IPv4::Addr::base_type addr)
|
||||||
|
{
|
||||||
|
ver = V4;
|
||||||
|
u.v4 = IPv4::Addr::from_uint32(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
union {
|
||||||
|
IPv4::Addr v4;
|
||||||
|
IPv6::Addr v6;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
Version ver;
|
||||||
|
};
|
||||||
|
|
||||||
|
OPENVPN_OSTREAM(Addr, to_string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_CITYHASH
|
||||||
|
OPENVPN_HASH_METHOD(openvpn::IP::Addr, hashval);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef OPENVPN_ADDR_IPERR_H
|
||||||
|
#define OPENVPN_ADDR_IPERR_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <openvpn/io/io.hpp>
|
||||||
|
|
||||||
|
namespace openvpn {
|
||||||
|
namespace IP {
|
||||||
|
namespace internal {
|
||||||
|
// Called internally by IP, IPv4, and IPv6 classes
|
||||||
|
|
||||||
|
inline std::string format_error(const std::string& ipstr, const char *title, const char *ipver, const openvpn_io::error_code& ec)
|
||||||
|
{
|
||||||
|
std::string err = "error parsing";
|
||||||
|
if (title)
|
||||||
|
{
|
||||||
|
err += ' ';
|
||||||
|
err += title;
|
||||||
|
}
|
||||||
|
err += " IP";
|
||||||
|
err += ipver;
|
||||||
|
err += " address '";
|
||||||
|
err += ipstr;
|
||||||
|
err += "' : ";
|
||||||
|
err += ec.message();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string format_error(const std::string& ipstr, const char *title, const char *ipver, const char *message)
|
||||||
|
{
|
||||||
|
std::string err = "error parsing";
|
||||||
|
if (title)
|
||||||
|
{
|
||||||
|
err += ' ';
|
||||||
|
err += title;
|
||||||
|
}
|
||||||
|
err += " IP";
|
||||||
|
err += ipver;
|
||||||
|
err += " address '";
|
||||||
|
err += ipstr;
|
||||||
|
err += '\'';
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
err += " : ";
|
||||||
|
err += message;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user