Remove openvpn from project to update subtree

This commit is contained in:
Sergey Abramchuk
2018-07-27 18:08:02 +03:00
parent 673aeabc2e
commit c5b0ceea2d
565 changed files with 0 additions and 98675 deletions

View File

@@ -1,4 +0,0 @@
README.html
x64
*.vcxproj.user
*.ipch

View File

@@ -1,60 +0,0 @@
dist: trusty
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="862aed305dcf91387535519c9549c17630339a12"
- LZ4_VERSION="1.7.5"
- MBEDTLS_VERSION="2.5.1"
- MBEDTLS_CFLAGS="-I${PREFIX}/include"
- MBEDTLS_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto"
- OPENSSL_VERSION="1.0.2l"
- OPENSSL_CFLAGS="-I${PREFIX}/include"
- OPENSSL_LIBS="-lssl -lcrypto"
- COVERITY_BRANCH="master"
matrix:
include:
- env: SSLLIB="openssl"
os: osx
osx_image: xcode8.3
compiler: clang
- env: SSLLIB="mbedtls"
os: osx
osx_image: xcode8.3
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

View File

@@ -1,75 +0,0 @@
#!/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++11 -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

View File

@@ -1,133 +0,0 @@
#!/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

View File

@@ -1,63 +0,0 @@
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.

View File

@@ -1,7 +0,0 @@
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>`_.

View File

@@ -1,661 +0,0 @@
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/>.

View File

@@ -1,15 +0,0 @@
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.

View File

@@ -1,615 +0,0 @@
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::
$ 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 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
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
Download and build dependencies::
> c:\Temp\O3>cd core\win
> c:\Temp\O3\core\win>set O3=C:\Temp\O3 && python buildep.py
Build test client::
> c:\Temp\O3\core\win>set O3=C:\Temp\O3 && python build.py
Visual Studio 2015 project and solution files are located in ``O3\core\win`` directory.
Before opening project you need to build dependencies and define OVPN3_ROOT
environmental variable (``C:\Temp\O3`` from example above).
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>`_.

View File

@@ -1,63 +0,0 @@
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``.

View File

@@ -1,612 +0,0 @@
// 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.
#ifndef OVPNCLI_HPP
#define OVPNCLI_HPP
#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;
// 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;
// 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;
};
// 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.
// Data will be prefixed by an optional PKCS#1 digest prefix
// per RFC 3447.
struct ExternalPKISignRequest : public ExternalPKIRequestBase
{
std::string data; // data rendered as base64 (client reads)
std::string sig; // RSA signature, rendered as base64 (client writes)
};
// 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().
virtual bool socket_protect(int socket) = 0;
// 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::clock_tick_ms
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);
// disable copy and assignment
OpenVPNClient(const OpenVPNClient&) = delete;
OpenVPNClient& operator=(const OpenVPNClient&) = delete;
};
}
}
#endif

View File

@@ -1,44 +0,0 @@
#!/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

View File

@@ -1,48 +0,0 @@
From 28cdfe3f923affa87420a47f8ac71e791c77bcde 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 b3b1a0cf..e1a07e06 100644
--- a/asio/include/asio/detail/impl/socket_ops.ipp
+++ b/asio/include/asio/detail/impl/socket_ops.ipp
@@ -3338,6 +3338,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.16.2

View File

@@ -1,38 +0,0 @@
From c6cb856ac923472e56d8dd631585b4ca58e71c31 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 4146a46b..f0ae258c 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.16.2

View File

@@ -1,38 +0,0 @@
From 69a6d6aec54b41f4ceac3ac2ba14465a36bf1984 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 43430161..0d1b0d28 100644
--- a/asio/include/asio/basic_socket.hpp
+++ b/asio/include/asio/basic_socket.hpp
@@ -865,6 +865,8 @@ public:
asio::error_code ec;
const protocol_type protocol = peer_endpoint.protocol();
this->get_service().open(this->get_implementation(), protocol, ec);
+ if (!ec)
+ async_connect_post_open(protocol, ec);
if (ec)
{
async_completion<ConnectHandler,
@@ -1741,6 +1743,11 @@ protected:
}
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.16.2

View File

@@ -1,4 +0,0 @@
#!/usr/bin/env bash
export NAME=asio
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
$DIR/../../scripts/snapshot

View File

@@ -1,87 +0,0 @@
--- 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,
--

View File

@@ -1,75 +0,0 @@
#!/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

View File

@@ -1,29 +0,0 @@
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 );
}

View File

@@ -1,16 +0,0 @@
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>

View File

@@ -1,47 +0,0 @@
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
}

View File

@@ -1,16 +0,0 @@
export ASIO_VERSION=asio-1-12-0
export ASIO_CSUM=fa8c3a16dc2163f5b3451f2a14ce95277c971f46700497d4e94af6059c00dc06
export LZ4_VERSION=lz4-1.8.0
export LZ4_CSUM=2ca482ea7a9bb103603108b5a7510b7592b90158c151ff50a28f1ca8389fccf6
export MBEDTLS_VERSION=mbedtls-2.7.0
export MBEDTLS_CSUM=aeb66d6cd43aa1c79c145d15845c655627a7fc30d624148aaafbb6c36d7f55ef
export OPENSSL_VERSION=openssl-1.0.2h
export JSONCPP_VERSION=1.8.4
export JSONCPP_CSUM=c49deac9e0933bcb7044f08516861a2d560988540b23de2ac1ad443b219afdb6
export TAP_VERSION=0e30f5c13b3c7b0bdd60da915350f653e4c14d92
export TAP_CSUM=8ff65f9e741c5ecfe1af904eaa38713f05639ce9457ef92041fd8e6b2a170315

View File

@@ -1,61 +0,0 @@
#!/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
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

View File

@@ -1,4 +0,0 @@
#!/usr/bin/env bash
export NAME=lz4
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
$DIR/../../scripts/snapshot

View File

@@ -1,62 +0,0 @@
#!/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
[ "$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 $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

View File

@@ -1,97 +0,0 @@
#!/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$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

View File

@@ -1,55 +0,0 @@
From 62dd1588a7ec3501edfaf9470cf7a1ca15cb4ba1 Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <antonio@openvpn.net>
Date: Tue, 20 Mar 2018 09:35:47 +0800
Subject: [PATCH] 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 371d6da1..df2cea81 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -565,13 +565,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
@@ -581,6 +588,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.16.2

View File

@@ -1,154 +0,0 @@
From 56df6d5003b20fa673b67fb06c2ec03a8197c4c2 Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <antonio@openvpn.net>
Date: Wed, 20 Dec 2017 07:03:55 +0800
Subject: [PATCH] pkcs5v2: add support for additional hmacSHA algorithms
Currently only SHA1 is supported as PRF algorithm for PBKDF2
(PKCS#5 v2.0).
This means that keys encrypted and authenticated using
another algorithm of the SHA family cannot be decrypted.
This deficiency has become particularly incumbent now that
PKIs created with OpenSSL1.1 are encrypting keys using
hmacSHA256 by default (OpenSSL1.0 used PKCS#5 v1.0 by default
and even if v2 was forced, it would still use hmacSHA1).
Enable support for all the digest algorithms of the SHA
family for PKCS#5 v2.0.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
include/mbedtls/oid.h | 18 +++++++++++++++
library/oid.c | 45 ++++++++++++++++++++++++++++++++++++++
library/pkcs5.c | 4 +---
tests/suites/test_suite_pkcs5.data | 4 ++--
4 files changed, 66 insertions(+), 5 deletions(-)
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
index bf2ef5ec..408645ec 100644
--- a/include/mbedtls/oid.h
+++ b/include/mbedtls/oid.h
@@ -228,6 +228,14 @@
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
+#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
+
+#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */
+
+#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */
+
+#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
+
/*
* Encryption algorithms
*/
@@ -514,6 +522,16 @@ int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg );
+
+/**
+ * \brief Translate hmac algorithm OID into md_type
+ *
+ * \param oid OID to use
+ * \param md_hmac place to store message hmac algorithm
+ *
+ * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac );
#endif /* MBEDTLS_MD_C */
/**
diff --git a/library/oid.c b/library/oid.c
index f13826ed..edea950f 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -625,6 +625,51 @@ static const oid_md_alg_t oid_md_alg[] =
FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg)
FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg)
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg)
+
+/*
+ * For HMAC digestAlgorithm
+ */
+typedef struct {
+ mbedtls_oid_descriptor_t descriptor;
+ mbedtls_md_type_t md_hmac;
+} oid_md_hmac_t;
+
+static const oid_md_hmac_t oid_md_hmac[] =
+{
+#if defined(MBEDTLS_SHA1_C)
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" },
+ MBEDTLS_MD_SHA1,
+ },
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" },
+ MBEDTLS_MD_SHA224,
+ },
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" },
+ MBEDTLS_MD_SHA256,
+ },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" },
+ MBEDTLS_MD_SHA384,
+ },
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" },
+ MBEDTLS_MD_SHA512,
+ },
+#endif /* MBEDTLS_SHA512_C */
+ {
+ { NULL, 0, NULL, NULL },
+ MBEDTLS_MD_NONE,
+ },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac)
+FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac)
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PKCS12_C)
diff --git a/library/pkcs5.c b/library/pkcs5.c
index e28d5a84..95f44fa9 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -96,11 +96,9 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
- if( MBEDTLS_OID_CMP( MBEDTLS_OID_HMAC_SHA1, &prf_alg_oid ) != 0 )
+ if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 )
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
- *md_type = MBEDTLS_MD_SHA1;
-
if( p != end )
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
diff --git a/tests/suites/test_suite_pkcs5.data b/tests/suites/test_suite_pkcs5.data
index e609d62b..4c2c0bb6 100644
--- a/tests/suites/test_suite_pkcs5.data
+++ b/tests/suites/test_suite_pkcs5.data
@@ -82,9 +82,9 @@ PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg overlong)
depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301D06092A864886F70D01050C301004082ED7F24A1D516DD7020208003001":"":"":MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
-PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg != HMAC-SHA1)
+PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg != HMAC-SHA*)
depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
-mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"302706092A864886F70D01050C301A04082ED7F24A1D516DD702020800300A06082A864886F70D0208":"":"":MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE:""
+mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"302706092A864886F70D01050C301A04082ED7F24A1D516DD702020800300A06082A864886F70D0206":"":"":MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE:""
PBES2 Decrypt (bad, PBKDF2 params extra data)
depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
--
2.16.2

View File

@@ -1,128 +0,0 @@
From bb029567d8a2b55e500a85c916a8d22ae9434ab3 Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <antonio@openvpn.net>
Date: Wed, 31 Jan 2018 23:23:02 +0800
Subject: [PATCH] tests/pkcs5/pbkdf2_hmac: add unit tests for additional SHA
algorithms
Test vectors for SHA224,256,384 and 512 have been
generated using Python's hashlib module by the
following oneliner:
import binascii, hashlib
binascii.hexlify(hashlib.pbkdf2_hmac(ALGO, binascii.unhexlify('PASSWORD'), binascii.unhexlify('SALT'), ITER, KEYLEN)))
where ALGO was 'sha224', 'sha256', 'sha384' and 'sha512'
respectively.
Values for PASSWORD, SALT, ITER and KEYLEN were copied from the
existent test vectors for SHA1.
For SHA256 we also have two test vectors coming from RFC7914 Sec 11.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tests/suites/test_suite_pkcs5.data | 88 ++++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/tests/suites/test_suite_pkcs5.data b/tests/suites/test_suite_pkcs5.data
index 4c2c0bb6..f3c421d0 100644
--- a/tests/suites/test_suite_pkcs5.data
+++ b/tests/suites/test_suite_pkcs5.data
@@ -18,6 +18,94 @@ PBKDF2 RFC 6070 Test Vector #6 (SHA1)
depends_on:MBEDTLS_SHA1_C
pbkdf2_hmac:MBEDTLS_MD_SHA1:"7061737300776f7264":"7361006c74":4096:16:"56fa6aa75548099dcc37d7f03425e0c3"
+PBKDF2 Python hashlib Test Vector #1 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"70617373776f7264":"73616c74":1:20:"3c198cbdb9464b7857966bd05b7bc92bc1cc4e6e"
+
+PBKDF2 Python hashlib Test Vector #2 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"70617373776f7264":"73616c74":2:20:"93200ffa96c5776d38fa10abdf8f5bfc0054b971"
+
+PBKDF2 Python hashlib Test Vector #3 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"70617373776f7264":"73616c74":4096:20:"218c453bf90635bd0a21a75d172703ff6108ef60"
+
+PBKDF2 Python hashlib Test Vector #5 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"70617373776f726450415353574f524470617373776f7264":"73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74":4096:25:"056c4ba438ded91fc14e0594e6f52b87e1f3690c0dc0fbc057"
+
+PBKDF2 Python hashlib Test Vector #6 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"7061737300776f7264":"7361006c74":4096:16:"9b4011b641f40a2a500a31d4a392d15c"
+
+PBKDF2 RFC 7914 Sec 11 Test Vector #1 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"706173737764":"73616c74":1:64:"55ac046e56e3089fec1691c22544b605f94185216dde0465e68b9d57c20dacbc49ca9cccf179b645991664b39d77ef317c71b845b1e30bd509112041d3a19783"
+
+PBKDF2 RFC 7914 Sec 11 Test Vector #2 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"50617373776f7264":"4e61436c":80000:64:"4ddcd8f60b98be21830cee5ef22701f9641a4418d04c0414aeff08876b34ab56a1d425a1225833549adb841b51c9b3176a272bdebba1d078478f62b397f33c8d"
+
+PBKDF2 Python hashlib Test Vector #1 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"70617373776f7264":"73616c74":1:20:"120fb6cffcf8b32c43e7225256c4f837a86548c9"
+
+PBKDF2 Python hashlib Test Vector #2 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"70617373776f7264":"73616c74":2:20:"ae4d0c95af6b46d32d0adff928f06dd02a303f8e"
+
+PBKDF2 Python hashlib Test Vector #3 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"70617373776f7264":"73616c74":4096:20:"c5e478d59288c841aa530db6845c4c8d962893a0"
+
+PBKDF2 Python hashlib Test Vector #5 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"70617373776f726450415353574f524470617373776f7264":"73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74":4096:25:"348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c"
+
+PBKDF2 Python hashlib Test Vector #6 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"7061737300776f7264":"7361006c74":4096:16:"89b69d0516f829893c696226650a8687"
+
+PBKDF2 Python hashlib Test Vector #1 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"70617373776f7264":"73616c74":1:20:"c0e14f06e49e32d73f9f52ddf1d0c5c719160923"
+
+PBKDF2 Python hashlib Test Vector #2 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"70617373776f7264":"73616c74":2:20:"54f775c6d790f21930459162fc535dbf04a93918"
+
+PBKDF2 Python hashlib Test Vector #3 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"70617373776f7264":"73616c74":4096:20:"559726be38db125bc85ed7895f6e3cf574c7a01c"
+
+PBKDF2 Python hashlib Test Vector #5 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"70617373776f726450415353574f524470617373776f7264":"73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74":4096:25:"819143ad66df9a552559b9e131c52ae6c5c1b0eed18f4d283b"
+
+PBKDF2 Python hashlib Test Vector #6 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"7061737300776f7264":"7361006c74":4096:16:"a3f00ac8657e095f8e0823d232fc60b3"
+
+PBKDF2 Python hashlib Test Vector #1 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"70617373776f7264":"73616c74":1:20:"867f70cf1ade02cff3752599a3a53dc4af34c7a6"
+
+PBKDF2 Python hashlib Test Vector #2 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"70617373776f7264":"73616c74":2:20:"e1d9c16aa681708a45f5c7c4e215ceb66e011a2e"
+
+PBKDF2 Python hashlib Test Vector #3 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"70617373776f7264":"73616c74":4096:20:"d197b1b33db0143e018b12f3d1d1479e6cdebdcc"
+
+PBKDF2 Python hashlib Test Vector #5 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"70617373776f726450415353574f524470617373776f7264":"73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74":4096:25:"8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868"
+
+PBKDF2 Python hashlib Test Vector #6 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"7061737300776f7264":"7361006c74":4096:16:"9d9e9c4cd21fe4be24d5b8244c759665"
+
PBES2 Decrypt (OK)
depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":0:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
--
2.16.2

View File

@@ -1,49 +0,0 @@
From d09cecb5f7d1e66476c97a35caee7248930ef425 Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <a@unstable.cc>
Date: Wed, 31 Jan 2018 23:45:09 +0800
Subject: [PATCH] tests/pkcs5/pbkdf2_hmac: extend array to accommodate longer
results
Some unit tests for pbkdf2_hmac() have results longer than
99bytes when represented in hexadecimal form.
For this reason extend the result array to accommodate
longer strings.
At the same time make memset() parametric to avoid
bugs in the future.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tests/suites/test_suite_pkcs5.function | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/suites/test_suite_pkcs5.function b/tests/suites/test_suite_pkcs5.function
index 8fabec08..3ad64805 100644
--- a/tests/suites/test_suite_pkcs5.function
+++ b/tests/suites/test_suite_pkcs5.function
@@ -14,7 +14,7 @@ void pbkdf2_hmac( int hash, char *hex_password_string,
{
unsigned char pw_str[100];
unsigned char salt_str[100];
- unsigned char dst_str[100];
+ unsigned char dst_str[200];
mbedtls_md_context_t ctx;
const mbedtls_md_info_t *info;
@@ -24,9 +24,9 @@ void pbkdf2_hmac( int hash, char *hex_password_string,
mbedtls_md_init( &ctx );
- memset(pw_str, 0x00, 100);
- memset(salt_str, 0x00, 100);
- memset(dst_str, 0x00, 100);
+ memset(pw_str, 0x00, sizeof(pw_str));
+ memset(salt_str, 0x00, sizeof(salt_str));
+ memset(dst_str, 0x00, sizeof(dst_str));
pw_len = unhexify( pw_str, hex_password_string );
salt_len = unhexify( salt_str, hex_salt_string );
--
2.16.2

View File

@@ -1,604 +0,0 @@
From 7ed2575f310fd889fba025aa760f74ec1b41924b Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <antonio@openvpn.net>
Date: Thu, 1 Feb 2018 14:03:36 +0800
Subject: [PATCH] tests_suite_pkparse: new PKCS8-v2 keys with PRF != SHA1
Extend the pkparse test suite with the newly created keys
encrypted using PKCS#8 with PKCS#5 v2.0 with PRF being
SHA224, 256, 384 and 512.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tests/suites/test_suite_pkparse.data | 576 +++++++++++++++++++++++++++++++++++
1 file changed, 576 insertions(+)
diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data
index 416f9dfe..1bf06270 100644
--- a/tests/suites/test_suite_pkparse.data
+++ b/tests/suites/test_suite_pkparse.data
@@ -362,6 +362,582 @@ Parse RSA Key #49.2 (PKCS#8 encrypted v2 PBKDF2 DES DER, 4096-bit, no PW)
depends_on:MBEDTLS_DES_C:MBEDTLS_SHA1_C:MBEDTLS_PKCS5_C
pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+Parse RSA Key #50 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #50.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #50.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #51 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #51.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #51.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #52 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #52.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #52.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #53 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #53.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #53.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #54 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #54.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #54.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #55 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #55.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #55.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #56 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #56.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #56.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #57 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #57.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #57.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #58 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #58.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #58.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #59 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #59.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #59.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #60 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #60.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #60.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #61 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #61.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #61.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #62 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #62.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #62.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #63 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #63.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #63.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #64 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #64.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #64.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #65 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #65.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #65.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #66 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #66.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #66.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #67 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #68.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #68.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #69 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #69.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #69.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #70 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #70.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #70.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #71 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #71.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #71.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #72 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #72.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #72.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #73 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #73.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #73.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #74 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #74.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #74.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #75 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #75.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #75.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #76 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #76.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #76.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #77 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #77.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #77.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #78 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #78.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #78.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #79 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #79.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #79.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #80 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #80.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #80.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #81 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #81.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #81.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #82 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #82.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #82.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #83 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #83.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #83.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #84 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #84.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #85.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #86 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #86.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #86.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #87 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #87.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #87.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #88 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #88.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #88.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #89 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #89.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #89.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #90 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #90.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #90.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #91 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #91.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #91.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #92 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #92.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #92.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #93 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #93.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #93.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #94 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #94.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #94.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #95 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #95.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #95.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #96 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #96.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #96.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #97 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #97.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #97.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #98 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #98.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #98.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #99 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #99.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #99.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
Parse Public RSA Key #1 (PKCS#8 wrapped)
depends_on:MBEDTLS_MD5_C:MBEDTLS_PEM_PARSE_C
pk_parse_public_keyfile_rsa:"data_files/format_gen.pub":0
--
2.16.2

View File

@@ -1,361 +0,0 @@
From 13dd5f71dfe345787c3c44ef177009530983bf20 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 fcecdafd..096b1b10 100644
--- a/include/mbedtls/oid.h
+++ b/include/mbedtls/oid.h
@@ -401,7 +401,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
@@ -409,6 +409,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 cc000700..cb779f86 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -695,6 +695,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
@@ -2234,6 +2238,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 06166d8b..adc6474f 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -89,6 +89,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 f13826ed..7c50f24f 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 661ae706..ed1f7b67 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4468,6 +4468,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 )
@@ -6344,6 +6347,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 c6209fb4..1a61e5e9 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -526,6 +526,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( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
{
@@ -585,9 +586,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;
@@ -595,6 +596,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 );
@@ -948,6 +953,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 00000000..7e0c5613
--- /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 b8c902e2..e7dcb61f 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -1574,6 +1574,12 @@ X509 File parse (trailing spaces, OK)
depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_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 0dfdd61c..2be1defd 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -395,6 +395,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.14.3 (Apple Git-98)

View File

@@ -1,32 +0,0 @@
--- 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...

View File

@@ -1,759 +0,0 @@
#!/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()

View File

@@ -1,730 +0,0 @@
#!/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()

View File

@@ -1,137 +0,0 @@
#!/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

View File

@@ -1,139 +0,0 @@
#!/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

View File

@@ -1,32 +0,0 @@
--- 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;

View File

@@ -1,63 +0,0 @@
#!/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
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/$OPENSSL.tar.gz
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

View File

@@ -1,86 +0,0 @@
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})

View File

@@ -1,12 +0,0 @@
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

View File

@@ -1,17 +0,0 @@
# 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)

View File

@@ -1,4 +0,0 @@
# specify the cross compiler
SET(CMAKE_C_COMPILER clang)
SET(CMAKE_CXX_COMPILER clang++)
SET(CMAKE_COMPILER_IS_GNUCC 1)

View File

@@ -1,32 +0,0 @@
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;

View File

@@ -1,24 +0,0 @@
#!/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'

View File

@@ -1,52 +0,0 @@
#!/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 ..

View File

@@ -1,167 +0,0 @@
#!/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

View File

@@ -1,30 +0,0 @@
#!/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

View File

@@ -1,959 +0,0 @@
/**
* \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 */

View File

@@ -1,16 +0,0 @@
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

View File

@@ -1,12 +0,0 @@
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)

View File

@@ -1,12 +0,0 @@
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

View File

@@ -1,9 +0,0 @@
#!/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

View File

@@ -1,22 +0,0 @@
#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);
}

View File

@@ -1,17 +0,0 @@
# 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)

View File

@@ -1,782 +0,0 @@
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;

View File

@@ -1,446 +0,0 @@
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

View File

@@ -1,24 +0,0 @@
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

View File

@@ -1,24 +0,0 @@
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

View File

@@ -1,118 +0,0 @@
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 +

View File

@@ -1,13 +0,0 @@
#!/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

View File

@@ -1,37 +0,0 @@
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;
}

View File

@@ -1,15 +0,0 @@
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;
}

View File

@@ -1,181 +0,0 @@
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) */

View File

@@ -1,12 +0,0 @@
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 ) );

View File

@@ -1,44 +0,0 @@
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

View File

@@ -1,66 +0,0 @@
#!/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

View File

@@ -1,198 +0,0 @@
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.

View File

@@ -1,12 +0,0 @@
#!/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

View File

@@ -1,19 +0,0 @@
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

View File

@@ -1,17 +0,0 @@
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

View File

@@ -1,17 +0,0 @@
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

View File

@@ -1,7 +0,0 @@
build
ovpncli_wrap.cxx
ovpncli_wrap.h
ovpncli.java
ovpncliJNI.java
ClientAPI_*.java
SWIGTYPE_*.java

View File

@@ -1,144 +0,0 @@
// 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;
}
}

View File

@@ -1,97 +0,0 @@
// 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);
}
}
}

View File

@@ -1,359 +0,0 @@
// 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);
}
}

View File

@@ -1,62 +0,0 @@
// 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;
}

View File

@@ -1,178 +0,0 @@
// 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);
}
}

View File

@@ -1,125 +0,0 @@
#!/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 \
-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/

View File

@@ -1,95 +0,0 @@
#!/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

View File

@@ -1,54 +0,0 @@
// 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>;
};
// 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"

View File

@@ -1 +0,0 @@
**/xcuserdata/

View File

@@ -1,326 +0,0 @@
// !$*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 */; };
/* 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>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
DF380AD3201F07AE0003272D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
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 = (
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,
);
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../..\"",
"\"$(SRCROOT)/../../../deps/asio/asio/include\"",
"\"$(SRCROOT)/../../../deps/mbedtls/mbedtls-osx/include\"",
);
LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../deps/mbedtls/mbedtls-osx/library\"";
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,
);
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../..\"",
"\"$(SRCROOT)/../../../deps/asio/asio/include\"",
"\"$(SRCROOT)/../../../deps/mbedtls/mbedtls-osx/include\"",
);
LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../deps/mbedtls/mbedtls-osx/library\"";
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 */;
}

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:ovpn3-core.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,65 +0,0 @@
// 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

View File

@@ -1,218 +0,0 @@
// 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

View File

@@ -1,982 +0,0 @@
// 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))
{
}
Addr(const std::string& ipstr, const std::string& title, Version required_version = UNSPEC)
: Addr(from_string(ipstr, title.c_str(), required_version))
{
}
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"));
}
void validate_version(const std::string& title, Version required_version) const
{
validate_version(title.c_str(), required_version);
}
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();
}
static std::string validate(const std::string& ipstr, const std::string& title, Version required_version = UNSPEC)
{
return validate(ipstr, title.c_str(), required_version);
}
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 = V4;
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

View File

@@ -1,75 +0,0 @@
// 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

View File

@@ -1,569 +0,0 @@
// 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_IPV4_H
#define OPENVPN_ADDR_IPV4_H
#include <cstring> // for std::memcpy, std::memset
#include <sstream>
#include <cstdint> // for std::uint32_t
#include <openvpn/io/io.hpp>
#include <openvpn/common/size.hpp>
#include <openvpn/common/exception.hpp>
#include <openvpn/common/endian.hpp>
#include <openvpn/common/ostream.hpp>
#include <openvpn/common/socktypes.hpp>
#include <openvpn/common/ffs.hpp>
#include <openvpn/common/hexstr.hpp>
#include <openvpn/addr/iperr.hpp>
namespace openvpn {
namespace IP {
class Addr;
}
// Fundamental classes for representing an IPv4 IP address.
namespace IPv4 {
OPENVPN_EXCEPTION(ipv4_exception);
class Addr // NOTE: must be union-legal, so default constructor does not initialize
{
friend class IP::Addr;
public:
enum { SIZE=32 };
typedef std::uint32_t base_type;
typedef std::int32_t signed_base_type;
static Addr from_addr(const Addr& addr)
{
return addr;
}
static Addr from_in_addr(const struct in_addr *in4)
{
Addr ret;
ret.u.addr = ntohl(in4->s_addr);
return ret;
}
struct in_addr to_in_addr() const
{
struct in_addr ret;
ret.s_addr = htonl(u.addr);
return ret;
}
static Addr from_sockaddr(const struct sockaddr_in *sa)
{
Addr ret;
ret.u.addr = ntohl(sa->sin_addr.s_addr);
return ret;
}
struct sockaddr_in to_sockaddr(const unsigned short port=0) const
{
struct sockaddr_in ret;
std::memset(&ret, 0, sizeof(ret));
ret.sin_family = AF_INET;
ret.sin_port = htons(port);
ret.sin_addr.s_addr = htonl(u.addr);
return ret;
}
static Addr from_uint32(const base_type addr) // host byte order
{
Addr ret;
ret.u.addr = addr;
return ret;
}
std::uint32_t to_uint32() const // host byte order
{
return u.addr;
}
static Addr from_uint32_net(const base_type addr) // addr in net byte order
{
Addr ret;
ret.u.addr = ntohl(addr);
return ret;
}
void to_byte_string(unsigned char *bytestr) const
{
*(base_type*)bytestr = ntohl(u.addr);
}
std::uint32_t to_uint32_net() const // return value in net byte order
{
return htonl(u.addr);
}
static Addr from_ulong(unsigned long ul)
{
Addr ret;
ret.u.addr = (base_type)ul;
return ret;
}
// return *this as a unsigned long
unsigned long to_ulong() const
{
return (unsigned long)u.addr;
}
static Addr from_long(long ul)
{
Addr ret;
ret.u.addr = (base_type)(signed_base_type)ul;
return ret;
}
// return *this as a long
long to_long() const
{
return (long)(signed_base_type)u.addr;
}
static Addr from_bytes(const unsigned char *bytes) // host byte order
{
Addr ret;
std::memcpy(ret.u.bytes, bytes, 4);
return ret;
}
static Addr from_bytes_net(const unsigned char *bytes) // network byte order
{
Addr ret;
std::memcpy(ret.u.bytes, bytes, 4);
ret.u.addr = ntohl(ret.u.addr);
return ret;
}
static Addr from_zero()
{
Addr ret;
ret.zero();
return ret;
}
static Addr from_one()
{
Addr ret;
ret.one();
return ret;
}
static Addr from_zero_complement()
{
Addr ret;
ret.zero_complement();
return ret;
}
// build a netmask using given prefix_len
static Addr netmask_from_prefix_len(const unsigned int prefix_len)
{
Addr ret;
ret.u.addr = prefix_len_to_netmask(prefix_len);
return ret;
}
// build a netmask using given extent
Addr netmask_from_extent() const
{
const int lb = find_last_set(u.addr - 1);
return netmask_from_prefix_len(SIZE - lb);
}
static Addr from_string(const std::string& ipstr, const char *title = nullptr)
{
openvpn_io::error_code ec;
openvpn_io::ip::address_v4 a = openvpn_io::ip::make_address_v4(ipstr, ec);
if (ec)
throw ipv4_exception(IP::internal::format_error(ipstr, title, "v4", ec));
return from_asio(a);
}
std::string to_string() const
{
const openvpn_io::ip::address_v4 a = to_asio();
std::string ret = a.to_string();
return ret;
}
static Addr from_hex(const std::string& s)
{
Addr ret;
ret.u.addr = 0;
size_t len = s.length();
size_t base = 0;
if (len > 0 && s[len-1] == 'L')
len -= 1;
if (len >= 2 && s[0] == '0' && s[1] == 'x')
{
base = 2;
len -= 2;
}
if (len < 1 || len > 8)
throw ipv4_exception("parse hex error");
size_t di = (len-1)>>1;
for (int i = (len & 1) ? -1 : 0; i < int(len); i += 2)
{
const size_t idx = base + i;
const int bh = (i >= 0) ? parse_hex_char(s[idx]) : 0;
const int bl = parse_hex_char(s[idx+1]);
if (bh == -1 || bl == -1)
throw ipv4_exception("parse hex error");
ret.u.bytes[Endian::e4(di--)] = (bh<<4) + bl;
}
return ret;
}
std::string to_hex() const
{
std::string ret;
ret.reserve(8);
bool firstnonzero = false;
for (size_t i = 0; i < 4; ++i)
{
const unsigned char b = u.bytes[Endian::e4rev(i)];
if (b || firstnonzero || i == 3)
{
const char bh = b >> 4;
if (bh || firstnonzero)
ret += render_hex_char(bh);
ret += render_hex_char(b & 0x0F);
firstnonzero = true;
}
}
return ret;
}
std::string arpa() const
{
std::ostringstream os;
os << int(u.bytes[Endian::e4(0)]) << '.'
<< int(u.bytes[Endian::e4(1)]) << '.'
<< int(u.bytes[Endian::e4(2)]) << '.'
<< int(u.bytes[Endian::e4(3)]) << ".in-addr.arpa";
return os.str();
}
static Addr from_asio(const openvpn_io::ip::address_v4& asio_addr)
{
Addr ret;
ret.u.addr = (std::uint32_t)asio_addr.to_uint();
return ret;
}
openvpn_io::ip::address_v4 to_asio() const
{
return openvpn_io::ip::address_v4(u.addr);
}
Addr operator&(const Addr& other) const {
Addr ret;
ret.u.addr = u.addr & other.u.addr;
return ret;
}
Addr operator|(const Addr& other) const {
Addr ret;
ret.u.addr = u.addr | other.u.addr;
return ret;
}
Addr operator+(const long delta) const {
Addr ret;
ret.u.addr = u.addr + (std::uint32_t)delta;
return ret;
}
Addr operator+(const Addr& other) const {
Addr ret;
ret.u.addr = u.addr + other.u.addr;
return ret;
}
Addr operator-(const long delta) const {
return operator+(-delta);
}
Addr operator-(const Addr& other) const {
Addr ret;
ret.u.addr = u.addr - other.u.addr;
return ret;
}
Addr operator*(const Addr& other) const {
Addr ret;
ret.u.addr = u.addr * other.u.addr;
return ret;
}
Addr operator/(const Addr& other) const {
Addr ret;
ret.u.addr = u.addr / other.u.addr;
return ret;
}
Addr operator%(const Addr& other) const {
Addr ret;
ret.u.addr = u.addr % other.u.addr;
return ret;
}
Addr operator<<(const unsigned int shift) const {
Addr ret;
ret.u.addr = u.addr << shift;
return ret;
}
Addr operator>>(const unsigned int shift) const {
Addr ret;
ret.u.addr = u.addr >> shift;
return ret;
}
Addr operator~() const {
Addr ret;
ret.u.addr = ~u.addr;
return ret;
}
// return the network that contains the current address
Addr network_addr(const unsigned int prefix_len) const
{
Addr ret;
ret.u.addr = u.addr & prefix_len_to_netmask(prefix_len);
return ret;
}
bool operator==(const Addr& other) const
{
return u.addr == other.u.addr;
}
bool operator!=(const Addr& other) const
{
return u.addr != other.u.addr;
}
bool operator<(const Addr& other) const
{
return u.addr < other.u.addr;
}
bool operator>(const Addr& other) const
{
return u.addr > other.u.addr;
}
bool operator<=(const Addr& other) const
{
return u.addr <= other.u.addr;
}
bool operator>=(const Addr& other) const
{
return u.addr >= other.u.addr;
}
bool unspecified() const
{
return all_zeros();
}
bool specified() const
{
return !unspecified();
}
bool all_zeros() const
{
return u.addr == 0;
}
bool all_ones() const
{
return ~u.addr == 0;
}
bool is_loopback() const
{
return (u.addr & 0x7F000000) == 0x7F000000;
}
// number of network bits in netmask,
// throws exception if addr is not a netmask
unsigned int prefix_len() const
{
const int ret = prefix_len_32(u.addr);
if (ret >= 0)
return ret;
else
throw ipv4_exception("malformed netmask");
}
int prefix_len_nothrow() const
{
return prefix_len_32(u.addr);
}
// number of host bits in netmask
unsigned int host_len() const
{
return SIZE - prefix_len();
}
// return the number of host addresses contained within netmask
Addr extent_from_netmask() const
{
Addr ret;
ret.u.addr = extent_from_netmask_uint32();
return ret;
}
std::uint32_t extent_from_netmask_uint32() const
{
const unsigned int hl = host_len();
if (hl < SIZE)
return 1 << hl;
else if (hl == SIZE)
return 0;
else
throw ipv4_exception("extent overflow");
}
// convert netmask in addr to prefix_len, will return -1 on error
static int prefix_len_32(const std::uint32_t addr)
{
if (addr == ~std::uint32_t(0))
return 32;
else if (addr == 0)
return 0;
else
{
unsigned int high = 32;
unsigned int low = 1;
for (unsigned int i = 0; i < 5; ++i)
{
const unsigned int mid = (high + low) / 2;
const IPv4::Addr::base_type test = prefix_len_to_netmask_unchecked(mid);
if (addr == test)
return mid;
else if (addr > test)
low = mid;
else
high = mid;
}
return -1;
}
}
// address size in bits
static unsigned int size()
{
return SIZE;
}
template <typename HASH>
void hash(HASH& h) const
{
h(u.addr);
}
#ifdef OPENVPN_IP_IMMUTABLE
private:
#endif
void negate()
{
u.addr = ~u.addr;
}
void zero()
{
u.addr = 0;
}
void zero_complement()
{
u.addr = ~0;
}
void one()
{
u.addr = 1;
}
Addr& operator++()
{
++u.addr;
return *this;
}
Addr& operator+=(const long delta)
{
u.addr += (std::uint32_t)delta;
return *this;
}
Addr& operator-=(const long delta)
{
return operator+=(-delta);
}
private:
static base_type prefix_len_to_netmask_unchecked(const unsigned int prefix_len)
{
if (prefix_len)
return ~((1 << (SIZE - prefix_len)) - 1);
else
return 0;
}
static base_type prefix_len_to_netmask(const unsigned int prefix_len)
{
if (prefix_len <= SIZE)
return prefix_len_to_netmask_unchecked(prefix_len);
else
throw ipv4_exception("bad prefix len");
}
union {
base_type addr; // host byte order
unsigned char bytes[4];
} u;
};
OPENVPN_OSTREAM(Addr, to_string)
}
}
#endif // OPENVPN_ADDR_IPV4_H

View File

@@ -1,828 +0,0 @@
// 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_IPV6_H
#define OPENVPN_ADDR_IPV6_H
#include <cstring> // for std::memcpy, std::memset
#include <algorithm> // for std::min
#include <cstdint> // for std::uint32_t
#include <openvpn/io/io.hpp>
#include <openvpn/common/size.hpp>
#include <openvpn/common/exception.hpp>
#include <openvpn/common/ostream.hpp>
#include <openvpn/common/socktypes.hpp>
#include <openvpn/common/ffs.hpp>
#include <openvpn/common/hexstr.hpp>
#include <openvpn/addr/ipv4.hpp>
#include <openvpn/addr/iperr.hpp>
namespace openvpn {
namespace IP {
class Addr;
}
// Fundamental classes for representing an IPv6 IP address.
namespace IPv6 {
OPENVPN_EXCEPTION(ipv6_exception);
class Addr // NOTE: must be union-legal, so default constructor does not initialize
{
friend class IP::Addr;
public:
enum { SIZE=128 };
static Addr from_addr(const Addr& addr)
{
return addr;
}
static Addr from_in6_addr(const struct in6_addr *in6)
{
Addr ret;
network_to_host_order(&ret.u, (const union ipv6addr *)in6->s6_addr);
ret.scope_id_ = 0;
return ret;
}
struct in6_addr to_in6_addr() const
{
struct in6_addr ret;
host_to_network_order((union ipv6addr *)&ret, &u);
return ret;
}
static Addr from_sockaddr(const struct sockaddr_in6 *sa)
{
Addr ret;
network_to_host_order(&ret.u, (const union ipv6addr *)sa->sin6_addr.s6_addr);
ret.scope_id_ = sa->sin6_scope_id;
return ret;
}
struct sockaddr_in6 to_sockaddr(const unsigned short port=0) const
{
struct sockaddr_in6 ret;
std::memset(&ret, 0, sizeof(ret));
ret.sin6_family = AF_INET6;
ret.sin6_port = htons(port);
host_to_network_order((union ipv6addr *)&ret.sin6_addr.s6_addr, &u);
ret.sin6_scope_id = scope_id_;
return ret;
}
static Addr from_string(const std::string& ipstr, const char *title = nullptr)
{
openvpn_io::error_code ec;
openvpn_io::ip::address_v6 a = openvpn_io::ip::make_address_v6(ipstr, ec);
if (ec)
throw ipv6_exception(IP::internal::format_error(ipstr, title, "v6", ec));
return from_asio(a);
}
std::string to_string() const
{
const openvpn_io::ip::address_v6 a = to_asio();
std::string ret = a.to_string();
return ret;
}
static Addr from_hex(const std::string& s)
{
Addr ret;
ret.scope_id_ = 0;
ret.zero();
size_t len = s.length();
size_t base = 0;
if (len > 0 && s[len-1] == 'L')
len -= 1;
if (len >= 2 && s[0] == '0' && s[1] == 'x')
{
base = 2;
len -= 2;
}
if (len < 1 || len > 32)
throw ipv6_exception("parse hex error");
size_t di = (len-1)>>1;
for (int i = (len & 1) ? -1 : 0; i < int(len); i += 2)
{
const size_t idx = base + i;
const int bh = (i >= 0) ? parse_hex_char(s[idx]) : 0;
const int bl = parse_hex_char(s[idx+1]);
if (bh == -1 || bl == -1)
throw ipv6_exception("parse hex error");
ret.u.bytes[Endian::e16(di--)] = (bh<<4) + bl;
}
return ret;
}
std::string to_hex() const
{
std::string ret;
ret.reserve(32);
bool firstnonzero = false;
for (size_t i = 0; i < 16; ++i)
{
const unsigned char b = u.bytes[Endian::e16rev(i)];
if (b || firstnonzero || i == 15)
{
const char bh = b >> 4;
if (bh || firstnonzero)
ret += render_hex_char(bh);
ret += render_hex_char(b & 0x0F);
firstnonzero = true;
}
}
return ret;
}
static Addr from_ulong(unsigned long ul)
{
Addr ret;
ret.scope_id_ = 0;
ret.u.u64[Endian::e2(0)] = std::uint64_t(ul);
ret.u.u64[Endian::e2(1)] = 0;
return ret;
}
// return *this as a unsigned long
unsigned long to_ulong() const
{
const unsigned long ret = (unsigned long)u.u64[Endian::e2(0)];
const std::uint64_t cmp = std::uint64_t(ret);
if (u.u64[Endian::e2(1)] || cmp != u.u64[Endian::e2(0)])
throw ipv6_exception("overflow in conversion from IPv6.Addr to unsigned long");
return ret;
}
static Addr from_long(long ul)
{
bool neg = false;
Addr ret;
ret.scope_id_ = 0;
if (ul < 0)
{
ul = -(ul + 1);
neg = true;
}
ret.u.u64[Endian::e2(0)] = std::uint64_t(ul);
ret.u.u64[Endian::e2(1)] = 0;
if (neg)
ret.negate();
return ret;
}
// return *this as a long
long to_long() const
{
bool neg = false;
Addr a = *this;
if (a.u.u64[Endian::e2(1)])
{
a.negate();
neg = true;
}
const long ret = (long)a.u.u64[Endian::e2(0)];
const std::uint64_t cmp = std::uint64_t(ret);
if (a.u.u64[Endian::e2(1)] || cmp != a.u.u64[Endian::e2(0)])
throw ipv6_exception("overflow in conversion from IPv6.Addr to long");
return neg ? -(ret + 1) : ret;
}
std::string arpa() const
{
throw ipv6_exception("arpa() not implemented");
}
static Addr from_asio(const openvpn_io::ip::address_v6& asio_addr)
{
Addr ret;
union ipv6addr addr;
addr.asio_bytes = asio_addr.to_bytes();
network_to_host_order(&ret.u, &addr);
ret.scope_id_ = (unsigned int)asio_addr.scope_id();
return ret;
}
static Addr from_byte_string(const unsigned char *bytestr)
{
Addr ret;
network_to_host_order(&ret.u, (const union ipv6addr *)bytestr);
ret.scope_id_ = 0;
return ret;
}
void to_byte_string(unsigned char *bytestr) const
{
host_to_network_order((union ipv6addr *)bytestr, &u);
}
static void v4_to_byte_string(unsigned char *bytestr,
const std::uint32_t v4addr)
{
union ipv6addr *a = (union ipv6addr *)bytestr;
a->u32[0] = a->u32[1] = a->u32[2] = 0;
a->u32[3] = v4addr;
}
static bool byte_string_is_v4(const unsigned char *bytestr)
{
const union ipv6addr *a = (const union ipv6addr *)bytestr;
return a->u32[0] == 0 && a->u32[1] == 0 && a->u32[2] == 0;
}
static std::uint32_t v4_from_byte_string(const unsigned char *bytestr)
{
const union ipv6addr *a = (const union ipv6addr *)bytestr;
return a->u32[3];
}
openvpn_io::ip::address_v6 to_asio() const
{
union ipv6addr addr;
host_to_network_order(&addr, &u);
return openvpn_io::ip::address_v6(addr.asio_bytes, scope_id_);
}
static Addr from_zero()
{
Addr ret;
ret.scope_id_ = 0;
ret.zero();
return ret;
}
static Addr from_one()
{
Addr ret;
ret.scope_id_ = 0;
ret.one();
return ret;
}
static Addr from_zero_complement()
{
Addr ret;
ret.scope_id_ = 0;
ret.zero_complement();
return ret;
}
// build a netmask using given prefix_len
static Addr netmask_from_prefix_len(const unsigned int prefix_len)
{
Addr ret;
ret.scope_id_ = 0;
ret.prefix_len_to_netmask(prefix_len);
return ret;
}
// build a netmask using given extent
Addr netmask_from_extent() const
{
const Addr lb = *this - 1;
for (size_t i = 4; i --> 0 ;)
{
const std::uint32_t v = lb.u.u32[Endian::e4(i)];
if (v)
return netmask_from_prefix_len(SIZE - (((unsigned int)i<<5) + find_last_set(v)));
}
return from_zero_complement();
}
Addr operator&(const Addr& other) const {
Addr ret;
ret.scope_id_ = scope_id_;
ret.u.u64[0] = u.u64[0] & other.u.u64[0];
ret.u.u64[1] = u.u64[1] & other.u.u64[1];
return ret;
}
Addr operator|(const Addr& other) const {
Addr ret;
ret.scope_id_ = scope_id_;
ret.u.u64[0] = u.u64[0] | other.u.u64[0];
ret.u.u64[1] = u.u64[1] | other.u.u64[1];
return ret;
}
Addr operator+(const long delta) const {
Addr ret = *this;
ret.u.u64[Endian::e2(0)] += delta;
ret.u.u64[Endian::e2(1)] += (delta >= 0)
? (ret.u.u64[Endian::e2(0)] < u.u64[Endian::e2(0)])
: -(ret.u.u64[Endian::e2(0)] > u.u64[Endian::e2(0)]);
return ret;
}
Addr operator+(const Addr& other) const {
Addr ret = *this;
add(ret.u, other.u);
return ret;
}
Addr operator-(const long delta) const {
return operator+(-delta);
}
Addr operator-(const Addr& other) const {
Addr ret = *this;
sub(ret.u, other.u);
return ret;
}
Addr operator*(const Addr& d) const {
Addr m = d;
Addr ret = from_zero();
for (unsigned int i = 0; i < SIZE; ++i)
{
if (bit(i))
ret += m;
m <<= 1;
}
return ret;
}
Addr operator/(const Addr& d) const {
Addr q, r;
div(*this, d, q, r);
return q;
}
Addr operator%(const Addr& d) const {
Addr q, r;
div(*this, d, q, r);
return r;
}
Addr operator<<(const unsigned int shift) const {
Addr ret = *this;
shiftl128(ret.u.u64[Endian::e2(0)],
ret.u.u64[Endian::e2(1)],
shift);
return ret;
}
Addr operator>>(const unsigned int shift) const {
Addr ret = *this;
shiftr128(ret.u.u64[Endian::e2(0)],
ret.u.u64[Endian::e2(1)],
shift);
return ret;
}
Addr operator~() const {
Addr ret;
ret.scope_id_ = scope_id_;
ret.u.u64[0] = ~u.u64[0];
ret.u.u64[1] = ~u.u64[1];
return ret;
}
// return the network that contains the current address
Addr network_addr(const unsigned int prefix_len) const
{
return *this & netmask_from_prefix_len(prefix_len);
}
bool operator==(const Addr& other) const
{
return u.u64[0] == other.u.u64[0] && u.u64[1] == other.u.u64[1] && scope_id_ == other.scope_id_;
}
bool operator!=(const Addr& other) const
{
return !operator==(other);
}
#define OPENVPN_IPV6_OPERATOR_REL(OP) \
bool operator OP(const Addr& other) const \
{ \
if (u.u64[Endian::e2(1)] == other.u.u64[Endian::e2(1)]) \
{ \
if (u.u64[Endian::e2(0)] != other.u.u64[Endian::e2(0)]) \
return u.u64[Endian::e2(0)] OP other.u.u64[Endian::e2(0)]; \
else \
return scope_id_ OP other.scope_id_; \
} \
else \
return u.u64[Endian::e2(1)] OP other.u.u64[Endian::e2(1)]; \
}
OPENVPN_IPV6_OPERATOR_REL(<)
OPENVPN_IPV6_OPERATOR_REL(>)
OPENVPN_IPV6_OPERATOR_REL(<=)
OPENVPN_IPV6_OPERATOR_REL(>=)
#undef OPENVPN_IPV6_OPERATOR_REL
bool unspecified() const
{
return all_zeros();
}
bool specified() const
{
return !unspecified();
}
bool all_zeros() const
{
return u.u64[0] == 0 && u.u64[1] == 0;
}
bool all_ones() const
{
return u.u64[0] == ~std::uint64_t(0) && u.u64[1] == ~std::uint64_t(0);
}
bool is_loopback() const // ::1
{
return u.u64[Endian::e2(1)] == 0 && u.u64[Endian::e2(0)] == 1;
}
bool bit(unsigned int pos) const
{
if (pos < 64)
return (u.u64[Endian::e2(0)] & (std::uint64_t(1)<<pos)) != 0;
else
return (u.u64[Endian::e2(1)] & (std::uint64_t(1)<<(pos-64))) != 0;
}
// number of network bits in netmask,
// throws exception if addr is not a netmask
unsigned int prefix_len() const
{
int idx = -1;
if (u.u32[Endian::e4(3)] != ~std::uint32_t(0))
{
if (!u.u32[Endian::e4(0)] && !u.u32[Endian::e4(1)] && !u.u32[Endian::e4(2)])
idx = 0;
}
else if (u.u32[Endian::e4(2)] != ~std::uint32_t(0))
{
if (!u.u32[Endian::e4(0)] && !u.u32[Endian::e4(1)])
idx = 1;
}
else if (u.u32[Endian::e4(1)] != ~std::uint32_t(0))
{
if (!u.u32[Endian::e4(0)])
idx = 2;
}
else
idx = 3;
if (idx >= 0)
{
const int ret = IPv4::Addr::prefix_len_32(u.u32[Endian::e4rev(idx)]);
if (ret >= 0)
return ret + (idx<<5);
}
throw ipv6_exception("malformed netmask");
}
// number of host bits in netmask
unsigned int host_len() const
{
return SIZE - prefix_len();
}
// return the number of host addresses contained within netmask
Addr extent_from_netmask() const
{
const unsigned int hl = host_len();
if (hl < SIZE)
{
Addr a;
a.scope_id_ = 0;
a.one();
return a << hl;
}
else if (hl == SIZE)
return from_zero();
else
throw ipv6_exception("extent overflow");
}
// address size in bits
static unsigned int size()
{
return SIZE;
}
template <typename HASH>
void hash(HASH& h) const
{
h(u.bytes, sizeof(u.bytes));
}
#ifdef OPENVPN_IP_IMMUTABLE
private:
#endif
void negate()
{
u.u64[0] = ~u.u64[0];
u.u64[1] = ~u.u64[1];
}
void zero()
{
u.u64[0] = 0;
u.u64[1] = 0;
}
void zero_complement()
{
u.u64[0] = ~std::uint64_t(0);
u.u64[1] = ~std::uint64_t(0);
}
void one()
{
u.u64[0] = 1;
u.u64[1] = 0;
}
Addr& operator++()
{
if (++u.u64[Endian::e2(0)] == 0)
++u.u64[Endian::e2(1)];
return *this;
}
Addr& operator+=(const long delta)
{
*this = *this + delta;
return *this;
}
Addr& operator-=(const long delta)
{
return operator+=(-delta);
}
Addr& operator+=(const Addr& other) {
add(u, other.u);
return *this;
}
Addr& operator-=(const Addr& other) {
sub(u, other.u);
return *this;
}
Addr& operator<<=(const unsigned int shift) {
shiftl128(u.u64[Endian::e2(0)],
u.u64[Endian::e2(1)],
shift);
return *this;
}
Addr& operator>>=(const unsigned int shift) {
shiftr128(u.u64[Endian::e2(0)],
u.u64[Endian::e2(1)],
shift);
return *this;
}
void set_clear_bit(unsigned int pos, bool value)
{
if (pos < 64)
{
if (value)
u.u64[Endian::e2(0)] |= (std::uint64_t(1)<<pos);
else
u.u64[Endian::e2(0)] &= ~(std::uint64_t(1)<<pos);
}
else
{
if (value)
u.u64[Endian::e2(1)] |= (std::uint64_t(1)<<(pos-64));
else
u.u64[Endian::e2(1)] &= ~(std::uint64_t(1)<<(pos-64));
}
}
void set_bit(unsigned int pos, bool value)
{
if (value)
{
if (pos < 64)
u.u64[Endian::e2(0)] |= (std::uint64_t(1)<<pos);
else
u.u64[Endian::e2(1)] |= (std::uint64_t(1)<<(pos-64));
}
}
static void div(const Addr& n, const Addr& d, Addr& q, Addr& r)
{
if (d.all_zeros())
throw ipv6_exception("division by 0");
q = from_zero(); // quotient
r = n; // remainder (init to numerator)
Addr ml = from_zero(); // mask low
Addr mh = d; // mask high (init to denominator)
for (unsigned int i = 0; i < SIZE; ++i)
{
ml >>= 1;
ml.set_bit(SIZE-1, mh.bit(0));
mh >>= 1;
if (mh.all_zeros() && r >= ml)
{
r -= ml;
q.set_bit((SIZE-1)-i, true);
}
}
}
int scope_id() const
{
return scope_id_;
}
private:
union ipv6addr {
std::uint64_t u64[2];
std::uint32_t u32[4]; // generally stored in host byte order
unsigned char bytes[16];
openvpn_io::ip::address_v6::bytes_type asio_bytes;
};
void prefix_len_to_netmask_unchecked(const unsigned int prefix_len)
{
if (prefix_len > 0)
{
const unsigned int pl = prefix_len - 1;
const std::uint32_t mask = ~((1 << (31 - (pl & 31))) - 1);
switch (pl >> 5)
{
case 0:
u.u32[Endian::e4(0)] = 0;
u.u32[Endian::e4(1)] = 0;
u.u32[Endian::e4(2)] = 0;
u.u32[Endian::e4(3)] = mask;
break;
case 1:
u.u32[Endian::e4(0)] = 0;
u.u32[Endian::e4(1)] = 0;
u.u32[Endian::e4(2)] = mask;
u.u32[Endian::e4(3)] = ~0;
break;
case 2:
u.u32[Endian::e4(0)] = 0;
u.u32[Endian::e4(1)] = mask;
u.u32[Endian::e4(2)] = ~0;
u.u32[Endian::e4(3)] = ~0;
break;
case 3:
u.u32[Endian::e4(0)] = mask;
u.u32[Endian::e4(1)] = ~0;
u.u32[Endian::e4(2)] = ~0;
u.u32[Endian::e4(3)] = ~0;
break;
}
}
else
zero();
}
void prefix_len_to_netmask(const unsigned int prefix_len)
{
if (prefix_len <= SIZE)
return prefix_len_to_netmask_unchecked(prefix_len);
else
throw ipv6_exception("bad prefix len");
}
static void host_to_network_order(union ipv6addr *dest, const union ipv6addr *src)
{
dest->u32[0] = htonl(src->u32[Endian::e4rev(0)]);
dest->u32[1] = htonl(src->u32[Endian::e4rev(1)]);
dest->u32[2] = htonl(src->u32[Endian::e4rev(2)]);
dest->u32[3] = htonl(src->u32[Endian::e4rev(3)]);
}
static void network_to_host_order(union ipv6addr *dest, const union ipv6addr *src)
{
dest->u32[0] = ntohl(src->u32[Endian::e4rev(0)]);
dest->u32[1] = ntohl(src->u32[Endian::e4rev(1)]);
dest->u32[2] = ntohl(src->u32[Endian::e4rev(2)]);
dest->u32[3] = ntohl(src->u32[Endian::e4rev(3)]);
}
static void shiftl128(std::uint64_t& low,
std::uint64_t& high,
unsigned int shift)
{
if (shift == 1)
{
high <<= 1;
if (low & (std::uint64_t(1) << 63))
high |= 1;
low <<= 1;
}
else if (shift == 0)
;
else if (shift <= 128)
{
if (shift >= 64)
{
high = low;
low = 0;
shift -= 64;
}
if (shift < 64)
{
high = (high << shift) | (low >> (64-shift));
low <<= shift;
}
else // shift == 64
high = 0;
}
else
throw ipv6_exception("l-shift too large");
}
static void shiftr128(std::uint64_t& low,
std::uint64_t& high,
unsigned int shift)
{
if (shift == 1)
{
low >>= 1;
if (high & 1)
low |= (std::uint64_t(1) << 63);
high >>= 1;
}
else if (shift == 0)
;
else if (shift <= 128)
{
if (shift >= 64)
{
low = high;
high = 0;
shift -= 64;
}
if (shift < 64)
{
low = (low >> shift) | (high << (64-shift));
high >>= shift;
}
else // shift == 64
low = 0;
}
else
throw ipv6_exception("r-shift too large");
}
static void add(ipv6addr& dest, const ipv6addr& src) {
const std::uint64_t dorigl = dest.u64[Endian::e2(0)];
dest.u64[Endian::e2(0)] += src.u64[Endian::e2(0)];
dest.u64[Endian::e2(1)] += src.u64[Endian::e2(1)];
// check for overflow of low 64 bits, add carry to high
if (dest.u64[Endian::e2(0)] < dorigl)
++dest.u64[Endian::e2(1)];
}
static void sub(ipv6addr& dest, const ipv6addr& src) {
const std::uint64_t dorigl = dest.u64[Endian::e2(0)];
dest.u64[Endian::e2(0)] -= src.u64[Endian::e2(0)];
dest.u64[Endian::e2(1)] -= src.u64[Endian::e2(1)]
+ (dorigl < dest.u64[Endian::e2(0)]);
}
union ipv6addr u;
unsigned int scope_id_;
};
OPENVPN_OSTREAM(Addr, to_string)
}
}
#endif // OPENVPN_ADDR_IPV6_H

View File

@@ -1,67 +0,0 @@
// 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_MACADDR_H
#define OPENVPN_ADDR_MACADDR_H
#include <ostream>
#include <cstring>
#include <string>
#include <openvpn/common/exception.hpp>
#include <openvpn/common/ostream.hpp>
#include <openvpn/common/hexstr.hpp>
namespace openvpn {
// Fundamental class for representing an ethernet MAC address.
class MACAddr {
public:
MACAddr()
{
std::memset(addr_, 0, sizeof(addr_));
}
MACAddr(const unsigned char *addr)
{
reset(addr);
}
void reset(const unsigned char *addr)
{
std::memcpy(addr_, addr, sizeof(addr_));
}
std::string to_string() const
{
return render_hex_sep(addr_, sizeof(addr_), ':');
}
private:
unsigned char addr_[6];
};
OPENVPN_OSTREAM(MACAddr, to_string)
} // namespace openvpn
#endif // OPENVPN_ADDR_MACADDR_H

View File

@@ -1,138 +0,0 @@
// 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_POOL_H
#define OPENVPN_ADDR_POOL_H
#include <string>
#include <sstream>
#include <deque>
#include <unordered_map>
#include <openvpn/common/size.hpp>
#include <openvpn/common/exception.hpp>
#include <openvpn/addr/ip.hpp>
#include <openvpn/addr/range.hpp>
namespace openvpn {
namespace IP {
// Maintain a pool of IP addresses.
// A should be IP::Addr, IPv4::Addr, or IPv6::Addr.
template <typename ADDR>
class PoolType
{
public:
PoolType() {}
// Add range of addresses to pool (pool will own the addresses).
void add_range(const RangeType<ADDR>& range)
{
typename RangeType<ADDR>::Iterator iter = range.iterator();
while (iter.more())
{
const ADDR& a = iter.addr();
add_addr(a);
iter.next();
}
}
// Add single address to pool (pool will own the address).
void add_addr(const ADDR& addr)
{
typename std::unordered_map<ADDR, bool>::const_iterator e = map.find(addr);
if (e == map.end())
{
freelist.push_back(addr);
map[addr] = false;
}
}
// Return number of pool addresses currently in use.
size_t n_in_use() const
{
return map.size() - freelist.size();
}
// Acquire an address from pool. Returns true if successful,
// with address placed in dest, or false if pool depleted.
bool acquire_addr(ADDR& dest)
{
while (true)
{
if (freelist.empty())
return false;
const ADDR& a = freelist.front();
typename std::unordered_map<ADDR, bool>::iterator e = map.find(a);
if (e == map.end()) // any address in freelist must exist in map
throw Exception("PoolType: address in freelist doesn't exist in map");
if (!e->second)
{
e->second = true;
dest = a;
freelist.pop_front();
return true;
}
freelist.pop_front();
}
}
// Acquire a specific address from pool, returning true if
// successful, or false if the address is not available.
bool acquire_specific_addr(const ADDR& addr)
{
typename std::unordered_map<ADDR, bool>::iterator e = map.find(addr);
if (e != map.end() && !e->second)
{
e->second = true;
return true;
}
else
return false;
}
// Return a previously acquired address to the pool. Does nothing if
// (a) the address is owned by the pool and marked as free, or
// (b) the address is not owned by the pool.
void release_addr(const ADDR& addr)
{
typename std::unordered_map<ADDR, bool>::iterator e = map.find(addr);
if (e != map.end() && e->second)
{
freelist.push_back(addr);
e->second = false;
}
}
// DEBUGGING -- get the map load factor
float load_factor() const { return map.load_factor(); }
private:
std::deque<ADDR> freelist;
std::unordered_map<ADDR, bool> map;
};
typedef PoolType<IP::Addr> Pool;
}
}
#endif

View File

@@ -1,137 +0,0 @@
// 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_RANGE_H
#define OPENVPN_ADDR_RANGE_H
#include <string>
#include <sstream>
#include <openvpn/common/size.hpp>
#include <openvpn/common/exception.hpp>
#include <openvpn/addr/ip.hpp>
namespace openvpn {
namespace IP {
// Denote a range of IP addresses with a start and extent,
// where A represents an address class.
// A should be a network address class such as IP::Addr, IPv4::Addr, or IPv6::Addr.
template <typename ADDR>
class RangeType
{
public:
class Iterator
{
friend class RangeType;
public:
bool more() const { return remaining_ > 0; }
const ADDR& addr() const { return addr_; }
void next()
{
if (more())
{
++addr_;
--remaining_;
}
}
private:
Iterator(const RangeType& range)
: addr_(range.start_), remaining_(range.extent_) {}
ADDR addr_;
size_t remaining_;
};
RangeType() : extent_(0) {}
RangeType(const ADDR& start, const size_t extent)
: start_(start), extent_(extent) {}
Iterator iterator() const { return Iterator(*this); }
const bool defined() const { return extent_ > 0; }
const ADDR& start() const { return start_; }
size_t extent() const { return extent_; }
RangeType pull_front(size_t extent)
{
if (extent > extent_)
extent = extent_;
RangeType ret(start_, extent);
start_ += extent;
extent_ -= extent;
return ret;
}
std::string to_string() const
{
std::ostringstream os;
os << start_.to_string() << '[' << extent_ << ']';
return os.str();
}
private:
ADDR start_;
size_t extent_;
};
template <typename ADDR>
class RangePartitionType
{
public:
RangePartitionType(const RangeType<ADDR>& src_range, const size_t n_partitions)
: range(src_range),
remaining(n_partitions)
{
}
bool next(RangeType<ADDR>& r)
{
if (remaining)
{
if (remaining > 1)
r = range.pull_front(range.extent() / remaining);
else
r = range;
--remaining;
return r.defined();
}
else
return false;
}
private:
RangeType<ADDR> range;
size_t remaining;
};
typedef RangeType<IP::Addr> Range;
typedef RangePartitionType<IP::Addr> RangePartition;
}
}
#endif

View File

@@ -1,59 +0,0 @@
// 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/>.
// Regular expressions for IPv4/v6
// Source: http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
#ifndef OPENVPN_ADDR_REGEX_H
#define OPENVPN_ADDR_REGEX_H
#include <string>
namespace openvpn {
namespace IP {
inline std::string v4_regex()
{
const std::string ipv4seg = "(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])";
return "(?:" + ipv4seg + "\\.){3,3}" + ipv4seg;
}
inline std::string v6_regex()
{
const std::string ipv6seg = "[0-9a-fA-F]{1,4}";
return "(?:"
"(?:" + ipv6seg + ":){7,7}" + ipv6seg + "|" // 1:2:3:4:5:6:7:8
"(?:" + ipv6seg + ":){1,7}:|" // 1:: 1:2:3:4:5:6:7::
"(?:" + ipv6seg + ":){1,6}:" + ipv6seg + "|" // 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
"(?:" + ipv6seg + ":){1,5}(?::" + ipv6seg + "){1,2}|" // 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
"(?:" + ipv6seg + ":){1,4}(?::" + ipv6seg + "){1,3}|" // 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
"(?:" + ipv6seg + ":){1,3}(?::" + ipv6seg + "){1,4}|" // 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
"(?:" + ipv6seg + ":){1,2}(?::" + ipv6seg + "){1,5}|" + // 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
ipv6seg + ":(?:(?::" + ipv6seg + "){1,6})|" // 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
":(?:(?::" + ipv6seg + "){1,7}|:)|" // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
"fe80:(?::" + ipv6seg + "){0,4}%[0-9a-zA-Z]{1,}|" // fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index)
"::(?:ffff(?::0{1,4}){0,1}:){0,1}" + v4_regex() + "|" // ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
"(?:" + ipv6seg + ":){1,4}:" + v4_regex() + // 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
")";
}
}
}
#endif

View File

@@ -1,287 +0,0 @@
// 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_ROUTE_H
#define OPENVPN_ADDR_ROUTE_H
#include <string>
#include <sstream>
#include <vector>
#include <cstdint> // for std::uint32_t
#include <tuple>
#include <openvpn/common/size.hpp>
#include <openvpn/common/exception.hpp>
#include <openvpn/common/number.hpp>
#include <openvpn/common/to_string.hpp>
#include <openvpn/common/split.hpp>
#include <openvpn/common/hash.hpp>
#include <openvpn/addr/ip.hpp>
namespace openvpn {
namespace IP {
// Basic route object
template <typename ADDR>
struct RouteType
{
typedef ADDR Addr;
ADDR addr;
unsigned int prefix_len;
OPENVPN_EXCEPTION(route_error);
RouteType()
: prefix_len(0)
{
}
RouteType(const std::string& rtstr, const char *title = nullptr)
: RouteType(RouteType::from_string(rtstr, title))
{
}
RouteType(const std::string& rtstr, const std::string& title)
: RouteType(RouteType::from_string(rtstr, title.c_str()))
{
}
RouteType(const ADDR& addr_arg,
const unsigned int prefix_len_arg)
: addr(addr_arg),
prefix_len(prefix_len_arg)
{
}
static RouteType from_string(const std::string& rtstr, const char *title = nullptr)
{
RouteType r;
std::vector<std::string> pair;
pair.reserve(2);
Split::by_char_void<std::vector<std::string>, NullLex, Split::NullLimit>(pair, rtstr, '/', 0, 1);
r.addr = ADDR::from_string(pair[0], title);
if (pair.size() >= 2)
{
r.prefix_len = parse_number_throw<unsigned int>(pair[1], "prefix length");
if (r.prefix_len > r.addr.size())
OPENVPN_THROW(route_error, (title ? title : "route") << " : bad prefix length : " << rtstr);
}
else
r.prefix_len = r.addr.size();
return r;
}
IP::Addr::Version version() const
{
return addr.version();
}
IP::Addr::VersionMask version_mask() const
{
return addr.version_mask();
}
ADDR netmask() const
{
return ADDR::netmask_from_prefix_len(version(), prefix_len);
}
size_t extent() const
{
return netmask().extent_from_netmask().to_ulong();
}
bool is_canonical() const
{
return (addr & netmask()) == addr;
}
void force_canonical()
{
addr = addr & netmask();
}
bool is_host() const
{
return addr.defined() && prefix_len == addr.size();
}
unsigned int host_bits() const
{
if (prefix_len < addr.size())
return addr.size() - prefix_len;
else
return 0;
}
bool contains(const ADDR& a) const // assumes canonical address/routes
{
if (addr.defined() && addr.version() == a.version())
return (a & netmask()) == addr;
else
return false;
}
bool contains(const RouteType& r) const // assumes canonical routes
{
return contains(r.addr) && r.prefix_len >= prefix_len;
}
bool split(RouteType& r1, RouteType& r2) const // assumes we are canonical
{
if (!is_host())
{
const unsigned int newpl = prefix_len + 1;
r1.addr = addr;
r1.prefix_len = newpl;
r2.addr = addr + ADDR::netmask_from_prefix_len(addr.version(), newpl).extent_from_netmask();
r2.prefix_len = newpl;
return true;
}
return false;
}
std::string to_string() const
{
return addr.to_string() + '/' + openvpn::to_string(prefix_len);
}
std::string to_string_by_netmask() const
{
return addr.to_string() + ' ' + netmask().to_string();
}
bool operator==(const RouteType& other) const
{
return std::tie(prefix_len, addr) == std::tie(other.prefix_len, other.addr);
}
bool operator<(const RouteType& other) const
{
return std::tie(prefix_len, addr) < std::tie(other.prefix_len, other.addr);
}
template <typename HASH>
void hash(HASH& h) const
{
addr.hash(h);
h(prefix_len);
}
#ifdef HAVE_CITYHASH
std::size_t hash_value() const
{
HashSizeT h;
hash(h);
return h.value();
}
#endif
};
template <typename ADDR>
struct RouteTypeList : public std::vector<RouteType<ADDR>>
{
typedef std::vector< RouteType<ADDR> > Base;
OPENVPN_EXCEPTION(route_list_error);
std::string to_string() const
{
std::ostringstream os;
for (auto &r : *this)
os << r.to_string() << std::endl;
return os.str();
}
IP::Addr::VersionMask version_mask() const
{
IP::Addr::VersionMask mask = 0;
for (auto &r : *this)
mask |= r.version_mask();
return mask;
}
void verify_canonical() const
{
for (auto &r : *this)
if (!r.is_canonical())
throw route_list_error("route not canonical: " + r.to_string());
}
template <typename R>
bool contains(const R& c) const
{
for (auto &r : *this)
if (r.contains(c))
return true;
return false;
}
};
typedef RouteType<IP::Addr> Route;
typedef RouteType<IPv4::Addr> Route4;
typedef RouteType<IPv6::Addr> Route6;
typedef RouteTypeList<IP::Addr> RouteList;
typedef RouteTypeList<IPv4::Addr> Route4List;
typedef RouteTypeList<IPv6::Addr> Route6List;
OPENVPN_OSTREAM(Route, to_string);
OPENVPN_OSTREAM(Route4, to_string);
OPENVPN_OSTREAM(Route6, to_string);
OPENVPN_OSTREAM(RouteList, to_string);
OPENVPN_OSTREAM(Route4List, to_string);
OPENVPN_OSTREAM(Route6List, to_string);
inline Route route_from_string_prefix(const std::string& addrstr,
const unsigned int prefix_len,
const std::string& title,
const IP::Addr::Version required_version = IP::Addr::UNSPEC)
{
Route r;
r.addr = IP::Addr(addrstr, title, required_version);
r.prefix_len = prefix_len;
if (r.prefix_len > r.addr.size())
OPENVPN_THROW(Route::route_error, title << " : bad prefix length : " << addrstr);
return r;
}
inline Route route_from_string(const std::string& rtstr,
const std::string& title,
const IP::Addr::Version required_version = IP::Addr::UNSPEC)
{
Route r(rtstr, title);
r.addr.validate_version(title, required_version);
return r;
}
}
}
#ifdef HAVE_CITYHASH
OPENVPN_HASH_METHOD(openvpn::IP::Route, hash_value);
OPENVPN_HASH_METHOD(openvpn::IP::Route4, hash_value);
OPENVPN_HASH_METHOD(openvpn::IP::Route6, hash_value);
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More