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