123456789_123456789_123456789_123456789_123456789_

Class: OpenSSL::PKey::PKey

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
DH, DSA, EC, RSA
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

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

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

Constructor Details

PKeyClass.newself

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

[ GitHub ]

  
# File 'ext/openssl/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.

[ GitHub ]

  
# File 'ext/openssl/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.

[ GitHub ]

  
# File 'ext/openssl/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.

[ GitHub ]

  
# File 'ext/openssl/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.

[ GitHub ]

  
# File 'ext/openssl/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.

[ GitHub ]

  
# File 'ext/openssl/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.

[ GitHub ]

  
# File 'ext/openssl/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 ::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.new('SHA256')
pkey = OpenSSL::PKey::RSA.new(2048)
signature = pkey.sign(digest, data)
[ GitHub ]

  
# File 'ext/openssl/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 ::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.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
[ GitHub ]

  
# File 'ext/openssl/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");
    }
}