Project

General

Profile

Bug #1012

strongSwan 5.x - charon can't access privkey of certain smartcards

Added by Jacques Henry over 5 years ago. Updated about 5 years ago.

Status:
Closed
Priority:
Normal
Category:
charon
Target version:
Start date:
29.06.2015
Due date:
Estimated time:
Affected version:
5.3.2
Resolution:
Fixed

Description

Hello,

I successfully set up my smartcard to work with Strongswan 4.5.2 on my Ubuntu 12.04.5.

I am trying to do the same thing on an Ubuntu 14.04 with Strongswan 5.1.2 (and 5.3.2 built myself). The thing is that charon doesn't load the private key from the smartcard:

Again, I remind that it works fine on Strongswan 4.5.2.

My smarcard contains the following objects:

root@ubuntu:~/strongswan-5.3.2# pkcs11-tool --module=/usr/lib/libidprimepkcs11.so  -O -l -p 246812
Using slot 0 with a present token (0x0)
Certificate Object, type = X.509 cert
  label:      31337
  ID:         42
Public Key Object; RSA 2048 bits
  label:      31337
  ID:         42
  Usage:      verify
Private Key Object; RSA 
  label:      31337
  ID:         42
  Usage:      sign

The usage is the following:

root@ubuntu:~/strongswan-5.3.2# ipsec listcerts

List of X.509 End Entity Certificates:

  subject:  "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=jacques, E=jacques@henry.fr" 
  issuer:   "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=MYPKI, E=pki@company.fr" 
  serial:    0c
  validity:  not before Aug 04 14:49:29 2014, ok
             not after  Aug 03 14:49:29 2017, ok 
  pubkey:    RSA 2048 bits
  keyid:     30:45:14:91:1b:dd:d1:61:1b:f8:62:ce:2c:ba:f1:96:04:26:82:4e
  subjkey:   c1:c3:72:96:86:8d:e3:97:5d:1e:32:d5:4b:17:ba:f8:04:a5:b4:65
  authkey:   51:58:7e:24:9d:55:3c:f6:3b:24:c1:e2:ea:db:9d:32:e6:15:c5:00

root@ubuntu:~/strongswan-5.3.2# ipsec secrets
Login to '%smartcard0:42' required
PIN: 
root@ubuntu:~/strongswan-5.3.2# ipsec listcerts

List of X.509 End Entity Certificates:

  subject:  "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=jacques, E=jacques@henry.fr" 
  issuer:   "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=MYPKI, E=pki@company.fr" 
  serial:    0c
  validity:  not before Aug 04 14:49:29 2014, ok
             not after  Aug 03 14:49:29 2017, ok 
  pubkey:    RSA 2048 bits
  keyid:     30:45:14:91:1b:dd:d1:61:1b:f8:62:ce:2c:ba:f1:96:04:26:82:4e
  subjkey:   c1:c3:72:96:86:8d:e3:97:5d:1e:32:d5:4b:17:ba:f8:04:a5:b4:65
  authkey:   51:58:7e:24:9d:55:3c:f6:3b:24:c1:e2:ea:db:9d:32:e6:15:c5:00

As you can see, the PIN was asked, but the "ipsec listcerts" doesn't show the ",has private key" label like it should do...
So when I try to bring my tunnel up:

root@ubuntu:~/strongswan-5.3.2# ipsec up mytunnel
initiating IKE_SA mytunnel[2] to 10.10.10.10
generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(HASH_ALG) ]
sending packet: from 192.168.0.37[500] to 10.10.10.10[500] (704 bytes)
received packet: from 10.10.10.10[500] to 192.168.0.37[500] (672 bytes)
parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) ]
local host is behind NAT, sending keep alives
sending cert request for "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=MYPKI, E=pki@company.fr" 
no private key found for 'C=FR, ST=France, O=COMPANY, OU=MYOU, CN=jacques, E=jacques@henry.fr'
establishing connection 'mytunnel' failed

The log shows the following when I launch the "ipsec secrets" command:

Jun 29 17:41:58 14[CFG] rereading secrets
Jun 29 17:41:58 14[CFG] loading secrets from '/etc/ipsec.secrets'
Jun 29 17:41:58 14[CFG] found key on PKCS#11 token 'libidprime':0
Jun 29 17:42:03 14[CFG]   loaded private key from %smartcard0:42

But during the "ipsec up" command:

Jun 29 17:42:20 04[IKE] <mytunnel|2> sending cert request for "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=MYPKI, E=pki@company.fr" 
Jun 29 17:42:20 04[ENC] <mytunnel|2> added payload of type CERTREQ to message
Jun 29 17:42:20 04[ENC] <mytunnel|2> added payload of type NOTIFY to message
Jun 29 17:42:20 04[ENC] <mytunnel|2> added payload of type ID_RESPONDER to message
Jun 29 17:42:20 04[ENC] <mytunnel|2> added payload of type ID_INITIATOR to message
Jun 29 17:42:20 04[ENC] <mytunnel|2> added payload of type NOTIFY to message
Jun 29 17:42:20 01[JOB] next event in 3s 889ms, waiting
Jun 29 17:42:20 04[IKE] <mytunnel|2> no private key found for 'C=FR, ST=France, O=COMPANY, OU=MYOU, CN=jacques, E=jacques@henry.fr'
Jun 29 17:42:20 04[MGR] <mytunnel|2> checkin and destroy IKE_SA mytunnel[2]
Jun 29 17:42:20 04[IKE] <mytunnel|2> IKE_SA mytunnel[2] state change: CONNECTING => DESTROYING
Jun 29 17:42:20 04[MGR] check-in and destroy of IKE_SA successful

It's like it "erased" or "forgot" the private key it successfully loaded before...!

Any idea?

Thanks in advance!

pkcs11-debug.patch (2.61 KB) pkcs11-debug.patch Tobias Brunner, 02.07.2015 11:38
charon.log (140 KB) charon.log Jacques Henry, 02.07.2015 13:59

Associated revisions

Revision b2efc618 (diff)
Added by Tobias Brunner over 5 years ago

pkcs11: Fix encoding of RSA keys if unnecessarily zero prefixed

Some tokens/libraries seem to prefix all numbers with zero bytes even
if not necessary (e.g. the default exponent 0x010001). If we don't fix
that, the fingerprints calculated based on the retrieved values will be
incorrect.

Even if the pkcs1 plugin can properly handle numbers that are not in
two's complement since a81bd670b086 ("Added PUBKEY_RSA_MODULUS
encoding type") we prefix them with zero if necessary as other encoders
might expect them in two's complement.

Fixes #1012.

History

#1 Updated by Tobias Brunner over 5 years ago

  • Status changed from New to Feedback

As you can see, the PIN was asked, but the "ipsec listcerts" doesn't show the ",has private key" label like it should do...

Yes, you should definitely see that if it worked correctly. The lookup for the private key is done via the SHA-1 hash of the public key in the certificate (subjkey). This is matched against the fingerprint of the public key associated with the private key. That public key is loaded from the smart card using the same CKA_ID used to load the private key (if no public key is found, it would be loaded from a certificate with the given ID). Not sure what could go wrong there. Does the public key stored on the card actually match the private key and the public key in the certificate?

#2 Updated by Jacques Henry over 5 years ago

Does the public key stored on the card actually match the private key and the public key in the certificate?

Yes I am absolutely sure the private key matches the public key in the certificate. The private key (and of course the public) has been generated on-board. Our mechanism only allow a certificate to be stored on the smartcard if they match.

Using the same smartcard on a Ubuntu 12.04 with Strongswan 4.5.2, this is what I get after a successful 'ipsec secrets' command:

# ipsec listcerts
000  
000 List of X.509 End Entity Certificates:
000  
000   subject:  "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=jacques, E=jacques@henry.fr" 
000   issuer:   "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=MYPKI, E=pki@company.fr" 
000   serial:    0c
000   validity:  not before Aug 04 14:49:29 2014 ok
000              not after  Aug 03 14:49:29 2017 ok
000   pubkey:    RSA 2048 bits, has private key
000   keyid:     30:45:14:91:1b:dd:d1:61:1b:f8:62:ce:2c:ba:f1:96:04:26:82:4e
000   subjkey:   c1:c3:72:96:86:8d:e3:97:5d:1e:32:d5:4b:17:ba:f8:04:a5:b4:65
000   authkey:   51:58:7e:24:9d:55:3c:f6:3b:24:c1:e2:ea:db:9d:32:e6:15:c5:00

#3 Updated by Tobias Brunner over 5 years ago

Does the public key stored on the card actually match the private key and the public key in the certificate?

Yes I am absolutely sure the private key matches the public key in the certificate. The private key (and of course the public) has been generated on-board. Our mechanism only allow a certificate to be stored on the smartcard if they match.

Then I'd recommend you debug the pkcs11 plugin to see why that lookup fails (perhaps getting the fingerprint from the public key associated with the private key fails).

Using the same smartcard on a Ubuntu 12.04 with Strongswan 4.5.2, this is what I get after a successful 'ipsec secrets' command:

You can't really compare these (at least not if you use IKEv1). The PKCS#11 code is totally different in pluto and charon.

#4 Updated by Jacques Henry over 5 years ago

You can't really compare these (at least not if you use IKEv1). The PKCS#11 code is totally different in pluto and charon.

No I am using charon in both tests cases (IKEv2) with the same ipsec.conf and ipsec.secrets files.

I will see what I can to debug myself the pkcs11 plugin...

#5 Updated by Tobias Brunner over 5 years ago

You can't really compare these (at least not if you use IKEv1). The PKCS#11 code is totally different in pluto and charon.

No I am using charon in both tests cases (IKEv2) with the same ipsec.conf and ipsec.secrets files.

OK. I went through the changes and saw that the key lookup changed with 4.6.0 (5d2fccf439, 30a3ede8ce and ffe42fa405, which was released with 5.0.2) the problem might be related to that.

I will see what I can to debug myself the pkcs11 plugin...

I'd start with pkcs11_private_key_connect and see if the public key is actually loaded directly from the token or extracted from the certificate. Then I'd have a look at the appropriate implementation of get_fingerprint (in pkcs11_public_key.c or, if the key is from a certificate, another public key implementation, depending on the loaded plugins) to see if the fingerprint calculation is successful and results in a matching value.

#6 Updated by Jacques Henry over 5 years ago

Thanks for the trails.

I'd start with pkcs11_private_key_connect and see if the public key is actually loaded directly from the token or extracted from the certificate.

The public key is loaded directly from the token (I have the debug message found key on PKCS#11 token from find_lib_by_keyid)

#7 Updated by Tobias Brunner over 5 years ago

I'd start with pkcs11_private_key_connect and see if the public key is actually loaded directly from the token or extracted from the certificate.

The public key is loaded directly from the token (I have the debug message found key on PKCS#11 token from find_lib_by_keyid)

find_lib_by_keyid logs the same message whether it finds a public key or a certificate with the given CKA_ID. Loading the actual public key comes later (via pkcs11_public_key_connect or find_pubkey_in_certs). And if the key is loaded successfully the question is why its SHA-1 hash would be different.

#8 Updated by Jacques Henry over 5 years ago

Well I am a little bit stuck here :-(

The private key is loaded from the smartcard: the load_pin function is successful, hence the load_secrets as well. The credentials are updated (at the end of load_secrets with replace_secrets)

However the get_private function in credential_manager.c fails: all the attempts to get_private_by_cert fail.

In get_private_by_cert it extracts the public key from the certificate and then compute a keyid (SHA1 fingerprint) from it and then search for the corresponding private key using get_private_by_keyid. For a reason I don't understand, and from my understanding, it doesn't find a private key corresponding to the keyid.

I noticed that the keyid passed to get_private_by_keyid is c1:c3:72:... which is the subjkey: (see my previous post) and not the keyid: value. That seemed odd to at the first time me but in 4.5.2 it is the same value which is used to retrieve the private key...

#9 Updated by Jacques Henry over 5 years ago

Loading the actual public key comes later (via pkcs11_public_key_connect or find_pubkey_in_certs). And if the key is loaded successfully the question is why its SHA-1 hash would be different.

pkcs11_public_key_connect is successful (so find_pubkey_in_certs is not called)

#10 Updated by Tobias Brunner over 5 years ago

In get_private_by_cert it extracts the public key from the certificate and then compute a keyid (SHA1 fingerprint) from it and then search for the corresponding private key using get_private_by_keyid. For a reason I don't understand, and from my understanding, it doesn't find a private key corresponding to the keyid.

Exactly, here you should check what happens in the get_fingerprint method in pkcs11_public_key.c (plus encode_rsa and perhaps even further down the call path, e.g. pkcs1_encode.c). Does that produce the same hash (c1:c3:72...)? Most likely not, so try to determine if perhaps the exponent or modulus (e/n) are different when the hash is calculated for this public key compared to when get_fingerprint is called for the certificate's public key e.g. in list_public_key of stroke_list.c (the call path there will be via gmp_rsa_public_key.c (or openssl_rsa_public_key.c depending on loaded plugins) but probably end up in pkcs1_encode.c too).

I noticed that the keyid passed to get_private_by_keyid is c1:c3:72:... which is the subjkey: (see my previous post) and not the keyid: value.

That's correct, subjkey is the SHA-1 hash of the public key (KEYID_PUBKEY_SHA1), while keyid is the SHA-1 hash of the complete subjectPublicKeyInfo structure (KEYID_PUBKEY_INFO_SHA1). For private key lookups KEYID_PUBKEY_SHA1 is used.

#11 Updated by Jacques Henry over 5 years ago

(the call path there will be via gmp_rsa_public_key.c (or openssl_rsa_public_key.c depending on loaded plugins)

The call path gets to openssl_rsa_public_key.c (I've enable the openssl plugin)

In get_private_key_by_cert I can see the fingerprint (in chunk) which is always c1:c3:72...

#12 Updated by Jacques Henry over 5 years ago

I noticed I never go in pkcs11_public_key_load in pkcs11_public_key.c. Is that a normal behaviour?

#13 Updated by Tobias Brunner over 5 years ago

I noticed I never go in pkcs11_public_key_load in pkcs11_public_key.c. Is that a normal behaviour?

Yes, that function is only used when you enable charon.plugins.pkcs11.use_pubkey (public key operations, also for certificates and keys not loaded from tokens, will then be performed on the token instead of in a plugin like openssl).

The call path gets to openssl_rsa_public_key.c (I've enable the openssl plugin)

In get_private_key_by_cert I can see the fingerprint (in chunk) which is always c1:c3:72...

I'm not exactly sure what function you refer to, but what about get_fingerprint/encode_rsa in pkcs11_public_key.c? I've attached a patch that prints out some messages there (and in the openssl plugin to compare them to).

By the way, to print identities (via DBG1() or fprintf() etc.) use %Y, chunks can also be printed via %B or %#B (pass a pointer to a chunk).

#14 Updated by Jacques Henry over 5 years ago

Thanks for your input.
I was able to print some debugging values, but it remains hard to interpret them...

I'm not exactly sure what function you refer to, but what about get_fingerprint/encode_rsa in pkcs11_public_key.c?

Yes

I've attached an extract of the Charon log. Already at the beginning of the file the hash values for the RSA Pub Key are not the same...

#15 Updated by Tobias Brunner over 5 years ago

Thanks for the log.

Already at the beginning of the file the hash values for the RSA Pub Key are not the same...

If you mean the first hash (30:45:...), that's because a different kind of fingerprint is calculated there (KEYID_PUBKEY_INFO_SHA1 instead of KEYID_PUBKEY_SHA1), so that's fine.

The actual problem is the exponent value. For some reason the exponent returned by the token in encode_rsa is prefixed with a zero byte:

Jul  2 13:45:25 14[LIB] <mytunnel|1> e => 4 bytes @ 0x7fa7c4004840
Jul  2 13:45:25 14[LIB] <mytunnel|1>    0: 00 01 00 01                                      ....

vs. the following from the certificate:

Jul  2 13:45:25 06[LIB] e => 3 bytes @ 0x7fa7cc001f30
Jul  2 13:45:25 06[LIB]    0: 01 00 01                                         ...

As the pkcs1 plugin uses this value pretty much as is to calculate the SHA-1 hash of the public key the end result won't be the same. I wonder what the intention of the PKCS#11 library or the token is. According to PKCS#11 the data type of CKA_PUBLIC_EXPONENT is Big integer, which is defined as

a string of CK_BYTEs representing an unsigned
integer of arbitrary size, most-significant byte first
(e.g., the integer 32768 is represented as the 2-byte
string 0x80 0x00)

So the value is by definition always positive, there is no need to force a two's complement positive number by prefixing all values with zero (if that was the idea). And the first bit of 0x010001 (65537) is not set, so no zero byte prefix is necessary in the two's complement representation (this is different for the modulus that starts with 0xD4).

The reason why this worked in earlier releases (i.e. before 4.6.0 or 5d2fccf439) is that a raw public key object was created from the modulus and exponent retrieved from the private key object (now we directly interact with the public key on the token). The values were passed to a registered plugin (e.g. openssl or gmp) that actually converted the given binary values to integers (via BN_bin2bn() or mpz_import(), respectively). These integers were then encoded again when the fingerprint was calculated, so the additional zero byte just disappeared.

I guess we could just remove the zero bytes and pass the values along to the encoder. I even saw that since 5.2.0 (or a81bd670b0) the pkcs1 plugin properly converts the passed values to ASN.1 integers. So we could probably also remove the current fixup for numbers that have the first bit set. However, I think the general convention is to pass integers in two's complement to CRED_PART_RSA_MODULUS and CRED_PART_RSA_PUB_EXP (that's what all other plugins do anyway). The patch in the pkcs11-zero-prefix branch removes zero bytes from the modulus and exponent but prefixes them again if necessary. Let me know if this works for you.

#16 Updated by Jacques Henry over 5 years ago

If you mean the first hash (30:45:...), that's because a different kind of fingerprint is calculated there (KEYID_PUBKEY_INFO_SHA1 instead of KEYID_PUBKEY_SHA1), so that's fine.

Yes, 2 minutes after updating the thread I also printed the type and saw the difference.

The actual problem is the exponent value. For some reason the exponent returned by the token in encode_rsa is prefixed with a zero byte:

Good catch! I didn't see it myself

As the pkcs1 plugin uses this value pretty much as is to calculate the SHA-1 hash of the public key the end result won't be the same. I wonder what the intention of the PKCS#11 library or the token is. According to PKCS#11 the data type of CKA_PUBLIC_EXPONENT is Big integer, which is defined as

Yes, the standard is pretty clear about this. The PKCS#11 documents even show examples with the value 0x010001

However "real world" examples show frequently the usual exponent with a 0x00010001 value:
https://dnssec.surfnet.nl/?p=873
http://www.dkgev.de/pdf/1007.pdf
...

Even our home-made tool shows that when dumping the raw public key:

1 Slot(s) detected
Session Opening
Public Key data:
        Modulus bits: 2048
        Modulus: d4c663a54080409927f891cf812ddcef205bbd5fbaa5b9577621d1d0510865aec34fb251ab2e904dd82120da24624fa9a20cd0199fd213732eede4fdeaa24d15c8b4191c4503962cb9b5d13cc94cdb535b6640cf73ad69b4c25218d901cce73a350ccd0106c32bee348a5fbad05f91dfcaa2b2ed5ebae36ab3af086e3a185bfdc31559a1b53b9a384bf8c120e21b5045f012bcc05922165d7e0110482d2f4cdbc93644a8bc50b55b780517348990834e64962b4fd9491df3c92e474233ad49e95499db93d9f0fb04ca86dae1571c2ecc89ee8a72d52f7098e75c1d6fab4af3ad7a5a6848cc590ca8568cb2af0cfb574e56390edce5221553d7694c70397ce1eb
        Public Exponent: 00010001
Session Closing

Thank you very much for the detailed explanations.

So I applied the patch, and it is working fine! (the tunnel is up)

However, the output of listcerts still doesn't show "has private key". Below an example in which I also have a certificate and a private key as files:
(the first certificate is on the smartcard, the second one as a file)

ubuntu:~/strongswan-5.3.2# ipsec listcerts

List of X.509 End Entity Certificates:

  subject:  "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=jacques, E=jacques@henry.fr" 
  issuer:   "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=MYPKI, E=pki@company.fr" 
  serial:    0c
  validity:  not before Aug 04 14:49:29 2014, ok
             not after  Aug 03 14:49:29 2017, ok 
  pubkey:    RSA 2048 bits
  keyid:     30:45:14:91:1b:dd:d1:61:1b:f8:62:ce:2c:ba:f1:96:04:26:82:4e
  subjkey:   c1:c3:72:96:86:8d:e3:97:5d:1e:32:d5:4b:17:ba:f8:04:a5:b4:65
  authkey:   51:58:7e:24:9d:55:3c:f6:3b:24:c1:e2:ea:db:9d:32:e6:15:c5:00

  subject:  "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=henry, E=henry@henry.fr" 
  issuer:   "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=MYPKI, E=pki@company.fr" 
  serial:    03:95:b3:a6
  validity:  not before Dec 05 09:19:44 2013, ok
             not after  Dec 05 09:19:44 2016, ok 
  pubkey:    RSA 2048 bits, has private key
  keyid:     e3:06:54:e8:44:c8:ad:0a:61:bf:9c:0f:6c:3e:49:73:a9:7a:4e:13
  subjkey:   85:0a:fd:83:0b:7a:5b:9a:f1:3d:79:33:0f:11:c3:48:03:62:f0:e7
  authkey:   09:f5:ab:ba:76:23:51:93:c9:57:c2:c6:ef:34:dd:92:e2:7d:c6:02@

And another thing which is still odd is when I display the statusall command.
The Security Association shows two SPIs:

ubuntu:~/strongswan-5.3.2# ipsec statusall
Status of IKE charon daemon (strongSwan 5.3.2, Linux 3.13.0-55-generic, x86_64):
  uptime: 14 seconds, since Jul 03 08:22:43 2015
  malloc: sbrk 2969600, mmap 0, used 696320, free 2273280
  worker threads: 10 of 16 idle, 6/0/0/0 working, job queue: 0/0/0/0, scheduled: 4
  loaded plugins: charon pkcs11 aes des rc2 sha1 sha2 md5 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp xcbc cmac hmac attr kernel-netlink resolve socket-default stroke updown xauth-generic
Listening IP addresses:
  192.168.0.37
Connections:
nomade-frontal:  %any...10.10.10.10  IKEv2, dpddelay=30s
nomade-frontal:   local:  [C=FR, ST=France, O=COMPANY, OU=MYOU, CN=jacques, E=jacques@henry.fr] uses public key authentication
nomade-frontal:    cert:  "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=jacques, E=jacques@henry.fr" 
nomade-frontal:   remote: [C=FR, ST=France, O=COMPANY, OU=MYOU, CN=gateway, E=gateway@henry.fr] uses public key authentication
nomade-frontal:    ca:    "C=FR, ST=France, O=COMPANY, OU=MYOU, CN=MYPKI, E=pki@company.fr" 
nomade-frontal:   child:  dynamic === 0.0.0.0/0 TUNNEL, dpdaction=restart
Security Associations (1 up, 0 connecting):
nomade-frontal[1]: ESTABLISHED 13 seconds ago, 192.168.0.37[C=FR, ST=France, O=COMPANY, OU=MYOU, CN=jacques, E=jacques@henry.fr]...10.10.10.10[C=FR, ST=France, O=COMPANY, OU=MYOU, CN=gateway, E=gateway@henry.fr]
nomade-frontal[1]: IKEv2 SPIs: 2f137dffceab9d84_i* 97dee809796e468e_r, rekeying in 23 hours
nomade-frontal[1]: IKE proposal: AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_4096
nomade-frontal{1}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: ce1b15da_i 799b08ee_o
nomade-frontal{1}:  AES_CBC_256/HMAC_SHA2_256_128, 0 bytes_i, 0 bytes_o, rekeying in 11 hours
nomade-frontal{1}:   172.19.0.3/32 === 0.0.0.0/0 
nomade-frontal{2}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: cb76f70f_i 799b08ef_o
nomade-frontal{2}:  AES_CBC_256/HMAC_SHA2_256_128, 0 bytes_i, 0 bytes_o, rekeying in 11 hours
nomade-frontal{2}:   172.19.0.3/32 === 0.0.0.0/0

IF I use the file certificate the security association shows:

Security Associations (1 up, 0 connecting):
nomade-frontal[1]: ESTABLISHED 93 seconds ago, 192.168.0.37[C=FR, ST=France, O=COMPANY, OU=MYOU, CN=henry, E=henry@henry.fr]...10.10.10.10[C=FR, ST=France, O=COMPANY, OU=MYOU, CN=gateway, E=gateway@henry.fr]
nomade-frontal[1]: IKEv2 SPIs: db00714ad9ee08e8_i* a752d9b07f6b8d61_r, rekeying in 23 hours
nomade-frontal[1]: IKE proposal: AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_4096
nomade-frontal{1}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: cfa5e902_i 799b08f0_o
nomade-frontal{1}:  AES_CBC_256/HMAC_SHA2_256_128, 0 bytes_i, 0 bytes_o, rekeying in 11 hours
nomade-frontal{1}:   172.19.0.3/32 === 0.0.0.0/0 @

#17 Updated by Jacques Henry over 5 years ago

Ouch, please forget my last remark about the 2 SPIs....
Since I added the PIN in ipsec.secrets (I was bored to type it each time I've reloaded it) and used auto=start, it wasn't necessary for me to do ipsec up mytunnel.... Hence the 2 SPIs...

#18 Updated by Jacques Henry over 5 years ago

You can also forget my first remark about the "has private key". I've done other tests (IKEv1 mainly) and since I see the flag in both scenarios...

So using your patch on 5.3.2 resolved the issue with my smartcard (IKEv1 and IKEv2)!

Tobias, many thanks for your support!

#19 Updated by Tobias Brunner over 5 years ago

  • Tracker changed from Issue to Bug
  • Status changed from Feedback to Resolved
  • Assignee set to Tobias Brunner
  • Target version set to 5.3.3
  • Resolution set to Fixed

As the pkcs1 plugin uses this value pretty much as is to calculate the SHA-1 hash of the public key the end result won't be the same. I wonder what the intention of the PKCS#11 library or the token is. According to PKCS#11 the data type of CKA_PUBLIC_EXPONENT is Big integer, which is defined as

Yes, the standard is pretty clear about this. The PKCS#11 documents even show examples with the value 0x010001

However "real world" examples show frequently the usual exponent with a 0x00010001 value:
https://dnssec.surfnet.nl/?p=873
http://www.dkgev.de/pdf/1007.pdf
...

Interesting, does not really explain it though. Perhaps it's some kind of 32-bit word size thing.

You can also forget my first remark about the "has private key". I've done other tests (IKEv1 mainly) and since I see the flag in both scenarios...

Ah, OK. Anything else would have surprised me actually. While the stroke plugin explicitly uses the KEYID_PUBKEY_SHA1 (subjkey) of the certificate's public key to do a lookup for a private key via get_private() of the credential manager. The latter does basically the same thing (via get_private_by_cert()) when it is called with the IKE ID instead of a keyid by the pubkey authenticator during IKE. So the result really should be the same.

So using your patch on 5.3.2 resolved the issue with my smartcard (IKEv1 and IKEv2)!

Great, thanks for testing! The fix will be included in the next release.

Tobias, many thanks for your support!

You're welcome.

#20 Updated by Tobias Brunner over 5 years ago

  • Status changed from Resolved to Closed

#21 Updated by Tobias Brunner about 5 years ago

  • Subject changed from Strongswan 5.x - charon doesn't load privkey from smartcard to strongSwan 5.x - charon can't access privkey of certain smartcards

Also available in: Atom PDF