Compare commits

...

88 Commits

Author SHA1 Message Date
Domonkos P. Tomcsanyi cea991aea8 Updated entity name in copyright statements 2022-05-18 17:32:30 +02:00
Tomcsányi, Domonkos 0ed91dc681 simaka_manager: Some more debug logging on success/failure cases 2021-08-26 19:48:11 +02:00
Tomcsányi, Domonkos 65f576bd9c ignore mismatch in received identity.
This is needed, because the standard mandates that the remote entity
must be configured as ims (mimicking the APN setting I think), but on
the other hand the ePDG will identify itself with its FQDN in the end. I
tested this and this is currently the only way to do it with strongswan
I think, because you cannot configure different identities.
2021-08-26 19:47:15 +02:00
Tomcsányi, Domonkos 18b4a240dd permit SHA-1, as some ePDGs require that 2021-08-26 19:46:49 +02:00
Tomcsányi, Domonkos f68dcde6c5 Add support for EAP-AKA against USIM in PC/SC reader 2021-08-26 19:45:59 +02:00
Andreas Steffen 4817d5ed0d Version bump to 5.9.3 2021-07-06 14:00:39 +02:00
Andreas Steffen a09a905e1d vici: Suppress trailing nul character 2021-07-06 12:06:23 +02:00
Tobias Brunner 2cd5314de7 testing: Use specific versions of swidGenerator and strongTNC
This way we get updated versions automatically (referencing "master"
required manually deleting the downloaded archives and the unpacked
directories).  It also allows switching versions when working in different
branches (note that REV can also be set to a commit ID, e.g. to test
changes before tagging them later and merging the branch).
2021-06-30 16:17:39 +02:00
Tobias Brunner 06e11b481b kernel-netlink: Fix theoretical memory leak when parsing routes
This currently can't happen as the kernel always puts RTA_TABLE as first
attribute in RTM_NEWROUTE messages.
2021-06-25 13:51:44 +02:00
Tobias Brunner f6aafb3005 Fixed some typos, courtesy of codespell
Main change is the conversion from the British cancelling/-ed to the
American canceling/-ed.
2021-06-25 11:32:29 +02:00
Andreas Steffen 30fab57124 Version bump to 5.9.3rc1 2021-06-24 09:18:54 +02:00
Tobias Brunner 19611b1d28 testing: Build wolfSSL from the Git repository
Use the same configure options etc. for both builds (no need for the cert
options as we don't use TLS or X.509 parsing) and switch to a Git commit
that includes the SHA-3 OID fix (it's actually the fix itself).
2021-06-22 17:54:15 +02:00
Andreas Steffen 4baca5ca80 testing: Fixed ikev2/farp scenario 2021-06-22 12:32:35 +02:00
Andreas Steffen dbd1534875 Version bump to 5.9.3dr4 2021-06-22 10:33:07 +02:00
Andreas Steffen eba2622587 testing: Migrate ikev2-stroke-bye scenarios to vici 2021-06-22 10:23:06 +02:00
Andreas Steffen 706c58b291 testing: Fixed pretest script of ikev1/rw-psk-aggressive scenario 2021-06-21 12:03:36 +02:00
Tobias Brunner 6d8890767c testing: Migrate ikev2/host2host-transport-nat scenario to vici
This also restores the test as it was before the referenced commit so it
again, as written in the description, demonstrates that venus is unable
to ping sun without IPsec tunnel.

Fixes: f27fb58ae0 ("testing: Update description and test evaluation of host2host-transport-nat")
2021-06-21 12:03:36 +02:00
Tobias Brunner 2b5c743952 testing: Migrate MOBIKE tests to vici
Note that the mobike-nat test has been removed as it basically did the same
as the mobike-virtual-ip-nat test.  Instead, the mobike-nat-mapping scenario
is added, which simulates a NAT router restart.
2021-06-21 12:03:36 +02:00
Tobias Brunner abe51389c5 ike-mobike: Force MOBIKE update after NAT mappings changed
The addresses observed by the client behind the NAT are exactly the same if
the NAT router gets restarted.

Fixes: 2b255f01af ("ike-mobike: Use ike_sa_t::update_hosts() to trigger events")
2021-06-21 12:03:36 +02:00
Tobias Brunner 036ae27645 ike-sa: Log IKE endpoint changes 2021-06-21 12:03:36 +02:00
Tobias Brunner 79b526deba ha: Register the correct IKE_SA with the manager after a rekeying
Fixes: 20dfbcad08 ("ha: Register new IKE_SAs before calling inherit_post()")
Closes strongswan/strongswan#456.
2021-06-21 10:02:26 +02:00
Tobias Brunner 4b9b4dc956 Merge branch 'vici-stuck'
Closes strongswan/strongswan#268.
2021-06-21 09:59:28 +02:00
Tobias Brunner eec3bdb04a vici: Signal waiting threads when skipping disconnected connections
If two threads are waiting in find_entry() and remove_entry(),
respectively, and the former is woken first, the latter remains stuck
as it won't get signaled.
2021-06-21 09:59:15 +02:00
Tobias Brunner b0e2187b6b vici: Signal waiting threads when removing a connection entry
If there are threads waiting in find_entry() and one in remove_entry()
and the latter is woken first by a thread calling put_entry(), the
former threads would remain stuck as they get never signaled.
2021-06-21 09:59:15 +02:00
Tobias Brunner 030e80957d kernel-netlink: Don't wait for VIPs to disappear during de-initialization
This can happen if an IKE_SA is terminated forcefully shortly before
terminating the daemon.  The thread that handles the terminate command
will call checkin_and_destroy(), which unregisters the IKE_SA from the
manager before destroying it.  The main thread that calls flush() on the
IKE_SA manager won't wait for this SA (its entry is already gone), so
the processor and in turn the watcher job/thread might get canceled
before the first thread started deleting the VIP.  It would then wait
indefinitely for a signal that can never be sent.

There is still a small chance the thread hangs in wait() if the state check
happens right before the watcher is canceled and it wasn't yet able to
deliver the event from the kernel, we counter that by rechecking the state
after a while.
2021-06-21 09:59:06 +02:00
Tobias Brunner 0fc8cf0013 NEWS: Add news for 5.9.3 2021-06-18 10:31:31 +02:00
Adrian-Ken Rueegsegger 859dedeab7 testing: Update Anet to version 0.4.2 2021-06-17 09:53:51 +02:00
Stefan Berghofer d7a9e723f3 charon-tkm: Remove useless checks when deriving IKE keys 2021-06-17 09:53:51 +02:00
Stefan Berghofer 22e7900718 charon-tkm: Delegate encryption/decryption of IKE traffic to TKM
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
2021-06-17 09:53:51 +02:00
Tobias Brunner 6537be9c8d pkcs11: Change how unavailable attributes like CKA_TRUSTED are handled
If a PKCS#11 library/token doesn't provide one or more attributes via
C_GetAttributeValue(), we get back CKR_ATTRIBUTE_TYPE_INVALID (similar
for protected attributes where CKR_ATTRIBUTE_SENSITIVE is returned).
This is not an error as the spec demands that all attributes have been
processed with the unavailable attributes having set their length
field to CK_UNAVAILABLE_INFORMATION.

We use this to handle the CKA_TRUSTED attribute, which some tokens
apparently don't support.  We previously used a version check to remove
the attribute from the call but even the latest spec doesn't make the
attribute mandatory (it's just in a list of "common" attributes for
CKO_CERTIFICATE objects, without a default value), so there are current
tokens that don't support it and prevent us from enumerating certificates.
2021-06-14 13:58:48 +02:00
Tobias Brunner a90716cd4d receiver: Avoid division by 0 after system start if CLOCK_MONOTONIC is used
Depending on how CLOCK_MONOTONIC is implemented, time_monotonic() might
return 0 within 1 second after the system is started.  If that's the
case, we just default to 0 for now to avoid a crash (doesn't "hide" the
system time, but it's only the uptime anyway in this case).

Closes strongswan/strongswan#435.
2021-06-14 13:24:08 +02:00
Tobias Brunner 8dbf40d19a charon-nm: Simplify certificate enumeration and allow IDs other than DNs
This allows using SANs as identity instead of having to use the subject DN.

References strongswan/strongswan#437.
2021-06-14 12:13:47 +02:00
Tobias Brunner ae71f8357d dhcp: Move log messages for received packets
This way they are logged in the context of the corresponding IKE_SA.

Closes strongswan/strongswan#417.
2021-06-08 17:03:17 +02:00
Thomas Egerer 4e29d6fac1 bus: Extend and reorder arguments of ike_derived_keys() hook
This now includes all key material derived for IKE_SAs in the order
defined in the RFC:

  {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr}
               = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)

Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
2021-06-07 17:08:27 +02:00
Andreas Steffen 9c85a52956 Version bump to 5.9.3dr3 2021-06-04 09:28:17 +02:00
Tobias Brunner e166423856 ikev1: Fix flags so NAT Vendor IDs are sent again
Fixes: 6c49ddfbca ("ike: Add additional Vendor IDs for third-party implementations")
2021-06-04 09:20:49 +02:00
Andreas Steffen cc4338267e testing: Added openssl-ikev2/net2net-sha3-rsa-cert scenario 2021-06-03 14:20:06 +02:00
Andreas Steffen 5688e631e3 openssl: Support SHA-3 based RSA_EMSA_PKCS1 signatures 2021-06-03 14:20:06 +02:00
Andreas Steffen de5ca4021a testing: Test wolfssl plugin 2021-06-03 10:22:59 +02:00
Andreas Steffen 8bbd7bbd36 wolfssl: Full support of SHA3 signatures 2021-06-03 10:20:18 +02:00
Andreas Steffen e0044e5f48 credential_factory: Store name of plugin registering a builder 2021-06-01 21:12:46 +02:00
Andreas Steffen 62c5ef035c wolfssl: Set RSA key type 2021-05-30 12:40:08 +02:00
Marius Tomaschewski d654117c66 ccm: Destroy IV generator on crypter creation failure
Closes strongswan/strongswan#343.
2021-05-27 17:43:03 +02:00
Tobias Brunner a82f13e7ce dhcp: Log MAC address when sending DISCOVER message
Closes strongswan/strongswan#239.
2021-05-27 12:06:47 +02:00
Noel Kuntze 6c49ddfbca ike: Add additional Vendor IDs for third-party implementations
For some that are followed by unknown data (e.g. detailed version
information) we only do a prefix match.

Co-authored-by: Tobias Brunner <tobias@strongswan.org>

Closes strongswan/strongswan#393.
2021-05-21 17:50:35 +02:00
Andreas Steffen d415673565 Version bump to 5.9.3dr2 2021-05-21 10:00:41 +02:00
Andreas Steffen 7c5a2974b9 testing: Reorganizing IKEv1 and IKEv2 examples
For documentation purposes the new folders ikev1-algs, ikev2-algs,
ikev1-multi-ca and ikev2-multi-ca have been created. Most of the
test cases have now been converted to the vici interface. The
remaining legacy stroke scenarios yet to be converted have been put
into the ikev2-stroke-bye folder.

For documentation purposes some legacy stroke scenarios will be kept
in the ikev1-stroke, ikev2-stroke and ipv6-stroke folders.
2021-05-21 09:42:50 +02:00
Tobias Brunner db93938297 notify-payload: Update reference for notify types for PPKs
draft-ietf-ipsecme-qr-ikev2 was released as RFC 8784 in June of 2020.
2021-05-11 14:30:05 +02:00
Tobias Brunner c13a1c2829 Don't report current text in parser error messages
The values of `yytext` and `yyleng` might not be properly defined when
the error function is called (in particular if the lexer reached EOF).
While this might just cause non-printable characters in the output, it
could actually lead to a crash depending on where `yytext` points.

Closes strongswan/strongswan#346.
2021-05-11 10:08:58 +02:00
Noel Kuntze cf6a164108 testing: Replace kvm with qemu-system-x86_64
It might not exist on all platforms and according to the man page:

  The kvm wrapper script is used to provide compatibility with old
  qemu-kvm package which has been merged into qemu as of version 1.3.

  The script executes
    qemu-system-x86_64 -enable-kvm
  passing all other command-line arguments to the qemu binary.

Closes strongswan/strongswan#385.
2021-05-10 11:14:00 +02:00
Tobias Brunner 1eb2d149db testing: Use host-passthrough CPU mode for all KVM guests
This should give us the best performance and feature set on modern
hardware (in particular when compared to code2duo, which e.g. does not allow
nested virtualization).

Closes strongswan/strongswan#340.
2021-05-10 10:04:28 +02:00
Tobias Brunner d4c337a42f Use Botan 2.18.0 for tests 2021-05-07 14:48:17 +02:00
Adrian-Ken Rueegsegger f0c25960ed openssl: Consider authorityKeyIdentifier in issued_by()
Prior to verifying the cryptographic signature, check if the
authorityKeyIdentifier matches the key ID of the issuing certificate if
it is available.
2021-05-07 14:29:24 +02:00
Adrian-Ken Rueegsegger 027c5c9dcb x509: Consider authorityKeyIdentifier in issued_by()
Prior to verifying the cryptographic signature, check if the
authorityKeyIdentifier matches the key ID of the issuing certificate if
it is available.
2021-05-07 14:29:24 +02:00
Adrian-Ken Rueegsegger 97c9158378 openssl: Bring CRL issued_by() in line with x509 plugin 2021-05-07 14:29:24 +02:00
Adrian-Ken Rueegsegger 9f468f454a ike: Set DCSP on keepalive packets 2021-05-07 14:29:24 +02:00
Tobias Brunner 546f61d3c8 openssl: Add support for AES in CCM mode
While CCM is available in earlier versions, we only use it with
OpenSSL 1.1.0 and newer because the generic control variables are not
available before and we default to GCM for them.

Closes strongswan/strongswan#353.
2021-05-06 18:29:16 +02:00
Noel Kuntze 5191c2b063 testing: Make sure $SHAREDDIR exists before mounting it
Closes strongswan/strongswan#344.
2021-05-06 17:21:59 +02:00
Tobias Brunner a730873211 github: Fix python build and checks on older Ubuntu releases
On 18.04, setuptools was apparently pulled in by python-pip but is not
by python3-pip and on Ubuntu 16.04 there is an issue with tox when
installed via pip3 (syntax error in one of the dependencies) and with
pip that dependency is not even available.
2021-05-06 15:16:42 +02:00
Tobias Brunner 9535c3f778 wolfssl: Properly handle failure to initialize SHAKE_256 2021-05-06 11:47:38 +02:00
Tobias Brunner 2f650e085b github: Don't fail LGTM test with an error if variables are missing
That's because forks are currently not allowed to be analyzed by LGTM (unlike
with SonarCloud) so this check can't actually be successful for forks even if
variables are defined.

References strongswan/strongswan#328.
2021-05-05 19:11:38 +02:00
Noel Kuntze 260e7b55f6 github: Fail LGTM test if required environment variables aren't set
Closes strongswan/strongswan#328.
2021-05-05 18:12:25 +02:00
Tobias Brunner cd7b80e869 github: Make LGTM project ID configurable via environment variable 2021-05-05 18:09:44 +02:00
Noel Kuntze f830e71457 github: Fail sonarcloud test if required environment variables aren't set
Closes strongswan/strongswan#330.
2021-05-05 18:10:03 +02:00
Tobias Brunner c603704bb3 github: Always upload lint results from Android build 2021-05-05 18:09:44 +02:00
Tobias Brunner 742e0f213c github: Fix build on Ubuntu 20.04 and add a job for 18.04
The nm test can only be done on Ubuntu 18.04 as the required libraries
are not available on newer systems.

Switch to pip3 to install tox (the only Python dependency we use).

Closes strongswan/strongswan#327.
2021-05-05 18:09:44 +02:00
Tobias Brunner eca1b81682 github: Fix installation of Python dependencies 2021-05-05 18:08:20 +02:00
Tobias Brunner 6405653da2 android: Avoid lint errors when determining column indices
The lint version used on our GitHub build hosts reported these errors:

Error: Value must be ≥ 0 [Range]
        db.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + cursor.getLong(cursor.getColumnIndex(KEY_ID)), null);

That's because get*() expect a valid index >= 0 but getColumnIndex()
can return -1 if the column name doesn't exist.
2021-05-05 16:40:14 +02:00
Tobias Brunner f0a20dd2b8 backtrace: The BFD API changed in newer versions 2021-05-05 16:17:54 +02:00
Noel Kuntze 1de13f9037 openssl: Fix OpenSSL version check for EC_POINT_set_affine_coordinates
Fixes: bd323ae6c8 ("openssl: Migrate from deprecated EC_POINT_[set|get]_affine_coordinates_GFp() functions")
Closes strongswan/strongswan#332
2021-05-04 14:51:18 +02:00
Noel Kuntze e9a55abce4 forecast: Restrict strncpy() call
Closes strongswan/strongswan#331.
2021-05-04 14:48:53 +02:00
Tobias Brunner 2b89676157 Merge branch 'doxygen-fixes'
Closes strongswan/strongswan#326.
2021-05-04 14:39:56 +02:00
Noel Kuntze 4886a2c7d8
Doxyfile.in: Remove deprecated variables 2021-04-15 16:13:22 +02:00
Noel Kuntze a11efc5214
doxygen: Fix documentation problems 2021-04-15 00:17:59 +02:00
Andreas Steffen 09df86c033 Version bump to 5.9.3dr1 2021-03-31 09:59:55 +02:00
Andreas Steffen 66ba50b217 testing: Migrated p2pnat/medsrv-psk scenario to vici 2021-03-30 22:12:00 +02:00
Andreas Steffen 03e1272ff2 testing: Migrated p2pnat/behind-same-nat scenario to vici 2021-03-30 22:12:00 +02:00
Andreas Steffen 68154033bb testing: Store mars credentials in the swanctl directory 2021-03-30 22:12:00 +02:00
Andreas Steffen 2cbf7da51a testing: Migrated redirect-active scenario to vici 2021-03-30 22:12:00 +02:00
Andreas Steffen 511b860916 testing: Migrated ha/both-active scenario to vici 2021-03-30 18:57:49 +02:00
Andreas Steffen 5c22e94f0f testing: Migrated ha/active-passive scenario to vici 2021-03-30 18:57:49 +02:00
Andreas Steffen 737f7fce51 testing: Switched PTS measurements to /usr/sbin
Due to Debian 10 linking /bin to /usr/bin which drastically
increased the number of files in /bin, the PTS measurement
was switched to /usr/sbin with a lesser number of files.
2021-03-23 10:54:48 +01:00
Andreas Steffen f412c97648 wolfssl: Support SHAKE_256 2021-03-20 11:19:12 +01:00
Andreas Steffen a91eb3eb96 wolfssl: Support SHA3 2021-03-20 11:15:42 +01:00
Andreas Steffen b57215ba2b wolfssl: Support AES_ECB 2021-03-20 11:15:42 +01:00
Andreas Steffen bd323ae6c8 openssl: Migrate from deprecated EC_POINT_[set|get]_affine_coordinates_GFp() functions 2021-03-19 08:50:27 +01:00
Petr Gotthard c5eac9c390 libcharon: Include libtpmtss in monolithic build 2021-03-17 12:14:47 +01:00
Andreas Steffen 6aef079f59 testing: Bump guest kernel to Linux 5.11 2021-03-07 14:39:44 +01:00
4547 changed files with 37026 additions and 23419 deletions

View File

@ -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

View File

@ -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

View File

@ -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 }}

View File

@ -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:

View File

@ -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
View File

@ -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

View File

@ -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 ##

View File

@ -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

View File

@ -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)

View File

@ -28,8 +28,6 @@
/**
* Initialize the NetworkManager backend.
*
* @return TRUE, if initialization was successful
*/
void nm_backend_register();

View File

@ -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*,

View File

@ -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;
}

View File

@ -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_ @}*/

View File

@ -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);

View File

@ -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;
}

View File

@ -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.

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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)
{

View File

@ -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.

View File

@ -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.

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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);
}
/**

View File

@ -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 {

View File

@ -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

View File

@ -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;
}

View File

@ -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_ @}*/

View File

@ -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;
}

View File

@ -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_ @}*/

View File

@ -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;

View File

@ -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(

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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()

View File

@ -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

View File

@ -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
{

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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
*/

View File

@ -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.
*

View File

@ -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))

View File

@ -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);

View File

@ -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);
}

View File

@ -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));
}
/**

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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]",

View File

@ -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);

View File

@ -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)

View File

@ -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
*/

View File

@ -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 */

View File

@ -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;
}

View File

@ -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:

View File

@ -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);
}

View File

@ -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.
*

View File

@ -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:

View File

@ -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.

View File

@ -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_

View File

@ -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_

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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),

View File

@ -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:

View File

@ -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:

View File

@ -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)
{

View File

@ -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));
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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
{

View File

@ -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));
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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_ @}*/

View File

@ -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 */

View File

@ -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();
}

View File

@ -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);
}
/**

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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