Class: OpenSSL::PKey::PKey
| Relationships & Source Files | |
| Extension / Inclusion / Inheritance Descendants | |
|
Subclasses:
|
|
| Inherits: | Object |
| Defined in: | ext/openssl/ossl_pkey_dh.c, ext/openssl/ossl_pkey.c, ext/openssl/ossl_pkey_dsa.c, ext/openssl/ossl_pkey_ec.c, ext/openssl/ossl_pkey_rsa.c |
Overview
Class Method Summary
-
PKeyClass.new ⇒ self
constructor
Because PKey is an abstract class, actually calling this method explicitly will raise a NotImplementedError.
Instance Method Summary
-
#sign(digest, data) ⇒ String
To sign the String data, digest, an instance of
::OpenSSL::Digest, must be provided. -
#verify(digest, signature, data) ⇒ String
To verify the String signature, digest, an instance of
::OpenSSL::Digest, must be provided to re-compute the message digest of the original data, also a String.
Constructor Details
PKeyClass.new ⇒ self
Because PKey is an abstract class, actually calling this method explicitly will raise a NotImplementedError.
# File 'ext/openssl/ossl_pkey.c', line 287
static VALUE
ossl_pkey_initialize(VALUE self)
{
if (rb_obj_is_instance_of(self, cPKey)) {
ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly");
}
return self;
}
Instance Method Details
#sign(digest, data) ⇒ String
To sign the String data, digest, an instance of ::OpenSSL::Digest, must be provided. The return value is again a String containing the signature. A PKeyError is raised should errors occur. Any previous state of the ::OpenSSL::Digest instance is irrelevant to the signature outcome, the digest instance is reset to its initial state during the operation.
Example
data = 'Sign me!'
digest = OpenSSL::Digest::SHA256.new
pkey = OpenSSL::PKey::RSA.new(2048)
signature = pkey.sign(digest, data)
# File 'ext/openssl/ossl_pkey.c', line 313
static VALUE
ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
{
EVP_PKEY *pkey;
const EVP_MD *md;
EVP_MD_CTX *ctx;
unsigned int buf_len;
VALUE str;
int result;
pkey = GetPrivPKeyPtr(self);
md = ossl_evp_get_digestbyname(digest);
StringValue(data);
str = rb_str_new(0, EVP_PKEY_size(pkey));
ctx = EVP_MD_CTX_new();
if (!ctx)
ossl_raise(ePKeyError, "EVP_MD_CTX_new");
if (!EVP_SignInit_ex(ctx, md, NULL)) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_SignInit_ex");
}
if (!EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_SignUpdate");
}
result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
EVP_MD_CTX_free(ctx);
if (!result)
ossl_raise(ePKeyError, "EVP_SignFinal");
rb_str_set_len(str, buf_len);
return str;
}
#verify(digest, signature, data) ⇒ String
To verify the String signature, digest, an instance of ::OpenSSL::Digest, must be provided to re-compute the message digest of the original data, also a String. The return value is true if the signature is valid, false otherwise. A PKeyError is raised should errors occur. Any previous state of the ::OpenSSL::Digest instance is irrelevant to the validation outcome, the digest instance is reset to its initial state during the operation.
Example
data = 'Sign me!'
digest = OpenSSL::Digest::SHA256.new
pkey = OpenSSL::PKey::RSA.new(2048)
signature = pkey.sign(digest, data)
pub_key = pkey.public_key
puts pub_key.verify(digest, signature, data) # => true
# File 'ext/openssl/ossl_pkey.c', line 369
static VALUE
ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
{
EVP_PKEY *pkey;
const EVP_MD *md;
EVP_MD_CTX *ctx;
int siglen, result;
GetPKey(self, pkey);
ossl_pkey_check_public_key(pkey);
md = ossl_evp_get_digestbyname(digest);
StringValue(sig);
siglen = RSTRING_LENINT(sig);
StringValue(data);
ctx = EVP_MD_CTX_new();
if (!ctx)
ossl_raise(ePKeyError, "EVP_MD_CTX_new");
if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_VerifyInit_ex");
}
if (!EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_VerifyUpdate");
}
result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), siglen, pkey);
EVP_MD_CTX_free(ctx);
switch (result) {
case 0:
ossl_clear_error();
return Qfalse;
case 1:
return Qtrue;
default:
ossl_raise(ePKeyError, "EVP_VerifyFinal");
}
}