Class: OpenSSL::PKey::PKey

Inherits:
Object
  • Object
show all
Defined in:
ext/openssl/ossl_pkey.c,
ext/openssl/ossl_pkey.c,
ext/openssl/ossl_pkey_dh.c,
ext/openssl/ossl_pkey_ec.c,
ext/openssl/ossl_pkey_dsa.c,
ext/openssl/ossl_pkey_rsa.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, DSA, EC, RSA

Instance Method Summary collapse

Constructor Details

#newself

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



265
266
267
268
269
270
271
272
# File 'ext/openssl/ossl_pkey.c', line 265

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 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)

Returns:

  • (String)


291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'ext/openssl/ossl_pkey.c', line 291

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 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

Returns:

  • (String)


347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'ext/openssl/ossl_pkey.c', line 347

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");
    }
}