Compare commits
88 Commits
5.9.2
...
laforge/sw
Author | SHA1 | Date |
---|---|---|
Domonkos P. Tomcsanyi | cea991aea8 | |
Tomcsányi, Domonkos | 0ed91dc681 | |
Tomcsányi, Domonkos | 65f576bd9c | |
Tomcsányi, Domonkos | 18b4a240dd | |
Tomcsányi, Domonkos | f68dcde6c5 | |
Andreas Steffen | 4817d5ed0d | |
Andreas Steffen | a09a905e1d | |
Tobias Brunner | 2cd5314de7 | |
Tobias Brunner | 06e11b481b | |
Tobias Brunner | f6aafb3005 | |
Andreas Steffen | 30fab57124 | |
Tobias Brunner | 19611b1d28 | |
Andreas Steffen | 4baca5ca80 | |
Andreas Steffen | dbd1534875 | |
Andreas Steffen | eba2622587 | |
Andreas Steffen | 706c58b291 | |
Tobias Brunner | 6d8890767c | |
Tobias Brunner | 2b5c743952 | |
Tobias Brunner | abe51389c5 | |
Tobias Brunner | 036ae27645 | |
Tobias Brunner | 79b526deba | |
Tobias Brunner | 4b9b4dc956 | |
Tobias Brunner | eec3bdb04a | |
Tobias Brunner | b0e2187b6b | |
Tobias Brunner | 030e80957d | |
Tobias Brunner | 0fc8cf0013 | |
Adrian-Ken Rueegsegger | 859dedeab7 | |
Stefan Berghofer | d7a9e723f3 | |
Stefan Berghofer | 22e7900718 | |
Tobias Brunner | 6537be9c8d | |
Tobias Brunner | a90716cd4d | |
Tobias Brunner | 8dbf40d19a | |
Tobias Brunner | ae71f8357d | |
Thomas Egerer | 4e29d6fac1 | |
Andreas Steffen | 9c85a52956 | |
Tobias Brunner | e166423856 | |
Andreas Steffen | cc4338267e | |
Andreas Steffen | 5688e631e3 | |
Andreas Steffen | de5ca4021a | |
Andreas Steffen | 8bbd7bbd36 | |
Andreas Steffen | e0044e5f48 | |
Andreas Steffen | 62c5ef035c | |
Marius Tomaschewski | d654117c66 | |
Tobias Brunner | a82f13e7ce | |
Noel Kuntze | 6c49ddfbca | |
Andreas Steffen | d415673565 | |
Andreas Steffen | 7c5a2974b9 | |
Tobias Brunner | db93938297 | |
Tobias Brunner | c13a1c2829 | |
Noel Kuntze | cf6a164108 | |
Tobias Brunner | 1eb2d149db | |
Tobias Brunner | d4c337a42f | |
Adrian-Ken Rueegsegger | f0c25960ed | |
Adrian-Ken Rueegsegger | 027c5c9dcb | |
Adrian-Ken Rueegsegger | 97c9158378 | |
Adrian-Ken Rueegsegger | 9f468f454a | |
Tobias Brunner | 546f61d3c8 | |
Noel Kuntze | 5191c2b063 | |
Tobias Brunner | a730873211 | |
Tobias Brunner | 9535c3f778 | |
Tobias Brunner | 2f650e085b | |
Noel Kuntze | 260e7b55f6 | |
Tobias Brunner | cd7b80e869 | |
Noel Kuntze | f830e71457 | |
Tobias Brunner | c603704bb3 | |
Tobias Brunner | 742e0f213c | |
Tobias Brunner | eca1b81682 | |
Tobias Brunner | 6405653da2 | |
Tobias Brunner | f0a20dd2b8 | |
Noel Kuntze | 1de13f9037 | |
Noel Kuntze | e9a55abce4 | |
Tobias Brunner | 2b89676157 | |
Noel Kuntze | 4886a2c7d8 | |
Noel Kuntze | a11efc5214 | |
Andreas Steffen | 09df86c033 | |
Andreas Steffen | 66ba50b217 | |
Andreas Steffen | 03e1272ff2 | |
Andreas Steffen | 68154033bb | |
Andreas Steffen | 2cbf7da51a | |
Andreas Steffen | 511b860916 | |
Andreas Steffen | 5c22e94f0f | |
Andreas Steffen | 737f7fce51 | |
Andreas Steffen | f412c97648 | |
Andreas Steffen | a91eb3eb96 | |
Andreas Steffen | b57215ba2b | |
Andreas Steffen | bd323ae6c8 | |
Petr Gotthard | c5eac9c390 | |
Andreas Steffen | 6aef079f59 |
|
@ -6,7 +6,7 @@ runs:
|
|||
run: ./scripts/test.sh deps
|
||||
shell: bash
|
||||
- name: "Install Python Dependencies"
|
||||
run: ./scripts/test.sh deps
|
||||
run: ./scripts/test.sh pydeps
|
||||
shell: bash
|
||||
- name: "Build Dependencies"
|
||||
run: ./scripts/test.sh build-deps
|
||||
|
|
|
@ -48,8 +48,7 @@ jobs:
|
|||
ccache -z
|
||||
- uses: ./.github/actions/default
|
||||
- run: ccache -s
|
||||
- if: ${{ success() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Lint Results
|
||||
path: src/frontends/android/app/build/reports/lint-results.xml
|
||||
|
|
|
@ -30,6 +30,7 @@ jobs:
|
|||
# so we continue to use the approach we used on Travis
|
||||
- env:
|
||||
LGTM_TOKEN: ${{ secrets.LGTM_TOKEN }}
|
||||
LGTM_PROJECT: ${{ secrets.LGTM_PROJECT }}
|
||||
BUILD_NUMBER: ${{ github.run_id }}
|
||||
COMMIT_ID: ${{ github.sha }}
|
||||
COMMIT_BASE: ${{ github.event.before }}
|
||||
|
|
|
@ -44,7 +44,6 @@ jobs:
|
|||
- test: apidoc
|
||||
- test: coverage
|
||||
- test: dist
|
||||
- test: nm
|
||||
- test: nm-no-glib
|
||||
- test: fuzzing
|
||||
compiler: clang
|
||||
|
@ -121,6 +120,44 @@ jobs:
|
|||
path: config.log
|
||||
retention-days: 5
|
||||
|
||||
bionic:
|
||||
needs: pre-check
|
||||
if: ${{ needs.pre-check.outputs.should_skip != 'true' }}
|
||||
runs-on: ubuntu-18.04
|
||||
strategy:
|
||||
matrix:
|
||||
test: [ all ]
|
||||
compiler: [ gcc, clang ]
|
||||
include:
|
||||
- test: nm
|
||||
env:
|
||||
LEAK_DETECTIVE: ${{ matrix.leak-detective || 'no' }}
|
||||
CC: ${{ matrix.compiler || 'gcc' }}
|
||||
TEST: ${{ matrix.test }}
|
||||
UBUNTU_BIONIC: yes
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-bionic-${{ env.CC }}-${{ matrix.test }}-${{ github.ref }}:${{ github.sha }}
|
||||
restore-keys: |
|
||||
ccache-bionic-${{ env.CC }}-${{ matrix.test }}-${{ github.ref }}:
|
||||
ccache-bionic-${{ env.CC }}-${{ matrix.test }}-
|
||||
ccache-bionic-${{ env.CC }}-
|
||||
- run: |
|
||||
sudo apt-get install -qq ccache
|
||||
echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
|
||||
ccache -z
|
||||
- uses: ./.github/actions/default
|
||||
- run: ccache -s
|
||||
- if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Logs ${{ github.job }}
|
||||
path: config.log
|
||||
retention-days: 5
|
||||
|
||||
xenial:
|
||||
needs: pre-check
|
||||
if: ${{ needs.pre-check.outputs.should_skip != 'true' }}
|
||||
|
@ -137,7 +174,6 @@ jobs:
|
|||
LEAK_DETECTIVE: ${{ matrix.leak-detective || 'no' }}
|
||||
CC: ${{ matrix.compiler || 'gcc' }}
|
||||
TEST: ${{ matrix.test }}
|
||||
UBUNTU_XENIAL: yes
|
||||
# this is the default with newer versions and fixes builds with clang
|
||||
CCACHE_CPP2: true
|
||||
steps:
|
||||
|
|
15
Doxyfile.in
15
Doxyfile.in
|
@ -1990,12 +1990,6 @@ EXTERNAL_GROUPS = YES
|
|||
|
||||
EXTERNAL_PAGES = YES
|
||||
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of 'which perl').
|
||||
# The default file (with absolute path) is: /usr/bin/perl.
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -2009,15 +2003,6 @@ PERL_PATH = /usr/bin/perl
|
|||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# You can define message sequence charts within doxygen comments using the \msc
|
||||
# command. Doxygen will then run the mscgen tool (see:
|
||||
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
|
||||
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||
# default search path.
|
||||
|
||||
MSCGEN_PATH =
|
||||
|
||||
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||
# then run dia to produce the diagram and insert it in the documentation. The
|
||||
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||
|
|
26
NEWS
26
NEWS
|
@ -1,3 +1,27 @@
|
|||
strongswan-5.9.3
|
||||
----------------
|
||||
|
||||
- Added AES_ECB, SHA-3 and SHAKE-256 support to wolfssl plugin.
|
||||
|
||||
- Added AES_CCM and SHA-3 signature support to openssl plugin.
|
||||
|
||||
- The x509 and openssl plugins now consider the authorityKeyIdentifier, if
|
||||
available, before verifying signatures, which avoids unnecessary signature
|
||||
verifications after a CA key rollover if both certificates are loaded.
|
||||
|
||||
- The pkcs11 plugin better handles optional attributes like CKA_TRUSTED, which
|
||||
previously depended on a version check.
|
||||
|
||||
- charon-nm now supports using SANs as client identities, not only full DNs.
|
||||
|
||||
- charon-tkm now handles IKE encryption.
|
||||
|
||||
- A MOBIKE update is sent again if a a change in the NAT mappings is detected
|
||||
but the endpoints stay the same.
|
||||
|
||||
- Converted most of the test case scenarios to the vici interface
|
||||
|
||||
|
||||
strongswan-5.9.2
|
||||
----------------
|
||||
|
||||
|
@ -2719,7 +2743,7 @@ strongswan-4.1.5
|
|||
strongswan-4.1.4
|
||||
----------------
|
||||
|
||||
- The pluto IKEv1 daemon now exhibits the same behaviour as its
|
||||
- The pluto IKEv1 daemon now exhibits the same behavior as its
|
||||
IKEv2 companion charon by inserting an explicit route via the
|
||||
_updown script only if a sourceip exists. This is admissible
|
||||
since routing through the IPsec tunnel is handled automatically
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# strongSwan Configuration #
|
||||
## Patched version, containing patch to disable parsing of AUTH payload in IKEv2 Phase2, because we only want EAP-AKA ##
|
||||
|
||||
## Overview ##
|
||||
|
||||
|
|
21
configure.ac
21
configure.ac
|
@ -3,6 +3,8 @@
|
|||
# Copyright (C) 2006-2019 Andreas Steffen
|
||||
# Copyright (C) 2006-2014 Martin Willi
|
||||
# HSR Hochschule fuer Technik Rapperswil
|
||||
# Copyright (C) 2017 Domonkos P. Tomcsanyi
|
||||
# umlaut Communications Gmbh.
|
||||
#
|
||||
# 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
|
||||
|
@ -19,7 +21,7 @@
|
|||
# initialize & set some vars
|
||||
# ============================
|
||||
|
||||
AC_INIT([strongSwan],[5.9.2])
|
||||
AC_INIT([strongSwan],[5.9.3])
|
||||
AM_INIT_AUTOMAKE(m4_esyscmd([
|
||||
echo tar-ustar
|
||||
echo subdir-objects
|
||||
|
@ -199,7 +201,8 @@ ARG_ENABL_SET([eap-sim-pcsc], [enable EAP-SIM backend based on a smartcard rea
|
|||
ARG_ENABL_SET([eap-aka], [enable EAP AKA authentication module.])
|
||||
ARG_ENABL_SET([eap-aka-3gpp], [enable EAP AKA backend implementing 3GPP MILENAGE algorithms in software.])
|
||||
ARG_ENABL_SET([eap-aka-3gpp2], [enable EAP AKA backend implementing 3GPP2 algorithms in software. Requires libgmp.])
|
||||
ARG_ENABL_SET([eap-simaka-sql], [enable EAP-SIM/AKA backend based on a triplet/quintuplet SQL database.])
|
||||
ARG_ENABL_SET([eap-simaka-pcsc], [enable EAP-SIM/AKA backend based on a smartcard reader. Requires libpcsclite.])
|
||||
ARG_ENABL_SET([eap-simaka-sql], [enable EAP-SIM/AKA backend based on a triplet/quintuplet SQL database.])
|
||||
ARG_ENABL_SET([eap-simaka-pseudonym], [enable EAP-SIM/AKA pseudonym storage plugin.])
|
||||
ARG_ENABL_SET([eap-simaka-reauth], [enable EAP-SIM/AKA reauthentication data storage plugin.])
|
||||
ARG_ENABL_SET([eap-identity], [enable EAP module providing EAP-Identity helper.])
|
||||
|
@ -1203,6 +1206,12 @@ if test x$eap_sim_pcsc = xtrue; then
|
|||
AC_SUBST(pcsclite_LIBS)
|
||||
fi
|
||||
|
||||
if test x$eap_simaka_pcsc = xtrue; then
|
||||
PKG_CHECK_MODULES(pcsclite, [libpcsclite])
|
||||
AC_SUBST(pcsclite_CFLAGS)
|
||||
AC_SUBST(pcsclite_LIBS)
|
||||
fi
|
||||
|
||||
if test x$nm = xtrue; then
|
||||
PKG_CHECK_MODULES(nm, [gthread-2.0 libnm])
|
||||
AC_SUBST(nm_CFLAGS)
|
||||
|
@ -1271,6 +1280,11 @@ if test x$bfd_backtraces = xtrue; then
|
|||
AC_CHECK_LIB([bfd],[bfd_init],[LIBS="$LIBS"],[AC_MSG_ERROR([binutils libbfd not found!])],[])
|
||||
AC_CHECK_HEADER([bfd.h],[AC_DEFINE([HAVE_BFD_H],,[have binutils bfd.h])],
|
||||
[AC_MSG_ERROR([binutils bfd.h header not found!])])
|
||||
AC_CHECK_DECLS(
|
||||
[bfd_section_flags, bfd_get_section_flags,
|
||||
bfd_section_vma, bfd_get_section_vma,
|
||||
bfd_section_size, bfd_get_section_size], [], [],
|
||||
[[#include <bfd.h>]])
|
||||
BFDLIB="-lbfd"
|
||||
AC_SUBST(BFDLIB)
|
||||
fi
|
||||
|
@ -1528,6 +1542,7 @@ ADD_PLUGIN([eap-sim-pcsc], [c charon])
|
|||
ADD_PLUGIN([eap-aka], [c charon])
|
||||
ADD_PLUGIN([eap-aka-3gpp], [c charon])
|
||||
ADD_PLUGIN([eap-aka-3gpp2], [c charon])
|
||||
ADD_PLUGIN([eap-simaka-pcsc], [c charon])
|
||||
ADD_PLUGIN([eap-simaka-sql], [c charon])
|
||||
ADD_PLUGIN([eap-simaka-pseudonym], [c charon])
|
||||
ADD_PLUGIN([eap-simaka-reauth], [c charon])
|
||||
|
@ -1699,6 +1714,7 @@ AM_CONDITIONAL(USE_RADATTR, test x$radattr = xtrue)
|
|||
AM_CONDITIONAL(USE_EAP_SIM, test x$eap_sim = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_SIM_FILE, test x$eap_sim_file = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_SIM_PCSC, test x$eap_sim_pcsc = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_SIMAKA_PCSC, test x$eap_simaka_pcsc = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_SIMAKA_SQL, test x$eap_simaka_sql = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_SIMAKA_PSEUDONYM, test x$eap_simaka_pseudonym = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_SIMAKA_REAUTH, test x$eap_simaka_reauth = xtrue)
|
||||
|
@ -1991,6 +2007,7 @@ AC_CONFIG_FILES([
|
|||
src/libcharon/plugins/eap_sim/Makefile
|
||||
src/libcharon/plugins/eap_sim_file/Makefile
|
||||
src/libcharon/plugins/eap_sim_pcsc/Makefile
|
||||
src/libcharon/plugins/eap_simaka_pcsc/Makefile
|
||||
src/libcharon/plugins/eap_simaka_sql/Makefile
|
||||
src/libcharon/plugins/eap_simaka_pseudonym/Makefile
|
||||
src/libcharon/plugins/eap_simaka_reauth/Makefile
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
build_botan()
|
||||
{
|
||||
# same revision used in the build recipe of the testing environment
|
||||
BOTAN_REV=2.17.1
|
||||
BOTAN_REV=2.18.0
|
||||
BOTAN_DIR=$DEPS_BUILD_DIR/botan
|
||||
|
||||
if test -d "$BOTAN_DIR"; then
|
||||
|
@ -37,7 +37,7 @@ build_botan()
|
|||
|
||||
build_wolfssl()
|
||||
{
|
||||
WOLFSSL_REV=v4.7.0-stable
|
||||
WOLFSSL_REV=0caf3ba456f1 # v4.7.1r + SHA-3 fix
|
||||
WOLFSSL_DIR=$DEPS_BUILD_DIR/wolfssl
|
||||
|
||||
if test -d "$WOLFSSL_DIR"; then
|
||||
|
@ -46,14 +46,15 @@ build_wolfssl()
|
|||
|
||||
echo "$ build_wolfssl()"
|
||||
|
||||
WOLFSSL_CFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DES_ECB -DHAVE_ECC_BRAINPOOL"
|
||||
WOLFSSL_CFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DES_ECB -DHAVE_AES_ECB \
|
||||
-DHAVE_ECC_BRAINPOOL -DWOLFSSL_MIN_AUTH_TAG_SZ=8"
|
||||
WOLFSSL_CONFIG="--prefix=$DEPS_PREFIX
|
||||
--disable-crypttests --disable-examples
|
||||
--enable-keygen --enable-rsapss --enable-aesccm
|
||||
--enable-aesctr --enable-des3 --enable-camellia
|
||||
--enable-curve25519 --enable-ed25519
|
||||
--enable-curve448 --enable-ed448
|
||||
--enable-sha3 --enable-shake256 --enable-ecccustcurves"
|
||||
--enable-aesccm --enable-aesctr --enable-camellia
|
||||
--enable-curve25519 --enable-curve448 --enable-des3
|
||||
--enable-ecccustcurves --enable-ed25519 --enable-ed448
|
||||
--enable-keygen --enable-md4 --enable-rsapss --enable-sha3
|
||||
--enable-shake256"
|
||||
|
||||
git clone https://github.com/wolfSSL/wolfssl.git $WOLFSSL_DIR &&
|
||||
cd $WOLFSSL_DIR &&
|
||||
|
@ -92,6 +93,12 @@ build_tss2()
|
|||
: ${DEPS_BUILD_DIR=$BUILD_DIR/..}
|
||||
: ${DEPS_PREFIX=/usr/local}
|
||||
|
||||
if [ -e /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
elif [ -e /usr/lib/os-release ]; then
|
||||
. /usr/lib/os-release
|
||||
fi
|
||||
|
||||
TARGET=check
|
||||
|
||||
DEPS="libgmp-dev"
|
||||
|
@ -111,7 +118,11 @@ openssl*)
|
|||
gcrypt)
|
||||
CONFIG="--disable-defaults --enable-pki --enable-gcrypt --enable-pkcs1"
|
||||
export TESTS_PLUGINS="test-vectors pkcs1 gcrypt!"
|
||||
DEPS="libgcrypt11-dev"
|
||||
if [ "$ID" = "ubuntu" -a "$VERSION_ID" = "20.04" ]; then
|
||||
DEPS="libgcrypt20-dev"
|
||||
else
|
||||
DEPS="libgcrypt11-dev"
|
||||
fi
|
||||
;;
|
||||
botan)
|
||||
CONFIG="--disable-defaults --enable-pki --enable-botan --enable-pem"
|
||||
|
@ -134,6 +145,13 @@ printf-builtin)
|
|||
CONFIG="--with-printf-hooks=builtin"
|
||||
;;
|
||||
all|coverage|sonarcloud)
|
||||
if [ "$TEST" = "sonarcloud" ]; then
|
||||
if [ -z "$SONAR_PROJECT" -o -z "$SONAR_ORGANIZATION" -o -z "$SONAR_TOKEN" ]; then
|
||||
echo "The SONAR_PROJECT, SONAR_ORGANIZATION and SONAR_TOKEN" \
|
||||
"environment variables are required to run this test"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
CONFIG="--enable-all --disable-android-dns --disable-android-log
|
||||
--disable-kernel-pfroute --disable-keychain
|
||||
--disable-lock-profiler --disable-padlock --disable-fuzzing
|
||||
|
@ -151,17 +169,24 @@ all|coverage|sonarcloud)
|
|||
DEPS="$DEPS lcov"
|
||||
fi
|
||||
# Botan requires newer compilers, so disable it on Ubuntu 16.04
|
||||
if test -n "$UBUNTU_XENIAL"; then
|
||||
if [ "$ID" = "ubuntu" -a "$VERSION_ID" = "16.04" ]; then
|
||||
CONFIG="$CONFIG --disable-botan"
|
||||
fi
|
||||
DEPS="$DEPS libcurl4-gnutls-dev libsoup2.4-dev libunbound-dev libldns-dev
|
||||
libmysqlclient-dev libsqlite3-dev clearsilver-dev libfcgi-dev
|
||||
libldap2-dev libpcsclite-dev libpam0g-dev binutils-dev libnm-dev
|
||||
libgcrypt20-dev libjson-c-dev iptables-dev python-pip libtspi-dev
|
||||
libsystemd-dev"
|
||||
PYDEPS="tox"
|
||||
libgcrypt20-dev libjson-c-dev python3-pip libtspi-dev libsystemd-dev"
|
||||
if [ "$ID" = "ubuntu" -a "$VERSION_ID" = "20.04" ]; then
|
||||
DEPS="$DEPS libiptc-dev"
|
||||
else
|
||||
DEPS="$DEPS iptables-dev python3-setuptools"
|
||||
fi
|
||||
# tox has dependencies that can't be resolved on 16.04 (even with pip)
|
||||
if [ "$ID" != "ubuntu" -o "$VERSION_ID" != "16.04" ]; then
|
||||
PYDEPS="tox"
|
||||
fi
|
||||
if test "$1" = "build-deps"; then
|
||||
if test -z "$UBUNTU_XENIAL"; then
|
||||
if [ "$ID" != "ubuntu" -o "$VERSION_ID" != "16.04" ]; then
|
||||
build_botan
|
||||
fi
|
||||
build_wolfssl
|
||||
|
@ -301,8 +326,12 @@ apidoc)
|
|||
TARGET=apidoc
|
||||
;;
|
||||
lgtm)
|
||||
if [ -z "$LGTM_PROJECT" -o -z "$LGTM_TOKEN" ]; then
|
||||
echo "The LGTM_PROJECT and LGTM_TOKEN environment variables" \
|
||||
"are required to run this test"
|
||||
exit 0
|
||||
fi
|
||||
DEPS="jq"
|
||||
|
||||
if test -z "$1"; then
|
||||
base=$COMMIT_BASE
|
||||
# after rebases or for new/duplicate branches, the passed base commit
|
||||
|
@ -314,12 +343,11 @@ lgtm)
|
|||
base=$(git merge-base origin/master ${COMMIT_ID})
|
||||
fi
|
||||
base=$(git rev-parse $base)
|
||||
project_id=1506185006272
|
||||
|
||||
echo "Starting code review for $COMMIT_ID (base $base) on lgtm.com"
|
||||
git diff --binary $base > lgtm.patch || exit $?
|
||||
curl -s -X POST --data-binary @lgtm.patch \
|
||||
"https://lgtm.com/api/v1.0/codereviews/${project_id}?base=${base}&external-id=${BUILD_NUMBER}" \
|
||||
"https://lgtm.com/api/v1.0/codereviews/${LGTM_PROJECT}?base=${base}&external-id=${BUILD_NUMBER}" \
|
||||
-H 'Content-Type: application/octet-stream' \
|
||||
-H 'Accept: application/json' \
|
||||
-H "Authorization: Bearer ${LGTM_TOKEN}" > lgtm.res || exit $?
|
||||
|
@ -384,7 +412,7 @@ deps)
|
|||
exit $?
|
||||
;;
|
||||
pydeps)
|
||||
test -z "$PYDEPS" || pip -q install --user $PYDEPS
|
||||
test -z "$PYDEPS" || pip3 -q install --user $PYDEPS
|
||||
exit $?
|
||||
;;
|
||||
build-deps)
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
/**
|
||||
* Initialize the NetworkManager backend.
|
||||
*
|
||||
* @return TRUE, if initialization was successful
|
||||
*/
|
||||
void nm_backend_register();
|
||||
|
||||
|
|
|
@ -77,32 +77,11 @@ struct private_nm_creds_t {
|
|||
};
|
||||
|
||||
/**
|
||||
* Enumerator for user certificate
|
||||
* Enumerator for user certificate (lock has to be locked)
|
||||
*/
|
||||
static enumerator_t *create_usercert_enumerator(private_nm_creds_t *this,
|
||||
certificate_type_t cert, key_type_t key)
|
||||
{
|
||||
public_key_t *public;
|
||||
|
||||
if (cert != CERT_ANY && cert != this->usercert->get_type(this->usercert))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (key != KEY_ANY)
|
||||
{
|
||||
public = this->usercert->get_public_key(this->usercert);
|
||||
if (!public)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (public->get_type(public) != key)
|
||||
{
|
||||
public->destroy(public);
|
||||
return NULL;
|
||||
}
|
||||
public->destroy(public);
|
||||
}
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_cleaner(
|
||||
enumerator_create_single(this->usercert, NULL),
|
||||
(void*)this->lock->unlock, this->lock);
|
||||
|
@ -114,6 +93,8 @@ static enumerator_t *create_usercert_enumerator(private_nm_creds_t *this,
|
|||
typedef struct {
|
||||
/** ref to credential credential store */
|
||||
private_nm_creds_t *this;
|
||||
/** certificate type we are looking for */
|
||||
certificate_type_t type;
|
||||
/** type of key we are looking for */
|
||||
key_type_t key;
|
||||
/** CA certificate ID */
|
||||
|
@ -131,55 +112,36 @@ CALLBACK(cert_filter, bool,
|
|||
cert_data_t *data, enumerator_t *orig, va_list args)
|
||||
{
|
||||
certificate_t *cert, **out;
|
||||
public_key_t *public;
|
||||
|
||||
VA_ARGS_VGET(args, out);
|
||||
|
||||
while (orig->enumerate(orig, &cert))
|
||||
{
|
||||
public = cert->get_public_key(cert);
|
||||
if (!public)
|
||||
if (certificate_matches(cert, data->type, data->key, data->id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (data->key != KEY_ANY && public->get_type(public) != data->key)
|
||||
{
|
||||
public->destroy(public);
|
||||
continue;
|
||||
}
|
||||
if (data->id && data->id->get_type(data->id) == ID_KEY_ID &&
|
||||
public->has_fingerprint(public, data->id->get_encoding(data->id)))
|
||||
{
|
||||
public->destroy(public);
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
}
|
||||
public->destroy(public);
|
||||
if (data->id && !cert->has_subject(cert, data->id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*out = cert;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create enumerator for trusted certificates
|
||||
* Create enumerator for trusted certificates (lock has to be locked)
|
||||
*/
|
||||
static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this,
|
||||
key_type_t key, identification_t *id)
|
||||
certificate_type_t type, key_type_t key,
|
||||
identification_t *id)
|
||||
{
|
||||
cert_data_t *data;
|
||||
|
||||
INIT(data,
|
||||
.this = this,
|
||||
.id = id,
|
||||
.type = type,
|
||||
.key = key,
|
||||
.id = id,
|
||||
);
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
this->certs->create_enumerator(this->certs),
|
||||
cert_filter, data, cert_data_destroy);
|
||||
|
@ -189,16 +151,14 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
|||
private_nm_creds_t *this, certificate_type_t cert, key_type_t key,
|
||||
identification_t *id, bool trusted)
|
||||
{
|
||||
this->lock->read_lock(this->lock);
|
||||
|
||||
if (id && this->usercert &&
|
||||
id->equals(id, this->usercert->get_subject(this->usercert)))
|
||||
certificate_matches(this->usercert, cert, key, id))
|
||||
{
|
||||
return create_usercert_enumerator(this, cert, key);
|
||||
}
|
||||
if (cert == CERT_X509 || cert == CERT_ANY)
|
||||
{
|
||||
return create_trusted_cert_enumerator(this, key, id);
|
||||
}
|
||||
return NULL;
|
||||
return create_trusted_cert_enumerator(this, cert, key, id);
|
||||
}
|
||||
|
||||
METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
|
||||
|
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Copyright (C) 2020 secunet Security Networks AG
|
||||
* Copyright (C) 2020 Stefan Berghofer
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <crypto/iv/iv_gen.h>
|
||||
#include <tkm/constants.h>
|
||||
#include <tkm/client.h>
|
||||
|
||||
#include "tkm_aead.h"
|
||||
#include "tkm_utils.h"
|
||||
|
||||
typedef struct private_aead_t private_aead_t;
|
||||
|
||||
/**
|
||||
* AEAD implementation using TKM
|
||||
*/
|
||||
struct private_aead_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
* */
|
||||
aead_t public;
|
||||
|
||||
/**
|
||||
* Internal IV generator for TKM
|
||||
*/
|
||||
iv_gen_t iv_gen;
|
||||
|
||||
/**
|
||||
* ISA context id
|
||||
*/
|
||||
isa_id_type isa_ctx_id;
|
||||
|
||||
/**
|
||||
* Block length of encryption algorithm
|
||||
*/
|
||||
block_len_type block_len;
|
||||
|
||||
/**
|
||||
* Length of integrity check value
|
||||
*/
|
||||
icv_len_type icv_len;
|
||||
|
||||
/**
|
||||
* Length of initialization vector
|
||||
*/
|
||||
iv_len_type iv_len;
|
||||
};
|
||||
|
||||
METHOD(iv_gen_t, get_iv, bool,
|
||||
iv_gen_t *this, uint64_t seq, size_t size, uint8_t *buffer)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(iv_gen_t, allocate_iv, bool,
|
||||
iv_gen_t *this, uint64_t seq, size_t size, chunk_t *chunk)
|
||||
{
|
||||
*chunk = chunk_alloc(size);
|
||||
return get_iv(this, seq, chunk->len, chunk->ptr);
|
||||
}
|
||||
|
||||
METHOD(aead_t, encrypt, bool,
|
||||
private_aead_t *this, chunk_t plain, chunk_t assoc,
|
||||
chunk_t iv, chunk_t *encrypted)
|
||||
{
|
||||
aad_plain_type aad_plain;
|
||||
iv_encrypted_icv_type iv_encrypted_icv;
|
||||
result_type res;
|
||||
|
||||
aad_plain = (aad_plain_type){
|
||||
.size = assoc.len + plain.len,
|
||||
};
|
||||
if (aad_plain.size > sizeof(aad_plain.data))
|
||||
{
|
||||
DBG1(DBG_IKE, "%u exceeds buffer size %u, encryption failed (isa: "
|
||||
"%llu)", aad_plain.size, sizeof(aad_plain.data), this->isa_ctx_id);
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(aad_plain.data, assoc.ptr, assoc.len);
|
||||
memcpy(aad_plain.data + assoc.len, plain.ptr, plain.len);
|
||||
|
||||
res = ike_isa_encrypt(this->isa_ctx_id, assoc.len, aad_plain,
|
||||
&iv_encrypted_icv);
|
||||
if (res != TKM_OK)
|
||||
{
|
||||
DBG1(DBG_IKE, "encryption failed (isa: %llu)", this->isa_ctx_id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (encrypted)
|
||||
{
|
||||
sequence_to_chunk(iv_encrypted_icv.data, iv_encrypted_icv.size,
|
||||
encrypted);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(plain.ptr, iv_encrypted_icv.data + iv.len,
|
||||
iv_encrypted_icv.size - iv.len);
|
||||
}
|
||||
memcpy(iv.ptr, iv_encrypted_icv.data, iv.len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(aead_t, decrypt, bool,
|
||||
private_aead_t *this, chunk_t encrypted, chunk_t assoc, chunk_t iv,
|
||||
chunk_t *plain)
|
||||
{
|
||||
aad_iv_encrypted_icv_type aad_iv_encrypted_icv;
|
||||
decrypted_type decrypted;
|
||||
result_type res;
|
||||
|
||||
aad_iv_encrypted_icv = (aad_iv_encrypted_icv_type){
|
||||
.size = assoc.len + iv.len + encrypted.len,
|
||||
};
|
||||
if (aad_iv_encrypted_icv.size > sizeof(aad_iv_encrypted_icv.data))
|
||||
{
|
||||
DBG1(DBG_IKE, "%u exceeds buffer size %u, decryption failed (isa: "
|
||||
"%llu)", aad_iv_encrypted_icv.size,
|
||||
sizeof(aad_iv_encrypted_icv.data), this->isa_ctx_id);
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(aad_iv_encrypted_icv.data, assoc.ptr, assoc.len);
|
||||
memcpy(aad_iv_encrypted_icv.data + assoc.len, iv.ptr, iv.len);
|
||||
memcpy(aad_iv_encrypted_icv.data + assoc.len + iv.len, encrypted.ptr,
|
||||
encrypted.len);
|
||||
|
||||
res = ike_isa_decrypt(this->isa_ctx_id, assoc.len, aad_iv_encrypted_icv,
|
||||
&decrypted);
|
||||
if (res != TKM_OK)
|
||||
{
|
||||
DBG1(DBG_IKE, "decryption failed (isa: %llu)", this->isa_ctx_id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (plain)
|
||||
{
|
||||
sequence_to_chunk(decrypted.data, decrypted.size, plain);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(encrypted.ptr, decrypted.data, decrypted.size);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_block_size, size_t,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return this->block_len;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_icv_size, size_t,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return this->icv_len;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_iv_size, size_t,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return this->iv_len;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_iv_gen, iv_gen_t*,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return &this->iv_gen;
|
||||
}
|
||||
|
||||
METHOD(aead_t, get_key_size, size_t,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
METHOD(aead_t, set_key, bool,
|
||||
private_aead_t *this, chunk_t key)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(aead_t, destroy, void,
|
||||
private_aead_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
aead_t *tkm_aead_create(isa_id_type isa_ctx_id, block_len_type block_len,
|
||||
icv_len_type icv_len, iv_len_type iv_len)
|
||||
{
|
||||
private_aead_t *aead;
|
||||
|
||||
INIT(aead,
|
||||
.public = {
|
||||
.encrypt = _encrypt,
|
||||
.decrypt = _decrypt,
|
||||
.get_block_size = _get_block_size,
|
||||
.get_icv_size = _get_icv_size,
|
||||
.get_iv_size = _get_iv_size,
|
||||
.get_iv_gen = _get_iv_gen,
|
||||
.get_key_size = _get_key_size,
|
||||
.set_key = _set_key,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.iv_gen = {
|
||||
.get_iv = _get_iv,
|
||||
.allocate_iv = _allocate_iv,
|
||||
.destroy = (void *)nop,
|
||||
},
|
||||
.isa_ctx_id = isa_ctx_id,
|
||||
.block_len = block_len,
|
||||
.icv_len = icv_len,
|
||||
.iv_len = iv_len,
|
||||
);
|
||||
|
||||
return &aead->public;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2020 secunet Security Networks AG
|
||||
* Copyright (C) 2020 Stefan Berghofer
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tkm-aead aead
|
||||
* @{ @ingroup tkm
|
||||
*/
|
||||
|
||||
#ifndef TKM_AEAD_H_
|
||||
#define TKM_AEAD_H_
|
||||
|
||||
typedef struct tkm_aead_t tkm_aead_t;
|
||||
|
||||
#include <crypto/aead.h>
|
||||
#include <tkm/types.h>
|
||||
|
||||
/**
|
||||
* Create an AEAD implementation providing encryption and integrity protection
|
||||
* using TKM.
|
||||
*
|
||||
* @param isa_ctx_id id of ISA context to use for encryption/decryption
|
||||
* @param block_len block length of encryption algorithm
|
||||
* @param icv_len length of integrity check value
|
||||
* @param iv_len length of initialization vector
|
||||
* @return created aead_t object
|
||||
*/
|
||||
aead_t *tkm_aead_create(isa_id_type isa_ctx_id, block_len_type block_len,
|
||||
icv_len_type icv_len, iv_len_type iv_len);
|
||||
|
||||
#endif /** TKM_AEAD_H_ @}*/
|
|
@ -25,6 +25,7 @@
|
|||
#include "tkm_utils.h"
|
||||
#include "tkm_diffie_hellman.h"
|
||||
#include "tkm_keymat.h"
|
||||
#include "tkm_aead.h"
|
||||
|
||||
typedef struct private_tkm_keymat_t private_tkm_keymat_t;
|
||||
|
||||
|
@ -44,14 +45,9 @@ struct private_tkm_keymat_t {
|
|||
bool initiator;
|
||||
|
||||
/**
|
||||
* Inbound AEAD.
|
||||
* AEAD implementation.
|
||||
*/
|
||||
aead_t *aead_in;
|
||||
|
||||
/**
|
||||
* Outbound AEAD.
|
||||
*/
|
||||
aead_t *aead_out;
|
||||
aead_t *aead;
|
||||
|
||||
/**
|
||||
* ISA context id.
|
||||
|
@ -79,91 +75,6 @@ struct private_tkm_keymat_t {
|
|||
hash_algorithm_set_t *hash_algorithms;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create AEAD transforms from given key chunks.
|
||||
*
|
||||
* @param in inbound AEAD transform to allocate, NULL if failed
|
||||
* @param out outbound AEAD transform to allocate, NULL if failed
|
||||
* @param sk_ai SK_ai key chunk
|
||||
* @param sk_ar SK_ar key chunk
|
||||
* @param sk_ei SK_ei key chunk
|
||||
* @param sk_er SK_er key chunk
|
||||
* @param enc_alg encryption algorithm to use
|
||||
* @param int_alg integrity algorithm to use
|
||||
* @param key_size encryption key size in bytes
|
||||
* @param initiator TRUE if initiator
|
||||
*/
|
||||
static void aead_create_from_keys(aead_t **in, aead_t **out,
|
||||
const chunk_t * const sk_ai, const chunk_t * const sk_ar,
|
||||
const chunk_t * const sk_ei, const chunk_t * const sk_er,
|
||||
const uint16_t enc_alg, const uint16_t int_alg,
|
||||
const uint16_t key_size, bool initiator)
|
||||
{
|
||||
*in = *out = NULL;
|
||||
signer_t *signer_i, *signer_r;
|
||||
crypter_t *crypter_i, *crypter_r;
|
||||
iv_gen_t *ivg_i, *ivg_r;
|
||||
|
||||
signer_i = lib->crypto->create_signer(lib->crypto, int_alg);
|
||||
signer_r = lib->crypto->create_signer(lib->crypto, int_alg);
|
||||
if (signer_i == NULL || signer_r == NULL)
|
||||
{
|
||||
DBG1(DBG_IKE, "%N %N not supported!",
|
||||
transform_type_names, INTEGRITY_ALGORITHM,
|
||||
integrity_algorithm_names, int_alg);
|
||||
return;
|
||||
}
|
||||
crypter_i = lib->crypto->create_crypter(lib->crypto, enc_alg, key_size);
|
||||
crypter_r = lib->crypto->create_crypter(lib->crypto, enc_alg, key_size);
|
||||
if (crypter_i == NULL || crypter_r == NULL)
|
||||
{
|
||||
signer_i->destroy(signer_i);
|
||||
signer_r->destroy(signer_r);
|
||||
DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
|
||||
transform_type_names, ENCRYPTION_ALGORITHM,
|
||||
encryption_algorithm_names, enc_alg, key_size);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG4(DBG_IKE, "Sk_ai %B", sk_ai);
|
||||
if (!signer_i->set_key(signer_i, *sk_ai))
|
||||
{
|
||||
return;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ar %B", sk_ar);
|
||||
if (!signer_r->set_key(signer_r, *sk_ar))
|
||||
{
|
||||
return;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ei %B", sk_ei);
|
||||
if (!crypter_i->set_key(crypter_i, *sk_ei))
|
||||
{
|
||||
return;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_er %B", sk_er);
|
||||
if (!crypter_r->set_key(crypter_r, *sk_er))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ivg_i = iv_gen_create_for_alg(enc_alg);
|
||||
ivg_r = iv_gen_create_for_alg(enc_alg);
|
||||
if (!ivg_i || !ivg_r)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (initiator)
|
||||
{
|
||||
*in = aead_create(crypter_r, signer_r, ivg_r);
|
||||
*out = aead_create(crypter_i, signer_i, ivg_i);
|
||||
}
|
||||
else
|
||||
{
|
||||
*in = aead_create(crypter_i, signer_i, ivg_i);
|
||||
*out = aead_create(crypter_r, signer_r, ivg_r);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(keymat_t, get_version, ike_version_t,
|
||||
private_tkm_keymat_t *this)
|
||||
{
|
||||
|
@ -187,46 +98,15 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||
chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
|
||||
pseudo_random_function_t rekey_function, chunk_t rekey_skd)
|
||||
{
|
||||
uint16_t enc_alg, int_alg, key_size;
|
||||
uint64_t nc_id, spi_loc, spi_rem;
|
||||
chunk_t *nonce, c_ai, c_ar, c_ei, c_er;
|
||||
chunk_t *nonce;
|
||||
tkm_diffie_hellman_t *tkm_dh;
|
||||
dh_id_type dh_id;
|
||||
nonce_type nonce_rem;
|
||||
result_type res;
|
||||
key_type sk_ai, sk_ar, sk_ei, sk_er;
|
||||
|
||||
/* Check encryption and integrity algorithms */
|
||||
if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &enc_alg,
|
||||
&key_size))
|
||||
{
|
||||
DBG1(DBG_IKE, "no %N selected", transform_type_names,
|
||||
ENCRYPTION_ALGORITHM);
|
||||
return FALSE;
|
||||
}
|
||||
if (encryption_algorithm_is_aead(enc_alg))
|
||||
{
|
||||
DBG1(DBG_IKE, "AEAD algorithm %N not supported",
|
||||
encryption_algorithm_names, enc_alg);
|
||||
return FALSE;
|
||||
}
|
||||
if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &int_alg, NULL))
|
||||
{
|
||||
DBG1(DBG_IKE, "no %N selected", transform_type_names,
|
||||
INTEGRITY_ALGORITHM);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(enc_alg == ENCR_AES_CBC && key_size == 256 &&
|
||||
int_alg == AUTH_HMAC_SHA2_512_256))
|
||||
{
|
||||
DBG1(DBG_IKE, "the TKM only supports aes256-sha512 at the moment, "
|
||||
"please update your configuration");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DBG2(DBG_IKE, "using %N for encryption, %N for integrity",
|
||||
encryption_algorithm_names, enc_alg, integrity_algorithm_names,
|
||||
int_alg);
|
||||
block_len_type block_len;
|
||||
icv_len_type icv_len;
|
||||
iv_len_type iv_len;
|
||||
|
||||
/* Acquire nonce context id */
|
||||
nonce = this->initiator ? &nonce_i : &nonce_r;
|
||||
|
@ -266,7 +146,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||
"spi_rem: %llx)", nc_id, dh_id, spi_loc, spi_rem);
|
||||
res = ike_isa_create(this->isa_ctx_id, this->ae_ctx_id, 1, dh_id, nc_id,
|
||||
nonce_rem, this->initiator, spi_loc, spi_rem,
|
||||
&sk_ai, &sk_ar, &sk_ei, &sk_er);
|
||||
&block_len, &icv_len, &iv_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -291,8 +171,8 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||
this->ae_ctx_id = isa_info.ae_id;
|
||||
res = ike_isa_create_child(this->isa_ctx_id, isa_info.parent_isa_id, 1,
|
||||
dh_id, nc_id, nonce_rem, this->initiator,
|
||||
spi_loc, spi_rem, &sk_ai, &sk_ar, &sk_ei,
|
||||
&sk_er);
|
||||
spi_loc, spi_rem, &block_len, &icv_len,
|
||||
&iv_len);
|
||||
chunk_free(&rekey_skd);
|
||||
}
|
||||
|
||||
|
@ -302,25 +182,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
sequence_to_chunk(sk_ai.data, sk_ai.size, &c_ai);
|
||||
sequence_to_chunk(sk_ar.data, sk_ar.size, &c_ar);
|
||||
sequence_to_chunk(sk_ei.data, sk_ei.size, &c_ei);
|
||||
sequence_to_chunk(sk_er.data, sk_er.size, &c_er);
|
||||
|
||||
aead_create_from_keys(&this->aead_in, &this->aead_out, &c_ai, &c_ar, &c_ei,
|
||||
&c_er, enc_alg, int_alg, key_size / 8,
|
||||
this->initiator);
|
||||
|
||||
chunk_clear(&c_ai);
|
||||
chunk_clear(&c_ar);
|
||||
chunk_clear(&c_ei);
|
||||
chunk_clear(&c_er);
|
||||
|
||||
if (!this->aead_in || !this->aead_out)
|
||||
{
|
||||
DBG1(DBG_IKE, "could not initialize AEAD transforms");
|
||||
return FALSE;
|
||||
}
|
||||
this->aead = tkm_aead_create(this->isa_ctx_id, block_len, icv_len, iv_len);
|
||||
|
||||
/* TODO: Add failure handler (see keymat_v2.c) */
|
||||
|
||||
|
@ -380,7 +242,7 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
|
|||
METHOD(keymat_t, get_aead, aead_t*,
|
||||
private_tkm_keymat_t *this, bool in)
|
||||
{
|
||||
return in ? this->aead_in : this->aead_out;
|
||||
return this->aead;
|
||||
}
|
||||
|
||||
METHOD(keymat_v2_t, get_auth_octets, bool,
|
||||
|
@ -474,8 +336,7 @@ METHOD(keymat_t, destroy, void,
|
|||
}
|
||||
|
||||
DESTROY_IF(this->hash_algorithms);
|
||||
DESTROY_IF(this->aead_in);
|
||||
DESTROY_IF(this->aead_out);
|
||||
DESTROY_IF(this->aead);
|
||||
chunk_free(&this->auth_payload);
|
||||
chunk_free(&this->other_init_msg);
|
||||
free(this);
|
||||
|
|
|
@ -235,7 +235,7 @@ public class VpnProfileDataSource
|
|||
{
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(KEY_UUID, UUID.randomUUID().toString());
|
||||
db.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + cursor.getLong(cursor.getColumnIndex(KEY_ID)), null);
|
||||
db.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + cursor.getLong(cursor.getColumnIndexOrThrow(KEY_ID)), null);
|
||||
}
|
||||
cursor.close();
|
||||
db.setTransactionSuccessful();
|
||||
|
@ -433,29 +433,29 @@ public class VpnProfileDataSource
|
|||
private VpnProfile VpnProfileFromCursor(Cursor cursor)
|
||||
{
|
||||
VpnProfile profile = new VpnProfile();
|
||||
profile.setId(cursor.getLong(cursor.getColumnIndex(KEY_ID)));
|
||||
profile.setUUID(UUID.fromString(cursor.getString(cursor.getColumnIndex(KEY_UUID))));
|
||||
profile.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME)));
|
||||
profile.setGateway(cursor.getString(cursor.getColumnIndex(KEY_GATEWAY)));
|
||||
profile.setVpnType(VpnType.fromIdentifier(cursor.getString(cursor.getColumnIndex(KEY_VPN_TYPE))));
|
||||
profile.setUsername(cursor.getString(cursor.getColumnIndex(KEY_USERNAME)));
|
||||
profile.setPassword(cursor.getString(cursor.getColumnIndex(KEY_PASSWORD)));
|
||||
profile.setCertificateAlias(cursor.getString(cursor.getColumnIndex(KEY_CERTIFICATE)));
|
||||
profile.setUserCertificateAlias(cursor.getString(cursor.getColumnIndex(KEY_USER_CERTIFICATE)));
|
||||
profile.setMTU(getInt(cursor, cursor.getColumnIndex(KEY_MTU)));
|
||||
profile.setPort(getInt(cursor, cursor.getColumnIndex(KEY_PORT)));
|
||||
profile.setSplitTunneling(getInt(cursor, cursor.getColumnIndex(KEY_SPLIT_TUNNELING)));
|
||||
profile.setLocalId(cursor.getString(cursor.getColumnIndex(KEY_LOCAL_ID)));
|
||||
profile.setRemoteId(cursor.getString(cursor.getColumnIndex(KEY_REMOTE_ID)));
|
||||
profile.setExcludedSubnets(cursor.getString(cursor.getColumnIndex(KEY_EXCLUDED_SUBNETS)));
|
||||
profile.setIncludedSubnets(cursor.getString(cursor.getColumnIndex(KEY_INCLUDED_SUBNETS)));
|
||||
profile.setSelectedAppsHandling(getInt(cursor, cursor.getColumnIndex(KEY_SELECTED_APPS)));
|
||||
profile.setSelectedApps(cursor.getString(cursor.getColumnIndex(KEY_SELECTED_APPS_LIST)));
|
||||
profile.setNATKeepAlive(getInt(cursor, cursor.getColumnIndex(KEY_NAT_KEEPALIVE)));
|
||||
profile.setFlags(getInt(cursor, cursor.getColumnIndex(KEY_FLAGS)));
|
||||
profile.setIkeProposal(cursor.getString(cursor.getColumnIndex(KEY_IKE_PROPOSAL)));
|
||||
profile.setEspProposal(cursor.getString(cursor.getColumnIndex(KEY_ESP_PROPOSAL)));
|
||||
profile.setDnsServers(cursor.getString(cursor.getColumnIndex(KEY_DNS_SERVERS)));
|
||||
profile.setId(cursor.getLong(cursor.getColumnIndexOrThrow(KEY_ID)));
|
||||
profile.setUUID(UUID.fromString(cursor.getString(cursor.getColumnIndexOrThrow(KEY_UUID))));
|
||||
profile.setName(cursor.getString(cursor.getColumnIndexOrThrow(KEY_NAME)));
|
||||
profile.setGateway(cursor.getString(cursor.getColumnIndexOrThrow(KEY_GATEWAY)));
|
||||
profile.setVpnType(VpnType.fromIdentifier(cursor.getString(cursor.getColumnIndexOrThrow(KEY_VPN_TYPE))));
|
||||
profile.setUsername(cursor.getString(cursor.getColumnIndexOrThrow(KEY_USERNAME)));
|
||||
profile.setPassword(cursor.getString(cursor.getColumnIndexOrThrow(KEY_PASSWORD)));
|
||||
profile.setCertificateAlias(cursor.getString(cursor.getColumnIndexOrThrow(KEY_CERTIFICATE)));
|
||||
profile.setUserCertificateAlias(cursor.getString(cursor.getColumnIndexOrThrow(KEY_USER_CERTIFICATE)));
|
||||
profile.setMTU(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_MTU)));
|
||||
profile.setPort(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_PORT)));
|
||||
profile.setSplitTunneling(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_SPLIT_TUNNELING)));
|
||||
profile.setLocalId(cursor.getString(cursor.getColumnIndexOrThrow(KEY_LOCAL_ID)));
|
||||
profile.setRemoteId(cursor.getString(cursor.getColumnIndexOrThrow(KEY_REMOTE_ID)));
|
||||
profile.setExcludedSubnets(cursor.getString(cursor.getColumnIndexOrThrow(KEY_EXCLUDED_SUBNETS)));
|
||||
profile.setIncludedSubnets(cursor.getString(cursor.getColumnIndexOrThrow(KEY_INCLUDED_SUBNETS)));
|
||||
profile.setSelectedAppsHandling(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_SELECTED_APPS)));
|
||||
profile.setSelectedApps(cursor.getString(cursor.getColumnIndexOrThrow(KEY_SELECTED_APPS_LIST)));
|
||||
profile.setNATKeepAlive(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_NAT_KEEPALIVE)));
|
||||
profile.setFlags(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_FLAGS)));
|
||||
profile.setIkeProposal(cursor.getString(cursor.getColumnIndexOrThrow(KEY_IKE_PROPOSAL)));
|
||||
profile.setEspProposal(cursor.getString(cursor.getColumnIndexOrThrow(KEY_ESP_PROPOSAL)));
|
||||
profile.setDnsServers(cursor.getString(cursor.getColumnIndexOrThrow(KEY_DNS_SERVERS)));
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ public class SimpleFetcher
|
|||
/**
|
||||
* Disable the fetcher and abort any future requests.
|
||||
*
|
||||
* The native thread is not cancelable as it is working on an IKE_SA (cancelling the methods of
|
||||
* The native thread is not cancelable as it is working on an IKE_SA (canceling the methods of
|
||||
* HttpURLConnection is not reliably possible anyway), so to abort while fetching we cancel the
|
||||
* Future (causing a return from fetch() immediately) and let the executor thread continue its
|
||||
* thing in the background.
|
||||
|
|
|
@ -46,7 +46,7 @@ echo location of your Java installation.
|
|||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
|
|
@ -64,7 +64,7 @@ typedef struct {
|
|||
} entry_t;
|
||||
|
||||
/**
|
||||
* Clean up an entry, cancelling connection
|
||||
* Clean up an entry, canceling connection
|
||||
*/
|
||||
static void destroy_entry(entry_t *entry)
|
||||
{
|
||||
|
|
|
@ -369,6 +369,13 @@ if MONOLITHIC
|
|||
endif
|
||||
endif
|
||||
|
||||
if USE_EAP_SIMAKA_PCSC
|
||||
SUBDIRS += plugins/eap_simaka_pcsc
|
||||
if MONOLITHIC
|
||||
libcharon_la_LIBADD += plugins/eap_simaka_pcsc/libstrongswan-eap-simaka-pcsc.la
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_EAP_SIMAKA_REAUTH
|
||||
SUBDIRS += plugins/eap_simaka_reauth
|
||||
if MONOLITHIC
|
||||
|
@ -733,6 +740,12 @@ if MONOLITHIC
|
|||
endif
|
||||
endif
|
||||
|
||||
if USE_TPM
|
||||
if MONOLITHIC
|
||||
libcharon_la_LIBADD += $(top_builddir)/src/libtpmtss/libtpmtss.la
|
||||
endif
|
||||
endif
|
||||
|
||||
if MONOLITHIC
|
||||
SUBDIRS += .
|
||||
endif
|
||||
|
|
|
@ -604,8 +604,8 @@ METHOD(bus_t, ike_keys, void,
|
|||
}
|
||||
|
||||
METHOD(bus_t, ike_derived_keys, void,
|
||||
private_bus_t *this, chunk_t sk_ei, chunk_t sk_er, chunk_t sk_ai,
|
||||
chunk_t sk_ar)
|
||||
private_bus_t *this, chunk_t sk_d, chunk_t sk_ai, chunk_t sk_ar,
|
||||
chunk_t sk_ei, chunk_t sk_er, chunk_t sk_pi, chunk_t sk_pr)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
ike_sa_t *ike_sa;
|
||||
|
@ -623,8 +623,9 @@ METHOD(bus_t, ike_derived_keys, void,
|
|||
continue;
|
||||
}
|
||||
entry->calling++;
|
||||
keep = entry->listener->ike_derived_keys(entry->listener, ike_sa, sk_ei,
|
||||
sk_er, sk_ai, sk_ar);
|
||||
keep = entry->listener->ike_derived_keys(entry->listener, ike_sa, sk_d,
|
||||
sk_ai, sk_ar, sk_ei, sk_er,
|
||||
sk_pi, sk_pr);
|
||||
entry->calling--;
|
||||
if (!keep)
|
||||
{
|
||||
|
|
|
@ -363,13 +363,17 @@ struct bus_t {
|
|||
/**
|
||||
* IKE_SA derived keys hook.
|
||||
*
|
||||
* @param sk_ei SK_ei, or Ka for IKEv1
|
||||
* @param sk_er SK_er
|
||||
* @param sk_d SK_d, or SKEYID_d for IKEv1
|
||||
* @param sk_ai SK_ai, or SKEYID_a for IKEv1
|
||||
* @param sk_ar SK_ar
|
||||
* @param sk_ei SK_ei, or Ka for IKEv1
|
||||
* @param sk_er SK_er
|
||||
* @param sk_pi SK_pi
|
||||
* @param sk_pr SK_pr
|
||||
*/
|
||||
void (*ike_derived_keys)(bus_t *this, chunk_t sk_ei, chunk_t sk_er,
|
||||
chunk_t sk_ai, chunk_t sk_ar);
|
||||
void (*ike_derived_keys)(bus_t *this, chunk_t sk_d, chunk_t sk_ai,
|
||||
chunk_t sk_ar, chunk_t sk_ei, chunk_t sk_er,
|
||||
chunk_t sk_pi, chunk_t sk_pr);
|
||||
|
||||
/**
|
||||
* CHILD_SA keymat hook.
|
||||
|
|
|
@ -100,13 +100,17 @@ struct listener_t {
|
|||
* Hook called with derived IKE_SA keys.
|
||||
*
|
||||
* @param ike_sa IKE_SA these keys belong to
|
||||
* @param sk_ei SK_ei, or Ka for IKEv1
|
||||
* @param sk_er SK_er
|
||||
* @param sk_d SK_d, or SKEYID_d for IKEv1
|
||||
* @param sk_ai SK_ai, or SKEYID_a for IKEv1
|
||||
* @param sk_ar SK_ar
|
||||
* @param sk_ei SK_ei, or Ka for IKEv1
|
||||
* @param sk_er SK_er
|
||||
* @param sk_pi SK_pi
|
||||
* @param sk_pr SK_pr
|
||||
*/
|
||||
bool (*ike_derived_keys)(listener_t *this, ike_sa_t *ike_sa, chunk_t sk_ei,
|
||||
chunk_t sk_er, chunk_t sk_ai, chunk_t sk_ar);
|
||||
bool (*ike_derived_keys)(listener_t *this, ike_sa_t *ike_sa, chunk_t sk_d,
|
||||
chunk_t sk_ai, chunk_t sk_ar, chunk_t sk_ei,
|
||||
chunk_t sk_er, chunk_t sk_pi, chunk_t sk_pr);
|
||||
|
||||
/**
|
||||
* Hook called with CHILD_SA key material.
|
||||
|
|
|
@ -153,11 +153,11 @@ enum notify_type_t {
|
|||
FRAGMENTATION_SUPPORTED = 16430,
|
||||
/* Signature Hash Algorithms, RFC 7427 */
|
||||
SIGNATURE_HASH_ALGORITHMS = 16431,
|
||||
/* Use Postquantum Preshared Key (draft-ietf-ipsecme-qr-ikev2) */
|
||||
/* Use Postquantum Preshared Key, RFC 8784 */
|
||||
USE_PPK = 16435,
|
||||
/* Postquantum Preshared Key Identity (draft-ietf-ipsecme-qr-ikev2) */
|
||||
/* Postquantum Preshared Key Identity, RFC 8784 */
|
||||
PPK_IDENTITY = 16436,
|
||||
/* No Postquantum Preshared Key Auth (draft-ietf-ipsecme-qr-ikev2) */
|
||||
/* No Postquantum Preshared Key Auth, RFC 8784 */
|
||||
NO_PPK_AUTH = 16437,
|
||||
/* IKEv1 initial contact */
|
||||
INITIAL_CONTACT_IKEV1 = 24578,
|
||||
|
|
|
@ -629,7 +629,7 @@ receiver_t *receiver_create()
|
|||
},
|
||||
.esp_cb_mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
||||
.secret_switch = now,
|
||||
.secret_offset = random() % now,
|
||||
.secret_offset = now ? random() % now : 0,
|
||||
);
|
||||
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
|
|
|
@ -66,7 +66,7 @@ METHOD(socket_manager_t, receiver, status_t,
|
|||
this->lock->unlock(this->lock);
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
/* receive is blocking and the thread can be cancelled */
|
||||
/* receive is blocking and the thread can be canceled */
|
||||
thread_cleanup_push((thread_cleanup_t)this->lock->unlock, this->lock);
|
||||
status = this->socket->receive(this->socket, packet);
|
||||
thread_cleanup_pop(TRUE);
|
||||
|
|
|
@ -307,11 +307,13 @@ static bool discover(private_dhcp_socket_t *this,
|
|||
{
|
||||
dhcp_option_t *option;
|
||||
dhcp_t dhcp;
|
||||
chunk_t mac;
|
||||
int optlen;
|
||||
|
||||
optlen = prepare_dhcp(this, transaction, DHCP_DISCOVER, &dhcp);
|
||||
|
||||
DBG1(DBG_CFG, "sending DHCP DISCOVER to %H", this->dst);
|
||||
mac = chunk_from_thing(dhcp.client_hw_addr);
|
||||
DBG1(DBG_CFG, "sending DHCP DISCOVER for %#B to %H", &mac, this->dst);
|
||||
|
||||
option = (dhcp_option_t*)&dhcp.options[optlen];
|
||||
option->type = DHCP_PARAM_REQ_LIST;
|
||||
|
@ -416,6 +418,9 @@ METHOD(dhcp_socket_t, enroll, dhcp_transaction_t*,
|
|||
DBG1(DBG_CFG, "DHCP DISCOVER timed out");
|
||||
return NULL;
|
||||
}
|
||||
DBG1(DBG_CFG, "received DHCP OFFER %H from %H",
|
||||
transaction->get_address(transaction),
|
||||
transaction->get_server(transaction));
|
||||
|
||||
try = 1;
|
||||
while (try <= DHCP_TRIES && request(this, transaction))
|
||||
|
@ -435,6 +440,8 @@ METHOD(dhcp_socket_t, enroll, dhcp_transaction_t*,
|
|||
return NULL;
|
||||
}
|
||||
this->mutex->unlock(this->mutex);
|
||||
DBG1(DBG_CFG, "received DHCP ACK for %H",
|
||||
transaction->get_address(transaction));
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
@ -548,7 +555,6 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
|
|||
server = host_create_from_chunk(AF_INET,
|
||||
chunk_from_thing(dhcp->server_address), DHCP_SERVER_PORT);
|
||||
}
|
||||
DBG1(DBG_CFG, "received DHCP OFFER %H from %H", offer, server);
|
||||
transaction->set_address(transaction, offer->clone(offer));
|
||||
transaction->set_server(transaction, server);
|
||||
}
|
||||
|
@ -564,10 +570,6 @@ static void handle_ack(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
|
|||
{
|
||||
dhcp_transaction_t *transaction;
|
||||
enumerator_t *enumerator;
|
||||
host_t *offer;
|
||||
|
||||
offer = host_create_from_chunk(AF_INET,
|
||||
chunk_from_thing(dhcp->your_address), 0);
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->request->create_enumerator(this->request);
|
||||
|
@ -575,7 +577,6 @@ static void handle_ack(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
|
|||
{
|
||||
if (transaction->get_id(transaction) == dhcp->transaction_id)
|
||||
{
|
||||
DBG1(DBG_CFG, "received DHCP ACK for %H", offer);
|
||||
this->request->remove_at(this->request, enumerator);
|
||||
this->completed->insert_last(this->completed, transaction);
|
||||
break;
|
||||
|
@ -584,7 +585,6 @@ static void handle_ack(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
|
|||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
this->condvar->broadcast(this->condvar);
|
||||
offer->destroy(offer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -63,8 +63,8 @@ typedef struct eap_aka_3gpp_plugin_t eap_aka_3gpp_plugin_t;
|
|||
* SQN with its own locally stored value. This potentially allows an attacker
|
||||
* to do replay attacks. But since the server has proven his identity via IKE,
|
||||
* such an attack is only possible between server and AAA (if any).
|
||||
* Note that SEQ_CHECK only controls the compile-time default behaviour,
|
||||
* but the run-time behaviour can always be controlled by setting the
|
||||
* Note that SEQ_CHECK only controls the compile-time default behavior,
|
||||
* but the run-time behavior can always be controlled by setting the
|
||||
* charon.plugins.eap-aka-3gpp.seq_check config variable.
|
||||
*/
|
||||
struct eap_aka_3gpp_plugin_t {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libcharon \
|
||||
-I$(top_srcdir)/src/libsimaka
|
||||
|
||||
AM_CFLAGS = \
|
||||
${pcsclite_CFLAGS} \
|
||||
$(PLUGIN_CFLAGS)
|
||||
|
||||
libstrongswan_eap_simaka_pcsc_la_LIBADD = ${pcsclite_LIBS}
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-eap-simaka-pcsc.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-eap-simaka-pcsc.la
|
||||
libstrongswan_eap_simaka_pcsc_la_LIBADD += $(top_builddir)/src/libsimaka/libsimaka.la
|
||||
endif
|
||||
|
||||
libstrongswan_eap_simaka_pcsc_la_SOURCES = \
|
||||
eap_simaka_pcsc_plugin.h eap_simaka_pcsc_plugin.c \
|
||||
eap_simaka_pcsc_card.h eap_simaka_pcsc_card.c
|
||||
|
||||
libstrongswan_eap_simaka_pcsc_la_LDFLAGS = -module -avoid-version
|
|
@ -0,0 +1,828 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Domonkos P. Tomcsanyi
|
||||
* umlaut Communications Gmbh.
|
||||
*
|
||||
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "eap_simaka_pcsc_card.h"
|
||||
#include <PCSC/wintypes.h>
|
||||
#include <PCSC/winscard.h>
|
||||
#include <daemon.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct private_eap_simaka_pcsc_card_t private_eap_simaka_pcsc_card_t;
|
||||
|
||||
/**
|
||||
* Private data of an eap_simaka_pcsc_card_t object.
|
||||
*/
|
||||
struct private_eap_simaka_pcsc_card_t {
|
||||
|
||||
/**
|
||||
* Public eap_simaka_pcsc_card_t interface.
|
||||
*/
|
||||
eap_simaka_pcsc_card_t public;
|
||||
};
|
||||
|
||||
/**
|
||||
* Maximum length for an IMSI.
|
||||
*/
|
||||
#define SIM_IMSI_MAX_LEN 15
|
||||
|
||||
/**
|
||||
* Length of the status at the end of response APDUs.
|
||||
*/
|
||||
#define APDU_STATUS_LEN 2
|
||||
|
||||
/**
|
||||
* First byte of status word indicating success.
|
||||
*/
|
||||
#define APDU_SW1_SUCCESS 0x90
|
||||
|
||||
/**
|
||||
* First byte of status word indicating there is response data to be read.
|
||||
*/
|
||||
#define APDU_SW1_RESPONSE_DATA 0x9f
|
||||
|
||||
/*
|
||||
* Communication status
|
||||
*/
|
||||
#define ERROR_NONE 0
|
||||
#define ERROR_SCARD 1
|
||||
#define ERROR_CARD_ERROR 2
|
||||
|
||||
/**
|
||||
* Decode IMSI EF (Elementary File) into an ASCII string
|
||||
*/
|
||||
static bool decode_imsi_ef(unsigned char *input, int input_len, char *output)
|
||||
{
|
||||
/* Only digits 0-9 valid in IMSIs */
|
||||
static const char bcd_num_digits[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '\0', '\0', '\0', '\0', '\0', '\0'
|
||||
};
|
||||
int i;
|
||||
|
||||
/* Check length byte matches how many bytes we have, and that input
|
||||
* is correct length for an IMSI */
|
||||
if (input[0] != input_len-1 || input_len < 2 || input_len > 9)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check type byte is IMSI (bottom 3 bits == 001) */
|
||||
if ((input[1] & 0x07) != 0x01)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*output++ = bcd_num_digits[input[1] >> 4];
|
||||
|
||||
for (i = 2; i < input_len; i++)
|
||||
{
|
||||
*output++ = bcd_num_digits[input[i] & 0xf];
|
||||
*output++ = bcd_num_digits[input[i] >> 4];
|
||||
}
|
||||
|
||||
*output++ = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(simaka_card_t, get_triplet, bool,
|
||||
private_eap_simaka_pcsc_card_t *this, identification_t *id,
|
||||
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
|
||||
{
|
||||
status_t found = FALSE;
|
||||
LONG rv;
|
||||
SCARDCONTEXT hContext;
|
||||
DWORD dwReaders;
|
||||
LPSTR mszReaders;
|
||||
char *cur_reader;
|
||||
char full_nai[128];
|
||||
SCARDHANDLE hCard;
|
||||
enum { DISCONNECTED, CONNECTED, TRANSACTION } hCard_status = DISCONNECTED;
|
||||
|
||||
snprintf(full_nai, sizeof(full_nai), "%Y", id);
|
||||
|
||||
DBG2(DBG_IKE, "looking for triplet: %Y rand %b", id, rand, SIM_RAND_LEN);
|
||||
|
||||
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardEstablishContext: %s", pcsc_stringify_error(rv));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardListReaders: %s", pcsc_stringify_error(rv));
|
||||
return FALSE;
|
||||
}
|
||||
mszReaders = malloc(sizeof(char)*dwReaders);
|
||||
|
||||
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardListReaders: %s", pcsc_stringify_error(rv));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* mszReaders is a multi-string of readers, separated by '\0' and
|
||||
* terminated by an additional '\0' */
|
||||
for (cur_reader = mszReaders; *cur_reader != '\0' && found == FALSE;
|
||||
cur_reader += strlen(cur_reader) + 1)
|
||||
{
|
||||
DWORD dwActiveProtocol = -1;
|
||||
const SCARD_IO_REQUEST *pioSendPci;
|
||||
SCARD_IO_REQUEST pioRecvPci;
|
||||
BYTE pbRecvBuffer[64];
|
||||
DWORD dwRecvLength;
|
||||
char imsi[SIM_IMSI_MAX_LEN + 1];
|
||||
|
||||
/* See GSM 11.11 for SIM APDUs */
|
||||
static const BYTE pbSelectMF[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00 };
|
||||
static const BYTE pbSelectDFGSM[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x7f, 0x20 };
|
||||
static const BYTE pbSelectIMSI[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x6f, 0x07 };
|
||||
static const BYTE pbReadBinary[] = { 0xa0, 0xb0, 0x00, 0x00, 0x09 };
|
||||
BYTE pbRunGSMAlgorithm[5 + SIM_RAND_LEN] = { 0xa0, 0x88, 0x00, 0x00, 0x10 };
|
||||
static const BYTE pbGetResponse[] = { 0xa0, 0xc0, 0x00, 0x00, 0x0c };
|
||||
|
||||
/* If on 2nd or later reader, make sure we end the transaction
|
||||
* and disconnect card in the previous reader */
|
||||
switch (hCard_status)
|
||||
{
|
||||
case TRANSACTION:
|
||||
SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
|
||||
/* FALLTHRU */
|
||||
case CONNECTED:
|
||||
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
|
||||
/* FALLTHRU */
|
||||
case DISCONNECTED:
|
||||
hCard_status = DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Copy RAND into APDU */
|
||||
memcpy(pbRunGSMAlgorithm + 5, rand, SIM_RAND_LEN);
|
||||
|
||||
rv = SCardConnect(hContext, cur_reader, SCARD_SHARE_SHARED,
|
||||
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardConnect: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
hCard_status = CONNECTED;
|
||||
|
||||
switch(dwActiveProtocol)
|
||||
{
|
||||
case SCARD_PROTOCOL_T0:
|
||||
pioSendPci = SCARD_PCI_T0;
|
||||
break;
|
||||
case SCARD_PROTOCOL_T1:
|
||||
pioSendPci = SCARD_PCI_T1;
|
||||
break;
|
||||
default:
|
||||
DBG1(DBG_IKE, "Unknown SCARD_PROTOCOL");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Start transaction */
|
||||
rv = SCardBeginTransaction(hCard);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardBeginTransaction: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
hCard_status = TRANSACTION;
|
||||
|
||||
/* APDU: Select MF */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, pbSelectMF, sizeof(pbSelectMF),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
|
||||
{
|
||||
DBG1(DBG_IKE, "Select MF failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* APDU: Select DF GSM */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, pbSelectDFGSM, sizeof(pbSelectDFGSM),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
|
||||
{
|
||||
DBG1(DBG_IKE, "Select DF GSM failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* APDU: Select IMSI */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, pbSelectIMSI, sizeof(pbSelectIMSI),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
|
||||
{
|
||||
DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* APDU: Read Binary (of IMSI) */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, pbReadBinary, sizeof(pbReadBinary),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!decode_imsi_ef(pbRecvBuffer, dwRecvLength-APDU_STATUS_LEN, imsi))
|
||||
{
|
||||
DBG1(DBG_IKE, "Couldn't decode IMSI EF: %b",
|
||||
pbRecvBuffer, (u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The IMSI could be post/prefixed in the full NAI, so just make sure
|
||||
* it's in there */
|
||||
if (!(strlen(full_nai) && strstr(full_nai, imsi)))
|
||||
{
|
||||
DBG1(DBG_IKE, "Not the SIM we're looking for, IMSI: %s", imsi);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* APDU: Run GSM Algorithm */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci,
|
||||
pbRunGSMAlgorithm, sizeof(pbRunGSMAlgorithm),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
|
||||
{
|
||||
DBG1(DBG_IKE, "Run GSM Algorithm failed: %b",
|
||||
pbRecvBuffer, (u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* APDU: Get Response (of Run GSM Algorithm) */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, pbGetResponse, sizeof(pbGetResponse),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "Get Response failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Extract out Kc and SRES from response */
|
||||
if (dwRecvLength == SIM_SRES_LEN + SIM_KC_LEN + APDU_STATUS_LEN)
|
||||
{
|
||||
memcpy(sres, pbRecvBuffer, SIM_SRES_LEN);
|
||||
memcpy(kc, pbRecvBuffer+4, SIM_KC_LEN);
|
||||
/* This will also cause the loop to exit */
|
||||
found = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "Get Response incorrect length: %b",
|
||||
pbRecvBuffer, (u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Transaction will be ended and card disconnected at the
|
||||
* beginning of this loop or after this loop */
|
||||
}
|
||||
|
||||
/* Make sure we end any previous transaction and disconnect card */
|
||||
switch (hCard_status)
|
||||
{
|
||||
case TRANSACTION:
|
||||
SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
|
||||
/* FALLTHRU */
|
||||
case CONNECTED:
|
||||
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
|
||||
/* FALLTHRU */
|
||||
case DISCONNECTED:
|
||||
hCard_status = DISCONNECTED;
|
||||
}
|
||||
|
||||
rv = SCardReleaseContext(hContext);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardReleaseContext: %s", pcsc_stringify_error(rv));
|
||||
}
|
||||
|
||||
free(mszReaders);
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(simaka_card_t, get_quintuplet, status_t,
|
||||
private_eap_simaka_pcsc_card_t *this, identification_t *id,
|
||||
char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
|
||||
char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
|
||||
{
|
||||
status_t found = SUCCESS;
|
||||
LONG rv;
|
||||
SCARDCONTEXT hContext;
|
||||
DWORD dwReaders;
|
||||
LPSTR mszReaders;
|
||||
char *cur_reader;
|
||||
char full_nai[128];
|
||||
SCARDHANDLE hCard;
|
||||
enum { DISCONNECTED, CONNECTED, TRANSACTION } hCard_status = DISCONNECTED;
|
||||
|
||||
snprintf(full_nai, sizeof(full_nai), "%Y", id);
|
||||
|
||||
DBG2(DBG_IKE, "looking for quintuplet: %Y rand %b", id, rand, SIM_RAND_LEN);
|
||||
|
||||
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardEstablishContext: %s", pcsc_stringify_error(rv));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardListReaders: %s", pcsc_stringify_error(rv));
|
||||
return FALSE;
|
||||
}
|
||||
mszReaders = malloc(sizeof(char)*dwReaders);
|
||||
|
||||
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardListReaders: %s", pcsc_stringify_error(rv));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* mszReaders is a multi-string of readers, separated by '\0' and
|
||||
* terminated by an additional '\0' */
|
||||
for (cur_reader = mszReaders; *cur_reader != '\0' && found == FALSE;
|
||||
cur_reader += strlen(cur_reader) + 1)
|
||||
{
|
||||
DWORD dwActiveProtocol = -1;
|
||||
const SCARD_IO_REQUEST *pioSendPci;
|
||||
SCARD_IO_REQUEST pioRecvPci;
|
||||
BYTE pbRecvBuffer[512];
|
||||
DWORD dwRecvLength;
|
||||
char imsi[SIM_IMSI_MAX_LEN + 1];
|
||||
char aid_pattern[] = {0xA0, 0x00, 0x00, 0x00, 0x87, 0x10, 0x02}; //based on mitshell/card USIM.py:SELECT_ADF_USIM()
|
||||
char *correct_aid = NULL;
|
||||
int resLen = 0;
|
||||
|
||||
/* USIM APDUs */
|
||||
BYTE abSelectEFDIR[] = {0x00, 0xA4, 0x08, 0x04, 0x02, 0x2F, 0x00};
|
||||
// CLA SELECT P1 P2 len
|
||||
// 0x00 0xC0 0x00 0x00 0x00
|
||||
BYTE abGetResponse[] = {0x00, 0xC0, 0x00, 0x00, 0x1C};
|
||||
// CLA SELECT P1 (by fileID) P2(UICC) len DATA (EF_IMSI address)
|
||||
// 0x00 0xA4 0x00 0x04 0x02 0x6F 0x07
|
||||
BYTE abSelectIMSI[] = {0x00, 0xA4, 0x00, 0x04, 0x02, 0x6F, 0x07};
|
||||
BYTE abReadRecord[] = {0x00, 0xB2, 0x01, 0x04, 0x00}; //Le byte (last one) set to 0x00 so complete record is read up to 256 bytes
|
||||
// CLA SELECT P1 (AID) P2(UICC) len DATA (AID)
|
||||
// 0x00 0xA4 0x04 0x04 '0xc', '0xa0', '0x0', '0x0', '0x0', '0x87', '0x10', '0x2', '0xff', '0x49', '0xff', '0x5', '0x89'
|
||||
BYTE abSelectUICC[] = {0x00, 0xA4, 0x04, 0x04};
|
||||
BYTE abReadBinary[] = {0x00, 0xB0, 0x00, 0x00, 0x09};
|
||||
BYTE abAuthenticate[5 + 1 + SIM_RAND_LEN + 1 + SIM_RAND_LEN] = { 0x00, 0x88, 0x00, 0x81, 0x22, 0x10 }; //TOTAL_LEN + LEN(RAND) + RAND + LEN(AUTN) + AUTN
|
||||
int i,j;
|
||||
/* If on 2nd or later reader, make sure we end the transaction
|
||||
* and disconnect card in the previous reader */
|
||||
switch (hCard_status)
|
||||
{
|
||||
case TRANSACTION:
|
||||
SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
|
||||
/* FALLTHRU */
|
||||
case CONNECTED:
|
||||
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
|
||||
/* FALLTHRU */
|
||||
case DISCONNECTED:
|
||||
hCard_status = DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Copy RAND into APDU */
|
||||
memcpy(abAuthenticate + 6, rand, SIM_RAND_LEN);
|
||||
abAuthenticate[6 + SIM_RAND_LEN] = 0x10; //LEN of AUTN
|
||||
memcpy(abAuthenticate + 6 + SIM_RAND_LEN + 1, autn, SIM_RAND_LEN); //Copy AUTN into APDU
|
||||
|
||||
rv = SCardConnect(hContext, cur_reader, SCARD_SHARE_SHARED,
|
||||
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardConnect: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
hCard_status = CONNECTED;
|
||||
|
||||
switch(dwActiveProtocol)
|
||||
{
|
||||
case SCARD_PROTOCOL_T0:
|
||||
pioSendPci = SCARD_PCI_T0;
|
||||
break;
|
||||
case SCARD_PROTOCOL_T1:
|
||||
pioSendPci = SCARD_PCI_T1;
|
||||
break;
|
||||
default:
|
||||
DBG1(DBG_IKE, "Unknown SCARD_PROTOCOL");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Start transaction */
|
||||
rv = SCardBeginTransaction(hCard);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardBeginTransaction: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
hCard_status = TRANSACTION;
|
||||
|
||||
/* APDU: Select EFDIR */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, abSelectEFDIR, sizeof(abSelectEFDIR),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
|
||||
|
||||
if (pbRecvBuffer[0] == 0x61 && dwRecvLength < 3)
|
||||
{ // Response bytes available, GET RESPONSE needs to be run
|
||||
abGetResponse[4] = pbRecvBuffer[1]; //setting the expected length to the one sent by the card
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, abGetResponse, sizeof(abGetResponse),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
|
||||
}
|
||||
else if ((pbRecvBuffer[0] == 0x6C && dwRecvLength < 3) || (pbRecvBuffer[0] == 0x67 && dwRecvLength < 3)) //WRONG length used, correcting it
|
||||
{
|
||||
abSelectEFDIR[4] = pbRecvBuffer[1]; //setting the expected length to the one sent by the card
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, abSelectEFDIR, sizeof(abSelectEFDIR),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
}
|
||||
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
|
||||
{
|
||||
DBG1(DBG_IKE, "Select EFDIR failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}*/
|
||||
|
||||
for(j=0; j<5; j++) //Fingers crossed there is no SIM card with more than 5 applications in its EF_DIR
|
||||
{
|
||||
/* APDU: Read Record */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
abReadRecord[2] = j;
|
||||
rv = SCardTransmit(hCard, pioSendPci, abReadRecord, sizeof(abReadRecord),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
|
||||
{
|
||||
DBG1(DBG_IKE, "Read Record failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
DBG1(DBG_IKE, "READ RECORD #%d: %b", j, pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
if ((pbRecvBuffer[0] == 0x6C && dwRecvLength < 3) || (pbRecvBuffer[0] == 0x67 && dwRecvLength < 3)) //WRONG length used, correcting it
|
||||
{
|
||||
abReadRecord[4] = pbRecvBuffer[1]; //setting the expected length to the one sent by the card
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, abReadRecord, sizeof(abReadRecord),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
}
|
||||
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((pbRecvBuffer[0]== 0x61) && (pbRecvBuffer[2] == 0x4F) && dwRecvLength > 6)
|
||||
{
|
||||
correct_aid = memmem(pbRecvBuffer, dwRecvLength, aid_pattern, sizeof(aid_pattern));
|
||||
DBG1(DBG_IKE, "Detecting AIDs...");
|
||||
if(correct_aid)
|
||||
break;
|
||||
} else {
|
||||
DBG1(DBG_IKE, "Failed to get AID, will not be able to proceed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(!correct_aid)
|
||||
{
|
||||
DBG1(DBG_IKE, "NOT finding USIM AID (see ETSI TS 101 220 Annex E) pattern, will not be able to proceed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
|
||||
} else {
|
||||
unsigned char aid[pbRecvBuffer[3]]; //the transaction buffer contains the right AID with its length
|
||||
for(i=0; i < sizeof(aid); i++) {
|
||||
aid[i] = (*correct_aid);
|
||||
correct_aid++;
|
||||
}
|
||||
unsigned char final_apdu[sizeof(aid)+4];
|
||||
for (i=0; i < sizeof(abSelectUICC); i++) {
|
||||
final_apdu[i] = abSelectUICC[i];
|
||||
}
|
||||
final_apdu[sizeof(abSelectUICC)] = sizeof(aid); //len byte
|
||||
for (i=0; i < sizeof(aid); i++) { //adding AID to the APDU
|
||||
final_apdu[i+5] = aid[i];
|
||||
}
|
||||
DBG1(DBG_IKE, "Got AID: %b", aid,
|
||||
sizeof(aid));
|
||||
|
||||
DBG1(DBG_IKE, "Selecting UICC...");
|
||||
/* APDU: Select UICC */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
DBG1(DBG_IKE, "Sending APDU: %b", final_apdu,
|
||||
(u_int)pbRecvBuffer[3]+5);
|
||||
|
||||
rv = SCardTransmit(hCard, pioSendPci, final_apdu, pbRecvBuffer[3]+5,
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
if (pbRecvBuffer[0] == 0x61 && dwRecvLength < 3)
|
||||
{ // Response bytes available, GET RESPONSE needs to be run
|
||||
abGetResponse[4] = pbRecvBuffer[1]; //setting the expected length to the one sent by the card
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, abGetResponse, sizeof(abGetResponse),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
}
|
||||
}
|
||||
|
||||
/* if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
|
||||
{
|
||||
DBG1(DBG_IKE, "Select UICC failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
DBG1(DBG_IKE, "Selecting IMSI...");
|
||||
/* APDU: Select IMSI */
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, abSelectIMSI, sizeof(abSelectIMSI),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
if (pbRecvBuffer[0] == 0x61 && dwRecvLength < 3)
|
||||
{ // Response bytes available, GET RESPONSE needs to be run
|
||||
abGetResponse[4] = pbRecvBuffer[1]; //setting the expected length to the one sent by the card
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, abGetResponse, sizeof(abGetResponse),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
}
|
||||
/*
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
|
||||
{
|
||||
DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
/* APDU: Read Binary (of IMSI) */
|
||||
DBG1(DBG_IKE, "Reading binary of IMSI...");
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, abReadBinary, sizeof(abReadBinary),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
DBG1(DBG_IKE, "Response: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
|
||||
if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "Read binary of IMSI failed: %b", pbRecvBuffer,
|
||||
(u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!decode_imsi_ef(pbRecvBuffer, dwRecvLength-APDU_STATUS_LEN, imsi))
|
||||
{
|
||||
DBG1(DBG_IKE, "Couldn't decode IMSI EF: %b",
|
||||
pbRecvBuffer, (u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
DBG1(DBG_IKE, "Got IMSI: %s", imsi);
|
||||
/* The IMSI could be post/prefixed in the full NAI, so just make sure
|
||||
* it's in there */
|
||||
if (!(strlen(full_nai) && strstr(full_nai, imsi)))
|
||||
{
|
||||
DBG1(DBG_IKE, "Not the SIM we're looking for, IMSI: %s", imsi);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* APDU: Authenticate */
|
||||
DBG1(DBG_IKE, "Running AUTHENTICATE...");
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci,
|
||||
abAuthenticate, sizeof(abAuthenticate),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pbRecvBuffer[0] == 0x61 && dwRecvLength < 3)
|
||||
{ // Response bytes available, GET RESPONSE needs to be run
|
||||
abGetResponse[4] = pbRecvBuffer[1]; //setting the expected length to the one sent by the card
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
rv = SCardTransmit(hCard, pioSendPci, abGetResponse, sizeof(abGetResponse),
|
||||
&pioRecvPci, pbRecvBuffer, &dwRecvLength);
|
||||
|
||||
}
|
||||
|
||||
DBG1(DBG_IKE, "Response: %b",
|
||||
pbRecvBuffer, (u_int)dwRecvLength);
|
||||
|
||||
/* if (dwRecvLength < APDU_STATUS_LEN ||
|
||||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
|
||||
{
|
||||
DBG1(DBG_IKE, "Authenticate failed: %b",
|
||||
pbRecvBuffer, (u_int)dwRecvLength);
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
/* Parsing data from the response into RES, CK, IK */
|
||||
if(pbRecvBuffer[0] == 0xDB)
|
||||
{
|
||||
DBG1(DBG_IKE, "Successful 3G authentication");
|
||||
if(pbRecvBuffer[1] == 0x08 || pbRecvBuffer[1] == 0x04) //RES
|
||||
{
|
||||
resLen = pbRecvBuffer[1];
|
||||
for(i=0; i< pbRecvBuffer[1]; i++)
|
||||
{
|
||||
res[i] = pbRecvBuffer[i+2];
|
||||
}
|
||||
(*res_len) = resLen;
|
||||
} else {
|
||||
DBG1(DBG_IKE, "RES not 8 or 4 byte long, can't copy it.\n");
|
||||
continue;
|
||||
}
|
||||
if(pbRecvBuffer[resLen+2] == 0x10) //CK SUCCESS_BYTE 0xDB(len=1) + RES_LEN(len1) + resLen
|
||||
{
|
||||
for(i=0; i<16; i++)
|
||||
{
|
||||
ck[i] = pbRecvBuffer[i+resLen+3];
|
||||
}
|
||||
} else {
|
||||
DBG1(DBG_IKE, "CK not 16 byte long, can't copy it\n");
|
||||
continue;
|
||||
}
|
||||
if(pbRecvBuffer[resLen+3+16] == 0x10) //IK SUCCESS_BYTE(len1) + RES_LEN(len1) + res + CK_LEN(len1) + CK(len16)
|
||||
{
|
||||
for(i=0; i<16; i++)
|
||||
{
|
||||
ik[i] = pbRecvBuffer[i+ resLen+3+16+1];
|
||||
}
|
||||
} else {
|
||||
DBG1(DBG_IKE, "IK not 16 byte long, can't copy it\n");
|
||||
continue;
|
||||
}
|
||||
DBG1(DBG_IKE, "KEYs established. RES: %b", res, resLen);
|
||||
DBG1(DBG_IKE, "KEYs established. CK: %b", ck, 16);
|
||||
DBG1(DBG_IKE, "KEYs established. IK: %b", ik, 16);
|
||||
found = SUCCESS;
|
||||
|
||||
}
|
||||
if(pbRecvBuffer[0] == 0xDC)
|
||||
{
|
||||
DBG1(DBG_IKE, "Sync error between SIM card and network, currently NOT supported.\n");
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Transaction will be ended and card disconnected at the
|
||||
* beginning of this loop or after this loop */
|
||||
}
|
||||
|
||||
/* Make sure we end any previous transaction and disconnect card */
|
||||
switch (hCard_status)
|
||||
{
|
||||
case TRANSACTION:
|
||||
SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
|
||||
/* FALLTHRU */
|
||||
case CONNECTED:
|
||||
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
|
||||
/* FALLTHRU */
|
||||
case DISCONNECTED:
|
||||
hCard_status = DISCONNECTED;
|
||||
}
|
||||
|
||||
rv = SCardReleaseContext(hContext);
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "SCardReleaseContext: %s", pcsc_stringify_error(rv));
|
||||
}
|
||||
|
||||
free(mszReaders);
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(eap_simaka_pcsc_card_t, destroy, void,
|
||||
private_eap_simaka_pcsc_card_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
eap_simaka_pcsc_card_t *eap_simaka_pcsc_card_create()
|
||||
{
|
||||
private_eap_simaka_pcsc_card_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.card = {
|
||||
.get_triplet = _get_triplet,
|
||||
.get_quintuplet = _get_quintuplet,
|
||||
.resync = (void*)return_false,
|
||||
.get_pseudonym = (void*)return_null,
|
||||
.set_pseudonym = (void*)nop,
|
||||
.get_reauth = (void*)return_null,
|
||||
.set_reauth = (void*)nop,
|
||||
},
|
||||
.destroy = _destroy,
|
||||
},
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Domonkos P. Tomcsanyi
|
||||
* umlaut Communications Gmbh.
|
||||
*
|
||||
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef EAP_SIMAKA_PCSC_CARD_H_
|
||||
#define EAP_SIMAKA_PCSC_CARD_H_
|
||||
|
||||
#include <simaka_card.h>
|
||||
|
||||
typedef struct eap_simaka_pcsc_card_t eap_simaka_pcsc_card_t;
|
||||
|
||||
/**
|
||||
* SIM card implementing PC/SC backend.
|
||||
*/
|
||||
struct eap_simaka_pcsc_card_t {
|
||||
|
||||
/**
|
||||
* Implements simaka_card_t interface
|
||||
*/
|
||||
simaka_card_t card;
|
||||
|
||||
/**
|
||||
* Destroy a eap_simaka_pcsc_card_t.
|
||||
*/
|
||||
void (*destroy)(eap_simaka_pcsc_card_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a eap_simaka_pcsc_card instance.
|
||||
*/
|
||||
eap_simaka_pcsc_card_t *eap_simaka_pcsc_card_create();
|
||||
|
||||
#endif /** EAP_SIMAKA_PCSC_CARD_H_ @}*/
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Domonkos P. Tomcsanyi
|
||||
* umlaut Communications Gmbh.
|
||||
*
|
||||
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "eap_simaka_pcsc_plugin.h"
|
||||
#include "eap_simaka_pcsc_card.h"
|
||||
|
||||
#include <daemon.h>
|
||||
|
||||
typedef struct private_eap_simaka_pcsc_t private_eap_simaka_pcsc_t;
|
||||
|
||||
/**
|
||||
* Private data of an eap_simaka_pcsc_t object.
|
||||
*/
|
||||
struct private_eap_simaka_pcsc_t {
|
||||
|
||||
/**
|
||||
* Public eap_simaka_pcsc_plugin_t interface.
|
||||
*/
|
||||
eap_simaka_pcsc_plugin_t public;
|
||||
|
||||
/**
|
||||
* SIM card
|
||||
*/
|
||||
eap_simaka_pcsc_card_t *card;
|
||||
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_eap_simaka_pcsc_t *this)
|
||||
{
|
||||
return "eap-simaka-pcsc";
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback providing our card to register
|
||||
*/
|
||||
static simaka_card_t* get_card(private_eap_simaka_pcsc_t *this)
|
||||
{
|
||||
if (!this->card)
|
||||
{
|
||||
this->card = eap_simaka_pcsc_card_create();
|
||||
}
|
||||
return &this->card->card;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_eap_simaka_pcsc_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(simaka_manager_register, get_card),
|
||||
PLUGIN_PROVIDE(CUSTOM, "aka-card"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
|
||||
PLUGIN_PROVIDE(CUSTOM, "sim-card"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_eap_simaka_pcsc_t *this)
|
||||
{
|
||||
DESTROY_IF(this->card);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
plugin_t *eap_simaka_pcsc_plugin_create()
|
||||
{
|
||||
private_eap_simaka_pcsc_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Domonkos P. Tomcsanyi
|
||||
* umlaut Communications Gmbh.
|
||||
*
|
||||
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef EAP_SIMAKA_PCSC_PLUGIN_H_
|
||||
#define EAP_SIMAKA_PCSC_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct eap_simaka_pcsc_plugin_t eap_simaka_pcsc_plugin_t;
|
||||
|
||||
/**
|
||||
* Plugin to provide EAP-AKA PC/SC based USIM card backend
|
||||
*/
|
||||
struct eap_simaka_pcsc_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** EAP_SIMAKA_PCSC_PLUGIN_H_ @}*/
|
|
@ -361,7 +361,8 @@ static int get_ifindex(private_kernel_listener_t *this, char *ifname)
|
|||
{
|
||||
struct ifreq ifr = {};
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
|
||||
|
||||
if (ioctl(this->raw, SIOCGIFINDEX, &ifr) == 0)
|
||||
{
|
||||
return ifr.ifr_ifindex;
|
||||
|
|
|
@ -262,7 +262,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
|
|||
{ /* register IKE_SA before calling inherit_post() so no scheduled
|
||||
* jobs are lost */
|
||||
charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
|
||||
old_sa);
|
||||
ike_sa);
|
||||
ike_sa->inherit_pre(ike_sa, old_sa);
|
||||
ike_sa->inherit_post(ike_sa, old_sa);
|
||||
charon->ike_sa_manager->checkin_and_destroy(
|
||||
|
|
|
@ -1372,6 +1372,7 @@ static void process_route(private_kernel_netlink_net_t *this,
|
|||
if (RTA_PAYLOAD(rta) == sizeof(uint32_t) &&
|
||||
this->routing_table == *(uint32_t*)RTA_DATA(rta))
|
||||
{
|
||||
DESTROY_IF(host);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -2548,9 +2549,11 @@ METHOD(kernel_net_t, del_ip, status_t,
|
|||
if (status == SUCCESS && wait)
|
||||
{ /* wait until the address is really gone */
|
||||
this->lock->write_lock(this->lock);
|
||||
while (is_known_vip(this, virtual_ip))
|
||||
{
|
||||
this->condvar->wait(this->condvar, this->lock);
|
||||
while (is_known_vip(this, virtual_ip) &&
|
||||
lib->watcher->get_state(lib->watcher) != WATCHER_STOPPED)
|
||||
{ /* don't wait during deinit when we can't get notified,
|
||||
* re-evaluate watcher state if we have to wait longer */
|
||||
this->condvar->timed_wait(this->condvar, this->lock, 1000);
|
||||
}
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
|
|
@ -624,7 +624,7 @@ static void add_ts(private_load_tester_config_t *this,
|
|||
/**
|
||||
* Allocate and install a dynamic external address to use
|
||||
*/
|
||||
static host_t *allocate_addr(private_load_tester_config_t *this, uint num)
|
||||
static host_t *allocate_addr(private_load_tester_config_t *this, u_int num)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
mem_pool_t *pool;
|
||||
|
@ -682,7 +682,7 @@ static host_t *allocate_addr(private_load_tester_config_t *this, uint num)
|
|||
/**
|
||||
* Generate a new initiator config, num = 0 for responder config
|
||||
*/
|
||||
static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
|
||||
static peer_cfg_t* generate_config(private_load_tester_config_t *this, u_int num)
|
||||
{
|
||||
ike_cfg_t *ike_cfg;
|
||||
child_cfg_t *child_cfg;
|
||||
|
|
|
@ -276,8 +276,9 @@ static inline void esp_names(proposal_t *proposal, const char **enc,
|
|||
}
|
||||
|
||||
METHOD(listener_t, ike_derived_keys, bool,
|
||||
private_save_keys_listener_t *this, ike_sa_t *ike_sa, chunk_t sk_ei,
|
||||
chunk_t sk_er, chunk_t sk_ai, chunk_t sk_ar)
|
||||
private_save_keys_listener_t *this, ike_sa_t *ike_sa, chunk_t sk_d,
|
||||
chunk_t sk_ai, chunk_t sk_ar, chunk_t sk_ei, chunk_t sk_er, chunk_t sk_pi,
|
||||
chunk_t sk_pr)
|
||||
{
|
||||
ike_version_t version;
|
||||
ike_sa_id_t *id;
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
* - vici_end_list(): Close a previously opened list
|
||||
* - vici_add_list_item() / vici_add_list_itemf(): Add list item
|
||||
*
|
||||
* Once the request message is complete, it can be sent or cancelled with:
|
||||
* Once the request message is complete, it can be sent or canceled with:
|
||||
*
|
||||
* - vici_submit()
|
||||
* - vici_free_req()
|
||||
|
|
|
@ -640,7 +640,7 @@ print $res ? "ok\n" : "failed: $errmsg\n";
|
|||
# close vici socket
|
||||
close($socket);
|
||||
|
||||
=head1 COPYRIGHT AND LICENCE
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (c) 2015 Andreas Steffen
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ static void vadd_kv_or_li(private_vici_builder_t *this, char *key,
|
|||
{
|
||||
value = chunk_alloc(len + 1);
|
||||
len = vsnprintf(value.ptr, value.len, fmt, args);
|
||||
value.len = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -191,6 +191,7 @@ static entry_t* find_entry(private_vici_socket_t *this, stream_t *stream,
|
|||
}
|
||||
if (entry->disconnecting)
|
||||
{
|
||||
entry->cond->signal(entry->cond);
|
||||
continue;
|
||||
}
|
||||
candidate = TRUE;
|
||||
|
@ -244,6 +245,7 @@ static entry_t* remove_entry(private_vici_socket_t *this, u_int id)
|
|||
break;
|
||||
}
|
||||
this->connections->remove_at(this->connections, enumerator);
|
||||
entry->cond->broadcast(entry->cond);
|
||||
found = entry;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -638,6 +638,29 @@ METHOD(ike_sa_t, get_message_id, uint32_t,
|
|||
return this->task_manager->get_mid(this->task_manager, initiate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set configured DSCP value on packet
|
||||
*/
|
||||
static void set_dscp(private_ike_sa_t *this, packet_t *packet)
|
||||
{
|
||||
ike_cfg_t *ike_cfg;
|
||||
|
||||
/* prefer IKE config on peer_cfg, as its selection is more accurate
|
||||
* then the initial IKE config */
|
||||
if (this->peer_cfg)
|
||||
{
|
||||
ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg);
|
||||
}
|
||||
else
|
||||
{
|
||||
ike_cfg = this->ike_cfg;
|
||||
}
|
||||
if (ike_cfg)
|
||||
{
|
||||
packet->set_dscp(packet, ike_cfg->get_dscp(ike_cfg));
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(ike_sa_t, send_keepalive, void,
|
||||
private_ike_sa_t *this, bool scheduled)
|
||||
{
|
||||
|
@ -681,6 +704,7 @@ METHOD(ike_sa_t, send_keepalive, void,
|
|||
packet = packet_create();
|
||||
packet->set_source(packet, this->my_host->clone(this->my_host));
|
||||
packet->set_destination(packet, this->other_host->clone(this->other_host));
|
||||
set_dscp(this, packet);
|
||||
data.ptr = malloc(1);
|
||||
data.ptr[0] = 0xFF;
|
||||
data.len = 1;
|
||||
|
@ -1172,10 +1196,30 @@ METHOD(ike_sa_t, update_hosts, void,
|
|||
}
|
||||
if (new_me)
|
||||
{
|
||||
if (this->state == IKE_ESTABLISHED)
|
||||
{
|
||||
DBG1(DBG_IKE, "local endpoint changed from %#H to %#H",
|
||||
this->my_host, new_me);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_IKE, "local endpoint changed from %#H to %#H",
|
||||
this->my_host, new_me);
|
||||
}
|
||||
set_my_host(this, new_me->clone(new_me));
|
||||
}
|
||||
if (new_other)
|
||||
{
|
||||
if (this->state == IKE_ESTABLISHED)
|
||||
{
|
||||
DBG1(DBG_IKE, "remote endpoint changed from %#H to %#H",
|
||||
this->other_host, new_other);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_IKE, "remote endpoint changed from %#H to %#H",
|
||||
this->other_host, new_other);
|
||||
}
|
||||
set_other_host(this, new_other->clone(new_other));
|
||||
}
|
||||
|
||||
|
@ -1204,29 +1248,6 @@ METHOD(ike_sa_t, update_hosts, void,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set configured DSCP value on packet
|
||||
*/
|
||||
static void set_dscp(private_ike_sa_t *this, packet_t *packet)
|
||||
{
|
||||
ike_cfg_t *ike_cfg;
|
||||
|
||||
/* prefer IKE config on peer_cfg, as its selection is more accurate
|
||||
* then the initial IKE config */
|
||||
if (this->peer_cfg)
|
||||
{
|
||||
ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg);
|
||||
}
|
||||
else
|
||||
{
|
||||
ike_cfg = this->ike_cfg;
|
||||
}
|
||||
if (ike_cfg)
|
||||
{
|
||||
packet->set_dscp(packet, ike_cfg->get_dscp(ike_cfg));
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(ike_sa_t, generate_message, status_t,
|
||||
private_ike_sa_t *this, message_t *message, packet_t **packet)
|
||||
{
|
||||
|
|
|
@ -1170,7 +1170,7 @@ struct ike_sa_t {
|
|||
void (*remove_task)(ike_sa_t *this, enumerator_t *enumerator);
|
||||
|
||||
/**
|
||||
* Flush a task queue, cancelling all tasks in it.
|
||||
* Flush a task queue, canceling all tasks in it.
|
||||
*
|
||||
* @param queue queue type to flush
|
||||
*/
|
||||
|
|
|
@ -142,7 +142,7 @@ struct ike_sa_manager_t {
|
|||
*
|
||||
* Measures are taken according to the uniqueness policy of the IKE_SA.
|
||||
* The return value indicates whether duplicates have been found and if
|
||||
* further measures should be taken (e.g. cancelling an IKE_AUTH exchange).
|
||||
* further measures should be taken (e.g. canceling an IKE_AUTH exchange).
|
||||
* check_uniqueness() must be called before the IKE_SA is complete,
|
||||
* deadlocks occur otherwise.
|
||||
*
|
||||
|
|
|
@ -484,7 +484,8 @@ METHOD(keymat_v1_t, derive_ike_keys, bool,
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
charon->bus->ike_derived_keys(charon->bus, ka, chunk_empty, this->skeyid_a,
|
||||
charon->bus->ike_derived_keys(charon->bus, this->skeyid_d, this->skeyid_a,
|
||||
chunk_empty, ka, chunk_empty, chunk_empty,
|
||||
chunk_empty);
|
||||
chunk_clear(&ka);
|
||||
if (!this->hasher && !this->public.create_hasher(&this->public, proposal))
|
||||
|
|
|
@ -487,7 +487,7 @@ METHOD(task_manager_t, initiate, status_t,
|
|||
message_t *message;
|
||||
host_t *me, *other;
|
||||
exchange_type_t exchange = EXCHANGE_TYPE_UNDEFINED;
|
||||
bool new_mid = FALSE, expect_response = FALSE, cancelled = FALSE, keep = FALSE;
|
||||
bool new_mid = FALSE, expect_response = FALSE, canceled = FALSE, keep = FALSE;
|
||||
|
||||
if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED &&
|
||||
this->initiating.type != INFORMATIONAL_V1)
|
||||
|
@ -672,7 +672,7 @@ METHOD(task_manager_t, initiate, status_t,
|
|||
/* processed, but task needs another exchange */
|
||||
continue;
|
||||
case ALREADY_DONE:
|
||||
cancelled = TRUE;
|
||||
canceled = TRUE;
|
||||
break;
|
||||
case FAILED:
|
||||
default:
|
||||
|
@ -697,7 +697,7 @@ METHOD(task_manager_t, initiate, status_t,
|
|||
{ /* tasks completed, no exchange active anymore */
|
||||
this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
|
||||
}
|
||||
if (cancelled)
|
||||
if (canceled)
|
||||
{
|
||||
message->destroy(message);
|
||||
return initiate(this);
|
||||
|
@ -754,7 +754,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
|
|||
task_t *task;
|
||||
message_t *message;
|
||||
host_t *me, *other;
|
||||
bool delete = FALSE, cancelled = FALSE, expect_request = FALSE;
|
||||
bool delete = FALSE, canceled = FALSE, expect_request = FALSE;
|
||||
|
||||
me = request->get_destination(request);
|
||||
other = request->get_source(request);
|
||||
|
@ -791,7 +791,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
|
|||
}
|
||||
continue;
|
||||
case ALREADY_DONE:
|
||||
cancelled = TRUE;
|
||||
canceled = TRUE;
|
||||
break;
|
||||
case INVALID_ARG:
|
||||
if (task->get_type(task) == TASK_QUICK_MODE)
|
||||
|
@ -813,7 +813,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
|
|||
enumerator->destroy(enumerator);
|
||||
|
||||
clear_packets(this->responding.packets);
|
||||
if (cancelled)
|
||||
if (canceled)
|
||||
{
|
||||
message->destroy(message);
|
||||
return initiate(this);
|
||||
|
|
|
@ -103,7 +103,7 @@ static bool establish(private_aggressive_mode_t *this)
|
|||
{
|
||||
if (!charon->bus->authorize(charon->bus, TRUE))
|
||||
{
|
||||
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
|
||||
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, canceling");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ static status_t send_notify(private_aggressive_mode_t *this, notify_type_t type)
|
|||
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)informational_create(this->ike_sa, notify));
|
||||
/* cancel all active/passive tasks in favour of informational */
|
||||
/* cancel all active/passive tasks in favor of informational */
|
||||
this->ike_sa->flush_queue(this->ike_sa,
|
||||
this->initiator ? TASK_QUEUE_ACTIVE : TASK_QUEUE_PASSIVE);
|
||||
return ALREADY_DONE;
|
||||
|
@ -190,7 +190,7 @@ static status_t send_delete(private_aggressive_mode_t *this)
|
|||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)isakmp_delete_create(this->ike_sa, TRUE));
|
||||
/* cancel all active tasks in favour of informational */
|
||||
/* cancel all active tasks in favor of informational */
|
||||
this->ike_sa->flush_queue(this->ike_sa,
|
||||
this->initiator ? TASK_QUEUE_ACTIVE : TASK_QUEUE_PASSIVE);
|
||||
return ALREADY_DONE;
|
||||
|
@ -320,7 +320,7 @@ METHOD(task_t, build_i, status_t,
|
|||
if (charon->ike_sa_manager->check_uniqueness(
|
||||
charon->ike_sa_manager, this->ike_sa, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "cancelling Aggressive Mode due to "
|
||||
DBG1(DBG_IKE, "canceling Aggressive Mode due to "
|
||||
"uniqueness policy");
|
||||
return send_notify(this, AUTHENTICATION_FAILED);
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ METHOD(task_t, process_r, status_t,
|
|||
if (!charon->bus->authorize(charon->bus, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "Aggressive Mode authorization hook forbids "
|
||||
"IKE_SA, cancelling");
|
||||
"IKE_SA, canceling");
|
||||
charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
|
||||
return send_delete(this);
|
||||
}
|
||||
|
@ -529,7 +529,7 @@ METHOD(task_t, process_r, status_t,
|
|||
if (charon->ike_sa_manager->check_uniqueness(
|
||||
charon->ike_sa_manager, this->ike_sa, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "cancelling Aggressive Mode due to "
|
||||
DBG1(DBG_IKE, "canceling Aggressive Mode due to "
|
||||
"uniqueness policy");
|
||||
return send_delete(this);
|
||||
}
|
||||
|
@ -709,7 +709,7 @@ METHOD(task_t, process_i, status_t,
|
|||
if (!charon->bus->authorize(charon->bus, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "Aggressive Mode authorization hook forbids IKE_SA, "
|
||||
"cancelling");
|
||||
"canceling");
|
||||
return send_notify(this, AUTHENTICATION_FAILED);
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,8 @@ static struct {
|
|||
ike_extension_t extension;
|
||||
/* send yourself? */
|
||||
bool send;
|
||||
/* stored id is just a prefix for a longer, more specific one */
|
||||
bool prefix;
|
||||
/* length of vendor ID string */
|
||||
int len;
|
||||
/* vendor ID string */
|
||||
|
@ -91,76 +93,139 @@ static struct {
|
|||
} vendor_ids[] = {
|
||||
|
||||
/* strongSwan MD5("strongSwan") */
|
||||
{ "strongSwan", EXT_STRONGSWAN, FALSE, 16,
|
||||
{ "strongSwan", EXT_STRONGSWAN, FALSE, FALSE, 16,
|
||||
"\x88\x2f\xe5\x6d\x6f\xd2\x0d\xbc\x22\x51\x61\x3b\x2e\xbe\x5b\xeb"},
|
||||
|
||||
/* XAuth, MD5("draft-ietf-ipsra-isakmp-xauth-06.txt") */
|
||||
{ "XAuth", EXT_XAUTH, TRUE, 8,
|
||||
{ "XAuth", EXT_XAUTH, TRUE, FALSE, 8,
|
||||
"\x09\x00\x26\x89\xdf\xd6\xb7\x12"},
|
||||
|
||||
/* Dead peer detection, RFC 3706 */
|
||||
{ "DPD", EXT_DPD, TRUE, 16,
|
||||
{ "DPD", EXT_DPD, TRUE, FALSE, 16,
|
||||
"\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00"},
|
||||
|
||||
/* CISCO-UNITY, similar to DPD the last two bytes indicate the version */
|
||||
{ "Cisco Unity", EXT_CISCO_UNITY, FALSE, 16,
|
||||
{ "Cisco Unity", EXT_CISCO_UNITY, FALSE, TRUE, 16,
|
||||
"\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00"},
|
||||
|
||||
/* Proprietary IKE fragmentation extension. Capabilities are handled
|
||||
* specially on receipt of this VID. Windows peers send this VID
|
||||
* without capabilities, but accept it with and without capabilities. */
|
||||
{ "FRAGMENTATION", EXT_IKE_FRAGMENTATION, FALSE, 20,
|
||||
{ "FRAGMENTATION", EXT_IKE_FRAGMENTATION, FALSE, FALSE, 20,
|
||||
"\x40\x48\xb7\xd5\x6e\xbc\xe8\x85\x25\xe7\xde\x7f\x00\xd6\xc2\xd3\x80\x00\x00\x00"},
|
||||
|
||||
/* Windows peers send this VID and a version number */
|
||||
{ "MS NT5 ISAKMPOAKLEY", EXT_MS_WINDOWS, FALSE, 20,
|
||||
{ "MS NT5 ISAKMPOAKLEY", EXT_MS_WINDOWS, FALSE, TRUE, 20,
|
||||
"\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x00"},
|
||||
|
||||
{ "Cisco VPN Concentrator", 0, FALSE, TRUE, 16,
|
||||
"\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a"},
|
||||
|
||||
{ "Cisco VPN 3000 client", 0, FALSE, FALSE, 20,
|
||||
"\xf6\xf7\xef\xc7\xf5\xae\xb8\xcb\x15\x8c\xb9\xd0\x94\xba\x69\xe7"},
|
||||
|
||||
{ "KAME/racoon", 0, FALSE, FALSE, 16,
|
||||
"\x70\x03\xcb\xc1\x09\x7d\xbe\x9c\x26\x00\xba\x69\x83\xbc\x8b\x35"},
|
||||
|
||||
{ "ZyXEL ZyWALL Router", 0, FALSE, FALSE, 20,
|
||||
"\xb8\x58\xd1\xad\xdd\x08\xc1\xe8\xad\xaf\xea\x15\x06\x08\xaa\x44\x97\xaa\x6c\xc8"},
|
||||
|
||||
{ "ZyXEL ZyWALL USG 100", 0, FALSE, FALSE, 14,
|
||||
"\xf7\x58\xf2\x26\x68\x75\x0f\x03\xb0\x8d\xf6\xeb\xe1\xd0"},
|
||||
|
||||
{ "ZyXEL ZyWALL", 0, FALSE, FALSE, 20,
|
||||
"\x62\x50\x27\x74\x9d\x5a\xb9\x7f\x56\x16\xc1\x60\x27\x65\xcf\x48\x0a\x3b\x7d\x0b"},
|
||||
|
||||
{ "Sonicwall 1", 0, FALSE, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf6\x00\x01"},
|
||||
|
||||
{ "Sonicwall 2", 0, FALSE, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf6\x00\x02"},
|
||||
|
||||
{ "Sonicwall 3", 0, FALSE, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf6\x00\x03"},
|
||||
|
||||
{ "Sonicwall 5", 0, FALSE, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf6\x00\x05"},
|
||||
|
||||
{ "Sonicwall 6", 0, FALSE, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf6\x00\x06"},
|
||||
|
||||
{ "Sonicwall 7", 0, FALSE, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf6\x00\x07"},
|
||||
|
||||
{ "Sonicwall 8", 0, FALSE, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf6\x00\x08"},
|
||||
|
||||
{ "Sonicwall a", 0, FALSE, TRUE, 8,
|
||||
"\x40\x4b\xf4\x39\x52\x2c\xa3\xf6"},
|
||||
|
||||
{ "Sonicwall b", 0, FALSE, TRUE, 8,
|
||||
"\xda\x8e\x93\x78\x80\x01\x00\x00"},
|
||||
|
||||
{ "Sonicwall c", 0, FALSE, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf7\x00\x01"},
|
||||
|
||||
{ "Fortigate", 0, FALSE, FALSE, 16,
|
||||
"\x1d\x6e\x17\x8f\x6c\x2c\x0b\xe2\x84\x98\x54\x65\x45\x0f\xe9\xd4"},
|
||||
|
||||
/* Checkpoint devices send a version blob after this VID */
|
||||
{ "Checkpoint Firewall", 0, FALSE, TRUE, 20,
|
||||
"\xf4\xed\x19\xe0\xc1\x14\xeb\x51\x6f\xaa\xac\x0e\xe3\x7d\xaf\x28\x07\xb4\x38\x1f"},
|
||||
|
||||
/* Juniper SRX and Netscreen devices send this VID and a version number */
|
||||
{ "NetScreen Technologies", 0, FALSE, TRUE, 20,
|
||||
"\x69\x93\x69\x22\x87\x41\xc6\xd4\xca\x09\x4c\x93\xe2\x42\xc9\xde\x19\xe7\xb7\xc6"},
|
||||
|
||||
/* Probably the Juniper SRX VID */
|
||||
{ "Juniper SRX", 0, FALSE, FALSE, 20,
|
||||
"\xfd\x80\x88\x04\xdf\x73\xb1\x51\x50\x70\x9d\x87\x80\x44\xcd\xe0\xac\x1e\xfc\xde"},
|
||||
|
||||
}, vendor_natt_ids[] = {
|
||||
|
||||
/* NAT-Traversal VIDs ordered by preference */
|
||||
|
||||
/* NAT-Traversal, MD5("RFC 3947") */
|
||||
{ "NAT-T (RFC 3947)", EXT_NATT, TRUE, 16,
|
||||
{ "NAT-T (RFC 3947)", EXT_NATT, TRUE, FALSE, 16,
|
||||
"\x4a\x13\x1c\x81\x07\x03\x58\x45\x5c\x57\x28\xf2\x0e\x95\x45\x2f"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike-03", EXT_NATT | EXT_NATT_DRAFT_02_03,
|
||||
FALSE, 16,
|
||||
FALSE, FALSE, 16,
|
||||
"\x7d\x94\x19\xa6\x53\x10\xca\x6f\x2c\x17\x9d\x92\x15\x52\x9d\x56"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike-02", EXT_NATT | EXT_NATT_DRAFT_02_03,
|
||||
FALSE, 16,
|
||||
FALSE, FALSE, 16,
|
||||
"\xcd\x60\x46\x43\x35\xdf\x21\xf8\x7c\xfd\xb2\xfc\x68\xb6\xa4\x48"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike-02\\n", EXT_NATT | EXT_NATT_DRAFT_02_03,
|
||||
TRUE, 16,
|
||||
TRUE, FALSE, 16,
|
||||
"\x90\xcb\x80\x91\x3e\xbb\x69\x6e\x08\x63\x81\xb5\xec\x42\x7b\x1f"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike-08", 0, FALSE, 16,
|
||||
{ "draft-ietf-ipsec-nat-t-ike-08", 0, FALSE, FALSE, 16,
|
||||
"\x8f\x8d\x83\x82\x6d\x24\x6b\x6f\xc7\xa8\xa6\xa4\x28\xc1\x1d\xe8"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike-07", 0, FALSE, 16,
|
||||
{ "draft-ietf-ipsec-nat-t-ike-07", 0, FALSE, FALSE, 16,
|
||||
"\x43\x9b\x59\xf8\xba\x67\x6c\x4c\x77\x37\xae\x22\xea\xb8\xf5\x82"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike-06", 0, FALSE, 16,
|
||||
{ "draft-ietf-ipsec-nat-t-ike-06", 0, FALSE, FALSE, 16,
|
||||
"\x4d\x1e\x0e\x13\x6d\xea\xfa\x34\xc4\xf3\xea\x9f\x02\xec\x72\x85"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike-05", 0, FALSE, 16,
|
||||
{ "draft-ietf-ipsec-nat-t-ike-05", 0, FALSE, FALSE, 16,
|
||||
"\x80\xd0\xbb\x3d\xef\x54\x56\x5e\xe8\x46\x45\xd4\xc8\x5c\xe3\xee"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike-04", 0, FALSE, 16,
|
||||
{ "draft-ietf-ipsec-nat-t-ike-04", 0, FALSE, FALSE, 16,
|
||||
"\x99\x09\xb6\x4e\xed\x93\x7c\x65\x73\xde\x52\xac\xe9\x52\xfa\x6b"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike-00", 0, FALSE, 16,
|
||||
{ "draft-ietf-ipsec-nat-t-ike-00", 0, FALSE, FALSE, 16,
|
||||
"\x44\x85\x15\x2d\x18\xb6\xbb\xcd\x0b\xe8\xa8\x46\x95\x79\xdd\xcc"},
|
||||
|
||||
{ "draft-ietf-ipsec-nat-t-ike", 0, FALSE, 16,
|
||||
{ "draft-ietf-ipsec-nat-t-ike", 0, FALSE, FALSE, 16,
|
||||
"\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62"},
|
||||
|
||||
{ "draft-stenberg-ipsec-nat-traversal-02", 0, FALSE, 16,
|
||||
{ "draft-stenberg-ipsec-nat-traversal-02", 0, FALSE, FALSE, 16,
|
||||
"\x61\x05\xc4\x22\xe7\x68\x47\xe4\x3f\x96\x84\x80\x12\x92\xae\xcd"},
|
||||
|
||||
{ "draft-stenberg-ipsec-nat-traversal-01", 0, FALSE, 16,
|
||||
{ "draft-stenberg-ipsec-nat-traversal-01", 0, FALSE, FALSE, 16,
|
||||
"\x27\xba\xb5\xdc\x01\xea\x07\x60\xea\x4e\x31\x90\xac\x27\xc0\xd0"},
|
||||
|
||||
};
|
||||
|
@ -175,29 +240,25 @@ static const uint32_t fragmentation_ike = 0x80000000;
|
|||
|
||||
static bool is_known_vid(chunk_t data, int i)
|
||||
{
|
||||
switch (vendor_ids[i].extension)
|
||||
if (vendor_ids[i].extension == EXT_IKE_FRAGMENTATION)
|
||||
{
|
||||
case EXT_IKE_FRAGMENTATION:
|
||||
if (data.len >= 16 && memeq(data.ptr, vendor_ids[i].id, 16))
|
||||
if (data.len >= 16 && memeq(data.ptr, vendor_ids[i].id, 16))
|
||||
{
|
||||
switch (data.len)
|
||||
{
|
||||
switch (data.len)
|
||||
{
|
||||
case 16:
|
||||
return TRUE;
|
||||
case 20:
|
||||
return untoh32(&data.ptr[16]) & fragmentation_ike;
|
||||
}
|
||||
case 16:
|
||||
return TRUE;
|
||||
case 20:
|
||||
return untoh32(&data.ptr[16]) & fragmentation_ike;
|
||||
}
|
||||
break;
|
||||
case EXT_MS_WINDOWS:
|
||||
return data.len == 20 && memeq(data.ptr, vendor_ids[i].id, 16);
|
||||
case EXT_CISCO_UNITY:
|
||||
return data.len == 16 && memeq(data.ptr, vendor_ids[i].id, 14);
|
||||
default:
|
||||
return chunk_equals(data, chunk_create(vendor_ids[i].id,
|
||||
vendor_ids[i].len));
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
if (vendor_ids[i].prefix)
|
||||
{
|
||||
data.len = min(data.len, vendor_ids[i].len);
|
||||
}
|
||||
return chunk_equals(data, chunk_create(vendor_ids[i].id,
|
||||
vendor_ids[i].len));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -100,7 +100,7 @@ static bool establish(private_main_mode_t *this)
|
|||
{
|
||||
if (!charon->bus->authorize(charon->bus, TRUE))
|
||||
{
|
||||
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
|
||||
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, canceling");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ static status_t send_notify(private_main_mode_t *this, notify_type_t type)
|
|||
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)informational_create(this->ike_sa, notify));
|
||||
/* cancel all active/passive tasks in favour of informational */
|
||||
/* cancel all active/passive tasks in favor of informational */
|
||||
this->ike_sa->flush_queue(this->ike_sa,
|
||||
this->initiator ? TASK_QUEUE_ACTIVE : TASK_QUEUE_PASSIVE);
|
||||
return ALREADY_DONE;
|
||||
|
@ -199,7 +199,7 @@ static status_t send_delete(private_main_mode_t *this)
|
|||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)isakmp_delete_create(this->ike_sa, TRUE));
|
||||
/* cancel all active tasks in favour of informational */
|
||||
/* cancel all active tasks in favor of informational */
|
||||
this->ike_sa->flush_queue(this->ike_sa,
|
||||
this->initiator ? TASK_QUEUE_ACTIVE : TASK_QUEUE_PASSIVE);
|
||||
return ALREADY_DONE;
|
||||
|
@ -483,7 +483,7 @@ METHOD(task_t, process_r, status_t,
|
|||
if (!charon->bus->authorize(charon->bus, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "Main Mode authorization hook forbids IKE_SA, "
|
||||
"cancelling");
|
||||
"canceling");
|
||||
charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
|
||||
return send_notify(this, AUTHENTICATION_FAILED);
|
||||
}
|
||||
|
@ -565,7 +565,7 @@ METHOD(task_t, build_r, status_t,
|
|||
if (charon->ike_sa_manager->check_uniqueness(
|
||||
charon->ike_sa_manager, this->ike_sa, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "cancelling Main Mode due to uniqueness "
|
||||
DBG1(DBG_IKE, "canceling Main Mode due to uniqueness "
|
||||
"policy");
|
||||
return send_notify(this, AUTHENTICATION_FAILED);
|
||||
}
|
||||
|
@ -725,7 +725,7 @@ METHOD(task_t, process_i, status_t,
|
|||
if (!charon->bus->authorize(charon->bus, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "Main Mode authorization hook forbids IKE_SA, "
|
||||
"cancelling");
|
||||
"canceling");
|
||||
charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
|
||||
return send_delete(this);
|
||||
}
|
||||
|
@ -748,7 +748,7 @@ METHOD(task_t, process_i, status_t,
|
|||
if (charon->ike_sa_manager->check_uniqueness(
|
||||
charon->ike_sa_manager, this->ike_sa, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "cancelling Main Mode due to uniqueness "
|
||||
DBG1(DBG_IKE, "canceling Main Mode due to uniqueness "
|
||||
"policy");
|
||||
return send_delete(this);
|
||||
}
|
||||
|
|
|
@ -773,7 +773,7 @@ static status_t send_notify(private_quick_mode_t *this, notify_type_t type)
|
|||
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)informational_create(this->ike_sa, notify));
|
||||
/* cancel all active/passive tasks in favour of informational */
|
||||
/* cancel all active/passive tasks in favor of informational */
|
||||
this->ike_sa->flush_queue(this->ike_sa,
|
||||
this->initiator ? TASK_QUEUE_ACTIVE : TASK_QUEUE_PASSIVE);
|
||||
return ALREADY_DONE;
|
||||
|
|
|
@ -150,17 +150,17 @@ static bool allowed(private_xauth_t *this)
|
|||
if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
|
||||
this->ike_sa, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "cancelling XAuth due to uniqueness policy");
|
||||
DBG1(DBG_IKE, "canceling XAuth due to uniqueness policy");
|
||||
return FALSE;
|
||||
}
|
||||
if (!charon->bus->authorize(charon->bus, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "XAuth authorization hook forbids IKE_SA, cancelling");
|
||||
DBG1(DBG_IKE, "XAuth authorization hook forbids IKE_SA, canceling");
|
||||
return FALSE;
|
||||
}
|
||||
if (!charon->bus->authorize(charon->bus, TRUE))
|
||||
{
|
||||
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
|
||||
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, canceling");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
|
|
@ -100,10 +100,10 @@ METHOD(keymat_t, create_nonce_gen, nonce_gen_t*,
|
|||
* Derive IKE keys for a combined AEAD algorithm
|
||||
*/
|
||||
static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg,
|
||||
uint16_t key_size, prf_plus_t *prf_plus)
|
||||
uint16_t key_size, prf_plus_t *prf_plus,
|
||||
chunk_t *sk_ei, chunk_t *sk_er)
|
||||
{
|
||||
aead_t *aead_i, *aead_r;
|
||||
chunk_t sk_ei = chunk_empty, sk_er = chunk_empty;
|
||||
u_int salt_size;
|
||||
|
||||
switch (alg)
|
||||
|
@ -146,22 +146,22 @@ static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg,
|
|||
{
|
||||
goto failure;
|
||||
}
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ei))
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_ei))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ei secret %B", &sk_ei);
|
||||
if (!aead_i->set_key(aead_i, sk_ei))
|
||||
DBG4(DBG_IKE, "Sk_ei secret %B", sk_ei);
|
||||
if (!aead_i->set_key(aead_i, *sk_ei))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_er))
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_er secret %B", &sk_er);
|
||||
if (!aead_r->set_key(aead_r, sk_er))
|
||||
DBG4(DBG_IKE, "Sk_er secret %B", sk_er);
|
||||
if (!aead_r->set_key(aead_r, *sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
@ -177,14 +177,10 @@ static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg,
|
|||
this->aead_out = aead_r;
|
||||
}
|
||||
aead_i = aead_r = NULL;
|
||||
charon->bus->ike_derived_keys(charon->bus, sk_ei, sk_er, chunk_empty,
|
||||
chunk_empty);
|
||||
|
||||
failure:
|
||||
DESTROY_IF(aead_i);
|
||||
DESTROY_IF(aead_r);
|
||||
chunk_clear(&sk_ei);
|
||||
chunk_clear(&sk_er);
|
||||
return this->aead_in && this->aead_out;
|
||||
}
|
||||
|
||||
|
@ -192,14 +188,14 @@ failure:
|
|||
* Derive IKE keys for traditional encryption and MAC algorithms
|
||||
*/
|
||||
static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg,
|
||||
uint16_t enc_size, uint16_t int_alg, prf_plus_t *prf_plus)
|
||||
uint16_t enc_size, uint16_t int_alg, prf_plus_t *prf_plus,
|
||||
chunk_t *sk_ai, chunk_t *sk_ar, chunk_t *sk_ei,
|
||||
chunk_t *sk_er)
|
||||
{
|
||||
crypter_t *crypter_i = NULL, *crypter_r = NULL;
|
||||
signer_t *signer_i, *signer_r;
|
||||
iv_gen_t *ivg_i, *ivg_r;
|
||||
size_t key_size;
|
||||
chunk_t sk_ei = chunk_empty, sk_er = chunk_empty,
|
||||
sk_ai = chunk_empty, sk_ar = chunk_empty;
|
||||
|
||||
signer_i = lib->crypto->create_signer(lib->crypto, int_alg);
|
||||
signer_r = lib->crypto->create_signer(lib->crypto, int_alg);
|
||||
|
@ -223,22 +219,22 @@ static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg,
|
|||
/* SK_ai/SK_ar used for integrity protection */
|
||||
key_size = signer_i->get_key_size(signer_i);
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ai))
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_ai))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ai secret %B", &sk_ai);
|
||||
if (!signer_i->set_key(signer_i, sk_ai))
|
||||
DBG4(DBG_IKE, "Sk_ai secret %B", sk_ai);
|
||||
if (!signer_i->set_key(signer_i, *sk_ai))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ar))
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_ar))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ar secret %B", &sk_ar);
|
||||
if (!signer_r->set_key(signer_r, sk_ar))
|
||||
DBG4(DBG_IKE, "Sk_ar secret %B", sk_ar);
|
||||
if (!signer_r->set_key(signer_r, *sk_ar))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
@ -246,22 +242,22 @@ static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg,
|
|||
/* SK_ei/SK_er used for encryption */
|
||||
key_size = crypter_i->get_key_size(crypter_i);
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ei))
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_ei))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_ei secret %B", &sk_ei);
|
||||
if (!crypter_i->set_key(crypter_i, sk_ei))
|
||||
DBG4(DBG_IKE, "Sk_ei secret %B", sk_ei);
|
||||
if (!crypter_i->set_key(crypter_i, *sk_ei))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_er))
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_er secret %B", &sk_er);
|
||||
if (!crypter_r->set_key(crypter_r, sk_er))
|
||||
DBG4(DBG_IKE, "Sk_er secret %B", sk_er);
|
||||
if (!crypter_r->set_key(crypter_r, *sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
@ -284,13 +280,8 @@ static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg,
|
|||
}
|
||||
signer_i = signer_r = NULL;
|
||||
crypter_i = crypter_r = NULL;
|
||||
charon->bus->ike_derived_keys(charon->bus, sk_ei, sk_er, sk_ai, sk_ar);
|
||||
|
||||
failure:
|
||||
chunk_clear(&sk_ai);
|
||||
chunk_clear(&sk_ar);
|
||||
chunk_clear(&sk_ei);
|
||||
chunk_clear(&sk_er);
|
||||
DESTROY_IF(signer_i);
|
||||
DESTROY_IF(signer_r);
|
||||
DESTROY_IF(crypter_i);
|
||||
|
@ -303,8 +294,10 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||
chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
|
||||
pseudo_random_function_t rekey_function, chunk_t rekey_skd)
|
||||
{
|
||||
chunk_t skeyseed = chunk_empty, key, secret, full_nonce, fixed_nonce;
|
||||
chunk_t skeyseed = chunk_empty, secret, full_nonce, fixed_nonce;
|
||||
chunk_t prf_plus_seed, spi_i, spi_r;
|
||||
chunk_t sk_ei = chunk_empty, sk_er = chunk_empty;
|
||||
chunk_t sk_ai = chunk_empty, sk_ar = chunk_empty, sk_pi, sk_pr;
|
||||
prf_plus_t *prf_plus = NULL;
|
||||
uint16_t alg, key_size, int_alg;
|
||||
prf_t *rekey_prf = NULL;
|
||||
|
@ -434,7 +427,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||
|
||||
if (encryption_algorithm_is_aead(alg))
|
||||
{
|
||||
if (!derive_ike_aead(this, alg, key_size, prf_plus))
|
||||
if (!derive_ike_aead(this, alg, key_size, prf_plus, &sk_ei, &sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
@ -448,7 +441,8 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||
transform_type_names, INTEGRITY_ALGORITHM);
|
||||
goto failure;
|
||||
}
|
||||
if (!derive_ike_traditional(this, alg, key_size, int_alg, prf_plus))
|
||||
if (!derive_ike_traditional(this, alg, key_size, int_alg, prf_plus,
|
||||
&sk_ai, &sk_ar, &sk_ei, &sk_er))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
@ -456,35 +450,40 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
|
|||
|
||||
/* SK_pi/SK_pr used for authentication => stored for later */
|
||||
key_size = this->prf->get_key_size(this->prf);
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &key))
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_pi))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_pi secret %B", &key);
|
||||
DBG4(DBG_IKE, "Sk_pi secret %B", &sk_pi);
|
||||
if (this->initiator)
|
||||
{
|
||||
this->skp_build = key;
|
||||
this->skp_build = sk_pi;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->skp_verify = key;
|
||||
this->skp_verify = sk_pi;
|
||||
}
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &key))
|
||||
if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_pr))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
DBG4(DBG_IKE, "Sk_pr secret %B", &key);
|
||||
DBG4(DBG_IKE, "Sk_pr secret %B", &sk_pr);
|
||||
if (this->initiator)
|
||||
{
|
||||
this->skp_verify = key;
|
||||
this->skp_verify = sk_pr;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->skp_build = key;
|
||||
this->skp_build = sk_pr;
|
||||
}
|
||||
charon->bus->ike_derived_keys(charon->bus,this->skd, sk_ai, sk_ar, sk_ei,
|
||||
sk_er, sk_pi, sk_pr);
|
||||
|
||||
/* all done, prf_plus not needed anymore */
|
||||
failure:
|
||||
chunk_clear(&sk_ai);
|
||||
chunk_clear(&sk_ar);
|
||||
chunk_clear(&sk_ei);
|
||||
chunk_clear(&sk_er);
|
||||
DESTROY_IF(prf_plus);
|
||||
DESTROY_IF(rekey_prf);
|
||||
|
||||
|
|
|
@ -887,7 +887,7 @@ METHOD(task_t, process_r, status_t,
|
|||
/* another auth round done, invoke authorize hook */
|
||||
if (!charon->bus->authorize(charon->bus, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "authorization hook forbids IKE_SA, cancelling");
|
||||
DBG1(DBG_IKE, "authorization hook forbids IKE_SA, canceling");
|
||||
this->authentication_failed = TRUE;
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
@ -1104,7 +1104,7 @@ METHOD(task_t, build_r, status_t,
|
|||
if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
|
||||
this->ike_sa, this->initial_contact))
|
||||
{
|
||||
DBG1(DBG_IKE, "cancelling IKE_SA setup due to uniqueness policy");
|
||||
DBG1(DBG_IKE, "canceling IKE_SA setup due to uniqueness policy");
|
||||
charon->bus->alert(charon->bus, ALERT_UNIQUE_KEEP);
|
||||
message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
|
||||
chunk_empty);
|
||||
|
@ -1112,7 +1112,7 @@ METHOD(task_t, build_r, status_t,
|
|||
}
|
||||
if (!charon->bus->authorize(charon->bus, TRUE))
|
||||
{
|
||||
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
|
||||
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, canceling");
|
||||
goto peer_auth_failed;
|
||||
}
|
||||
if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_REDIRECTION) &&
|
||||
|
@ -1362,7 +1362,7 @@ METHOD(task_t, process_i, status_t,
|
|||
/* another auth round done, invoke authorize hook */
|
||||
if (!charon->bus->authorize(charon->bus, FALSE))
|
||||
{
|
||||
DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling");
|
||||
DBG1(DBG_IKE, "authorization forbids IKE_SA, canceling");
|
||||
goto peer_auth_failed;
|
||||
}
|
||||
|
||||
|
@ -1453,7 +1453,7 @@ METHOD(task_t, process_i, status_t,
|
|||
if (!charon->bus->authorize(charon->bus, TRUE))
|
||||
{
|
||||
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, "
|
||||
"cancelling");
|
||||
"canceling");
|
||||
goto peer_auth_failed;
|
||||
}
|
||||
DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
|
||||
|
|
|
@ -443,8 +443,6 @@ METHOD(task_t, process_r, status_t,
|
|||
other_old = this->ike_sa->get_other_host(this->ike_sa);
|
||||
if (!other->equals(other, other_old))
|
||||
{
|
||||
DBG1(DBG_IKE, "remote address changed from %H to %H", other_old,
|
||||
other);
|
||||
other_new = other;
|
||||
/* our address might have changed too if the responder used
|
||||
* a different address from our list to reach us */
|
||||
|
@ -501,6 +499,8 @@ METHOD(task_t, process_i, status_t,
|
|||
}
|
||||
else if (message->get_exchange_type(message) == INFORMATIONAL)
|
||||
{
|
||||
bool force = FALSE;
|
||||
|
||||
if (is_newer_update_queued(this))
|
||||
{
|
||||
return SUCCESS;
|
||||
|
@ -535,6 +535,7 @@ METHOD(task_t, process_i, status_t,
|
|||
}
|
||||
else if (this->natd->has_mapping_changed(this->natd))
|
||||
{ /* force a check/update if mappings have changed during a DPD */
|
||||
force = TRUE;
|
||||
this->check = TRUE;
|
||||
DBG1(DBG_IKE, "detected changes in NAT mappings, "
|
||||
"initiating MOBIKE update");
|
||||
|
@ -555,7 +556,7 @@ METHOD(task_t, process_i, status_t,
|
|||
{
|
||||
other_new = other;
|
||||
}
|
||||
if (me_new || other_new)
|
||||
if (me_new || other_new || force)
|
||||
{
|
||||
this->ike_sa->update_hosts(this->ike_sa, me_new, other_new,
|
||||
UPDATE_HOSTS_FORCE_ALL);
|
||||
|
|
|
@ -74,6 +74,8 @@ typedef struct {
|
|||
ike_extension_t extension;
|
||||
/* Value from strongswan.conf, whether to send vendor ID */
|
||||
char *setting;
|
||||
/* Prefix matching only */
|
||||
bool prefix;
|
||||
/* length of vendor ID string, 0 for NULL terminated */
|
||||
int len;
|
||||
/* vendor ID string */
|
||||
|
@ -83,7 +85,7 @@ typedef struct {
|
|||
/**
|
||||
* Get the data of a vendor ID as a chunk
|
||||
*/
|
||||
static chunk_t get_vid_data(vid_data_t *data)
|
||||
static inline chunk_t get_vid_data(vid_data_t *data)
|
||||
{
|
||||
return chunk_create(data->id, data->len ?: strlen(data->id));
|
||||
}
|
||||
|
@ -93,26 +95,54 @@ static chunk_t get_vid_data(vid_data_t *data)
|
|||
*/
|
||||
static vid_data_t vids[] = {
|
||||
/* strongSwan MD5("strongSwan") */
|
||||
{ "strongSwan", EXT_STRONGSWAN, "send_vendor_id", 16,
|
||||
{ "strongSwan", EXT_STRONGSWAN, "send_vendor_id", FALSE, 16,
|
||||
"\x88\x2f\xe5\x6d\x6f\xd2\x0d\xbc\x22\x51\x61\x3b\x2e\xbe\x5b\xeb"},
|
||||
{ "Cisco Delete Reason", 0, NULL, 0,
|
||||
{ "Cisco Delete Reason", 0, NULL, FALSE, 0,
|
||||
"CISCO-DELETE-REASON" },
|
||||
{ "Cisco FlexVPN Supported", 0, "cisco_flexvpn", 0,
|
||||
{ "Cisco FlexVPN Supported", 0, "cisco_flexvpn", FALSE, 0,
|
||||
"FLEXVPN-SUPPORTED" },
|
||||
{ "Cisco Copyright (c) 2009", 0, NULL, 0,
|
||||
{ "Cisco Copyright (c) 2009", 0, NULL, FALSE, 0,
|
||||
"CISCO(COPYRIGHT)&Copyright (c) 2009 Cisco Systems, Inc." },
|
||||
{ "FRAGMENTATION", 0, NULL, 16,
|
||||
{ "FRAGMENTATION", 0, NULL, FALSE, 16,
|
||||
"\x40\x48\xb7\xd5\x6e\xbc\xe8\x85\x25\xe7\xde\x7f\x00\xd6\xc2\xd3"},
|
||||
{ "MS NT5 ISAKMPOAKLEY v7", 0, NULL, 20,
|
||||
{ "MS NT5 ISAKMPOAKLEY v7", 0, NULL, FALSE, 20,
|
||||
"\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x07"},
|
||||
{ "MS NT5 ISAKMPOAKLEY v8", 0, NULL, 20,
|
||||
{ "MS NT5 ISAKMPOAKLEY v8", 0, NULL, FALSE, 20,
|
||||
"\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x08"},
|
||||
{ "MS NT5 ISAKMPOAKLEY v9", 0, NULL, 20,
|
||||
{ "MS NT5 ISAKMPOAKLEY v9", 0, NULL, FALSE, 20,
|
||||
"\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x09"},
|
||||
{ "MS-Negotiation Discovery Capable", 0, NULL, 16,
|
||||
{ "MS-Negotiation Discovery Capable", 0, NULL, FALSE, 16,
|
||||
"\xfb\x1d\xe3\xcd\xf3\x41\xb7\xea\x16\xb7\xe5\xbe\x08\x55\xf1\x20"},
|
||||
{ "Vid-Initial-Contact", 0, NULL, 16,
|
||||
{ "Vid-Initial-Contact", 0, NULL, FALSE, 16,
|
||||
"\x26\x24\x4d\x38\xed\xdb\x61\xb3\x17\x2a\x36\xe3\xd0\xcf\xb8\x19"},
|
||||
{ "Cisco VPN Concentrator", 0, NULL, TRUE, 16,
|
||||
"\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a"},
|
||||
{ "Cisco VPN 3000 client", 0, NULL, FALSE, 20,
|
||||
"\xf6\xf7\xef\xc7\xf5\xae\xb8\xcb\x15\x8c\xb9\xd0\x94\xba\x69\xe7"},
|
||||
{ "ZyXEL ZyWALL Router", 0, NULL, FALSE, 20,
|
||||
"\xb8\x58\xd1\xad\xdd\x08\xc1\xe8\xad\xaf\xea\x15\x06\x08\xaa\x44\x97\xaa\x6c\xc8"},
|
||||
{ "ZyXEL ZyWALL USG 100", 0, NULL, FALSE, 14,
|
||||
"\xf7\x58\xf2\x26\x68\x75\x0f\x03\xb0\x8d\xf6\xeb\xe1\xd0"},
|
||||
{ "ZyXEL ZyWALL", 0, NULL, FALSE, 20,
|
||||
"\x62\x50\x27\x74\x9d\x5a\xb9\x7f\x56\x16\xc1\x60\x27\x65\xcf\x48\x0a\x3b\x7d\x0b"},
|
||||
{ "Sonicwall 7", 0, NULL, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf6\x00\x07"},
|
||||
{ "Sonicwall 8", 0, NULL, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf6\x00\x08"},
|
||||
{ "Sonicwall a", 0, NULL, TRUE, 8,
|
||||
"\x40\x4b\xf4\x39\x52\x2c\xa3\xf6"},
|
||||
{ "Sonicwall b", 0, NULL, TRUE, 8,
|
||||
"\xda\x8e\x93\x78\x80\x01\x00\x00"},
|
||||
{ "Sonicwall c", 0, NULL, TRUE, 8,
|
||||
"\x5b\x36\x2b\xc8\x20\xf7\x00\x01"},
|
||||
{ "Fortigate", 0, NULL, FALSE, 16,
|
||||
"\x1d\x6e\x17\x8f\x6c\x2c\x0b\xe2\x84\x98\x54\x65\x45\x0f\xe9\xd4"},
|
||||
{ "Checkpoint Firewall", 0, NULL, TRUE, 20,
|
||||
"\xf4\xed\x19\xe0\xc1\x14\xeb\x51\x6f\xaa\xac\x0e\xe3\x7d\xaf\x28\x07\xb4\x38\x1f"},
|
||||
{ "NetScreen Technologies", 0, NULL, TRUE, 20,
|
||||
"\x69\x93\x69\x22\x87\x41\xc6\xd4\xca\x09\x4c\x93\xe2\x42\xc9\xde\x19\xe7\xb7\xc6"},
|
||||
{ "Juniper SRX", 0, NULL, FALSE, 20,
|
||||
"\xfd\x80\x88\x04\xdf\x73\xb1\x51\x50\x70\x9d\x87\x80\x44\xcd\xe0\xac\x1e\xfc\xde"},
|
||||
};
|
||||
|
||||
METHOD(task_t, build, status_t,
|
||||
|
@ -143,6 +173,20 @@ METHOD(task_t, build, status_t,
|
|||
return this->initiator ? NEED_MORE : SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given known vendor ID matches a received VID or its prefix
|
||||
*/
|
||||
static inline bool known_vid(vid_data_t *vid, chunk_t data)
|
||||
{
|
||||
chunk_t known = get_vid_data(vid);
|
||||
|
||||
if (vid->prefix)
|
||||
{
|
||||
data.len = min(data.len, known.len);
|
||||
}
|
||||
return chunk_equals(known, data);
|
||||
}
|
||||
|
||||
METHOD(task_t, process, status_t,
|
||||
private_ike_vendor_t *this, message_t *message)
|
||||
{
|
||||
|
@ -164,7 +208,7 @@ METHOD(task_t, process, status_t,
|
|||
|
||||
for (i = 0; i < countof(vids); i++)
|
||||
{
|
||||
if (chunk_equals(get_vid_data(&vids[i]), data))
|
||||
if (known_vid(&vids[i], data))
|
||||
{
|
||||
DBG1(DBG_IKE, "received %s vendor ID", vids[i].desc);
|
||||
if (vids[i].extension)
|
||||
|
|
|
@ -293,7 +293,7 @@ struct task_manager_t {
|
|||
void (*flush)(task_manager_t *this);
|
||||
|
||||
/**
|
||||
* Flush a queue, cancelling all tasks.
|
||||
* Flush a queue, canceling all tasks.
|
||||
*
|
||||
* @param queue queue to flush
|
||||
*/
|
||||
|
|
|
@ -1731,7 +1731,7 @@ INSERT INTO policies ( /* 10 */
|
|||
INSERT INTO policies ( /* 11 */
|
||||
type, name, dir, rec_fail, rec_noresult
|
||||
) VALUES (
|
||||
8, 'Get /bin', 1, 0, 0
|
||||
8, 'Get /usr/sbin', 12, 0, 0
|
||||
);
|
||||
|
||||
INSERT INTO policies ( /* 12 */
|
||||
|
@ -1761,7 +1761,7 @@ INSERT INTO policies ( /* 15 */
|
|||
INSERT INTO policies ( /* 16 */
|
||||
type, name, dir, rec_fail, rec_noresult
|
||||
) VALUES (
|
||||
9, 'Measure /bin', 1, 2, 2
|
||||
9, 'Measure /usr/sbin', 12, 2, 2
|
||||
);
|
||||
|
||||
INSERT INTO policies ( /* 17 */
|
||||
|
|
|
@ -121,13 +121,18 @@ METHOD(simaka_manager_t, card_get_quintuplet, status_t,
|
|||
switch (status)
|
||||
{ /* try next on error, but not on INVALID_STATE */
|
||||
case SUCCESS:
|
||||
DBG1(DBG_LIB, "SUCCESS");
|
||||
case INVALID_STATE:
|
||||
DBG1(DBG_LIB, "INVALID STATE");
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
return status;
|
||||
case NOT_SUPPORTED:
|
||||
DBG1(DBG_LIB, "NOT_SUPPORTED");
|
||||
case FAILED:
|
||||
DBG1(DBG_LIB, "FAILED");
|
||||
default:
|
||||
DBG1(DBG_LIB, "DEFAULT");
|
||||
tried++;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -944,6 +944,7 @@ METHOD(auth_cfg_t, complies, bool,
|
|||
|
||||
id1 = (identification_t*)value;
|
||||
id2 = get(this, t1);
|
||||
/*
|
||||
if (!id2 || !id2->matches(id2, id1))
|
||||
{
|
||||
if (t1 == AUTH_RULE_IDENTITY &&
|
||||
|
@ -965,6 +966,10 @@ METHOD(auth_cfg_t, complies, bool,
|
|||
"EAP ", id1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
DBG1(DBG_CFG, "constraint check failed, but we are ignoring it for now: %sidentity '%Y'"
|
||||
" required ", t1 == AUTH_RULE_IDENTITY ? "" :
|
||||
"EAP ", id1);
|
||||
break;
|
||||
}
|
||||
case AUTH_RULE_AUTH_CLASS:
|
||||
|
|
|
@ -67,19 +67,22 @@ struct entry_t {
|
|||
int subtype;
|
||||
/** registered with final flag? */
|
||||
bool final;
|
||||
/** plugin that registered this algorithm */
|
||||
const char *plugin_name;
|
||||
/** builder function */
|
||||
builder_function_t constructor;
|
||||
};
|
||||
|
||||
METHOD(credential_factory_t, add_builder, void,
|
||||
private_credential_factory_t *this, credential_type_t type, int subtype,
|
||||
bool final, builder_function_t constructor)
|
||||
bool final, const char *plugin_name, builder_function_t constructor)
|
||||
{
|
||||
entry_t *entry = malloc_thing(entry_t);
|
||||
|
||||
entry->type = type;
|
||||
entry->subtype = subtype;
|
||||
entry->final = final;
|
||||
entry->plugin_name = plugin_name;
|
||||
entry->constructor = constructor;
|
||||
this->lock->write_lock(this->lock);
|
||||
this->constructors->insert_last(this->constructors, entry);
|
||||
|
@ -115,6 +118,22 @@ METHOD(credential_factory_t, create, void*,
|
|||
void *construct = NULL;
|
||||
int failures = 0;
|
||||
uintptr_t level;
|
||||
enum_name_t *names;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CRED_CERTIFICATE:
|
||||
names = certificate_type_names;
|
||||
break;
|
||||
case CRED_CONTAINER:
|
||||
names = container_type_names;
|
||||
break;
|
||||
case CRED_PRIVATE_KEY:
|
||||
case CRED_PUBLIC_KEY:
|
||||
default:
|
||||
names = key_type_names;
|
||||
break;
|
||||
}
|
||||
|
||||
level = (uintptr_t)this->recursive->get(this->recursive);
|
||||
this->recursive->set(this->recursive, (void*)level + 1);
|
||||
|
@ -125,6 +144,9 @@ METHOD(credential_factory_t, create, void*,
|
|||
{
|
||||
if (entry->type == type && entry->subtype == subtype)
|
||||
{
|
||||
DBG2(DBG_LIB, "builder L%d %N - %N of plugin '%s'",
|
||||
(int)level, credential_type_names, type, names, subtype,
|
||||
entry->plugin_name);
|
||||
va_start(args, subtype);
|
||||
construct = entry->constructor(subtype, args);
|
||||
va_end(args);
|
||||
|
@ -140,22 +162,6 @@ METHOD(credential_factory_t, create, void*,
|
|||
|
||||
if (!construct && !level)
|
||||
{
|
||||
enum_name_t *names;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CRED_CERTIFICATE:
|
||||
names = certificate_type_names;
|
||||
break;
|
||||
case CRED_CONTAINER:
|
||||
names = container_type_names;
|
||||
break;
|
||||
case CRED_PRIVATE_KEY:
|
||||
case CRED_PUBLIC_KEY:
|
||||
default:
|
||||
names = key_type_names;
|
||||
break;
|
||||
}
|
||||
DBG1(DBG_LIB, "building %N - %N failed, tried %d builders",
|
||||
credential_type_names, type, names, subtype, failures);
|
||||
}
|
||||
|
|
|
@ -80,11 +80,12 @@ struct credential_factory_t {
|
|||
* @param type type of credential the builder creates
|
||||
* @param subtype subtype of the credential, type specific
|
||||
* @param final TRUE if this build does not invoke other builders
|
||||
* @param plugin_name plugin that registered this builder
|
||||
* @param constructor builder constructor function to register
|
||||
*/
|
||||
void (*add_builder)(credential_factory_t *this,
|
||||
credential_type_t type, int subtype, bool final,
|
||||
builder_function_t constructor);
|
||||
const char *plugin_name, builder_function_t constructor);
|
||||
/**
|
||||
* Unregister a credential builder function.
|
||||
*
|
||||
|
|
|
@ -343,16 +343,16 @@ bool hasher_algorithm_for_ikev2(hash_algorithm_t alg)
|
|||
{
|
||||
switch (alg)
|
||||
{
|
||||
case HASH_IDENTITY:
|
||||
case HASH_SHA1:
|
||||
case HASH_SHA256:
|
||||
case HASH_SHA384:
|
||||
case HASH_SHA512:
|
||||
return TRUE;
|
||||
case HASH_IDENTITY:
|
||||
case HASH_UNKNOWN:
|
||||
case HASH_MD2:
|
||||
case HASH_MD4:
|
||||
case HASH_MD5:
|
||||
case HASH_SHA1:
|
||||
case HASH_SHA224:
|
||||
case HASH_SHA3_224:
|
||||
case HASH_SHA3_256:
|
||||
|
|
|
@ -117,7 +117,7 @@ struct fetcher_t {
|
|||
*
|
||||
* The fetcher returns NOT_SUPPORTED to indicate that it is uncappable
|
||||
* to handle such URLs. Other return values indicate a failure, and
|
||||
* fetching of that URL gets cancelled.
|
||||
* fetching of that URL gets canceled.
|
||||
* If no FETCH_CALLBACK function is set as option, userdata must be
|
||||
* a chunk_t*. This chunk gets allocated, accumulated data using the
|
||||
* fetcher_default_callback() function.
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup botan_ec_public_key botan_ec_public_key
|
||||
* @{ @ingroup botan_p
|
||||
*/
|
||||
|
||||
#ifndef BOTAN_EC_PUBLIC_KEY_H_
|
||||
#define BOTAN_EC_PUBLIC_KEY_H_
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup botan_ed_public_key botan_ed_public_key
|
||||
* @{ @ingroup botan_p
|
||||
*/
|
||||
|
||||
#ifndef BOTAN_ED_PUBLIC_KEY_H_
|
||||
#define BOTAN_ED_PUBLIC_KEY_H_
|
||||
|
||||
|
|
|
@ -417,6 +417,7 @@ ccm_aead_t *ccm_aead_create(encryption_algorithm_t algo,
|
|||
|
||||
if (!this->crypter)
|
||||
{
|
||||
this->iv_gen->destroy(this->iv_gen);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ static job_requeue_t monitor_changes(private_keychain_creds_t *this)
|
|||
{
|
||||
this->loop = CFRunLoopGetCurrent();
|
||||
|
||||
/* does not return until cancelled */
|
||||
/* does not return until canceled */
|
||||
CFRunLoopRun();
|
||||
|
||||
this->loop = NULL;
|
||||
|
|
|
@ -29,10 +29,17 @@
|
|||
#define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG
|
||||
#endif
|
||||
|
||||
/* not defined for older versions of BoringSSL */
|
||||
#ifndef EVP_CIPH_CCM_MODE
|
||||
#define EVP_CIPH_CCM_MODE 0xffff
|
||||
#endif
|
||||
|
||||
/** as defined in RFC 4106 */
|
||||
#define IV_LEN 8
|
||||
#define SALT_LEN 4
|
||||
#define NONCE_LEN (IV_LEN + SALT_LEN)
|
||||
#define IV_LEN 8
|
||||
#define SALT_LEN 4
|
||||
#define NONCE_LEN (IV_LEN + SALT_LEN)
|
||||
/** as defined in RFC 4309 */
|
||||
#define CCM_SALT_LEN 3
|
||||
|
||||
typedef struct private_aead_t private_aead_t;
|
||||
|
||||
|
@ -56,6 +63,11 @@ struct private_aead_t {
|
|||
*/
|
||||
char salt[SALT_LEN];
|
||||
|
||||
/**
|
||||
* Size of the salt
|
||||
*/
|
||||
size_t salt_size;
|
||||
|
||||
/**
|
||||
* Size of the integrity check value
|
||||
*/
|
||||
|
@ -83,27 +95,39 @@ static bool crypt(private_aead_t *this, chunk_t data, chunk_t assoc, chunk_t iv,
|
|||
bool success = FALSE;
|
||||
int len;
|
||||
|
||||
memcpy(nonce, this->salt, SALT_LEN);
|
||||
memcpy(nonce + SALT_LEN, iv.ptr, IV_LEN);
|
||||
memcpy(nonce, this->salt, this->salt_size);
|
||||
memcpy(nonce + this->salt_size, iv.ptr, IV_LEN);
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
||||
if (!EVP_CipherInit_ex(ctx, this->cipher, NULL, NULL, NULL, enc) ||
|
||||
!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, NONCE_LEN, NULL) ||
|
||||
!EVP_CipherInit_ex(ctx, NULL, NULL, this->key.ptr, nonce, enc))
|
||||
!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
|
||||
this->salt_size + IV_LEN, NULL))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
if (!enc && !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, this->icv_size,
|
||||
data.ptr + data.len))
|
||||
{ /* set ICV for verification on decryption */
|
||||
if ((!enc || EVP_CIPHER_mode(this->cipher) == EVP_CIPH_CCM_MODE) &&
|
||||
!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, this->icv_size,
|
||||
enc ? NULL : data.ptr + data.len))
|
||||
{ /* set ICV for verification on decryption, CCM requires the ICV length
|
||||
* when encrypting */
|
||||
goto done;
|
||||
}
|
||||
if (!EVP_CipherInit_ex(ctx, NULL, NULL, this->key.ptr, nonce, enc))
|
||||
{ /* set key and nonce */
|
||||
goto done;
|
||||
}
|
||||
if (EVP_CIPHER_mode(this->cipher) == EVP_CIPH_CCM_MODE &&
|
||||
!EVP_CipherUpdate(ctx, NULL, &len, NULL, data.len))
|
||||
{ /* CCM requires setting the total input length (plain or cipher+ICV) */
|
||||
goto done;
|
||||
}
|
||||
if (assoc.len && !EVP_CipherUpdate(ctx, NULL, &len, assoc.ptr, assoc.len))
|
||||
{ /* set AAD if specified */
|
||||
goto done;
|
||||
}
|
||||
if (!EVP_CipherUpdate(ctx, out, &len, data.ptr, data.len) ||
|
||||
/* CCM doesn't like NULL pointers as input, make sure we don't pass one */
|
||||
if (!EVP_CipherUpdate(ctx, out, &len, data.ptr ?: out, data.len) ||
|
||||
!EVP_CipherFinal_ex(ctx, out + len, &len))
|
||||
{ /* EVP_CipherFinal_ex fails if ICV is incorrect on decryption */
|
||||
goto done;
|
||||
|
@ -183,7 +207,7 @@ METHOD(aead_t, get_iv_gen, iv_gen_t*,
|
|||
METHOD(aead_t, get_key_size, size_t,
|
||||
private_aead_t *this)
|
||||
{
|
||||
return this->key.len + SALT_LEN;
|
||||
return this->key.len + this->salt_size;
|
||||
}
|
||||
|
||||
METHOD(aead_t, set_key, bool,
|
||||
|
@ -193,7 +217,7 @@ METHOD(aead_t, set_key, bool,
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(this->salt, key.ptr + key.len - SALT_LEN, SALT_LEN);
|
||||
memcpy(this->salt, key.ptr + key.len - this->salt_size, this->salt_size);
|
||||
memcpy(this->key.ptr, key.ptr, this->key.len);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -226,17 +250,21 @@ aead_t *openssl_aead_create(encryption_algorithm_t algo,
|
|||
.set_key = _set_key,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.salt_size = SALT_LEN,
|
||||
);
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case ENCR_AES_GCM_ICV8:
|
||||
case ENCR_AES_CCM_ICV8:
|
||||
this->icv_size = 8;
|
||||
break;
|
||||
case ENCR_AES_GCM_ICV12:
|
||||
case ENCR_AES_CCM_ICV12:
|
||||
this->icv_size = 12;
|
||||
break;
|
||||
case ENCR_AES_GCM_ICV16:
|
||||
case ENCR_AES_CCM_ICV16:
|
||||
this->icv_size = 16;
|
||||
break;
|
||||
case ENCR_CHACHA20_POLY1305:
|
||||
|
@ -247,13 +275,6 @@ aead_t *openssl_aead_create(encryption_algorithm_t algo,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (salt_size && salt_size != SALT_LEN)
|
||||
{
|
||||
/* currently not supported */
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case ENCR_AES_GCM_ICV8:
|
||||
|
@ -278,6 +299,31 @@ aead_t *openssl_aead_create(encryption_algorithm_t algo,
|
|||
return NULL;
|
||||
}
|
||||
break;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
|
||||
case ENCR_AES_CCM_ICV8:
|
||||
case ENCR_AES_CCM_ICV12:
|
||||
case ENCR_AES_CCM_ICV16:
|
||||
switch (key_size)
|
||||
{
|
||||
case 0:
|
||||
key_size = 16;
|
||||
/* FALL */
|
||||
case 16:
|
||||
this->cipher = EVP_aes_128_ccm();
|
||||
break;
|
||||
case 24:
|
||||
this->cipher = EVP_aes_192_ccm();
|
||||
break;
|
||||
case 32:
|
||||
this->cipher = EVP_aes_256_ccm();
|
||||
break;
|
||||
default:
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->salt_size = CCM_SALT_LEN;
|
||||
break;
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL && !defined(OPENSSL_NO_CHACHA)
|
||||
case ENCR_CHACHA20_POLY1305:
|
||||
switch (key_size)
|
||||
|
@ -299,6 +345,13 @@ aead_t *openssl_aead_create(encryption_algorithm_t algo,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (salt_size && salt_size != this->salt_size)
|
||||
{
|
||||
/* currently not supported */
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!this->cipher)
|
||||
{
|
||||
free(this);
|
||||
|
|
|
@ -288,9 +288,10 @@ METHOD(certificate_t, issued_by, bool,
|
|||
private_openssl_crl_t *this, certificate_t *issuer,
|
||||
signature_params_t **scheme)
|
||||
{
|
||||
chunk_t fingerprint, tbs;
|
||||
chunk_t tbs;
|
||||
public_key_t *key;
|
||||
x509_t *x509;
|
||||
chunk_t keyid = chunk_empty;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
const ASN1_BIT_STRING *sig;
|
||||
#else
|
||||
|
@ -307,26 +308,29 @@ METHOD(certificate_t, issued_by, bool,
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
key = issuer->get_public_key(issuer);
|
||||
if (!key)
|
||||
|
||||
/* compare keyIdentifiers if available, otherwise use DNs */
|
||||
if (this->authKeyIdentifier.ptr)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (this->authKeyIdentifier.ptr && key)
|
||||
{
|
||||
if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
|
||||
!chunk_equals(fingerprint, this->authKeyIdentifier))
|
||||
keyid = x509->get_subjectKeyIdentifier(x509);
|
||||
if (keyid.len && !chunk_equals(keyid, this->authKeyIdentifier))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!keyid.len)
|
||||
{
|
||||
if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
key = issuer->get_public_key(issuer);
|
||||
if (!key)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* i2d_re_X509_CRL_tbs() was added with 1.1.0 when X509_CRL became opaque */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
tbs = openssl_i2chunk(re_X509_CRL_tbs, this->crl);
|
||||
|
|
|
@ -506,7 +506,11 @@ EC_GROUP *ec_group_new_brainpool(bp_curve *curve)
|
|||
goto failed;
|
||||
}
|
||||
G = EC_POINT_new(group);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
|
||||
if (!G || !EC_POINT_set_affine_coordinates(group, G, x, y, ctx))
|
||||
#else
|
||||
if (!G || !EC_POINT_set_affine_coordinates_GFp(group, G, x, y, ctx))
|
||||
#endif
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
|
|
|
@ -615,6 +615,18 @@ METHOD(plugin_t, get_features, int,
|
|||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 16),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 24),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 32),
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
|
||||
/* CCM is available before 1.1.0 but not via generic controls */
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 16),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 24),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 32),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 16),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 24),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 32),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 16),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 24),
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 32),
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
#endif /* OPENSSL_NO_AES */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL && !defined(OPENSSL_NO_CHACHA)
|
||||
PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32),
|
||||
|
@ -682,6 +694,16 @@ METHOD(plugin_t, get_features, int,
|
|||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512),
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHA3)
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_224),
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_256),
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_384),
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_512),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_224),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_256),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_384),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_512),
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
|
||||
|
|
|
@ -279,6 +279,16 @@ METHOD(private_key_t, sign, bool,
|
|||
return build_emsa_pkcs1_signature(this, NID_sha384, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
|
||||
return build_emsa_pkcs1_signature(this, NID_sha512, data, signature);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHA3) && !defined(OPENSSL_IS_BORINGSSL)
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_224:
|
||||
return build_emsa_pkcs1_signature(this, NID_sha3_224, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_256:
|
||||
return build_emsa_pkcs1_signature(this, NID_sha3_256, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_384:
|
||||
return build_emsa_pkcs1_signature(this, NID_sha3_384, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_512:
|
||||
return build_emsa_pkcs1_signature(this, NID_sha3_512, data, signature);
|
||||
#endif
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
return build_emsa_pkcs1_signature(this, NID_sha1, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_MD5:
|
||||
|
|
|
@ -280,6 +280,16 @@ METHOD(public_key_t, verify, bool,
|
|||
return verify_emsa_pkcs1_signature(this, NID_sha384, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
|
||||
return verify_emsa_pkcs1_signature(this, NID_sha512, data, signature);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHA3) && !defined(OPENSSL_IS_BORINGSSL)
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_224:
|
||||
return verify_emsa_pkcs1_signature(this, NID_sha3_224, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_256:
|
||||
return verify_emsa_pkcs1_signature(this, NID_sha3_256, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_384:
|
||||
return verify_emsa_pkcs1_signature(this, NID_sha3_384, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_512:
|
||||
return verify_emsa_pkcs1_signature(this, NID_sha3_512, data, signature);
|
||||
#endif
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
return verify_emsa_pkcs1_signature(this, NID_sha1, data, signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_MD5:
|
||||
|
|
|
@ -391,6 +391,7 @@ METHOD(certificate_t, issued_by, bool,
|
|||
public_key_t *key;
|
||||
bool valid;
|
||||
x509_t *x509 = (x509_t*)issuer;
|
||||
chunk_t keyid = chunk_empty;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
const ASN1_BIT_STRING *sig;
|
||||
#else
|
||||
|
@ -417,10 +418,24 @@ METHOD(certificate_t, issued_by, bool,
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
|
||||
|
||||
/* compare keyIdentifiers if available, otherwise use DNs */
|
||||
if (this->authKeyIdentifier.ptr)
|
||||
{
|
||||
return FALSE;
|
||||
keyid = x509->get_subjectKeyIdentifier(x509);
|
||||
if (keyid.len && !chunk_equals(keyid, this->authKeyIdentifier))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (!keyid.len)
|
||||
{
|
||||
if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
key = issuer->get_public_key(issuer);
|
||||
if (!key)
|
||||
{
|
||||
|
|
|
@ -83,21 +83,21 @@ static void find_certificates(private_pkcs11_creds_t *this,
|
|||
|
||||
/* store result in a temporary list, avoid recursive operation */
|
||||
raw = linked_list_create();
|
||||
/* do not use trusted argument if not supported */
|
||||
if (!(this->lib->get_features(this->lib) & PKCS11_TRUSTED_CERTS))
|
||||
{
|
||||
count--;
|
||||
}
|
||||
enumerator = this->lib->create_object_enumerator(this->lib,
|
||||
session, tmpl, countof(tmpl), attr, count);
|
||||
while (enumerator->enumerate(enumerator, &object))
|
||||
{
|
||||
entry = malloc(sizeof(*entry));
|
||||
entry->value = chunk_clone(
|
||||
chunk_create(attr[0].pValue, attr[0].ulValueLen));
|
||||
entry->label = chunk_clone(
|
||||
chunk_create(attr[1].pValue, attr[1].ulValueLen));
|
||||
entry->trusted = trusted;
|
||||
if (attr[0].ulValueLen == CK_UNAVAILABLE_INFORMATION ||
|
||||
attr[1].ulValueLen == CK_UNAVAILABLE_INFORMATION)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
INIT(entry,
|
||||
.value = chunk_clone(chunk_create(attr[0].pValue, attr[0].ulValueLen)),
|
||||
.label = chunk_clone(chunk_create(attr[1].pValue, attr[1].ulValueLen)),
|
||||
/* assume trusted certificates if attribute is not available */
|
||||
.trusted = attr[2].ulValueLen == CK_UNAVAILABLE_INFORMATION || trusted,
|
||||
);
|
||||
raw->insert_last(raw, entry);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
@ -339,7 +339,8 @@ certificate_t *pkcs11_creds_load(certificate_type_t type, va_list args)
|
|||
}
|
||||
certs = p11->create_object_enumerator(p11, session,
|
||||
tmpl, countof(tmpl), attr, countof(attr));
|
||||
if (certs->enumerate(certs, &object))
|
||||
if (certs->enumerate(certs, &object) &&
|
||||
attr[0].ulValueLen != CK_UNAVAILABLE_INFORMATION)
|
||||
{
|
||||
data = chunk_clone(chunk_create(attr[0].pValue, attr[0].ulValueLen));
|
||||
}
|
||||
|
|
|
@ -624,6 +624,8 @@ typedef struct {
|
|||
pkcs11_library_t *lib;
|
||||
/* attributes to retrieve */
|
||||
CK_ATTRIBUTE_PTR attr;
|
||||
/* copy of the original attributes provided by the caller */
|
||||
CK_ATTRIBUTE_PTR orig_attr;
|
||||
/* number of attributes */
|
||||
CK_ULONG count;
|
||||
/* object handle in case of a single object */
|
||||
|
@ -633,17 +635,36 @@ typedef struct {
|
|||
} object_enumerator_t;
|
||||
|
||||
/**
|
||||
* Free contents of attributes in a list
|
||||
* Keep a copy of the original attribute values so we can restore them while
|
||||
* enumerating e.g. if an attribute was unavailable for a particular object.
|
||||
*/
|
||||
static void init_attrs(object_enumerator_t *this)
|
||||
{
|
||||
int i;
|
||||
|
||||
this->orig_attr = calloc(this->count, sizeof(CK_ATTRIBUTE));
|
||||
for (i = 0; i < this->count; i++)
|
||||
{
|
||||
this->orig_attr[i] = this->attr[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free contents of allocated attributes and reset them to their original
|
||||
* values.
|
||||
*/
|
||||
static void free_attrs(object_enumerator_t *this)
|
||||
{
|
||||
CK_ATTRIBUTE_PTR attr;
|
||||
int i;
|
||||
|
||||
while (this->freelist->remove_last(this->freelist, (void**)&attr) == SUCCESS)
|
||||
{
|
||||
free(attr->pValue);
|
||||
attr->pValue = NULL;
|
||||
attr->ulValueLen = 0;
|
||||
}
|
||||
for (i = 0; i < this->count; i++)
|
||||
{
|
||||
this->attr[i] = this->orig_attr[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -687,7 +708,9 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
|
|||
/* get length of objects first */
|
||||
rv = this->lib->f->C_GetAttributeValue(this->session, object,
|
||||
this->attr, this->count);
|
||||
if (rv != CKR_OK)
|
||||
if (rv != CKR_OK &&
|
||||
rv != CKR_ATTRIBUTE_SENSITIVE &&
|
||||
rv != CKR_ATTRIBUTE_TYPE_INVALID)
|
||||
{
|
||||
DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
|
||||
return FALSE;
|
||||
|
@ -695,8 +718,12 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
|
|||
/* allocate required chunks */
|
||||
for (i = 0; i < this->count; i++)
|
||||
{
|
||||
if (this->attr[i].pValue == NULL &&
|
||||
this->attr[i].ulValueLen != 0 && this->attr[i].ulValueLen != -1)
|
||||
if (this->attr[i].ulValueLen == CK_UNAVAILABLE_INFORMATION)
|
||||
{ /* reset this unavailable attribute before the next call */
|
||||
this->attr[i] = this->orig_attr[i];
|
||||
}
|
||||
else if (this->attr[i].pValue == NULL &&
|
||||
this->attr[i].ulValueLen != 0)
|
||||
{
|
||||
this->attr[i].pValue = malloc(this->attr[i].ulValueLen);
|
||||
this->freelist->insert_last(this->freelist, &this->attr[i]);
|
||||
|
@ -705,9 +732,10 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
|
|||
/* get the data */
|
||||
rv = this->lib->f->C_GetAttributeValue(this->session, object,
|
||||
this->attr, this->count);
|
||||
if (rv != CKR_OK)
|
||||
if (rv != CKR_OK &&
|
||||
rv != CKR_ATTRIBUTE_SENSITIVE &&
|
||||
rv != CKR_ATTRIBUTE_TYPE_INVALID)
|
||||
{
|
||||
free_attrs(this);
|
||||
DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -774,6 +802,7 @@ METHOD(enumerator_t, object_destroy, void,
|
|||
}
|
||||
free_attrs(this);
|
||||
this->freelist->destroy(this->freelist);
|
||||
free(this->orig_attr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
|
@ -804,6 +833,7 @@ METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*,
|
|||
.count = acount,
|
||||
.freelist = linked_list_create(),
|
||||
);
|
||||
init_attrs(enumerator);
|
||||
return &enumerator->public;
|
||||
}
|
||||
|
||||
|
@ -826,6 +856,7 @@ METHOD(pkcs11_library_t, create_object_attr_enumerator, enumerator_t*,
|
|||
.object = object,
|
||||
.freelist = linked_list_create(),
|
||||
);
|
||||
init_attrs(enumerator);
|
||||
return &enumerator->public;
|
||||
}
|
||||
|
||||
|
@ -1033,7 +1064,6 @@ static void check_features(private_pkcs11_library_t *this, CK_INFO *info)
|
|||
{
|
||||
if (has_version(info, 2, 20))
|
||||
{
|
||||
this->features |= PKCS11_TRUSTED_CERTS;
|
||||
this->features |= PKCS11_ALWAYS_AUTH_KEYS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,8 @@ typedef struct pkcs11_library_t pkcs11_library_t;
|
|||
* Optional PKCS#11 features some libraries support, some not
|
||||
*/
|
||||
enum pkcs11_feature_t {
|
||||
/** CKA_TRUSTED attribute supported for certificate objects */
|
||||
PKCS11_TRUSTED_CERTS = (1<<0),
|
||||
/** CKA_ALWAYS_AUTHENTICATE attribute supported for private keys */
|
||||
PKCS11_ALWAYS_AUTH_KEYS = (1<<1),
|
||||
PKCS11_ALWAYS_AUTH_KEYS = (1<<0),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -73,6 +71,8 @@ struct pkcs11_library_t {
|
|||
* An optional attribute array is automatically filled in with the
|
||||
* objects associated attributes. If the value of an output attribute
|
||||
* is NULL, the value gets allocated/freed during enumeration.
|
||||
* For attributes that are unavailable, the length field will be set to
|
||||
* CK_UNAVAILABLE_INFORMATION.
|
||||
*
|
||||
* @param session session to use
|
||||
* @param tmpl search template
|
||||
|
@ -92,6 +92,8 @@ struct pkcs11_library_t {
|
|||
* The given attribute array is automatically filled in with the
|
||||
* associated attributes. If the value of an output attribute is NULL,
|
||||
* the required memory gets allocated/freed during enumeration.
|
||||
* For attributes that are unavailable, the length field will be set to
|
||||
* CK_UNAVAILABLE_INFORMATION.
|
||||
*
|
||||
* @param session session to use
|
||||
* @param object object handle
|
||||
|
|
|
@ -173,7 +173,7 @@ CALLBACK(dispatch_slot_events, job_requeue_t,
|
|||
rv = entry->lib->f->C_WaitForSlotEvent(0, &slot, NULL);
|
||||
if (rv == CKR_FUNCTION_NOT_SUPPORTED || rv == CKR_NO_EVENT)
|
||||
{
|
||||
DBG1(DBG_CFG, "module '%s' does not support hot-plugging, cancelled",
|
||||
DBG1(DBG_CFG, "module '%s' does not support hot-plugging, canceled",
|
||||
entry->lib->get_name(entry->lib));
|
||||
return JOB_REQUEUE_NONE;
|
||||
}
|
||||
|
@ -389,4 +389,3 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
|
|||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -153,8 +153,8 @@ static bool handle_certs(private_pkcs11_plugin_t *this,
|
|||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE,
|
||||
CERT_X509, FALSE, (void*)pkcs11_creds_load);
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, FALSE,
|
||||
get_name(this), (void*)pkcs11_creds_load);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -627,13 +627,17 @@ static pkcs11_library_t* find_lib_and_keyid_by_skid(chunk_t keyid_chunk,
|
|||
attr, countof(attr));
|
||||
while (certs->enumerate(certs, &object))
|
||||
{
|
||||
INIT(entry,
|
||||
.value = chunk_clone(
|
||||
chunk_create(attr[0].pValue, attr[0].ulValueLen)),
|
||||
.ckaid = chunk_clone(
|
||||
chunk_create(attr[1].pValue, attr[1].ulValueLen)),
|
||||
);
|
||||
raw->insert_last(raw, entry);
|
||||
if (attr[0].ulValueLen != CK_UNAVAILABLE_INFORMATION &&
|
||||
attr[1].ulValueLen != CK_UNAVAILABLE_INFORMATION)
|
||||
{
|
||||
INIT(entry,
|
||||
.value = chunk_clone(
|
||||
chunk_create(attr[0].pValue, attr[0].ulValueLen)),
|
||||
.ckaid = chunk_clone(
|
||||
chunk_create(attr[1].pValue, attr[1].ulValueLen)),
|
||||
);
|
||||
raw->insert_last(raw, entry);
|
||||
}
|
||||
}
|
||||
certs->destroy(certs);
|
||||
|
||||
|
@ -708,7 +712,8 @@ static bool find_key(private_pkcs11_private_key_t *this, chunk_t keyid)
|
|||
}
|
||||
enumerator = this->lib->create_object_enumerator(this->lib,
|
||||
this->session, tmpl, countof(tmpl), attr, count);
|
||||
if (enumerator->enumerate(enumerator, &object))
|
||||
if (enumerator->enumerate(enumerator, &object) &&
|
||||
attr[0].ulValueLen != CK_UNAVAILABLE_INFORMATION)
|
||||
{
|
||||
this->type = KEY_RSA;
|
||||
switch (type)
|
||||
|
@ -717,7 +722,10 @@ static bool find_key(private_pkcs11_private_key_t *this, chunk_t keyid)
|
|||
this->type = KEY_ECDSA;
|
||||
/* fall-through */
|
||||
case CKK_RSA:
|
||||
this->reauth = reauth;
|
||||
if (attr[1].ulValueLen != CK_UNAVAILABLE_INFORMATION)
|
||||
{
|
||||
this->reauth = reauth;
|
||||
}
|
||||
this->object = object;
|
||||
found = TRUE;
|
||||
break;
|
||||
|
@ -803,7 +811,8 @@ static public_key_t* find_pubkey_in_certs(private_pkcs11_private_key_t *this,
|
|||
|
||||
enumerator = this->lib->create_object_enumerator(this->lib, this->session,
|
||||
tmpl, countof(tmpl), attr, countof(attr));
|
||||
if (enumerator->enumerate(enumerator, &object))
|
||||
if (enumerator->enumerate(enumerator, &object) &&
|
||||
attr[0].ulValueLen != CK_UNAVAILABLE_INFORMATION)
|
||||
{
|
||||
data = chunk_clone(chunk_create(attr[0].pValue, attr[0].ulValueLen));
|
||||
}
|
||||
|
|
|
@ -888,7 +888,8 @@ static private_pkcs11_public_key_t *find_key_by_keyid(pkcs11_library_t *p11,
|
|||
|
||||
enumerator = p11->create_object_enumerator(p11, session, tmpl, count, attr,
|
||||
countof(attr));
|
||||
if (enumerator->enumerate(enumerator, &object))
|
||||
if (enumerator->enumerate(enumerator, &object) &&
|
||||
attr[0].ulValueLen != CK_UNAVAILABLE_INFORMATION)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
|
@ -518,24 +518,24 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
|
|||
case FEATURE_PRIVKEY_GEN:
|
||||
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY,
|
||||
feature->arg.privkey, reg->arg.reg.final,
|
||||
reg->arg.reg.f);
|
||||
name, reg->arg.reg.f);
|
||||
break;
|
||||
case FEATURE_PUBKEY:
|
||||
lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY,
|
||||
feature->arg.pubkey, reg->arg.reg.final,
|
||||
reg->arg.reg.f);
|
||||
name, reg->arg.reg.f);
|
||||
break;
|
||||
case FEATURE_CERT_DECODE:
|
||||
case FEATURE_CERT_ENCODE:
|
||||
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE,
|
||||
feature->arg.cert, reg->arg.reg.final,
|
||||
reg->arg.reg.f);
|
||||
name, reg->arg.reg.f);
|
||||
break;
|
||||
case FEATURE_CONTAINER_DECODE:
|
||||
case FEATURE_CONTAINER_ENCODE:
|
||||
lib->creds->add_builder(lib->creds, CRED_CONTAINER,
|
||||
feature->arg.container, reg->arg.reg.final,
|
||||
reg->arg.reg.f);
|
||||
name, reg->arg.reg.f);
|
||||
break;
|
||||
case FEATURE_DATABASE:
|
||||
lib->db->add_database(lib->db, reg->arg.reg.f);
|
||||
|
|
|
@ -165,7 +165,7 @@ static bool read_result(private_winhttp_fetcher_t *this, HINTERNET request,
|
|||
}
|
||||
if (!this->cb(user, chunk_create(buf, received)))
|
||||
{
|
||||
DBG1(DBG_LIB, "processing response failed or cancelled");
|
||||
DBG1(DBG_LIB, "processing response failed or canceled");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,8 @@ libstrongswan_wolfssl_la_SOURCES = \
|
|||
wolfssl_rng.h wolfssl_rng.c \
|
||||
wolfssl_sha1_prf.h wolfssl_sha1_prf.c \
|
||||
wolfssl_x_diffie_hellman.h wolfssl_x_diffie_hellman.c \
|
||||
wolfssl_util.h wolfssl_util.c
|
||||
wolfssl_util.h wolfssl_util.c \
|
||||
wolfssl_xof.h wolfssl_xof.c
|
||||
|
||||
|
||||
libstrongswan_wolfssl_la_LDFLAGS = -module -avoid-version
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
* Copyright (C) 2021 Andreas Steffen, strongSec GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -47,7 +48,7 @@ struct private_wolfssl_crypter_t {
|
|||
* wolfSSL cipher
|
||||
*/
|
||||
union {
|
||||
#if !defined(NO_AES) && (!defined(NO_AES_CBC) || defined(WOLFSSL_AES_COUNTER))
|
||||
#if !defined(NO_AES) && (!defined(NO_AES_CBC) || defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_COUNTER))
|
||||
Aes aes;
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
|
@ -128,6 +129,18 @@ METHOD(crypter_t, decrypt, bool,
|
|||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AES_ECB)
|
||||
case ENCR_AES_ECB:
|
||||
ret = wc_AesSetKey(&this->cipher.aes, this->key.ptr, this->key.len,
|
||||
iv.ptr, AES_DECRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesEcbDecrypt(&this->cipher.aes, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
if (out == data.ptr)
|
||||
|
@ -248,6 +261,18 @@ METHOD(crypter_t, encrypt, bool,
|
|||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AES_ECB)
|
||||
case ENCR_AES_ECB:
|
||||
ret = wc_AesSetKey(&this->cipher.aes, this->key.ptr, this->key.len,
|
||||
iv.ptr, AES_ENCRYPTION);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = wc_AesEcbEncrypt(&this->cipher.aes, out, data.ptr,
|
||||
data.len);
|
||||
}
|
||||
success = (ret == 0);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
if (out == data.ptr)
|
||||
|
@ -365,6 +390,11 @@ METHOD(crypter_t, destroy, void,
|
|||
wc_AesFree(&this->cipher.aes);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AES_ECB)
|
||||
case ENCR_AES_ECB:
|
||||
wc_AesFree(&this->cipher.aes);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
wc_AesFree(&this->cipher.aes);
|
||||
|
@ -418,6 +448,24 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
|
|||
}
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AES_ECB)
|
||||
case ENCR_AES_ECB:
|
||||
switch (key_size)
|
||||
{
|
||||
case 0:
|
||||
key_size = 16;
|
||||
/* fall-through */
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
block_size = AES_BLOCK_SIZE;
|
||||
iv_size = AES_IV_SIZE;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
switch (key_size)
|
||||
|
@ -504,6 +552,11 @@ wolfssl_crypter_t *wolfssl_crypter_create(encryption_algorithm_t algo,
|
|||
ret = wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AES_ECB)
|
||||
case ENCR_AES_ECB:
|
||||
ret = wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ENCR_AES_CTR:
|
||||
ret = wc_AesInit(&this->cipher.aes, NULL, INVALID_DEVID);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
* Copyright (C) 2021 Andreas Steffen, strongSec GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -40,6 +41,7 @@
|
|||
#include "wolfssl_rng.h"
|
||||
#include "wolfssl_sha1_prf.h"
|
||||
#include "wolfssl_x_diffie_hellman.h"
|
||||
#include "wolfssl_xof.h"
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
#define FIPS_MODE 0
|
||||
|
@ -80,6 +82,11 @@ METHOD(plugin_t, get_features, int,
|
|||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
|
||||
#endif
|
||||
#if !defined(NO_AES) && defined(HAVE_AES_ECB)
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 16),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 24),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 32),
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24),
|
||||
|
@ -113,6 +120,22 @@ METHOD(plugin_t, get_features, int,
|
|||
#ifdef WOLFSSL_SHA512
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA512),
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA3_224),
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA3_256),
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA3_384),
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA3_512),
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHAKE256) && LIBWOLFSSL_VERSION_HEX >= 0x04007001
|
||||
PLUGIN_REGISTER(XOF, wolfssl_xof_create),
|
||||
PLUGIN_PROVIDE(XOF, XOF_SHAKE_256),
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
/* keyed sha1 hasher (aka prf) */
|
||||
PLUGIN_REGISTER(PRF, wolfssl_sha1_prf_create),
|
||||
|
@ -279,37 +302,55 @@ METHOD(plugin_t, get_features, int,
|
|||
/* signature/encryption schemes */
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
|
||||
#ifdef WC_RSA_PSS
|
||||
#ifdef WC_RSA_PSS
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS),
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_224),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_224),
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_256),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_384),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384),
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_512),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512),
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
|
||||
#endif
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && LIBWOLFSSL_VERSION_HEX >= 0x04007001
|
||||
#ifndef WOLFSSL_NOSHA3_224
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_224),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_224),
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA3_256
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_256),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_256),
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA3_384
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_384),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_384),
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA3_512
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_512),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_512),
|
||||
#endif
|
||||
#endif /* WOLFSSL_SHA3 */
|
||||
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1),
|
||||
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1),
|
||||
#ifndef WC_NO_RSA_OAEP
|
||||
#ifndef NO_MD5
|
||||
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
|
||||
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
|
||||
#endif
|
||||
#ifndef WC_NO_RSA_OAEP
|
||||
#ifndef NO_SHA
|
||||
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_OAEP_SHA1),
|
||||
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_OAEP_SHA1),
|
||||
|
@ -330,7 +371,7 @@ METHOD(plugin_t, get_features, int,
|
|||
PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_OAEP_SHA512),
|
||||
PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_OAEP_SHA512),
|
||||
#endif
|
||||
#endif /* !WC_NO_RSA_OAEP */
|
||||
#endif /* !WC_NO_RSA_OAEP */
|
||||
#endif /* !NO_RSA */
|
||||
#ifdef HAVE_ECC
|
||||
#ifdef HAVE_ECC_KEY_IMPORT
|
||||
|
|
|
@ -200,6 +200,26 @@ METHOD(private_key_t, sign, bool,
|
|||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA512, data,
|
||||
signature);
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_224:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_224,
|
||||
data, signature);
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_256:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_256,
|
||||
data, signature);
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_384:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_384,
|
||||
data, signature);
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_512:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_512,
|
||||
data, signature);
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA, data,
|
||||
|
@ -686,6 +706,8 @@ wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_load(key_type_t type,
|
|||
}
|
||||
else if (n.ptr && e.ptr && d.ptr)
|
||||
{
|
||||
this->rsa.type = RSA_PRIVATE;
|
||||
|
||||
if (mp_read_unsigned_bin(&this->rsa.n, n.ptr, n.len) != 0)
|
||||
{
|
||||
goto error;
|
||||
|
|
|
@ -187,6 +187,18 @@ METHOD(public_key_t, verify, bool,
|
|||
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA512, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_224:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_224, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_256:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_256, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_384:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_384, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA3_512:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_512, data,
|
||||
signature);
|
||||
case SIGN_RSA_EMSA_PKCS1_SHA1:
|
||||
return verify_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA, data,
|
||||
signature);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
|
||||
* Copyright (C) 2021 Andreas Steffen, strongSec GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -147,6 +148,26 @@ bool wolfssl_hash2type(hash_algorithm_t hash, enum wc_HashType *type)
|
|||
case HASH_SHA512:
|
||||
*type = WC_HASH_TYPE_SHA512;
|
||||
break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
|
||||
case HASH_SHA3_224:
|
||||
*type = WC_HASH_TYPE_SHA3_224;
|
||||
break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
|
||||
case HASH_SHA3_256:
|
||||
*type = WC_HASH_TYPE_SHA3_256;
|
||||
break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
|
||||
case HASH_SHA3_384:
|
||||
*type = WC_HASH_TYPE_SHA3_384;
|
||||
break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
|
||||
case HASH_SHA3_512:
|
||||
*type = WC_HASH_TYPE_SHA3_512;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return FALSE;
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Andreas Steffen, strongSec GmbH
|
||||
*
|
||||
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
|
||||
#ifdef WOLFSSL_SHAKE256
|
||||
|
||||
#include <wolfssl/wolfcrypt/sha3.h>
|
||||
|
||||
#include "wolfssl_xof.h"
|
||||
|
||||
#define KECCAK_STATE_SIZE 200 /* 1600 bits */
|
||||
#define SHAKE256_CAPACITY 64 /* 512 bits */
|
||||
|
||||
typedef struct private_xof_t private_xof_t;
|
||||
|
||||
/**
|
||||
* Private data
|
||||
*/
|
||||
struct private_xof_t {
|
||||
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
xof_t public;
|
||||
|
||||
/**
|
||||
* Internal context
|
||||
*/
|
||||
wc_Shake shake;
|
||||
|
||||
/**
|
||||
* Current seed
|
||||
*/
|
||||
chunk_t seed;
|
||||
|
||||
/**
|
||||
* Offset into generated data
|
||||
*/
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
METHOD(xof_t, get_type, ext_out_function_t,
|
||||
private_xof_t *this)
|
||||
{
|
||||
return XOF_SHAKE_256;
|
||||
}
|
||||
|
||||
METHOD(xof_t, get_bytes, bool,
|
||||
private_xof_t *this, size_t out_len, uint8_t *buffer)
|
||||
{
|
||||
bool success = FALSE;
|
||||
chunk_t data;
|
||||
|
||||
/* we can call wc_Shake256_Final() only once, so to support an arbitrary
|
||||
* number of calls to get_bytes(), we request all the data we already
|
||||
* requested previously and just ignore what we already handed out */
|
||||
if (wc_Shake256_Update(&this->shake, this->seed.ptr, this->seed.len) == 0)
|
||||
{
|
||||
data = chunk_alloc(out_len + this->offset);
|
||||
if (wc_Shake256_Final(&this->shake, data.ptr, data.len) == 0)
|
||||
{
|
||||
memcpy(buffer, data.ptr + this->offset, out_len);
|
||||
this->offset += out_len;
|
||||
success = TRUE;
|
||||
}
|
||||
chunk_clear(&data);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(xof_t, allocate_bytes, bool,
|
||||
private_xof_t *this, size_t out_len, chunk_t *chunk)
|
||||
{
|
||||
*chunk = chunk_alloc(out_len);
|
||||
return get_bytes(this, out_len, chunk->ptr);
|
||||
}
|
||||
|
||||
METHOD(xof_t, get_block_size, size_t,
|
||||
private_xof_t *this)
|
||||
{
|
||||
return KECCAK_STATE_SIZE - SHAKE256_CAPACITY;
|
||||
}
|
||||
|
||||
METHOD(xof_t, get_seed_size, size_t,
|
||||
private_xof_t *this)
|
||||
{
|
||||
return SHAKE256_CAPACITY;
|
||||
}
|
||||
|
||||
METHOD(xof_t, set_seed, bool,
|
||||
private_xof_t *this, chunk_t seed)
|
||||
{
|
||||
chunk_clear(&this->seed);
|
||||
this->seed = chunk_clone(seed);
|
||||
this->offset = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(xof_t, destroy, void,
|
||||
private_xof_t *this)
|
||||
{
|
||||
wc_Shake256_Free(&this->shake);
|
||||
chunk_clear(&this->seed);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
xof_t *wolfssl_xof_create(ext_out_function_t algorithm)
|
||||
{
|
||||
private_xof_t *this;
|
||||
|
||||
if (algorithm != XOF_SHAKE_256)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_type = _get_type,
|
||||
.get_bytes = _get_bytes,
|
||||
.allocate_bytes = _allocate_bytes,
|
||||
.get_block_size = _get_block_size,
|
||||
.get_seed_size = _get_seed_size,
|
||||
.set_seed = _set_seed,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
);
|
||||
|
||||
if (wc_InitShake256(&this->shake, NULL, 0) != 0)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SHAKE256 */
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Andreas Steffen, strongSec GmbH
|
||||
*
|
||||
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of the SHAKE128/256 XOF algorithm using OpenSSL.
|
||||
*
|
||||
* @defgroup wolfssl_xof wolfssl_xof
|
||||
* @{ @ingroup wolfssl_p
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_XOF_H_
|
||||
#define WOLFSSL_XOF_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Creates a new xof_t object.
|
||||
*
|
||||
* @param algorithm XOF algorithm to create
|
||||
* @return object, NULL if not supported
|
||||
*/
|
||||
xof_t *wolfssl_xof_create(ext_out_function_t algorithm);
|
||||
|
||||
#endif /** WOLFSSL_XOF_H_ @}*/
|
|
@ -1710,6 +1710,7 @@ METHOD(certificate_t, issued_by, bool,
|
|||
public_key_t *key;
|
||||
bool valid;
|
||||
x509_t *x509 = (x509_t*)issuer;
|
||||
chunk_t keyid = chunk_empty;
|
||||
|
||||
if (&this->public.interface.interface == issuer)
|
||||
{
|
||||
|
@ -1733,9 +1734,22 @@ METHOD(certificate_t, issued_by, bool,
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
|
||||
|
||||
/* compare keyIdentifiers if available, otherwise use DNs */
|
||||
if (this->authKeyIdentifier.ptr)
|
||||
{
|
||||
return FALSE;
|
||||
keyid = x509->get_subjectKeyIdentifier(x509);
|
||||
if (keyid.len && !chunk_equals(keyid, this->authKeyIdentifier))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (!keyid.len)
|
||||
{
|
||||
if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the public key of the issuer */
|
||||
|
|
|
@ -186,12 +186,12 @@ static void update(private_watcher_t *this)
|
|||
}
|
||||
|
||||
/**
|
||||
* Cleanup function if callback gets cancelled
|
||||
* Cleanup function if callback gets canceled
|
||||
*/
|
||||
static void unregister(notify_data_t *data)
|
||||
{
|
||||
/* if a thread processing a callback gets cancelled, we mark the entry
|
||||
* as cancelled, like the callback would return FALSE. This is required
|
||||
/* if a thread processing a callback gets canceled, we mark the entry
|
||||
* as canceled, like the callback would return FALSE. This is required
|
||||
* to not queue this watcher again if all threads have been gone. */
|
||||
data->keep = FALSE;
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ static void activate_all(private_watcher_t *this)
|
|||
{
|
||||
entry_t *entry;
|
||||
|
||||
/* When the watcher thread gets cancelled, we have to reactivate any entry
|
||||
/* When the watcher thread gets canceled, we have to reactivate any entry
|
||||
* and signal threads in remove() to go on. */
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
|
@ -398,7 +398,7 @@ static job_requeue_t watch(private_watcher_t *this)
|
|||
if (res == -1 && errno == EINTR)
|
||||
{
|
||||
/* LinuxThreads interrupts poll(), but does not make it a
|
||||
* cancellation point. Manually test if we got cancelled. */
|
||||
* cancellation point. Manually test if we got canceled. */
|
||||
thread_cancellation_point();
|
||||
}
|
||||
|
||||
|
|
|
@ -207,14 +207,7 @@ valuepart:
|
|||
*/
|
||||
static void settings_parser_error(parser_helper_t *ctx, const char *s)
|
||||
{
|
||||
char *text = settings_parser_get_text(ctx->scanner);
|
||||
int len = settings_parser_get_leng(ctx->scanner);
|
||||
|
||||
if (len && text[len-1] == '\n')
|
||||
{ /* cut off newline at the end to avoid muti-line log messages */
|
||||
len--;
|
||||
}
|
||||
PARSER_DBG1(ctx, "%s [%.*s]", s, len, text);
|
||||
PARSER_DBG1(ctx, "%s", s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1130,7 +1130,7 @@ static void *cancel_onoff_run(void *data_in)
|
|||
thread_cancelability(FALSE);
|
||||
data->cancellable = FALSE;
|
||||
|
||||
/* we should not get cancelled here */
|
||||
/* we should not get canceled here */
|
||||
data->sem->wait(data->sem);
|
||||
|
||||
data->cancellable = TRUE;
|
||||
|
|
|
@ -84,7 +84,7 @@ struct private_thread_t {
|
|||
bool detached_or_joined;
|
||||
|
||||
/**
|
||||
* TRUE if the threads has terminated (cancelled, via thread_exit or
|
||||
* TRUE if the threads has terminated (canceled, via thread_exit or
|
||||
* returned from the main function)
|
||||
*/
|
||||
bool terminated;
|
||||
|
@ -130,7 +130,7 @@ static thread_value_t *current_thread;
|
|||
#endif
|
||||
|
||||
/* the signal handler for SIG_CANCEL uses pthread_exit to terminate the
|
||||
* "cancelled" thread */
|
||||
* "canceled" thread */
|
||||
static void cancel_signal_handler(int sig)
|
||||
{
|
||||
pthread_exit(NULL);
|
||||
|
|
|
@ -109,7 +109,7 @@ u_int thread_current_id();
|
|||
|
||||
/**
|
||||
* Push a function onto the current thread's cleanup handler stack.
|
||||
* The callback function is called whenever the thread is cancelled, exits or
|
||||
* The callback function is called whenever the thread is canceled, exits or
|
||||
* thread_cleanup_pop is called with TRUE as execute argument.
|
||||
*
|
||||
* @param cleanup function called on thread exit
|
||||
|
|
|
@ -87,7 +87,7 @@ struct private_thread_t {
|
|||
bool cancelability;
|
||||
|
||||
/**
|
||||
* Has the thread been cancelled by thread->cancel()?
|
||||
* Has the thread been canceled by thread->cancel()?
|
||||
*/
|
||||
bool canceled;
|
||||
|
||||
|
|
|
@ -144,6 +144,32 @@ void backtrace_deinit()
|
|||
#include <collections/hashtable.h>
|
||||
#include <threading/mutex.h>
|
||||
|
||||
/* interface changes for newer BFD versions, note that older versions declared
|
||||
* some of the new functions as macros but with different arguments */
|
||||
#if HAVE_DECL_BFD_GET_SECTION_FLAGS
|
||||
#define get_section_flags(a, s) bfd_get_section_flags(a, s)
|
||||
#elif HAVE_DECL_BFD_SECTION_FLAGS
|
||||
#define get_section_flags(a, s) bfd_section_flags(s)
|
||||
#else
|
||||
#error Unknown BFD API
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_BFD_GET_SECTION_VMA
|
||||
#define get_section_vma(a, s) bfd_get_section_vma(a, s)
|
||||
#elif HAVE_DECL_BFD_SECTION_VMA
|
||||
#define get_section_vma(a, s) bfd_section_vma(s)
|
||||
#else
|
||||
#error Unknown BFD API
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_BFD_GET_SECTION_SIZE
|
||||
#define get_section_size bfd_get_section_size
|
||||
#elif HAVE_DECL_BFD_SECTION_SIZE
|
||||
#define get_section_size bfd_section_size
|
||||
#else
|
||||
#error Unknown BFD API
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Hashtable-cached bfd handle
|
||||
*/
|
||||
|
@ -248,12 +274,12 @@ static void find_addr(bfd *abfd, asection *section, bfd_find_data_t *data)
|
|||
char fbuf[512] = "", sbuf[512] = "";
|
||||
u_int line;
|
||||
|
||||
if (!data->found || (bfd_get_section_flags(abfd, section) & SEC_ALLOC) != 0)
|
||||
if (!data->found || (get_section_flags(abfd, section) & SEC_ALLOC) != 0)
|
||||
{
|
||||
vma = bfd_get_section_vma(abfd, section);
|
||||
vma = get_section_vma(abfd, section);
|
||||
if (data->vma >= vma)
|
||||
{
|
||||
size = bfd_get_section_size(section);
|
||||
size = get_section_size(section);
|
||||
if (data->vma < vma + size)
|
||||
{
|
||||
data->found = bfd_find_nearest_line(abfd, section,
|
||||
|
|
|
@ -299,7 +299,7 @@ struct identification_t {
|
|||
* - ID_RFC822_ADDR: alice@wonderland.org
|
||||
* - ID_DER_ASN1_DN: C=CH, O=Linux strongSwan, CN=bob
|
||||
*
|
||||
* In favour of pluto, domainnames are prepended with an @, since
|
||||
* In favor of pluto, domainnames are prepended with an @, since
|
||||
* pluto resolves domainnames without an @ to IPv4 addresses. Since
|
||||
* we use a separate host_t class for addresses, this doesn't
|
||||
* make sense for us.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue