# class OpenSSL::PKey::PKey

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

### Public Class Methods

new → self click to toggle source

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

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

### Public Instance Methods

sign(digest, data) → String click to toggle source

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)

    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 click to toggle source

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

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