3

I'm on Ubuntu 17.10 trying to sign a string with smart card. What I need is a pkcs7-signedData object. I can do some signing with the command below and I get some binary foo.sig file. What is it? How can I make it into PKCS#7 signature?

$ echo foobar | pkcs11-tool --module ./VdsPKCS1164.so --login --pin $PIN \
   --sign --id 5378 --output-file foo.sig
Using slot 0 with a present token (0x1)
Using signature algorithm RSA-PKCS

$ openssl asn1parse -in foo.sig
Error: offset too large

$ openssl asn1parse -inform der -in foo.sig
Error in encoding
139905918145984:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:../crypto/asn1/asn1_lib.c:101:
cprn
  • 1,015
  • 3
  • 14
  • 25
  • 1
    Try a different input format for asn1parse: `openssl asn1parse -inform DER -in foo.sig`. The default format is PEM, which is Base64 encoded. – Johan Myréen Nov 15 '17 at 17:33
  • Sorry for not putting this in - yeah, I tried `der`, it doesn't help. I don't think it's `asn1` structure. I think what I get is raw hash with given algorithm and I have to somehow build the rest of `pkcs7-signedData`, i.e. add some header, unsigned data, signed data, chain (?), footer. – cprn Nov 16 '17 at 08:10

1 Answers1

2

After extensive research:

pkcs11-tool --sign command produces a binary result of selected hashing algorithm that isn't a PKCS structure itself but can be used with a 3rd party library to generate something asn1 compliant; it's a tedious and not recommended process but it's possible to build a verifiable pkcs7-signedData signature.

openssl smime -sign command is recommended; it needs to be configured to use the pkcs11 engine with the same module as pkcs11-tool and can build the PKCS#7 structure without additional libs.

OpenSSL config file example:

openssl_conf = openssl_def

[openssl_def]
engines = engine_section

[engine_section]
pkcs11 = pkcs11_section

[pkcs11_section]
dynamic_path = /usr/lib/x86_64-linux-gnu/openssl-1.0.0/engines/pkcs11.so
engine_id = pkcs11
MODULE_PATH = ./VdsPKCS1164.so
PIN = 1234
default_algorithms = ALL
init = 1

Command to generate PKCS#7 signature example:

$ echo foobar > input.data
$ OPENSSL_CONF=./openssl.cnf openssl smime -sign -engine pkcs11 \
    -md sha1 -binary -in input.data -out foo.sig -outform der \
    -keyform engine -inkey id_5378 -certfile extra.cert.pem -signer cert.pem

File cert.pem (and any extra certs if required) can be extracted from the token card and converted to PEM with:

$ pkcs11-tool --module ./VdsPKCS1164.so --login --pin $PIN \
    --read-object --type cert -id 5378 --output-file cert.crt
$ openssl x509 -inform der -in cert.crt -out cert.pem
cprn
  • 1,015
  • 3
  • 14
  • 25
  • Failed: engine "pkcs11" set. Unable to enumerate certificates PKCS11_get_private_key returned NULL cannot load signing key file from engine 139683594417816:error:26096080:engine routines:ENGINE_load_private_key:failed loading private key:eng_pkey.c:124: unable to load signing key file unable to write 'random state' – Like Jan 22 '20 at 03:53
  • Maybe wrong module or path? I also remember having issues with OpenSSL versions newer than 1.0.2g (Library: OpenSSL 1.0.2n) from Ubuntu repos. – cprn Jan 23 '20 at 12:07
  • My OS is Ubuntu 16.04 and device is safenet 5110 – Like Jan 24 '20 at 03:30
  • Does the producer of Safenet 5110 support a Linux pkcs11 module for this device? Make sure you're using a recommended module and supported OpenSSL version. – cprn Jan 24 '20 at 18:55
  • Safenet 5110 has safenetauthenticationclient 9.0.43 deb. opensc can list keys and export public key with openssl pkcs11 engine and safenet module. – Like Jan 27 '20 at 04:05
  • I didn't had that issue. It seems unusual to me because I was under the impression OpenSSL doesn't have to load a private key at all and just asks the card token to sign data. I understand how frustrating it is because there were no resources when I needed a solution either. Maybe `strace` will tell you enough to contact the token's producer and ask for support. – cprn Jan 27 '20 at 08:50