I have at hand Gemalto Safenet eToken with eIDAS Qualified Electronic Seal (also known as e-Seal or Digital Stamp or Document Signing Certificate) issued by SK ID Solutions. I want to sign sha256 hash with. First I will check some general information about the keypair. We need token label(or slot=8 or slotIndex=0x11) for signature and public key ID (00000000) for verification.
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so -L
...
Slot 8 (0x11): SafeNet eToken 5100 [eToken 5110 SC] 01 (Digital Signature Pin)
token label : eID Easy (Digital Signature Pin)
token manufacturer : Gemalto
token model : ID Prime MD
token flags : login required, rng, token initialized, PIN initialized, other flags=0x200
hardware version : 0.0
firmware version : 0.0
serial num : 06E2CF0B29CA6BD0
pin min/max : 4/16
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so --token-label "eID Easy (Digital Signature Pin)" -O
Certificate Object; type = X.509 cert
label:
subject: DN: organizationIdentifier=NTREE-14080014/serialNumber=14080014, ST=Harjumaa, L=Tallinn, C=EE, O=EID Easy O\xC3\x9C, CN=eID Easy
ID: 00000000
Public Key Object; RSA 2048 bits
label: eID Easy
ID: 00000000
Usage: verify, wrap
Access: local
Next I will prepare digest that should be signed. I have it in hex for so I will convert it to binary into the file digest.bin
$ echo "19d512fc649e1668eb84741284ad95ec03f3225719a83e40389dbade4eabe5ed" > digest.txt
$ xxd -r -p digest.txt digest.bin
Now the most important part, creating the signature.
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so --pin=$PIN --token-label "eID Easy (Digital Signature Pin)" -s -i digest.bin -m RSA-PKCS > signature.bin
Using signature algorithm RSA-PKCS
$ base64 signature.bin -w0
RseZYWjkyNRcU1lI1KR+I+0C1jC+FVp2kTAhyOUsE2x6UGf+UMSf3kqD4KGBb+eIryXDFTzNsdo8XroUtWvYQvHgPLPaRQ8xfPtTOZS/crQY168S2lk4buAeDZWat/xiGeXgU4rL7hdbjojdkfbeGWHfIERcese6wv521t9x9w5K3XGz50Ec9Y/C4cPPo4xuQMSQlCrx1iIlfeGbkElxGIdIkZvt2nTrhl/ico5YCbTJfuDqZaaaJxPkXcfgAcvFVU/kILi7U3XQCvz7zohZoRj4vkeTutanW6I7qGyWvIcxXGJx29MInF3pohT0+KUzegN4A1GfkW5hfk5HyCP2Gw==
It makes sense to verify the signature to make sure all is good. We will extract the public key from the token and use it to verify the signature, then verify the signature which will basically extract the original digest and if the original digest matches the one taken from signature then we are all good.
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so --token-label "eID Easy (Digital Signature Pin)" --read-object --type pubkey --id=00000000 > public-key.der
$ openssl rsa -inform DER -outform PEM -in public-key.der -pubin > public-key.pem
writing RSA key
$ openssl rsautl -verify -inkey public-key.pem -in signature.bin -pubin > verified.bin
$ xxd -p -c32 verified.bin verified.txt
$ cat digest.txt verified.txt
19d512fc649e1668eb84741284ad95ec03f3225719a83e40389dbade4eabe5ed
19d512fc649e1668eb84741284ad95ec03f3225719a83e40389dbade4eabe5ed
In this case we used signature mechanism RSA-PKCS which signs the data without hashing anything. There are more signature methods supported in this token. Most interestingly there are SHA256-RSA-PKCS and also SHA256-RSA-PKCS-PSS. If there is SHAXXX then before signing the data is hashed. If there is PSS then there is also salt added and signature will be different every time.
Here is the reference of all signature mechanisms supported
$ pkcs11-tool --module /usr/lib/libIDPrimePKCS11.so -M --slot 0x11 |grep sign
DES3-MAC, keySize={24,24}, sign, verify
DES3-MAC-GENERAL, keySize={24,24}, sign, verify
AES-MAC, keySize={16,32}, sign, verify
AES-MAC-GENERAL, keySize={16,32}, sign, verify
RSA-PKCS, keySize={2048,2048}, hw, encrypt, decrypt, sign, sign_recover, verify, verify_recover, wrap, unwrap
RSA-PKCS-PSS, keySize={2048,2048}, hw, sign, verify
SHA256-RSA-PKCS-PSS, keySize={2048,2048}, hw, sign, verify
SHA384-RSA-PKCS-PSS, keySize={2048,2048}, hw, sign, verify
SHA512-RSA-PKCS-PSS, keySize={2048,2048}, hw, sign, verify
SHA256-RSA-PKCS, keySize={2048,2048}, hw, sign, verify
SHA384-RSA-PKCS, keySize={2048,2048}, hw, sign, verify
SHA512-RSA-PKCS, keySize={2048,2048}, hw, sign, verify
mechtype-0x252, keySize={112,2048}, sign, verify
SHA256-HMAC, keySize={112,2048}, sign, verify
mechtype-0x262, keySize={112,2048}, sign, verify
SHA384-HMAC, keySize={112,2048}, sign, verify
mechtype-0x272, keySize={112,2048}, sign, verify
SHA512-HMAC, keySize={112,2048}, sign, verify