In Files

  • openssl/ossl_pkey.c

Class/Module Index [+]

Quicksearch

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

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