Class: OpenSSL::PKey::PKey

Inherits:
Object
  • Object
show all
Defined in:
ossl_pkey.c,
ossl_pkey.c

Overview

An abstract class that bundles signature creation (PKey#sign) and validation (PKey#verify) that is common to all implementations except OpenSSL::PKey::DH

  • OpenSSL::PKey::RSA

  • OpenSSL::PKey::DSA

  • OpenSSL::PKey::EC

Direct Known Subclasses

DH, EC

Instance Method Summary collapse

Constructor Details

#newself

Because PKey is an abstract class, actually calling this method explicitly will raise a NotImplementedError.


245
246
247
248
249
250
251
252
# File 'ossl_pkey.c', line 245

static VALUE
ossl_pkey_initialize(VALUE self)
{
    if (rb_obj_is_instance_of(self, cPKey)) {
  ossl_raise(rb_eNotImpError, "OpenSSL::PKey::PKey is an abstract class.");
    }
    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 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)

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'ossl_pkey.c', line 271

static VALUE
ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
{
    EVP_PKEY *pkey;
    EVP_MD_CTX ctx;
    unsigned int buf_len;
    VALUE str;

    if (rb_funcall(self, id_private_q, 0, NULL) != Qtrue) {
  ossl_raise(rb_eArgError, "Private key is needed.");
    }
    GetPKey(self, pkey);
    EVP_SignInit(&ctx, GetDigestPtr(digest));
    StringValue(data);
    EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
    str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
    if (!EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey))
  ossl_raise(ePKeyError, NULL);
    assert((long)buf_len <= RSTRING_LEN(str));
    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 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

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'ossl_pkey.c', line 316

static VALUE
ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
{
    EVP_PKEY *pkey;
    EVP_MD_CTX ctx;

    GetPKey(self, pkey);
    EVP_VerifyInit(&ctx, GetDigestPtr(digest));
    StringValue(sig);
    StringValue(data);
    EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
    switch (EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey)) {
    case 0:
  return Qfalse;
    case 1:
  return Qtrue;
    default:
  ossl_raise(ePKeyError, NULL);
    }
    return Qnil; /* dummy */
}