[ruby/openssl] pkcs12: add PKCS12#set_mac
Add a binding for PKCS12_set_mac() to set MAC parameters and (re-)calculate MAC for the content. This allows generating PKCS #12 with consistent MAC parameters with different OpenSSL versions. OpenSSL 3.0 changed the default hash function used for HMAC and the KDF from SHA-1 to SHA-256. Fixes: https://github.com/ruby/openssl/issues/772 https://github.com/ruby/openssl/commit/f5ed2a74b6
This commit is contained in:
parent
78f55ccd9b
commit
c79b435407
Notes:
git
2024-12-21 18:34:05 +00:00
@ -251,6 +251,48 @@ ossl_pkcs12_to_der(VALUE self)
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* pkcs12.set_mac(pass, salt = nil, iter = nil, md_type = nil)
|
||||
*
|
||||
* Sets MAC parameters and generates MAC over the PKCS #12 structure.
|
||||
*
|
||||
* This method uses HMAC and the PKCS #12 specific password-based KDF as
|
||||
* specified in the original PKCS #12.
|
||||
*
|
||||
* See also the man page PKCS12_set_mac(3).
|
||||
*
|
||||
* Added in version 3.3.0.
|
||||
*/
|
||||
static VALUE
|
||||
pkcs12_set_mac(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
PKCS12 *p12;
|
||||
VALUE pass, salt, iter, md_name;
|
||||
int iter_i = 0;
|
||||
const EVP_MD *md_type = NULL;
|
||||
|
||||
rb_scan_args(argc, argv, "13", &pass, &salt, &iter, &md_name);
|
||||
rb_check_frozen(self);
|
||||
GetPKCS12(self, p12);
|
||||
|
||||
StringValue(pass);
|
||||
if (!NIL_P(salt))
|
||||
StringValue(salt);
|
||||
if (!NIL_P(iter))
|
||||
iter_i = NUM2INT(iter);
|
||||
if (!NIL_P(md_name))
|
||||
md_type = ossl_evp_get_digestbyname(md_name);
|
||||
|
||||
if (!PKCS12_set_mac(p12, RSTRING_PTR(pass), RSTRING_LENINT(pass),
|
||||
!NIL_P(salt) ? (unsigned char *)RSTRING_PTR(salt) : NULL,
|
||||
!NIL_P(salt) ? RSTRING_LENINT(salt) : 0,
|
||||
iter_i, md_type))
|
||||
ossl_raise(ePKCS12Error, "PKCS12_set_mac");
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
void
|
||||
Init_ossl_pkcs12(void)
|
||||
{
|
||||
@ -276,6 +318,7 @@ Init_ossl_pkcs12(void)
|
||||
rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse);
|
||||
rb_define_method(cPKCS12, "initialize", ossl_pkcs12_initialize, -1);
|
||||
rb_define_method(cPKCS12, "to_der", ossl_pkcs12_to_der, 0);
|
||||
rb_define_method(cPKCS12, "set_mac", pkcs12_set_mac, -1);
|
||||
|
||||
/* MSIE specific PKCS12 key usage extensions */
|
||||
rb_define_const(cPKCS12, "KEY_EX", INT2NUM(KEY_EX));
|
||||
|
@ -337,6 +337,48 @@ BC8fv38mue8LZVcbHQQIUNrWKEnskCoCAggA
|
||||
)
|
||||
assert_equal p12.to_der, p12.dup.to_der
|
||||
end
|
||||
|
||||
def test_set_mac_pkcs12kdf
|
||||
p12 = OpenSSL::PKCS12.create(
|
||||
"pass",
|
||||
"name",
|
||||
@mykey,
|
||||
@mycert,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
1234, # mac_iter
|
||||
nil,
|
||||
)
|
||||
macdata = macdata(p12)
|
||||
# Depends on the OpenSSL version: SHA256 in OpenSSL >= 3.0
|
||||
assert_include ["SHA1", "SHA256"], macdata[:mac_algo]
|
||||
assert_equal 1234, macdata[:iter]
|
||||
|
||||
p12.set_mac("pass", "macsalt", 2345, "SHA384")
|
||||
macdata = macdata(p12)
|
||||
assert_equal "SHA384", macdata[:mac_algo]
|
||||
assert_equal "macsalt", macdata[:salt]
|
||||
assert_equal 2345, macdata[:iter]
|
||||
assert_equal @mykey.to_der, OpenSSL::PKCS12.new(p12.to_der, "pass").key.to_der
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def macdata(p12)
|
||||
# See RFC 7292
|
||||
asn1 = OpenSSL::ASN1.decode(p12.to_der)
|
||||
macdata = asn1.value[2]
|
||||
mac = macdata.value[0]
|
||||
mac_algo = mac.value[0].value[0].value
|
||||
_mac_params = mac.value[0].value[1]
|
||||
{
|
||||
mac_algo: mac_algo,
|
||||
salt: macdata.value[1].value,
|
||||
iter: macdata.value[2]&.value,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user