@@ -251,6 +251,48 @@ ossl_pkcs12_to_der(VALUE self)
251251 return str ;
252252}
253253
254+ /*
255+ * call-seq:
256+ * pkcs12.set_mac(pass, salt = nil, iter = nil, md_type = nil)
257+ *
258+ * Sets MAC parameters and generates MAC over the PKCS #12 structure.
259+ *
260+ * This method uses HMAC and the PKCS #12 specific password-based KDF as
261+ * specified in the original PKCS #12.
262+ *
263+ * See also the man page PKCS12_set_mac(3).
264+ *
265+ * Added in version 3.3.0.
266+ */
267+ static VALUE
268+ pkcs12_set_mac (int argc , VALUE * argv , VALUE self )
269+ {
270+ PKCS12 * p12 ;
271+ VALUE pass , salt , iter , md_name ;
272+ int iter_i = 0 ;
273+ const EVP_MD * md_type = NULL ;
274+
275+ rb_scan_args (argc , argv , "13" , & pass , & salt , & iter , & md_name );
276+ rb_check_frozen (self );
277+ GetPKCS12 (self , p12 );
278+
279+ StringValue (pass );
280+ if (!NIL_P (salt ))
281+ StringValue (salt );
282+ if (!NIL_P (iter ))
283+ iter_i = NUM2INT (iter );
284+ if (!NIL_P (md_name ))
285+ md_type = ossl_evp_get_digestbyname (md_name );
286+
287+ if (!PKCS12_set_mac (p12 , RSTRING_PTR (pass ), RSTRING_LENINT (pass ),
288+ !NIL_P (salt ) ? (unsigned char * )RSTRING_PTR (salt ) : NULL ,
289+ !NIL_P (salt ) ? RSTRING_LENINT (salt ) : 0 ,
290+ iter_i , md_type ))
291+ ossl_raise (ePKCS12Error , "PKCS12_set_mac" );
292+
293+ return Qnil ;
294+ }
295+
254296void
255297Init_ossl_pkcs12 (void )
256298{
@@ -276,6 +318,7 @@ Init_ossl_pkcs12(void)
276318 rb_attr (cPKCS12 , rb_intern ("ca_certs" ), 1 , 0 , Qfalse );
277319 rb_define_method (cPKCS12 , "initialize" , ossl_pkcs12_initialize , -1 );
278320 rb_define_method (cPKCS12 , "to_der" , ossl_pkcs12_to_der , 0 );
321+ rb_define_method (cPKCS12 , "set_mac" , pkcs12_set_mac , -1 );
279322
280323 /* MSIE specific PKCS12 key usage extensions */
281324 rb_define_const (cPKCS12 , "KEY_EX" , INT2NUM (KEY_EX ));
0 commit comments