class OpenSSL::PKey::PKey - RDoc Documentation

# 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

inspect → string click to toggle source

Returns a string describing the `PKey` object.

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

oid → string click to toggle source

Returns the short name of the OID associated with pkey.

    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_der → string click to toggle source
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.

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

private_to_pem → string click to toggle source
private_to_pem(cipher, password) → string

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

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

public_to_der → string click to toggle source

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

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

public_to_pem → string click to toggle source

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

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

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

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