[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;
|
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
|
void
|
||||||
Init_ossl_pkcs12(void)
|
Init_ossl_pkcs12(void)
|
||||||
{
|
{
|
||||||
@ -276,6 +318,7 @@ Init_ossl_pkcs12(void)
|
|||||||
rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse);
|
rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse);
|
||||||
rb_define_method(cPKCS12, "initialize", ossl_pkcs12_initialize, -1);
|
rb_define_method(cPKCS12, "initialize", ossl_pkcs12_initialize, -1);
|
||||||
rb_define_method(cPKCS12, "to_der", ossl_pkcs12_to_der, 0);
|
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 */
|
/* MSIE specific PKCS12 key usage extensions */
|
||||||
rb_define_const(cPKCS12, "KEY_EX", INT2NUM(KEY_EX));
|
rb_define_const(cPKCS12, "KEY_EX", INT2NUM(KEY_EX));
|
||||||
|
@ -337,6 +337,48 @@ BC8fv38mue8LZVcbHQQIUNrWKEnskCoCAggA
|
|||||||
)
|
)
|
||||||
assert_equal p12.to_der, p12.dup.to_der
|
assert_equal p12.to_der, p12.dup.to_der
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user