Important!

Blog moved to https://blog.apdu.fr/

I moved my blog from https://ludovicrousseau.blogspot.com/ to https://blog.apdu.fr/ . Why? I wanted to move away from Blogger (owne...

Showing posts with label pykcs11. Show all posts
Showing posts with label pykcs11. Show all posts

Friday, April 14, 2023

Verify with OpenSSL a signature computed by PyKCS11

With PyKCS11 I provide a sample code signature.py to compute a RSA+SHA256 signature. The Python sample also contains the code to check the signature using PyKCS11.

But what if you want to verify the signature using OpenSSL?

Export the public key

PYKCS11LIB environment variable is used to indicate what PKCS#11 library to use. For the tests I use SoftHSM so I set the variable using:
$ export PYKCS11LIB=/usr/local/lib/softhsm/libsofthsm2.so
#!/bin/bash

set -e

# get the 1st key object ID
ID=$(pkcs11-tool --module $PYKCS11LIB --list-objects --type pubkey \
    | grep ID \
    | cut -d: -f 2)
echo "Object id: $ID"

# export the public key
pkcs11-tool --module $PYKCS11LIB --read-object --type pubkey --id $ID -o rsa_pub.key

# convert the public key to PEM
openssl rsa -pubin -inform DER -in rsa_pub.key -outform PEM -out rsa_pub.pem

The RSA key pair has been generated by the generate.py script and is stored in the PKCS#11 token. We need to export it so that OpenSSL can use it to check the signature.

To export the key I use pkcs11-tool from the OpenSC project. We need to know the object ID of the public key. This ID is configured in generate.py script line 22. We dump the public keys and get the object ID.

$ pkcs11-tool --module $PYKCS11LIB --list-objects --type pubkey
Using slot 0 with a present token (0x27ca3aa)
Public Key Object; RSA 1024 bits
  label:      My Public Key
  ID:         22
  Usage:      encrypt, verify, wrap
  Access:     local

The script will work correctly if only one public key is present in the token. I let you handle more complex cases.

output

$ ./export_key.sh 
Using slot 0 with a present token (0x27ca3aa)
Object id:          22
Using slot 0 with a present token (0x27ca3aa)
writing RSA key

Compute signature

I modified the original signature.py script to also save the clear text message in a file cleartext.txt and the signature in a file sig_sha256.bin so these files can be used later by OpenSSL.

#!/usr/bin/env python3

from PyKCS11 import *
import binascii

pkcs11 = PyKCS11Lib()
pkcs11.load()  # define environment variable PYKCS11LIB=YourPKCS11Lib

# get 1st slot
slot = pkcs11.getSlotList(tokenPresent=True)[0]

session = pkcs11.openSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login("1234")

# message to sign
toSign = "Hello World!\n"
mechanism = Mechanism(CKM_SHA256_RSA_PKCS, None)

# find first private key and compute signature
privKey = session.findObjects([(CKA_CLASS, CKO_PRIVATE_KEY)])[0]
signature = session.sign(privKey, toSign, mechanism)
print("\nsignature: {}".format(binascii.hexlify(bytearray(signature))))

# save the clear text in a file
with open("cleartext.txt", "w") as f:
    f.write(toSign)

# save to a signature in a file
with open("sig_sha256.bin", "bw") as f:
    f.write(bytearray(signature))

# find first public key and verify signature
pubKey = session.findObjects([(CKA_CLASS, CKO_PUBLIC_KEY)])[0]
result = session.verify(pubKey, toSign, signature, mechanism)
print("\nVerified:", result)

# logout
session.logout()
session.closeSession()

Output

$ ./signature.py 

signature: b'322c1591cb9aba1e361264b02464a2bd9d55693bf772b4253da0862616e611dc139005742c511795c27c8f609e4ddbaafceba1c3b3ce278b8e0af564c84de54a639cff67a9a3f97dcc542cd6f0200954ef7fce4a0f87b61636272e21fc1e3ef9f0b683e360cca4231405dd90ae2c4a3638ca7a85e2b62f6ae30975ff3885ab60'

Verified: True

Verify signature

#!/bin/bash

set -e

# verify signature
openssl dgst -sha256 -verify rsa_pub.pem -signature sig_sha256.bin cleartext.txt

Output

$ ./verify.sh 
Verified OK

Conclusion

Thanks to Leon Rman for the initial code and the idea.

I let you write the code to do the symmetrical operations: sign using OpenSSL and verify using PyKCS11.

Monday, April 10, 2023

New PyKCS11 1.5.12 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction" or "PyKCS11’s documentation".

The project is registered at Pypi: https://pypi.org/project/PyKCS11/
 

Changes:

1.5.12 - April 2023, Ludovic Rousseau
  • add setAttributeValue()
  • minor improvements

 

Sunday, September 4, 2022

New PyKCS11 1.5.11 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction" or "PyKCS11’s documentation".

The project is registered at Pypi: https://pypi.org/project/PyKCS11/
 

Changes:

1.5.11 - September 2022, Ludovic Rousseau

  • add deriveKey() with CKM_ECDH1_DERIVE and CK_ECDH1_DERIVE_PARAMS
  • support pSourceData in OAEP params
  • remove use of (deprecated) distutils
  • samples: port to Python 3
  • fix code coverage generation

Thursday, December 31, 2020

New PyKCS11 1.5.10 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction" or "PyKCS11’s documentation".

The project is registered at Pypi: https://pypi.org/project/PyKCS11/ 
 

Changes

1.5.10 - December 2020, Ludovic Rousseau
  • Add CKH_* constants
  • CKA_HW_FEATURE_TYPE artibute value is a number
  • Makefile: use python3 by default
  • minor improvements
 

Friday, July 31, 2020

New PyKCS11 1.5.9 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction" or "PyKCS11’s documentation".

The project is registered at Pypi: https://pypi.org/project/PyKCS11/

Changes

1.5.9 - July 2020, Ludovic Rousseau
  • call C_GetSlotList() with a NULL parameter to correctly initialize some PKCS#11 lib conforming to PKCS#11 version 2.40.

Friday, May 15, 2020

New PyKCS11 1.5.8 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction" or "PyKCS11’s documentation".

The project is registered at Pypi: https://pypi.org/project/PyKCS11/

Changes:

1.5.8 - May 2020, Ludovic Rousseau
  • CKA_ALWAYS_AUTHENTICATE is boolean
  • CKM_VENDOR_DEFINED_...
    • Fix name: use CKM_ instead of CKR_ prefix
    • Use an explicit hex prefix: CKM_VENDOR_DEFINED_0x45
  • Add missing CKM_*, CKA_*, CKF_*, CKD_*, CKK_*, CKN_*, CKO_*, CKR_* from PKCS#11 v3.0
  • fix test_asymetric.py for RSA_PSS_Mechanism

Wednesday, December 18, 2019

New PyKCS11 1.5.7 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction" or "PyKCS11’s documentation".

Changes:

1.5.7 - December 2019, Ludovic Rousseau
  • add missing files in the .tar.gz

1.5.6 - December 2019, Ludovic Rousseau
  • AppVeyor:
    • generate bdist_wheel
    • add Python 3.7 and 3.8
  • Sample events.py: add a -f/--full argument
  • Add support of CKM_AES_GCM mechanism
  • CPKCS11Lib::Load(): return different error codes
  • minor improvements

Wednesday, April 17, 2019

New PyKCS11 1.5.5 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction" or "PyKCS11’s documentation".

Changes:

1.5.5 - April 2019, Ludovic Rousseau
  • fix source package generation

1.5.4 - April 2019, Ludovic Rousseau
  • getTokenInfo: replace NUL char by ' ' in utcTime
  • dumpit:
    • print hardwareVersion and firmwareVersion
    • print slot flags
    • move to next slot if token not present
  • add support of CKA_WRAP_TEMPLATE/CKA_UNWRAP_TEMPLATE
  • add samples for ECC key generation and use
  • move from distutils to setuptools
  • upload of wheels to pypi on "make dist"

Friday, October 12, 2018

New PyKCS11 1.5.3 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction" or "PyKCS11’s documentation".

Changes:

1.5.3 - October 2018, Ludovic Rousseau
  • Do not fail when converting a UTF-8 string
  • Documentation: convert from Epydoc to Sphinx
  • some minor improvements

Thursday, April 12, 2018

New PyKCS11 1.5.2 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction".

Changes:

1.5.2 - April 2018, Ludovic Rousseau
  • Fix initPin()
  • add tests for initPin(), setPin(), initToken()

Friday, March 30, 2018

New PyKCS11 1.5.1 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction".

Changes:

1.5.1 - March 2018, Ludovic Rousseau
  • Fix "pip install"

Monday, March 26, 2018

New PyKCS11 1.5.0 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.
See "PyKCS11 introduction".

Changes:

1.5.0 - March 2018, Ludovic Rousseau
  • Python 3: use strings instead of binary buffers for CK_UTF8CHAR PKCS#11 types. The behaviour is now the same as with Python 2
  • allow non string PIN values (binary PIN) for login(), initToken(), initPin(), setPin()
  • fix support of RSA PKCS PSS mechanism
    The mechanism object now uses a parameter "mechanism" instead of hard coding the mechanism value to CKM_RSA_PKCS_PSS.
  • add support of Python 2.7 on Windows
  • add AppVeyor configuration (automatic Windows builds)
  • ckbytelist: remove possibility to give a initial size
  • samples/getinfo: do not list the mechanisms by default
  • samples/events:
    • do not list the mechanisms by default
    • add support of pinpad readers
  • some minor improvements

Windows

If you are a Windows user and you want binary packages then please work on the AppVeyor configuration:

Wednesday, October 11, 2017

New PyKCS11 1.4.4 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

Changes:
1.4.4 - October 2017, Ludovic Rousseau
  • getAttributeValue(): handle CKR_ARGUMENTS_BAD error
  • seedRandom: fix the seed conversion
  • Add vendor errors support to PyKCS11Error
  • samples/getinfo & dumpit: list only slots with a token present by default
  • run_test: add support of OpenSC PKCS#11 spy
  • ckbytelist: update __repr__()
  • include tests files in the archive
  • dumpit: display the error if getAttributeValue() fails
  • some minor improvements

Source code available on:

Saturday, June 24, 2017

New PyKCS11 1.4.3 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

Changes:
1.4.3 - June 2017, Ludovic Rousseau
  • Add support of CKM_RSA_PKCS_PSS mechanism
  • fix CKM_AES_CBC issue with Python 3
  • add Unitary Tests (make tests)
  • add tox support (automate and standardize testing in Python)
  • add coverage support (measuring code coverage of Python programs)
  • add Travis-CI configuration (automatic build and tests)
  • some minor improvements

Source code available on:

Results available on:

Sunday, May 21, 2017

New PyKCS11 1.4.2 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

See PyKCS11 introduction for more details about PyKCS11.

Changes:
1.4.2 - May 2017, Ludovic Rousseau
  • Moved the project from https://bitbucket.org/PyKCS11/pykcs11 to https://github.com/LudovicRousseau/PyKCS11
  • Makefile: use a better default value for PREFIX
  • Fix PyKCS11.__del__(): test that every module is accessible
  • getSlotList(): add optional tokenPresent parameter
    By default the method returns all the slots (like before the change).
  • Always call C_Initialize() in ::Load() to work with some bogus PKCS#11 library (like libCryptoki2 from Safenet Luna SA HSM)
  • LowLevel samples: use PYKCS11LIB environment variable
  • some minor improvements

Available on:

Saturday, February 11, 2017

New PyKCS11 1.4.1 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

See PyKCS11 introduction for more details about PyKCS11.

Changes:
1.4.1 - February 2017, Ludovic Rousseau
  • fix compilation under Python 3
  • add rsa encryption sample program

Saturday, February 4, 2017

New PyKCS11 1.4.0 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

See PyKCS11 introduction for more details about PyKCS11.

 Changes:
1.4.0 - February 2017, Ludovic Rousseau
  • fix closeAllSessions() and move it from Session to PKCS11Lib
  • add RSAOAEPMechanism to support RSA Encryption
  • add DigestSession which enables multi-part digesting
  • add Elliptic Curve keypair generating mechanism
  • fix bug in Templates using booleans CK_TRUE/CK_FALSE
    Templates are used by generateKey(), generateKeyPair(), findObjects() createObject(), unwrapKey()
  • fix dumpit.py sample for Python 3

I also noticed that I forgot to blog about the previous version: 1.3.3

1.3.3 - November 2016, Ludovic Rousseau
  • PKCS#11 definitions: sync with Cryptoki version 2.40
    • add missing CKM_* and CKP_* defines
  • Add generateKey() with default mechanism CKM_AES_KEY_GEN
  • Make sure the PyKCS11Lib is referenced as long as Session object is live
  • Fix OverflowError on Windows
  • Attribute CKA_WRAP_WITH_TRUSTED is bool
  • samples
    • dumpit: ask to enter the PIN on the pinpad if needed
    • getinfo & dumpit: add --slot= parameter
  • some minor improvements

Wednesday, January 27, 2016

New PyKCS11 1.3.2 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

See PyKCS11 introduction for more details about PyKCS11.

Changes:
1.3.2 - January 2016, Ludovic Rousseau
  • Add wrappers for C_Verify, C_WrapKey, C_UnwrapKey
  • PKCS#11 definitions: sync with Cryptoki version 2.30
  • Generate CKM[CKM_VENDOR_DEFINED+x] values on the fly
  • Fix use of a pinpad reader CKF_PROTECTED_AUTHENTICATION_PATH
  • dumpit.py: lots of small fixes
  • Setup call make to build pykcs11_wrap.cpp using SWIG
  • Fix build on Windows
  • Small bugs fixed

I also noticed that I forgot to blog about the previous version: 1.3.1

Changes:
1.3.1 - October 2015, Ludovic Rousseau
  • PKCS#11 definitions: sync with Cryptoki version 2.30
  • Add user type CK_CONTEXT_SPECIFIC
  • Fixes #9, incorrect assignment of pParameter for CK_MECHANISMs.
  • CKA_DERIVE is a CK_BBOOL and not byte array
  • Add digest() and encrypt method to Session class
  • Add samples:
    • key-pair generation
    • key-pair generation + certificate import
    • printing public key modulus
    • computing signature
  • small bugs fixed

Tuesday, January 19, 2016

PyKCS11 repository has moved

PyKCS11 is the Python wrapper above a PKCS#11 library. I presented it in "PyKCS11 introduction"

New location

I moved the PyKCS11 Mercurial repository in a team repository.
The new repository is now at: https://bitbucket.org/PyKCS11/pykcs11

Upgrade

  1. Create a new local repository using the new URL.
    $ hg clone https://bitbucket.org/PyKCS11/pykcs11
  2. Apply your local changes, if any.

Saturday, July 26, 2014

New PyKCS11 1.3.0 available

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

See PyKCS11 introduction for more details about PyKCS11.

The changelog is short:
1.3.0 - July 2014, Ludovic Rousseau
  • add Python3 support
After some efforts I also uploaded the package python3-pykcs11 to Debian. It is my first Python3 package.