Hi,
with a lot of help from Martin, I managed to setup smartcard support in
strongSwan 4.5.0 ikev2 (NM). To do so, I had to apply some patches
to the strongSwan sourcecode [1].
>From these patches, I created one patch against the current stable
version of strongSwan 4.5.0, which includes all patches that I got from
Martin. I have attached the patch to this email. With this patched
strongSwan Version smartcard support is working fine for me.
However, I found the following, when I use the current snapshot of
strongSwan. For some reason, the private key on the smartcard is no
longer found and finally the connection fails, see the logs below.
The same Crypto-Stick is working with the patched Version of strongswan
4.5.0. The only difference I see is, that one certificate is untrusted
in the logs of the snapshot version.
Thanks
peter
client.log:
00[DMN] Starting IKEv2 charon daemon (strongSwan 4.5.0-185-g6aa144d)
00[CFG] loaded PKCS#11 v2.20 library 'openSC' (/usr/lib/opensc-pkcs11.so)
00[CFG] OpenSC (www.opensc-project.org): Smart card PKCS#11 API v0.0
00[CFG] found token in slot 'openSC':5 (Feitian SCR301 01 00)
00[CFG] MoPo SC (User PIN) (EnterSafe: PKCS#15)
00[CFG] loaded untrusted cert 'Certificate'
00[CFG] loaded trusted cert 'Certificate'
...
00[DMN] loaded plugins: random x509 revocation pubkey pkcs1 pgp pem
openssl agent pkcs11 xcbc hmac attr kernel-netlink resolve
socket-default eap-md5 eap-gtc eap-mschapv2 nm
00[JOB] spawning 16 worker threads
06[CFG] received initiate for NetworkManager connection Crypto Stick
06[CFG] using gateway certificate, identity 'C=DE, O=Uni, CN=vpn.de'
06[CFG] found key on PKCS#11 token 'openSC':5
06[CFG] using smartcard certificate '[email protected]'
06[IKE] initiating IKE_SA Mobile Pools Crypto Stick[1] to 10.1.0.2
06[ENC] generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP)
N(NATD_D_IP) ]
06[NET] sending packet: from 10.205.4.184[500] to 10.1.0.2[500]
11[NET] received packet: from 10.1.0.2[500] to 10.205.4.184[500]
11[ENC] parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP)
N(NATD_D_IP) CERTREQ N(MULT_AUTH) ]
11[IKE] received cert request for "C=DE, O=Uni, CN=CA"
11[IKE] sending cert request for "C=DE, O=Uni, CN=CA"
11[IKE] no private key found for '[email protected]'
NetworkManager[927]: <warn> VPN plugin failed: 0
pkcs15-tool --list-pins --list-keys --list-certificates
X.509 Certificate [Certificate]
Flags : 2
Authority: no
Path : 3f0050153100
ID : c43dab133732791b034c327598877219cddaf116
Encoded serial: 02 02 190E
X.509 Certificate [Certificate]
Flags : 2
Authority: yes
Path : 3f0050153101
ID : 366549997716cc5bdd87a7db215b1142808fbbcc
Encoded serial: 02 01 00
Private RSA Key [Private Key]
Com. Flags : 3
Usage : [0x4], sign
Access Flags: [0x0]
ModLength : 1024
Key ref : 1
Native : yes
Path : 3f005015
Auth ID : 01
ID : 8f1f90a190e89feb7b144c5a900c36336b8f024e
PIN [User PIN]
Com. Flags: 0x3
ID : 01
Flags : [0x32], local, initialized, needs-padding
Length : min_len:4, max_len:16, stored_len:16
Pad char : 0x00
Reference : 1
Type : ascii-numeric
Path : 3f005015
[1]https://lists.strongswan.org/pipermail/users/2010-December/005669.html
diff -crB strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c
*** strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c 2010-08-08 14:28:56.000000000 +0200
--- strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c 2010-11-26 10:57:16.000000000 +0100
***************
*** 62,68 ****
CK_ATTRIBUTE tmpl[] = {
{CKA_CLASS, &class, sizeof(class)},
{CKA_CERTIFICATE_TYPE, &type, sizeof(type)},
- {CKA_TRUSTED, &trusted, sizeof(trusted)},
};
CK_OBJECT_HANDLE object;
CK_ATTRIBUTE attr[] = {
--- 62,67 ----
***************
*** 136,142 ****
}
find_certificates(this, session, CK_TRUE);
- find_certificates(this, session, CK_FALSE);
this->lib->f->C_CloseSession(session);
return TRUE;
--- 135,140 ----
diff -crB strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_library.c strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
*** strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_library.c 2010-08-06 06:01:38.000000000 +0200
--- strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_library.c 2010-11-26 10:57:16.000000000 +0100
***************
*** 466,471 ****
--- 466,476 ----
* Name as passed to the constructor
*/
char *name;
+
+ /**
+ * Supported feature set
+ */
+ pkcs11_feature_t features;
};
METHOD(pkcs11_library_t, get_name, char*,
***************
*** 474,479 ****
--- 479,490 ----
return this->name;
}
+ METHOD(pkcs11_library_t, get_features, pkcs11_feature_t,
+ private_pkcs11_library_t *this)
+ {
+ return this->features;
+ }
+
/**
* Object enumerator
*/
***************
*** 766,784 ****
}
/**
* Initialize a PKCS#11 library
*/
! static bool initialize(private_pkcs11_library_t *this, char *name, char *file)
{
CK_C_GetFunctionList pC_GetFunctionList;
CK_INFO info;
CK_RV rv;
! CK_C_INITIALIZE_ARGS args = {
.CreateMutex = CreateMutex,
.DestroyMutex = DestroyMutex,
.LockMutex = LockMutex,
.UnlockMutex = UnlockMutex,
};
pC_GetFunctionList = dlsym(this->handle, "C_GetFunctionList");
if (!pC_GetFunctionList)
--- 777,821 ----
}
/**
+ * Check if the library has at least a given cryptoki version
+ */
+ static bool has_version(CK_INFO *info, int major, int minor)
+ {
+ return info->cryptokiVersion.major > major ||
+ (info->cryptokiVersion.major == major &&
+ info->cryptokiVersion.minor >= minor);
+ }
+
+ /**
+ * Check for optional PKCS#11 library functionality
+ */
+ 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;
+ }
+ }
+
+ /**
* Initialize a PKCS#11 library
*/
! static bool initialize(private_pkcs11_library_t *this, char *name, char *file,
! bool os_locking)
{
CK_C_GetFunctionList pC_GetFunctionList;
CK_INFO info;
CK_RV rv;
! static CK_C_INITIALIZE_ARGS args = {
.CreateMutex = CreateMutex,
.DestroyMutex = DestroyMutex,
.LockMutex = LockMutex,
.UnlockMutex = UnlockMutex,
};
+ static CK_C_INITIALIZE_ARGS args_os = {
+ .flags = CKF_OS_LOCKING_OK,
+ };
pC_GetFunctionList = dlsym(this->handle, "C_GetFunctionList");
if (!pC_GetFunctionList)
***************
*** 793,806 ****
name, ck_rv_names, rv);
return FALSE;
}
!
! rv = this->public.f->C_Initialize(&args);
! if (rv == CKR_CANT_LOCK)
! { /* try OS locking */
! memset(&args, 0, sizeof(args));
! args.flags = CKF_OS_LOCKING_OK;
rv = this->public.f->C_Initialize(&args);
}
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_Initialize() error for '%s': %N",
--- 830,848 ----
name, ck_rv_names, rv);
return FALSE;
}
! if (os_locking)
! {
! rv = CKR_CANT_LOCK;
! }
! else
! {
rv = this->public.f->C_Initialize(&args);
}
+ if (rv == CKR_CANT_LOCK)
+ { /* fallback to OS locking */
+ os_locking = TRUE;
+ rv = this->public.f->C_Initialize(&args_os);
+ }
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_Initialize() error for '%s': %N",
***************
*** 826,848 ****
DBG1(DBG_CFG, " %s: %s v%d.%d",
info.manufacturerID, info.libraryDescription,
info.libraryVersion.major, info.libraryVersion.minor);
! if (args.flags & CKF_OS_LOCKING_OK)
{
DBG1(DBG_CFG, " uses OS locking functions");
}
return TRUE;
}
/**
* See header
*/
! pkcs11_library_t *pkcs11_library_create(char *name, char *file)
{
private_pkcs11_library_t *this;
INIT(this,
.public = {
.get_name = _get_name,
.create_object_enumerator = _create_object_enumerator,
.create_mechanism_enumerator = _create_mechanism_enumerator,
.destroy = _destroy,
--- 868,893 ----
DBG1(DBG_CFG, " %s: %s v%d.%d",
info.manufacturerID, info.libraryDescription,
info.libraryVersion.major, info.libraryVersion.minor);
! if (os_locking)
{
DBG1(DBG_CFG, " uses OS locking functions");
}
+
+ check_features(this, &info);
return TRUE;
}
/**
* See header
*/
! pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_locking)
{
private_pkcs11_library_t *this;
INIT(this,
.public = {
.get_name = _get_name,
+ .get_features = _get_features,
.create_object_enumerator = _create_object_enumerator,
.create_mechanism_enumerator = _create_mechanism_enumerator,
.destroy = _destroy,
***************
*** 858,864 ****
return NULL;
}
! if (!initialize(this, name, file))
{
dlclose(this->handle);
free(this);
--- 903,909 ----
return NULL;
}
! if (!initialize(this, name, file, os_locking))
{
dlclose(this->handle);
free(this);
diff -crB strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_library.h strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
*** strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_library.h 2010-08-06 06:01:38.000000000 +0200
--- strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_library.h 2010-11-26 10:57:16.000000000 +0100
***************
*** 21,26 ****
--- 21,27 ----
#ifndef PKCS11_LIBRARY_H_
#define PKCS11_LIBRARY_H_
+ typedef enum pkcs11_feature_t pkcs11_feature_t;
typedef struct pkcs11_library_t pkcs11_library_t;
#include "pkcs11.h"
***************
*** 29,34 ****
--- 30,45 ----
#include <utils/enumerator.h>
/**
+ * 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),
+ };
+
+ /**
* A loaded and initialized PKCS#11 library.
*/
struct pkcs11_library_t {
***************
*** 46,51 ****
--- 57,69 ----
char* (*get_name)(pkcs11_library_t *this);
/**
+ * Get the feature set supported by this library.
+ *
+ * @return ORed set of features supported
+ */
+ pkcs11_feature_t (*get_features)(pkcs11_library_t *this);
+
+ /**
* Create an enumerator over CK_OBJECT_HANDLE using a search template.
*
* An optional attribute array is automatically filled in with the
***************
*** 103,110 ****
*
* @param name an arbitrary name, for debugging
* @param file pkcs11 library file to dlopen()
* @return library abstraction
*/
! pkcs11_library_t *pkcs11_library_create(char *name, char *file);
#endif /** PKCS11_LIBRARY_H_ @}*/
--- 121,129 ----
*
* @param name an arbitrary name, for debugging
* @param file pkcs11 library file to dlopen()
+ * @param os_lock enforce OS Locking for this library
* @return library abstraction
*/
! pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_lock);
#endif /** PKCS11_LIBRARY_H_ @}*/
diff -crB strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
*** strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c 2010-09-02 22:29:43.000000000 +0200
--- strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c 2010-11-26 10:57:16.000000000 +0100
***************
*** 373,379 ****
free(entry);
continue;
}
! entry->lib = pkcs11_library_create(module, entry->path);
if (!entry->lib)
{
free(entry);
--- 373,382 ----
free(entry);
continue;
}
! entry->lib = pkcs11_library_create(module, entry->path,
! lib->settings->get_bool(lib->settings,
! "libstrongswan.plugins.pkcs11.modules.%s.os_locking",
! FALSE, module));
if (!entry->lib)
{
free(entry);
diff -crB strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
*** strongswan-4.5.0/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c 2010-08-20 06:24:11.000000000 +0200
--- strongswan-4.5.0-patched/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c 2010-12-01 19:46:02.430530042 +0100
***************
*** 401,418 ****
};
CK_OBJECT_HANDLE object;
CK_KEY_TYPE type;
! CK_BBOOL reauth;
CK_ATTRIBUTE attr[] = {
{CKA_KEY_TYPE, &type, sizeof(type)},
- {CKA_ALWAYS_AUTHENTICATE, &reauth, sizeof(reauth)},
{CKA_MODULUS, NULL, 0},
{CKA_PUBLIC_EXPONENT, NULL, 0},
};
enumerator_t *enumerator;
chunk_t modulus, pubexp;
enumerator = this->lib->create_object_enumerator(this->lib,
! this->session, tmpl, countof(tmpl), attr, countof(attr));
if (enumerator->enumerate(enumerator, &object))
{
switch (type)
--- 401,425 ----
};
CK_OBJECT_HANDLE object;
CK_KEY_TYPE type;
! CK_BBOOL reauth = FALSE;
CK_ATTRIBUTE attr[] = {
{CKA_KEY_TYPE, &type, sizeof(type)},
{CKA_MODULUS, NULL, 0},
{CKA_PUBLIC_EXPONENT, NULL, 0},
+ {CKA_ALWAYS_AUTHENTICATE, &reauth, sizeof(reauth)},
};
enumerator_t *enumerator;
chunk_t modulus, pubexp;
+ int count = countof(attr);
+ /* do not use CKA_ALWAYS_AUTHENTICATE if not supported */
+ if (!(this->lib->get_features(this->lib) & PKCS11_ALWAYS_AUTH_KEYS))
+ {
+ count--;
+ }
+
enumerator = this->lib->create_object_enumerator(this->lib,
! this->session, tmpl, countof(tmpl), attr, count);
if (enumerator->enumerate(enumerator, &object))
{
switch (type)
_______________________________________________
Users mailing list
[email protected]
https://lists.strongswan.org/mailman/listinfo/users