Class: OpenSSL::PKey::PKey

Inherits:
Object
  • Object
show all
Defined in:
ossl_pkey.c,
ossl_pkey.c,
ossl_pkey_dh.c,
ossl_pkey_ec.c,
ossl_pkey_dsa.c,
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.


293
294
295
296
297
298
299
300
# File 'ossl_pkey.c', line 293

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

#inspectString

Returns a string describing the PKey object.

Returns:

  • (String)

325
326
327
328
329
330
331
332
333
334
335
336
# File 'ossl_pkey.c', line 325

static VALUE
ossl_pkey_inspect(VALUE self)
{
    EVP_PKEY *pkey;
    int nid;

    GetPKey(self, pkey);
    nid = EVP_PKEY_id(pkey);
    return rb_sprintf("#<%"PRIsVALUE":%p oid=%s>",
                      rb_class_name(CLASS_OF(self)), (void *)self,
                      OBJ_nid2sn(nid));
}

#oidString

Returns the short name of the OID associated with pkey.

Returns:

  • (String)

308
309
310
311
312
313
314
315
316
317
# File 'ossl_pkey.c', line 308

static VALUE
ossl_pkey_oid(VALUE self)
{
    EVP_PKEY *pkey;
    int nid;

    GetPKey(self, pkey);
    nid = EVP_PKEY_id(pkey);
    return rb_str_new_cstr(OBJ_nid2sn(nid));
}

#private_to_derString #private_to_der(cipher, password) ⇒ String

Serializes the private key to DER-encoded PKCS #8 format. If called without arguments, unencrypted PKCS #8 PrivateKeyInfo format is used. If called with a cipher name and a password, PKCS #8 EncryptedPrivateKeyInfo format with PBES2 encryption scheme is used.

Overloads:

  • #private_to_derString

    Returns:

    • (String)
  • #private_to_der(cipher, password) ⇒ String

    Returns:

    • (String)

387
388
389
390
391
# File 'ossl_pkey.c', line 387

static VALUE
ossl_pkey_private_to_der(int argc, VALUE *argv, VALUE self)
{
    return do_pkcs8_export(argc, argv, self, 1);
}

#private_to_pemString #private_to_pem(cipher, password) ⇒ String

Serializes the private key to PEM-encoded PKCS #8 format. See #private_to_der for more details.

Overloads:

  • #private_to_pemString

    Returns:

    • (String)
  • #private_to_pem(cipher, password) ⇒ String

    Returns:

    • (String)

401
402
403
404
405
# File 'ossl_pkey.c', line 401

static VALUE
ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
{
    return do_pkcs8_export(argc, argv, self, 0);
}

#public_to_derString

Serializes the public key to DER-encoded X.509 SubjectPublicKeyInfo format.

Returns:

  • (String)

438
439
440
441
442
# File 'ossl_pkey.c', line 438

static VALUE
ossl_pkey_public_to_der(VALUE self)
{
    return do_spki_export(self, 1);
}

#public_to_pemString

Serializes the public key to PEM-encoded X.509 SubjectPublicKeyInfo format.

Returns:

  • (String)

450
451
452
453
454
# File 'ossl_pkey.c', line 450

static VALUE
ossl_pkey_public_to_pem(VALUE self)
{
    return do_spki_export(self, 0);
}

#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.new('SHA256')
pkey = OpenSSL::PKey::RSA.new(2048)
signature = pkey.sign(digest, data)

Returns:

  • (String)

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
# File 'ossl_pkey.c', line 473

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.new('SHA256')
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)

529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
# File 'ossl_pkey.c', line 529

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