-
Notifications
You must be signed in to change notification settings - Fork 188
Fix test_pkcs12.rb in FIPS. #997
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
base: master
Are you sure you want to change the base?
Conversation
|
I feel these existing tests should simply be skipped. My impression is that PKCS#12 is currently effectively unsupported in FIPS environments as I doubt password-based PKCS#12 is actually used without a MAC. I think On a side note, RFC 9579 / RFC 9879 introduced an alternative MAC algorithm based on PBMAC1 from PKCS#5v2, which I think is FIPS-compatible. However, this is still pretty new and we don't have a wrapper for it yet: https://docs.openssl.org/master/man3/PKCS12_gen_mac/ |
24b8de6 to
4c7ffa6
Compare
Okay. That makes sense. I think we want to test popular use cases. I rebased the PR without MAC less key. I am still using the However, LibreSSL's https://man.openbsd.org/PKCS12_newpass.3
And AWS-LC's If you don't like this conditional logic, I can change this PR's source code back to use the What do you think? |
test/openssl/test_pkcs12.rb
Outdated
| # algorithm, the case is typical. See also the man page openssl-pkcs12(1). | ||
| # OpenSSL::PKCS12.create raises UNKNOWN_ALGORITHM in AWS-LC with AES-256-CBC. | ||
| DEFAULT_PBE_PKEYS = aws_lc? ? "PBE-SHA1-3DES" : "AES-256-CBC" | ||
| DEFAULT_PBE_CERTS = aws_lc? ? "PBE-SHA1-3DES" : "AES-256-CBC" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be precise, PBE-SHA1-3DES uses PBKDF1 in PKCS#5 rather than PKCS12KDF. PKCS12KDF is only used for the outer MAC. I'd drop the FIPS reference because it's not relevant.
I noticed you updated the base64-encoded examples to use PBES2, and these tests are passing even with AWS-LC. Did we run into an incompatibility in PKCS12_create()? If so, it might be better to just skip these tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be precise, PBE-SHA1-3DES uses PBKDF1 in PKCS#5 rather than PKCS12KDF. PKCS12KDF is only used for the outer MAC. I'd drop the FIPS reference because it's not relevant.
I would agree on removing the conditional parts, keeping the original parts. Because the entire content of this file is not relevant to FIPS. However, I still don't understand your opinion PBE-SHA1-3DES uses PBKDF1 in PKCS#5 rather than PKCS12KDF. Because when I added the following test test_foo, and ran it in FIPS, I got the following error message "error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported (Global default library context, Algorithm (PKCS12KDF : 0), Properties ())" which indicated the PKCS12KDF was unsupported in the case. As I did set the mac_iter as -1 not to use the MAC key, I don't think this error comes from the MAC key. I think it comes from the PBE-SHA1-3DES itself. What do you think?
test_pkcs12.rb
...
def test_foo
OpenSSL.debug = true
pkcs12 = OpenSSL::PKCS12.create(
"omg",
"hello",
@mykey,
@mycert,
nil,
"PBE-SHA1-3DES",
"PBE-SHA1-3DES",
nil,
-1,
)
end
...
$ echo $OPENSSL_DIR
/home/jaruga/.local/openssl-4.0.0-dev-fips-debug-1cb0d36b39
$ $OPENSSL_DIR/bin/openssl version
OpenSSL 4.0.0-dev (Library: OpenSSL 4.0.0-dev )
$ OPENSSL_CONF=$OPENSSL_DIR/ssl/openssl_fips.cnf \
ruby test/openssl/test_pkcs12.rb --name=test_foo
Loaded suite test/openssl/test_pkcs12
Started
test/openssl/test_pkcs12.rb:39: warning: error on stack: error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported (Global default library context, Algorithm (PKCS12KDF : 0), Properties (<null>))
test/openssl/test_pkcs12.rb:39: warning: error on stack: error:1180006B:PKCS12 routines:PKCS12_PBE_keyivgen_ex:key gen error
test/openssl/test_pkcs12.rb:39: warning: error on stack: error:11800067:PKCS12 routines:PKCS12_item_i2d_encrypt_ex:encrypt error
test/openssl/test_pkcs12.rb:39: warning: error on stack: error:11800067:PKCS12 routines:PKCS12_pack_p7encdata_ex:encrypt error
E
========================================================================================
Error: test_foo(OpenSSL::TestPKCS12): OpenSSL::PKCS12::PKCS12Error: encrypt error
test/openssl/test_pkcs12.rb:39:in 'OpenSSL::PKCS12.create'
test/openssl/test_pkcs12.rb:39:in 'OpenSSL::TestPKCS12#test_foo'
36: def test_foo
37: OpenSSL.debug = true
38:
=> 39: pkcs12 = OpenSSL::PKCS12.create(
40: "omg",
41: "hello",
42: @mykey,
========================================================================================
Finished in 0.044698029 seconds.
----------------------------------------------------------------------------------------
1 tests, 1 assertions, 0 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
----------------------------------------------------------------------------------------
22.37 tests/s, 22.37 assertions/s
I noticed you updated the base64-encoded examples to use PBES2, and these tests are passing even with AWS-LC. Did we run into an incompatibility in PKCS12_create()? If so, it might be better to just skip these tests.
Yes, good point. The based64-encoded texts are based on the AES-256-CBC in the test_new_with_no_keys and test_new_with_no_certs. However, the tests passes using the PBE-SHA1-3DES in AWS-LC. It seemed weird to me. But I assumed this might be just a specification.
Anyway, I will revert this part to the original logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I debugged the following error with gdb. I see this calls the PKCS12_key_gen_uni_ex, and failing to fetch PKCS12KDF in it. So,
$ OPENSSL_CONF=$OPENSSL_DIR/ssl/openssl_fips.cnf \
gdb --args ruby test/openssl/test_pkcs12.rb --name=test_foo
(gdb) f
#0 PKCS12_key_gen_uni_ex (pass=0xde6ba0 "", passlen=8, salt=0xde6b60 "#\365]\304\r=\023R", saltlen=8, id=1, iter=2048, n=24, out=0x7fffffff5070 "\220P\377\377\377\177", md_type=0xd8ea40, libctx=0x0, propq=0x0)
at crypto/pkcs12/p12_key.c:93
93 if (kdf == NULL)
(gdb) l
88
89 if (n <= 0)
90 return 0;
91
92 kdf = EVP_KDF_fetch(libctx, "PKCS12KDF", propq);
93 if (kdf == NULL)
94 return 0;
95 ctx = EVP_KDF_CTX_new(kdf);
96 EVP_KDF_free(kdf);
97 if (ctx == NULL)
(gdb) p kdf
$3 = (EVP_KDF *) 0x0
(gdb) bt
#0 PKCS12_key_gen_uni_ex (pass=0xde6ba0 "", passlen=8, salt=0xde6b60 "#\365]\304\r=\023R", saltlen=8, id=1, iter=2048, n=24, out=0x7fffffff5070 "\220P\377\377\377\177", md_type=0xd8ea40, libctx=0x0, propq=0x0)
at crypto/pkcs12/p12_key.c:93
#1 0x00007fffcd8a6468 in PKCS12_key_gen_utf8_ex (pass=0x7fffce0afe20 "omg", passlen=3, salt=0xde6b60 "#\365]\304\r=\023R", saltlen=8, id=1, iter=2048, n=24, out=0x7fffffff5070 "\220P\377\377\377\177", md_type=0xd8ea40,
ctx=0x0, propq=0x0) at crypto/pkcs12/p12_key.c:65
#2 0x00007fffcd8a4529 in PKCS12_PBE_keyivgen_ex (ctx=0xde6a40, pass=0x7fffce0afe20 "omg", passlen=3, param=0xde4c80, cipher=0xde4890, md=0xd8ea40, en_de=1, libctx=0x0, propq=0x0) at crypto/pkcs12/p12_crpt.c:51
#3 0x00007fffcd77646a in EVP_PBE_CipherInit_ex (pbe_obj=0x7fffcdc85b90 <nid_objs+5840>, pass=0x7fffce0afe20 "omg", passlen=3, param=0xde4c80, ctx=0xde6a40, en_de=1, libctx=0x0, propq=0x0) at crypto/evp/evp_pbe.c:158
#4 0x00007fffcd8a5762 in PKCS12_pbe_crypt_ex (algor=0xde4ca0, pass=0x7fffce0afe20 "omg", passlen=-1,
in=0xde6470 "0\202\005\3000\202\005\274\006\v*\206H\206\367\r\001\f\n\001\003\240\202\005i0\202\005e\006\n*\206H\206\367\r\001\t\026\001\240\202\005U\004\202\005Q0\202\005M0\202\0035\240\003\002\001\002\002\001\0030\r\006\t*\206H\206\367\r\001\001\v\005", inlen=1476, data=0xdd02e8, datalen=0xdd02e0, en_de=1, libctx=0x0, propq=0x0) at crypto/pkcs12/p12_decr.c:37
#5 0x00007fffcd8a5e9d in PKCS12_item_i2d_encrypt_ex (algor=0xde4ca0, it=0x7fffcdc93c00 <local_it>, pass=0x7fffce0afe20 "omg", passlen=-1, obj=0xdcf280, zbuf=1, ctx=0x0, propq=0x0) at crypto/pkcs12/p12_decr.c:202
#6 0x00007fffcd8a3841 in PKCS12_pack_p7encdata_ex (pbe_nid=146, pass=0x7fffce0afe20 "omg", passlen=-1, salt=0x0, saltlen=0, iter=2048, bags=0xdcf280, ctx=0x0, propq=0x0) at crypto/pkcs12/p12_add.c:132
#7 0x00007fffcd8a53ad in PKCS12_add_safe_ex (psafes=0x7fffffff5470, bags=0xdcf280, nid_safe=146, iter=2048, pass=0x7fffce0afe20 "omg", ctx=0x0, propq=0x0) at crypto/pkcs12/p12_crt.c:323
#8 0x00007fffcd8a4beb in PKCS12_create_ex2 (pass=0x7fffce0afe20 "omg", name=0x7fffce0afdf8 "hello", pkey=0xc2f6b0, cert=0xdcddc0, ca=0x0, nid_key=146, nid_cert=146, iter=2048, mac_iter=-1, keytype=0, ctx=0x0, propq=0x0,
cb=0x0, cbarg=0x0) at crypto/pkcs12/p12_crt.c:111
#9 0x00007fffcd8a4f76 in PKCS12_create_ex (pass=0x7fffce0afe20 "omg", name=0x7fffce0afdf8 "hello", pkey=0xc2f6b0, cert=0xdcddc0, ca=0x0, nid_key=146, nid_cert=146, iter=0, mac_iter=-1, keytype=0, ctx=0x0, propq=0x0)
at crypto/pkcs12/p12_crt.c:176
#10 0x00007fffcd8a4fd0 in PKCS12_create (pass=0x7fffce0afe20 "omg", name=0x7fffce0afdf8 "hello", pkey=0xc2f6b0, cert=0xdcddc0, ca=0x0, nid_key=146, nid_cert=146, iter=0, mac_iter=-1, keytype=0)
at crypto/pkcs12/p12_crt.c:185
#11 0x00007fffce041459 in ossl_pkcs12_s_create (argc=9, argv=0x7fffe92ff828, self=140736648167080) at ossl_pkcs12.c:150
...
Below is the part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. PKCS#12 was more complicated than I had always assumed. https://datatracker.ietf.org/doc/html/rfc7292#appendix-C says:
The PBES1 encryption scheme defined in PKCS [#]5 provides a number of algorithm identifiers for deriving keys and IVs; here, we specify a few more, all of which use the procedure detailed in Appendices B.2 and B.3 to construct keys (and IVs, where needed).
[...]
pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3}
I also realized that PBKDF1 can't be used for 3DES in the first place due to its larger key size, so PKCS#12 had to use something else.
Thanks for pointing this out.
Anyway, I will revert this part to the original logic.
I'm fine with either keeping AES only or 3DES only. I just don't feel we need to test different things with different OpenSSL variants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reverted this conditional logic.
Note that I wrote about the above error with the OpenSSL::PKCS12.create with key_pbe: PBE-SHA1-3DES, cert_pbe: PBE-SHA1-3DES, mac_iter: -1 into the comment and commit message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I noticed you added your comment 2 hours ago. Let me check the comment tomorrow.
This is interesting. It appears that the underlying function in OpenSSL, I also think using PBES2/AES is better, but I'd prefer to reduce conditionals because I'm not very familiar with PKCS#12 and want to keep it simple. |
Yes your preference makes sense to me. I will revert the conditional logic to the original logic. |
* OpenSSL::PKCS12.create calling the PKCS12_create() has the argument mac_iter which uses a MAC key using PKCS12KDF which is not FIPS-approved. * OpenSSL::PKCS12.new with base64-encoded example calling PKCS12_parse() verifies the MAC key using PKCS12KDF which is not FIPS-approved. * OpenSSL::PKCS12.create with key_pbe: PBE-SHA1-3DES, cert_pbe: PBE-SHA1-3DES and mac_iter: -1 to omit the MAC key, fails by trying to fetch PKCS12KDF. https://github.com/openssl/openssl/blob/1cb0d36b39f69367d63e940976faaa2c252763b4/crypto/pkcs12/p12_key.c#L92-L94
* More precisely * Updating the rsa-1.pem file path.
4c7ffa6 to
342049e
Compare
|
I rebased this PR, fixing mentioned from you. Now there are 2 commits in the PR. The first commit is to the main. The 2nd commit is to update the comments. Could you review the PR again? Thanks. |
This PR is working in progress.
I see the test failures on LibreSSL and AWS-LC cases.
AES-256-CBCusingPBKDF2which is FIPS-approved, instead of thePBE-SHA1-3DESusingPKCS12KDFwhich is not FIPS-approved. See also the man page openssl-pkcs12(1).OpenSSL::PKCS12.createcalling thePKCS12_createhas the argumentmac_iterwhich uses a MAC key usingPKCS12KDFwhich is not FIPS-approved. In the FIPS case, set themac_iter = -1to omit the MAC key. See also the man page PKCS12_create(3).OpenSSL::PKCS12.newcallingPKCS12_parseverifies the MAC usingPKCS12KDFwhich is not FIPS-approved, I created the test data without MAC by theopenssl pkcs12 -nomac.