Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trustonic pkcs11 #1600

Merged
merged 22 commits into from
Apr 25, 2019
Merged

Conversation

AlexandreGonzalo
Copy link
Contributor

Hi,
In this pull request I am mainly adding the support for CKM_RSA_PKCS_OAEP for the "pkcs11-tool --test" command.
I am also fixing the "pkcs11-tool --verify" when the file to verify is larger than 1025 bytes.
Finally, I fixed a minor build issue because RIPEMD and CAST are not defined by my version of OpenSsl.
I have only tested with my own implementation of the PKCS#11 library.
Notice that this is my first contribution so let me know if I am not doing the things correctly.
Best Regards,
Alexandre.

… value in call to util_fatal(). fix formatting.
…RSA and supports decryption, otherwise skip it.
…OAEP params for CKM_RSA_PKCS_OAEP, I had an issue with a variable not initialized.
Copy link
Member

@Jakuje Jakuje left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution. I added few comments to the code that would be nice to have improved before merging.

For the tests, I see that you actually updated the pkcs11-tool --test itself, but that is not ran during the tests itself yet, but a test like the following should be enough (just running the --test against the softhsm and checking the exit code):

https://github.com/Jakuje/OpenSC/commits/tests-oaep

This obviously fails with current master.

@@ -4650,7 +4652,9 @@ static int test_signature(CK_SESSION_HANDLE sess)
CKM_RSA_PKCS,
CKM_SHA1_RSA_PKCS,
CKM_MD5_RSA_PKCS,
#ifndef OPENSSL_NO_RIPEMD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, do not indent the #ifdef and #endif macros.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by 3d09823

@@ -5231,7 +5235,9 @@ static int test_unwrap(CK_SESSION_HANDLE sess)
errors += wrap_unwrap(sess, EVP_des_cbc(), privKeyObject);
errors += wrap_unwrap(sess, EVP_des_ede3_cbc(), privKeyObject);
errors += wrap_unwrap(sess, EVP_bf_cbc(), privKeyObject);
#ifndef OPENSSL_NO_CAST
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, do not indent the #ifdef and #endif macros.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by 3d09823

EVP_PKEY_free(pkey);
encrypted_len = outlen;

} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should also explicitly check for CKM_RSA_PKCS as the decryption does so we can fail earlier if the user provided unsupported mechanism.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, we need to check explicitly for CKM_RSA_PKCS and properly handle the case of CKM_RSA_X_509.
I will try to fix this issue during the week.

src/tools/pkcs11-tool.c Show resolved Hide resolved
case CKM_RSA_PKCS_OAEP:
case CKM_RSA_X_509:
//case CKM_RSA_PKCS_TPM_1_1:
//case CKM_RSA_PKCS_OAEP_TPM_1_1:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need these comments here? Do you have a pkcs11 that presents them? Does it work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two mechanisms are defined in the "official" header files that I am using and described in the 2.40 specifications.
They don't exist in the header files of your project, this is why I have commented them.
My pkcs11 won't support them, so I won't be able to test.
I can remove these two lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 lines removed @d25fbe3

@AlexandreGonzalo
Copy link
Contributor Author

I tested my new changes with 2 keys:
pkcs11-tool --list-objects
Using slot 0 with a present token (0x0)
Public Key Object; RSA 1024 bits
label: NotSupported
ID: 1024
Usage: encrypt, verify
Public Key Object; RSA 4096 bits
label: NotSupported
ID: 4096
Usage: encrypt, verify
Private Key Object; RSA
label: NotSupported
ID: 1024
Usage: decrypt, sign
Private Key Object; RSA
label: NotSupported
ID: 4096
Usage: decrypt, sign
pkcs11-tool --test
Using slot 0 with a present token (0x0)
C_SeedRandom() and C_GenerateRandom():
seeding (C_SeedRandom) not supported
seems to be OK
Digests:
all 4 digest functions seem to work
SHA-1: OK
Signatures (currently only for RSA)
testing key 0 (NotSupported)
all 4 signature functions seem to work
testing signature mechanisms:
SHA1-RSA-PKCS: OK
SHA256-RSA-PKCS: OK
testing key 1 (4096 bits, label=NotSupported) with 1 signature mechanism
SHA1-RSA-PKCS: OK
Verify (currently only for RSA)
testing key 0 (NotSupported)
SHA1-RSA-PKCS: OK
testing key 1 (NotSupported) with 1 mechanism
SHA1-RSA-PKCS: OK
Unwrap: not implemented
Decryption (currently only for RSA)
testing key 0 (NotSupported)
RSA-X-509: OK
RSA-PKCS: OK
OAEP parameters: hashAlg=SHA-1, mgf=MGF1-SHA1, source_type=0, source_ptr=0x0, source_len=0
RSA-PKCS-OAEP: OK
-- mechanism can't be used to decrypt, skipping
-- mechanism can't be used to decrypt, skipping
testing key 1 (NotSupported)
RSA-X-509: OK
RSA-PKCS: OK
OAEP parameters: hashAlg=SHA-1, mgf=MGF1-SHA1, source_type=0, source_ptr=0x0, source_len=0
RSA-PKCS-OAEP: OK
-- mechanism can't be used to decrypt, skipping
-- mechanism can't be used to decrypt, skipping
No errors

@AlexandreGonzalo
Copy link
Contributor Author

With OPENSSL_VERSION=1.0.1j, the digest of OAEP is hardcoded to SHA-1.
So I can't test for other digests.

@mouse07410
Copy link
Contributor

OpenSSL 1.0.1 is outdated and should not be used in new designs. SHA1 has been deprecated and must not be used, let alone hardcoded.

Please change to OpenSSL 1.0.2 (at least) and SHA2.

@AlexandreGonzalo
Copy link
Contributor Author

Hi,
I totally agree that SHA1 is broken and should not be used anymore.
I am only using this version of OpenSsl for testing purpose and I have to update it to a newer version.
I will be able to finalize this pull request only when I will be able to test with this newer OpenSsl.
Thanks,
Alex.

Copy link
Member

@Jakuje Jakuje left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for addressing my comments. It looks much better now. I did another read-through and noticed few more inconsistencies. It would be nice if you could check them too.

hash_alg = CKM_SHA_1;
} else if (opt_hash_alg != CKM_SHA_1) {
printf("Only CKM_RSA_PKCS_OAEP with CKM_SHA_1 supported\n");
return 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I see right, here you reject any other opt_hash_alg than CKM_SHA1 (default) and on the line 5346 you again check for all the other possible hashes that can not happen. I think you should allow other hashes to be used too here for the sake of universality (might need some more switches for the openssl).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed this code now I am able to test against OpenSsl 1.1.a.

src/tools/pkcs11-tool.c Show resolved Hide resolved
src/tools/pkcs11-tool.c Show resolved Hide resolved
@AlexandreGonzalo
Copy link
Contributor Author

AlexandreGonzalo commented Feb 7, 2019

I have noticed something weird with OpenSsl 1.1.1a.
I have a Segmentation fault when the pkcs11-tool is exiting.
I don't have this crash when I remove the OPENSSL_INIT_LOAD_CONFIG flag to the call to OPENSSL_init_crypto().
I am wondering why this function is called since it is supposed to be done automatically with OpenSSL >= 1.1.0.
https://wiki.openssl.org/index.php/Library_Initialization#libcrypto_Initialization
"If you are using OpenSSL 1.1.0 or above, then the library will initialize itself automatically"

@frankmorgner
Copy link
Member

https://travis-ci.org/OpenSC/OpenSC/jobs/489960037:

pkcs11-tool.c: In function ‘encrypt_decrypt’:
pkcs11-tool.c:5384:3: error: implicit declaration of function ‘EVP_PKEY_CTX_set_rsa_oaep_md’ [-Werror=implicit-function-declaration]
   if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) {
   ^
cc1: all warnings being treated as errors

Can you debug the crash with gdb, valgrind or VS?

@AlexandreGonzalo
Copy link
Contributor Author

AlexandreGonzalo commented Feb 12, 2019

Hi Frank,
Thank you for pointing out this build issue.
I am a beginner in this project and I am a making many mistakes...
I have submitted a new patch to fix this build issue.
Unfortunately, this week I won't have much time to try to debug this crash.
It is most probably linked to my environment.
I am trying to use the P11 engine and my PKCS#11 library which is still under development.
It looks like a memory corruption which is "detected" when the buffers are freed during the process exit.
I will get back to you when I will have more information.
Regards,
Alexandre.

Copy link
Member

@Jakuje Jakuje left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few more changes suggested. Anyway I see you are trying and learning :)

if (hash_alg != CKM_SHA_1) {
printf("This version of OpenSsl only supports SHA1 for OAEP, returning\n");
return 0;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, use the tabs for indentation here and above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this is my editor which is defaulting to spaces instead of tabs as by default we don't use tabs in our software.
Do you have a kind of checkpatch or astyle script that I can run before submitting patches?
This is fixed by 9ae507c

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately not. If you have some recommendation for service or even just a script, contributions are welcomed.

src/tools/pkcs11-tool.c Show resolved Hide resolved
Copy link
Member

@frankmorgner frankmorgner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jakub asked about unifying encrypt_decrypt() and decrypt(), what do you think about that?

src/tools/pkcs11-tool.c Show resolved Hide resolved
src/tools/pkcs11-tool.c Outdated Show resolved Hide resolved
src/tools/pkcs11-tool.c Show resolved Hide resolved
src/tools/pkcs11-tool.c Show resolved Hide resolved
src/tools/pkcs11-tool.c Outdated Show resolved Hide resolved
src/tools/pkcs11-tool.c Show resolved Hide resolved
src/tools/pkcs11-tool.c Show resolved Hide resolved
@AlexandreGonzalo
Copy link
Contributor Author

AlexandreGonzalo commented Mar 6, 2019

Jakub asked about unifying encrypt_decrypt() and decrypt(), what do you think about that?

It is true that I originally copied code from decrypt_data() but since I have done many changes and I don't think that it is worth to try to factorize it otherwise it will be less readable.

Now it is working fine for me with my PKCS#11 implementation and the latest OpenSsl.

Jakuje added a commit to Jakuje/OpenSC that referenced this pull request Mar 6, 2019
Note, that it does not work now until OpenSC#1600 will get resolved. Then,
move the test to TESTS in the Makefile.am
Jakuje added a commit to Jakuje/OpenSC that referenced this pull request Mar 8, 2019
Note, that it does not work now until OpenSC#1600 will get resolved. Then,
move the test to TESTS in the Makefile.am
@AlexandreGonzalo
Copy link
Contributor Author

AlexandreGonzalo commented Mar 11, 2019

Hi Frank,
Thank you for pointing out this build issue.
I am a beginner in this project and I am a making many mistakes...
I have submitted a new patch to fix this build issue.
Unfortunately, this week I won't have much time to try to debug this crash.
It is most probably linked to my environment.
I am trying to use the P11 engine and my PKCS#11 library which is still under development.
It looks like a memory corruption which is "detected" when the buffers are freed during the process exit.
I will get back to you when I will have more information.
Regards,
Alexandre.

I tried to figure out why I have a seg fault with the OpenSSL 1.1.1a.
In fact, it seems that the issue is in the libp11 engine.
It is crashing when ERR_unload_strings() is called in eng_err.c/ERR_unload_ENG_strings().
I have the following dump in logcat.
It is like if the err_string_lock used in ERR_unload_strings() was freed before the engine is destroyed.

01-21 23:14:33.801 23399 23399 F DEBUG : ABI: 'arm'
01-21 23:14:33.801 23399 23399 F DEBUG : pid: 23396, tid: 23396, name: pkcs11-tool >>> pkcs11-tool <<<
01-21 23:14:33.801 23399 23399 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
01-21 23:14:33.801 23399 23399 F DEBUG : Cause: null pointer dereference
01-21 23:14:33.802 23399 23399 F DEBUG : r0 00000000 r1 00000001 r2 00000002 r3 f616cf3f
01-21 23:14:33.802 23399 23399 F DEBUG : r4 f5e144c8 r5 f5de8ad0 r6 f616ea8d r7 ffd954a0
01-21 23:14:33.802 23399 23399 F DEBUG : r8 f5e14564 r9 f616ea8d r10 f61f0034 r11 ffd95478
01-21 23:14:33.802 23399 23399 F DEBUG : ip f5de7360 sp ffd95478 lr f5d56554 pc f6174966
01-21 23:14:33.803 23399 23399 F DEBUG :
01-21 23:14:33.803 23399 23399 F DEBUG : backtrace:
01-21 23:14:33.803 23399 23399 F DEBUG : #00 pc 00064966 /system/lib/libc.so (pthread_rwlock_wrlock)
01-21 23:14:33.803 23399 23399 F DEBUG : #1 pc 00185550 /system/lib/libcrypto.so.1.1 (CRYPTO_THREAD_write_lock+8)

@frankmorgner
Copy link
Member

@mtrojnar, any ideas regarding the problem with OpenSSL 1.1.1?

@mtrojnar
Copy link
Member

@frankmorgner It is hard to draw any conclusions without a complete stack backtrace.

@AlexandreGonzalo
Copy link
Contributor Author

AlexandreGonzalo commented Mar 11, 2019

@frankmorgner It is hard to draw any conclusions without a complete stack backtrace.
I am seeing that err_cleanup() is called before engine_destroy().
It is quite strange because engine_cleanup_int() is supposed to be called before err_cleanup().

When OPENSSL_init_crypto() is commented out in pkcs11-tool.c, engine_destroy() is called before err_cleanup() and I don't have the seg fault.

OPENSSL_init_crypto() is not needed anymore with OpenSSL 1.1.1a.
"As of version 1.1.0 OpenSSL will automatically allocate all resources that it
needs so no explicit initialisation is required. Similarly it will also
automatically deinitialise as required."

…a segmentation fault when the process exits.
@frankmorgner
Copy link
Member

both, pkcs11-tool and libp11 are calling OPENSSL_init_crypto, whereas the man page indicates that there are some circumstances where it must not be used... However, I it's not clear to me what causes the problem in this particular case. I think using automatic initialization for 1.1.0 and later is the way to go if it solves the problem.

Copy link
Member

@frankmorgner frankmorgner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general the PR looks good. There were still two minor questions without response...

The segmentation fault is a problem, however. That may be a sign that we're getting some of OpenSSL's memory handling wrong. Would it be possible to debug with some other PKCS#11 module, maybe softhsm?

src/tools/pkcs11-tool.c Show resolved Hide resolved
src/tools/pkcs11-tool.c Show resolved Hide resolved
Jakuje added a commit to Jakuje/OpenSC that referenced this pull request Apr 4, 2019
Note, that it does not work now until OpenSC#1600 will get resolved. Then,
move the test to TESTS in the Makefile.am
frankmorgner pushed a commit that referenced this pull request Apr 8, 2019
Note, that it does not work now until #1600 will get resolved. Then,
move the test to TESTS in the Makefile.am
@AlexandreGonzalo
Copy link
Contributor Author

Hi Frank,
I added the missing check in my latest commit.
Do you need more fixes or clarifications?
Regards,
Alexandre.

Copy link
Member

@frankmorgner frankmorgner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good now

@Jakuje
Copy link
Member

Jakuje commented Apr 23, 2019

When I try to build your branch I am getting the following failures:

pkcs11-tool.c: In function ‘encrypt_decrypt’:
pkcs11-tool.c:6524:6: error: ‘mgf’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   if (mi->mech == mgf)
      ^
pkcs11-tool.c:5290:23: note: ‘mgf’ was declared here
  CK_RSA_PKCS_MGF_TYPE mgf;
                       ^~~
cc1: all warnings being treated as errors

@Jakuje
Copy link
Member

Jakuje commented Apr 23, 2019

When I fixed the above and tried to run the OEAP tests with pkcs11-tool, I am still getting failures:

Using slot 0 with a present token (0x7ab4c146)
OAEP parameters: hashAlg=SHA256, mgf=MGF1-SHA256, source_type=0, source_ptr=(nil), source_len=0
error: PKCS11 function C_DecryptInit failed: rv = CKR_ARGUMENTS_BAD (0x7)
Aborting.
C_SeedRandom() and C_GenerateRandom():
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  SHA-1: OK
Signatures: not implemented
Verify (currently only for RSA)
  testing key 0 (ECC_auth) -- non-RSA, skipping
  testing key 1 (RSA_auth) with 1 mechanism
    RSA-X-509: OK
  testing key 2 (ECC521) with 1 mechanism -- non-RSA, skipping
  testing key 3 (RSA2048) with 1 mechanism
    RSA-X-509: OK
Unwrap: not implemented
Decryption (currently only for RSA)
  testing key 0 (ECC_auth)  -- non-RSA, skipping
  testing key 1 (RSA_auth)
    RSA-PKCS: OK
    RSA-X-509: OK
    RSA-PKCS-OAEP: mgf not set, defaulting to MGF1-SHA256

(from tests/test-pkcs11-tool-test.sh with SoftHSM)

@AlexandreGonzalo
Copy link
Contributor Author

When I try to build your branch I am getting the following failures:

pkcs11-tool.c: In function ‘encrypt_decrypt’:
pkcs11-tool.c:6524:6: error: ‘mgf’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   if (mi->mech == mgf)
      ^
pkcs11-tool.c:5290:23: note: ‘mgf’ was declared here
  CK_RSA_PKCS_MGF_TYPE mgf;
                       ^~~
cc1: all warnings being treated as errors

I am trying to understand why mgf is not initialized.
for the case CKM_RSA_PKCS_OAEP, it is set for all the cases.
for default case, we have a fall through which sets mgf = CKG_MGF1_SHA256;

@AlexandreGonzalo
Copy link
Contributor Author

When I fixed the above and tried to run the OEAP tests with pkcs11-tool, I am still getting failures:

Using slot 0 with a present token (0x7ab4c146)
OAEP parameters: hashAlg=SHA256, mgf=MGF1-SHA256, source_type=0, source_ptr=(nil), source_len=0
error: PKCS11 function C_DecryptInit failed: rv = CKR_ARGUMENTS_BAD (0x7)
Aborting.
C_SeedRandom() and C_GenerateRandom():
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  SHA-1: OK
Signatures: not implemented
Verify (currently only for RSA)
  testing key 0 (ECC_auth) -- non-RSA, skipping
  testing key 1 (RSA_auth) with 1 mechanism
    RSA-X-509: OK
  testing key 2 (ECC521) with 1 mechanism -- non-RSA, skipping
  testing key 3 (RSA2048) with 1 mechanism
    RSA-X-509: OK
Unwrap: not implemented
Decryption (currently only for RSA)
  testing key 0 (ECC_auth)  -- non-RSA, skipping
  testing key 1 (RSA_auth)
    RSA-PKCS: OK
    RSA-X-509: OK
    RSA-PKCS-OAEP: mgf not set, defaulting to MGF1-SHA256

(from tests/test-pkcs11-tool-test.sh with SoftHSM)

Maybe your PKCS11 implementation does not support this mechanism?

@Jakuje
Copy link
Member

Jakuje commented Apr 23, 2019

OK, it looks like the SoftHSM supports only SHA1 hash and MGF1, which is the reason for the failure here. But the build issue should be addressed. From what I see, it really looks like false positive of my gcc, but assigning the default value during initialization of a variable is a good practice.

@AlexandreGonzalo
Copy link
Contributor Author

I initialized the variable as suggested in my latest commit.

@Jakuje
Copy link
Member

Jakuje commented Apr 25, 2019

Thanks. I think we are good.

@frankmorgner
Copy link
Member

thanks everyone

@frankmorgner frankmorgner merged commit bfa94dc into OpenSC:master Apr 25, 2019
@AlexandreGonzalo
Copy link
Contributor Author

Thanks for your help Jakub and Frank!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants