Class: OpenSSL::PKey::RSA
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
PKey
|
|
Instance Chain:
self,
::OpenSSL::Marshal ,
PKey
|
|
Inherits: |
OpenSSL::PKey::PKey
|
Defined in: | ext/openssl/ossl_pkey_rsa.c, ext/openssl/lib/openssl/pkey.rb |
Overview
RSA
is an asymmetric public key algorithm that has been formalized in RFC 3447. It is in widespread use in public key infrastructures (PKI) where certificates (cf. ::OpenSSL::X509::Certificate
) often are issued on the basis of a public/private RSA
key pair. RSA
is used in a wide field of applications such as secure (symmetric) key exchange, e.g. when establishing a secure TLS/SSL connection. It is also used in various digital signature schemes.
Constant Summary
-
NO_PADDING =
# File 'ext/openssl/lib/openssl/pkey.rb', line 4533
-
PKCS1_OAEP_PADDING =
# File 'ext/openssl/lib/openssl/pkey.rb', line 4544
-
PKCS1_PADDING =
# File 'ext/openssl/lib/openssl/pkey.rb', line 4511
-
SSLV23_PADDING =
# File 'ext/openssl/lib/openssl/pkey.rb', line 4522
Class Method Summary
-
.generate(size, exponent = 65537) ⇒ RSA
Generates an RSA keypair.
-
.new ⇒ RSA
constructor
Internal use only
Generates or loads an RSA keypair.
PKey
- Inherited
.new | Because PKey is an abstract class, actually calling this method explicitly will raise a NotImplementedError. |
Instance Attribute Summary
-
#private? ⇒ Boolean
readonly
Does this keypair contain a private key?
-
#public? ⇒ Boolean
readonly
The return value is always
true
since every private key is also a public key.
Instance Method Summary
-
#export([cipher, password]) ⇒ PEM-format String
Alias for #to_s.
- #initialize_copy(other)
-
#params ⇒ Hash
THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
-
#private_decrypt(string) ⇒ String
Decrypt
string
, which has been encrypted with the public key, with the private key. -
#private_encrypt(string) ⇒ String
Encrypt
string
with the private key. -
#public_decrypt(string) ⇒ String
Decrypt
string
, which has been encrypted with the private key, with the public key. -
#public_encrypt(string) ⇒ String
Encrypt
string
with the public key. -
#public_key ⇒ RSA
Returns a new
RSA
instance that carries just the public key components. -
#set_crt_params(dmp1, dmq1, iqmp) ⇒ self
Sets dmp1, dmq1, iqmp for the
RSA
instance. -
#set_factors(p, q) ⇒ self
Sets p, q for the
RSA
instance. -
#set_key(n, e, d) ⇒ self
Sets n, e, d for the
RSA
instance. -
#sign_pss(digest, data, salt_length:, mgf1_hash:) ⇒ String
Signs data using the Probabilistic Signature Scheme (RSA-PSS) and returns the calculated signature.
-
#to_der ⇒ DER-format String
Serializes a private or public key to a DER-encoding.
-
#to_pem([cipher, password]) ⇒ PEM-format String
Alias for #to_s.
-
#to_s([cipher, password]) ⇒ PEM-format String
(also: #export, #to_pem)
Serializes a private or public key to a PEM-encoding.
-
#verify_pss(digest, signature, data, salt_length:, mgf1_hash:) ⇒ Boolean
Verifies data using the Probabilistic Signature Scheme (RSA-PSS).
- #translate_padding_mode(num) private
::OpenSSL::Marshal
- Included
PKey
- Inherited
#compare? | Used primarily to check if an X509::Certificate#public_key compares to its private key. |
#decrypt | Performs a public key decryption operation using |
#derive | Derives a shared secret from pkey and peer_pkey. |
#encrypt | Performs a public key encryption operation using |
#initialize_copy, | |
#inspect | Returns a string describing the |
#oid | Returns the short name of the OID associated with pkey. |
#private_to_der | Serializes the private key to DER-encoded PKCS #8 format. |
#private_to_pem | Serializes the private key to PEM-encoded PKCS #8 format. |
#public_to_der | Serializes the public key to DER-encoded X.509 SubjectPublicKeyInfo format. |
#public_to_pem | Serializes the public key to PEM-encoded X.509 SubjectPublicKeyInfo format. |
#raw_private_key | See the |
#raw_public_key | See the |
#sign | Hashes and signs the |
#sign_raw | Signs |
#to_text | Dumps key parameters, public key, and private key components contained in the key into a human-readable text. |
#verify | Verifies the |
#verify_raw | Verifies the |
#verify_recover | Recovers the signed data from |
Constructor Details
.new ⇒ RSA
.new(encoded_key [, password ]) ⇒ RSA
.new(encoded_key) ⇒ RSA
.new(size [, exponent]) ⇒ RSA
RSA
.new(encoded_key [, password ]) ⇒ RSA
.new(encoded_key) ⇒ RSA
.new(size [, exponent]) ⇒ RSA
Generates or loads an RSA keypair.
If called without arguments, creates a new instance with no key components set. They can be set individually by #set_key, #set_factors, and #set_crt_params.
If called with a String, tries to parse as DER or PEM encoding of an RSA key. Note that if password is not specified, but the key is encrypted with a password, OpenSSL will prompt for it. See also OpenSSL::PKey.read which can parse keys of any kind.
If called with a number, generates a new key pair. This form works as an alias of .generate.
Examples:
OpenSSL::PKey::RSA.new 2048
OpenSSL::PKey::RSA.new File.read 'rsa.pem'
OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my password'
# File 'ext/openssl/ossl_pkey_rsa.c', line 76
static VALUE ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; RSA *rsa; BIO *in = NULL; VALUE arg, pass; int type; TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); if (pkey) rb_raise(rb_eTypeError, "pkey already initialized"); /* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ rb_scan_args(argc, argv, "02", &arg, &pass); if (argc == 0) { rsa = RSA_new(); if (!rsa) ossl_raise(eRSAError, "RSA_new"); goto legacy; } pass = ossl_pem_passwd_value(pass); arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); /* First try RSAPublicKey format */ rsa = d2i_RSAPublicKey_bio(in, NULL); if (rsa) goto legacy; OSSL_BIO_reset(in); rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); if (rsa) goto legacy; OSSL_BIO_reset(in); /* Use the generic routine */ pkey = ossl_pkey_read_generic(in, pass); BIO_free(in); if (!pkey) ossl_raise(eRSAError, "Neither PUB key nor PRIV key"); type = EVP_PKEY_base_id(pkey); if (type != EVP_PKEY_RSA) { EVP_PKEY_free(pkey); rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type)); } RTYPEDDATA_DATA(self) = pkey; return self; legacy: BIO_free(in); pkey = EVP_PKEY_new(); if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) { EVP_PKEY_free(pkey); RSA_free(rsa); ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); } RTYPEDDATA_DATA(self) = pkey; return self; }
Class Method Details
.generate(size, exponent = 65537) ⇒ RSA
Generates an RSA keypair.
See also OpenSSL::PKey.generate_key.
size
-
The desired key size in bits.
exponent
-
An odd Integer, normally 3, 17, or 65537.
# File 'ext/openssl/lib/openssl/pkey.rb', line 343
def generate(size, exp = 0x10001, &blk) OpenSSL::PKey.generate_key("RSA", { "rsa_keygen_bits" => size, "rsa_keygen_pubexp" => exp, }, &blk) end
Instance Attribute Details
#private? ⇒ Boolean
(readonly)
Does this keypair contain a private key?
# File 'ext/openssl/ossl_pkey_rsa.c', line 193
static VALUE ossl_rsa_is_private(VALUE self) { OSSL_3_const RSA *rsa; GetRSA(self, rsa); return RSA_PRIVATE(self, rsa) ? Qtrue : Qfalse; }
#public? ⇒ Boolean
(readonly)
The return value is always true
since every private key is also a public key.
# File 'ext/openssl/ossl_pkey_rsa.c', line 174
static VALUE ossl_rsa_is_public(VALUE self) { OSSL_3_const RSA *rsa; GetRSA(self, rsa); /* * This method should check for n and e. BUG. */ (void)rsa; return Qtrue; }
Instance Method Details
#export([cipher, password]) ⇒ PEM
-format
String
#to_pem([cipher, password]) ⇒ PEM
-format
String
#to_s([cipher, password]) ⇒ PEM
-format
String
PEM
-format
String
#to_pem([cipher, password]) ⇒ PEM
-format
String
#to_s([cipher, password]) ⇒ PEM
-format
String
Alias for #to_s.
#initialize_copy(other)
[ GitHub ]# File 'ext/openssl/ossl_pkey_rsa.c', line 139
static VALUE ossl_rsa_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; RSA *rsa, *rsa_new; TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); if (pkey) rb_raise(rb_eTypeError, "pkey already initialized"); GetRSA(other, rsa); rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, (d2i_of_void *)d2i_RSAPrivateKey, (char *)rsa); if (!rsa_new) ossl_raise(eRSAError, "ASN1_dup"); pkey = EVP_PKEY_new(); if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa_new) != 1) { RSA_free(rsa_new); ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); } RTYPEDDATA_DATA(self) = pkey; return self; }
#params ⇒ Hash
THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
Stores all parameters of key to the hash. The hash has keys ‘n’, ‘e’, ‘d’, ‘p’, ‘q’, ‘dmp1’, ‘dmq1’, ‘iqmp’.
Don’t use :-)) (It’s up to you)
# File 'ext/openssl/ossl_pkey_rsa.c', line 508
static VALUE ossl_rsa_get_params(VALUE self) { OSSL_3_const RSA *rsa; VALUE hash; const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; GetRSA(self, rsa); RSA_get0_key(rsa, &n, &e, &d); RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); hash = rb_hash_new(); rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(n)); rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(e)); rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(d)); rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q)); rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(dmp1)); rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(dmq1)); rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(iqmp)); return hash; }
#private_decrypt(string) ⇒ String
#private_decrypt(string, padding) ⇒ String
String
#private_decrypt(string, padding) ⇒ String
Decrypt string
, which has been encrypted with the public key, with the private key. padding
defaults to PKCS1_PADDING, which is known to be insecure but is kept for backwards compatibility.
Deprecated in version 3.0. Consider using PKey#encrypt and PKey#decrypt instead.
# File 'ext/openssl/lib/openssl/pkey.rb', line 439
def private_decrypt(data, padding = PKCS1_PADDING) n or raise OpenSSL::PKey::RSAError, "incomplete RSA" private? or raise OpenSSL::PKey::RSAError, "private key needed." begin decrypt(data, { "rsa_padding_mode" => translate_padding_mode(padding), }) rescue OpenSSL::PKey::PKeyError raise OpenSSL::PKey::RSAError, $!. end end
#private_encrypt(string) ⇒ String
#private_encrypt(string, padding) ⇒ String
String
#private_encrypt(string, padding) ⇒ String
Encrypt string
with the private key. padding
defaults to PKCS1_PADDING, which is known to be insecure but is kept for backwards compatibility. The encrypted string output can be decrypted using #public_decrypt.
Deprecated in version 3.0. Consider using PKey#sign_raw and PKey#verify_raw, and PKey#verify_recover instead.
# File 'ext/openssl/lib/openssl/pkey.rb', line 373
def private_encrypt(string, padding = PKCS1_PADDING) n or raise OpenSSL::PKey::RSAError, "incomplete RSA" private? or raise OpenSSL::PKey::RSAError, "private key needed." begin sign_raw(nil, string, { "rsa_padding_mode" => translate_padding_mode(padding), }) rescue OpenSSL::PKey::PKeyError raise OpenSSL::PKey::RSAError, $!. end end
#public_decrypt(string) ⇒ String
#public_decrypt(string, padding) ⇒ String
String
#public_decrypt(string, padding) ⇒ String
Decrypt string
, which has been encrypted with the private key, with the public key. padding
defaults to PKCS1_PADDING which is known to be insecure but is kept for backwards compatibility.
Deprecated in version 3.0. Consider using PKey#sign_raw and PKey#verify_raw, and PKey#verify_recover instead.
# File 'ext/openssl/lib/openssl/pkey.rb', line 396
def public_decrypt(string, padding = PKCS1_PADDING) n or raise OpenSSL::PKey::RSAError, "incomplete RSA" begin verify_recover(nil, string, { "rsa_padding_mode" => translate_padding_mode(padding), }) rescue OpenSSL::PKey::PKeyError raise OpenSSL::PKey::RSAError, $!. end end
#public_encrypt(string) ⇒ String
#public_encrypt(string, padding) ⇒ String
String
#public_encrypt(string, padding) ⇒ String
Encrypt string
with the public key. padding
defaults to PKCS1_PADDING, which is known to be insecure but is kept for backwards compatibility. The encrypted string output can be decrypted using #private_decrypt.
Deprecated in version 3.0. Consider using PKey#encrypt and PKey#decrypt instead.
# File 'ext/openssl/lib/openssl/pkey.rb', line 418
def public_encrypt(data, padding = PKCS1_PADDING) n or raise OpenSSL::PKey::RSAError, "incomplete RSA" begin encrypt(data, { "rsa_padding_mode" => translate_padding_mode(padding), }) rescue OpenSSL::PKey::PKeyError raise OpenSSL::PKey::RSAError, $!. end end
#public_key ⇒ RSA
Returns a new RSA
instance that carries just the public key components.
This method is provided for backwards compatibility. In most cases, there is no need to call this method.
For the purpose of serializing the public key, to PEM or DER encoding of X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and PKey#public_to_der.
#set_crt_params(dmp1, dmq1, iqmp) ⇒ self
Sets dmp1, dmq1, iqmp for the RSA
instance. They are calculated by d mod (p - 1)
, d mod (q - 1)
and q^(-1) mod p
respectively.
#set_factors(p, q) ⇒ self
Sets p, q for the RSA
instance.
#set_key(n, e, d) ⇒ self
Sets n, e, d for the RSA
instance.
#sign_pss(digest, data, salt_length:, mgf1_hash:) ⇒ String
Signs data using the Probabilistic Signature Scheme (RSA-PSS) and returns the calculated signature.
RSAError
will be raised if an error occurs.
See #verify_pss for the verification operation.
Parameters
- digest
-
A String containing the message digest algorithm name.
- data
-
A String. The data to be signed.
- salt_length
-
The length in octets of the salt. Two special values are reserved:
:digest
means the digest length, and:max
means the maximum possible length for the combination of the private key and the selected message digest algorithm. - mgf1_hash
-
The hash algorithm used in MGF1 (the currently supported mask generation function (MGF)).
Example
data = "Sign me!"
pkey = OpenSSL::PKey::RSA.new(2048)
signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256")
pub_key = OpenSSL::PKey.read(pkey.public_to_der)
puts pub_key.verify_pss("SHA256", signature, data,
salt_length: :auto, mgf1_hash: "SHA256") # => true
# File 'ext/openssl/ossl_pkey_rsa.c', line 340
static VALUE ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) { VALUE digest, data, options, kwargs[2], signature; static ID kwargs_ids[2]; EVP_PKEY *pkey; EVP_PKEY_CTX *pkey_ctx; const EVP_MD *md, *mgf1md; EVP_MD_CTX *md_ctx; size_t buf_len; int salt_len; if (!kwargs_ids[0]) { kwargs_ids[0] = rb_intern_const("salt_length"); kwargs_ids[1] = rb_intern_const("mgf1_hash"); } rb_scan_args(argc, argv, "2:", &digest, &data, &options); rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs); if (kwargs[0] == ID2SYM(rb_intern("max"))) salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */ else if (kwargs[0] == ID2SYM(rb_intern("digest"))) salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ else salt_len = NUM2INT(kwargs[0]); mgf1md = ossl_evp_get_digestbyname(kwargs[1]); pkey = GetPrivPKeyPtr(self); buf_len = EVP_PKEY_size(pkey); md = ossl_evp_get_digestbyname(digest); StringValue(data); signature = rb_str_new(NULL, (long)buf_len); md_ctx = EVP_MD_CTX_new(); if (!md_ctx) goto err; if (EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) goto err; if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1) goto err; if (EVP_DigestSignUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) goto err; if (EVP_DigestSignFinal(md_ctx, (unsigned char *)RSTRING_PTR(signature), &buf_len) != 1) goto err; rb_str_set_len(signature, (long)buf_len); EVP_MD_CTX_free(md_ctx); return signature; err: EVP_MD_CTX_free(md_ctx); ossl_raise(eRSAError, NULL); }
#to_der ⇒ DER
-format
String
Serializes a private or public key to a DER-encoding.
See #to_pem for details.
This method is kept for compatibility. This should only be used when the PKCS #1 RSAPrivateKey format is required.
Consider using #public_to_der
or #private_to_der
instead.
# File 'ext/openssl/ossl_pkey_rsa.c', line 298
static VALUE ossl_rsa_to_der(VALUE self) { if (can_export_rsaprivatekey(self)) return ossl_pkey_export_traditional(0, NULL, self, 1); else return ossl_pkey_export_spki(self, 1); }
#export([cipher, password]) ⇒ PEM
-format
String
#to_pem([cipher, password]) ⇒ PEM
-format
String
#to_s([cipher, password]) ⇒ PEM
-format
String
PEM
-format
String
#to_pem([cipher, password]) ⇒ PEM
-format
String
#to_s([cipher, password]) ⇒ PEM
-format
String
Alias for #to_s.
#export([cipher, password]) ⇒ PEM
-format
String
#to_pem([cipher, password]) ⇒ PEM
-format
String
#to_s([cipher, password]) ⇒ PEM
-format
String
Also known as: #export, #to_pem
PEM
-format
String
#to_pem([cipher, password]) ⇒ PEM
-format
String
#to_s([cipher, password]) ⇒ PEM
-format
String
Serializes a private or public key to a PEM-encoding.
- When the key contains public components only
-
Serializes it into an X.509 SubjectPublicKeyInfo. The parameters cipher and password are ignored.
A PEM-encoded key will look like:
-----BEGIN PUBLIC KEY----- [...] -----END PUBLIC KEY-----
Consider using #public_to_pem instead. This serializes the key into an X.509 SubjectPublicKeyInfo regardless of whether the key is a public key or a private key.
- When the key contains private components, and no parameters are given
-
Serializes it into a PKCS #1 RSAPrivateKey.
A PEM-encoded key will look like:
-----BEGIN RSA PRIVATE KEY----- [...] -----END RSA PRIVATE KEY-----
- When the key contains private components, and cipher and password are given
-
Serializes it into a PKCS #1 RSAPrivateKey and encrypts it in OpenSSL’s traditional PEM encryption format. cipher must be a cipher name understood by OpenSSL::Cipher.new or an instance of OpenSSL::Cipher.
An encrypted PEM-encoded key will look like:
-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 [...] -----END RSA PRIVATE KEY-----
Note that this format uses MD5 to derive the encryption key, and hence will not be available on FIPS-compliant systems.
This method is kept for compatibility. This should only be used when the PKCS #1 RSAPrivateKey format is required.
Consider using #public_to_pem
(X.509 SubjectPublicKeyInfo) or #private_to_pem
(PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
# File 'ext/openssl/ossl_pkey_rsa.c', line 276
static VALUE ossl_rsa_export(int argc, VALUE *argv, VALUE self) { if (can_export_rsaprivatekey(self)) return ossl_pkey_export_traditional(argc, argv, self, 0); else return ossl_pkey_export_spki(self, 0); }
#translate_padding_mode(num) (private)
[ GitHub ]# File 'ext/openssl/lib/openssl/pkey.rb', line 456
private def translate_padding_mode(num) case num when PKCS1_PADDING "pkcs1" when SSLV23_PADDING "sslv23" when NO_PADDING "none" when PKCS1_OAEP_PADDING "oaep" else raise OpenSSL::PKey::PKeyError, "unsupported padding mode" end end
#verify_pss(digest, signature, data, salt_length:, mgf1_hash:) ⇒ Boolean
Verifies data using the Probabilistic Signature Scheme (RSA-PSS).
The return value is true
if the signature is valid, false
otherwise. RSAError
will be raised if an error occurs.
See #sign_pss for the signing operation and an example code.
Parameters
- digest
-
A String containing the message digest algorithm name.
- data
-
A String. The data to be signed.
- salt_length
-
The length in octets of the salt. Two special values are reserved:
:digest
means the digest length, and:auto
means automatically determining the length based on the signature. - mgf1_hash
-
The hash algorithm used in MGF1.
# File 'ext/openssl/ossl_pkey_rsa.c', line 427
static VALUE ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self) { VALUE digest, signature, data, options, kwargs[2]; static ID kwargs_ids[2]; EVP_PKEY *pkey; EVP_PKEY_CTX *pkey_ctx; const EVP_MD *md, *mgf1md; EVP_MD_CTX *md_ctx; int result, salt_len; if (!kwargs_ids[0]) { kwargs_ids[0] = rb_intern_const("salt_length"); kwargs_ids[1] = rb_intern_const("mgf1_hash"); } rb_scan_args(argc, argv, "3:", &digest, &signature, &data, &options); rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs); if (kwargs[0] == ID2SYM(rb_intern("auto"))) salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */ else if (kwargs[0] == ID2SYM(rb_intern("digest"))) salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ else salt_len = NUM2INT(kwargs[0]); mgf1md = ossl_evp_get_digestbyname(kwargs[1]); GetPKey(self, pkey); md = ossl_evp_get_digestbyname(digest); StringValue(signature); StringValue(data); md_ctx = EVP_MD_CTX_new(); if (!md_ctx) goto err; if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) goto err; if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1) goto err; if (EVP_DigestVerifyUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) goto err; result = EVP_DigestVerifyFinal(md_ctx, (unsigned char *)RSTRING_PTR(signature), RSTRING_LEN(signature)); switch (result) { case 0: ossl_clear_error(); EVP_MD_CTX_free(md_ctx); return Qfalse; case 1: EVP_MD_CTX_free(md_ctx); return Qtrue; default: goto err; } err: EVP_MD_CTX_free(md_ctx); ossl_raise(eRSAError, NULL); }