summaryrefslogtreecommitdiffstats
path: root/OpenSSL/PKey/PKey.html
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSSL/PKey/PKey.html')
-rw-r--r--OpenSSL/PKey/PKey.html825
1 files changed, 772 insertions, 53 deletions
diff --git a/OpenSSL/PKey/PKey.html b/OpenSSL/PKey/PKey.html
index 5f981ef2..7b3cf677 100644
--- a/OpenSSL/PKey/PKey.html
+++ b/OpenSSL/PKey/PKey.html
@@ -73,6 +73,11 @@
<ul class="link-list" role="directory">
<li ><a href="#method-c-new">::new</a>
+ <li ><a href="#method-i-compare-3F">#compare?</a>
+ <li ><a href="#method-i-decrypt">#decrypt</a>
+ <li ><a href="#method-i-derive">#derive</a>
+ <li ><a href="#method-i-encrypt">#encrypt</a>
+ <li ><a href="#method-i-initialize_copy">#initialize_copy</a>
<li ><a href="#method-i-inspect">#inspect</a>
<li ><a href="#method-i-oid">#oid</a>
<li ><a href="#method-i-private_to_der">#private_to_der</a>
@@ -80,7 +85,11 @@
<li ><a href="#method-i-public_to_der">#public_to_der</a>
<li ><a href="#method-i-public_to_pem">#public_to_pem</a>
<li ><a href="#method-i-sign">#sign</a>
+ <li ><a href="#method-i-sign_raw">#sign_raw</a>
+ <li ><a href="#method-i-to_text">#to_text</a>
<li ><a href="#method-i-verify">#verify</a>
+ <li ><a href="#method-i-verify_raw">#verify_raw</a>
+ <li ><a href="#method-i-verify_recover">#verify_recover</a>
</ul>
</div>
@@ -149,6 +158,316 @@ ossl_pkey_initialize(VALUE self)
<h3>Public Instance Methods</h3>
</header>
+ <div id="method-i-compare-3F" class="method-detail ">
+ <div class="method-heading">
+ <span class="method-callseq">
+ compare?(another_pkey) &rarr; true | false
+ </span>
+ <span class="method-click-advice">click to toggle source</span>
+ </div>
+
+ <div class="method-description">
+ <p>Used primarily to check if an <a href="../X509/Certificate.html#method-i-public_key"><code>OpenSSL::X509::Certificate#public_key</code></a> compares to its private key.</p>
+
+<h2 id="method-i-compare-3F-label-Example">Example<span><a href="#method-i-compare-3F-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h2>
+
+<pre class="ruby"><span class="ruby-identifier">x509</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">X509</span><span class="ruby-operator">::</span><span class="ruby-constant">Certificate</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">pem_encoded_certificate</span>)
+<span class="ruby-identifier">rsa_key</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">PKey</span><span class="ruby-operator">::</span><span class="ruby-constant">RSA</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">pem_encoded_private_key</span>)
+
+<span class="ruby-identifier">rsa_key</span>.<span class="ruby-identifier">compare?</span>(<span class="ruby-identifier">x509</span>.<span class="ruby-identifier">public_key</span>) <span class="ruby-operator">=&gt;</span> <span class="ruby-keyword">true</span> <span class="ruby-operator">|</span> <span class="ruby-keyword">false</span>
+</pre>
+
+ <div class="method-source-code" id="compare-3F-source">
+ <pre>static VALUE
+ossl_pkey_compare(VALUE self, VALUE other)
+{
+ int ret;
+ EVP_PKEY *selfPKey;
+ EVP_PKEY *otherPKey;
+
+ GetPKey(self, selfPKey);
+ GetPKey(other, otherPKey);
+
+ /* Explicitly check the key type given EVP_PKEY_ASN1_METHOD(3)
+ * docs param_cmp could return any negative number.
+ */
+ if (EVP_PKEY_id(selfPKey) != EVP_PKEY_id(otherPKey))
+ ossl_raise(rb_eTypeError, &quot;cannot match different PKey types&quot;);
+
+ ret = EVP_PKEY_eq(selfPKey, otherPKey);
+
+ if (ret == 0)
+ return Qfalse;
+ else if (ret == 1)
+ return Qtrue;
+ else
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_eq&quot;);
+}</pre>
+ </div>
+ </div>
+
+
+ </div>
+
+ <div id="method-i-decrypt" class="method-detail ">
+ <div class="method-heading">
+ <span class="method-callseq">
+ decrypt(data [, options]) &rarr; string
+ </span>
+ <span class="method-click-advice">click to toggle source</span>
+ </div>
+
+ <div class="method-description">
+ <p>Performs a public key decryption operation using <code>pkey</code>.</p>
+
+<p>See <a href="PKey.html#method-i-encrypt"><code>encrypt</code></a> for a description of the parameters and an example.</p>
+
+<p>Added in version 3.0. See also the man page EVP_PKEY_decrypt(3).</p>
+
+ <div class="method-source-code" id="decrypt-source">
+ <pre>static VALUE
+ossl_pkey_decrypt(int argc, VALUE *argv, VALUE self)
+{
+ EVP_PKEY *pkey;
+ EVP_PKEY_CTX *ctx;
+ VALUE data, options, str;
+ size_t outlen;
+ int state;
+
+ GetPKey(self, pkey);
+ rb_scan_args(argc, argv, &quot;11&quot;, &amp;data, &amp;options);
+ StringValue(data);
+
+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
+ if (!ctx)
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_CTX_new&quot;);
+ if (EVP_PKEY_decrypt_init(ctx) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_decrypt_init&quot;);
+ }
+ if (!NIL_P(options)) {
+ pkey_ctx_apply_options(ctx, options, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ }
+ if (EVP_PKEY_decrypt(ctx, NULL, &amp;outlen,
+ (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data)) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_decrypt&quot;);
+ }
+ if (outlen &gt; LONG_MAX) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_raise(ePKeyError, &quot;decrypted data would be too large&quot;);
+ }
+ str = ossl_str_new(NULL, (long)outlen, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ if (EVP_PKEY_decrypt(ctx, (unsigned char *)RSTRING_PTR(str), &amp;outlen,
+ (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data)) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_decrypt&quot;);
+ }
+ EVP_PKEY_CTX_free(ctx);
+ rb_str_set_len(str, outlen);
+ return str;
+}</pre>
+ </div>
+ </div>
+
+
+ </div>
+
+ <div id="method-i-derive" class="method-detail ">
+ <div class="method-heading">
+ <span class="method-callseq">
+ derive(peer_pkey) &rarr; string
+ </span>
+ <span class="method-click-advice">click to toggle source</span>
+ </div>
+
+ <div class="method-description">
+ <p>Derives a shared secret from <em>pkey</em> and <em>peer_pkey</em>. <em>pkey</em> must contain the private components, <em>peer_pkey</em> must contain the public components.</p>
+
+ <div class="method-source-code" id="derive-source">
+ <pre>static VALUE
+ossl_pkey_derive(int argc, VALUE *argv, VALUE self)
+{
+ EVP_PKEY *pkey, *peer_pkey;
+ EVP_PKEY_CTX *ctx;
+ VALUE peer_pkey_obj, str;
+ size_t keylen;
+ int state;
+
+ GetPKey(self, pkey);
+ rb_scan_args(argc, argv, &quot;1&quot;, &amp;peer_pkey_obj);
+ GetPKey(peer_pkey_obj, peer_pkey);
+
+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
+ if (!ctx)
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_CTX_new&quot;);
+ if (EVP_PKEY_derive_init(ctx) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_derive_init&quot;);
+ }
+ if (EVP_PKEY_derive_set_peer(ctx, peer_pkey) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_derive_set_peer&quot;);
+ }
+ if (EVP_PKEY_derive(ctx, NULL, &amp;keylen) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_derive&quot;);
+ }
+ if (keylen &gt; LONG_MAX)
+ rb_raise(ePKeyError, &quot;derived key would be too large&quot;);
+ str = ossl_str_new(NULL, (long)keylen, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ if (EVP_PKEY_derive(ctx, (unsigned char *)RSTRING_PTR(str), &amp;keylen) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_derive&quot;);
+ }
+ EVP_PKEY_CTX_free(ctx);
+ rb_str_set_len(str, keylen);
+ return str;
+}</pre>
+ </div>
+ </div>
+
+
+ </div>
+
+ <div id="method-i-encrypt" class="method-detail ">
+ <div class="method-heading">
+ <span class="method-callseq">
+ encrypt(data [, options]) &rarr; string
+ </span>
+ <span class="method-click-advice">click to toggle source</span>
+ </div>
+
+ <div class="method-description">
+ <p>Performs a public key encryption operation using <code>pkey</code>.</p>
+
+<p>See <a href="PKey.html#method-i-decrypt"><code>decrypt</code></a> for the reverse operation.</p>
+
+<p>Added in version 3.0. See also the man page EVP_PKEY_encrypt(3).</p>
+<dl class="rdoc-list note-list"><dt><code>data</code>
+<dd>
+<p>A String to be encrypted.</p>
+</dd><dt><code>options</code>
+<dd>
+<p>A Hash that contains algorithm specific control operations to OpenSSL. See OpenSSL’s man page EVP_PKEY_CTX_ctrl_str(3) for details.</p>
+</dd></dl>
+
+<p>Example:</p>
+
+<pre class="ruby"><span class="ruby-identifier">pkey</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">PKey</span>.<span class="ruby-identifier">generate_key</span>(<span class="ruby-string">&quot;RSA&quot;</span>, <span class="ruby-value">rsa_keygen_bits:</span> <span class="ruby-value">2048</span>)
+<span class="ruby-identifier">data</span> = <span class="ruby-string">&quot;secret data&quot;</span>
+<span class="ruby-identifier">encrypted</span> = <span class="ruby-identifier">pkey</span>.<span class="ruby-identifier">encrypt</span>(<span class="ruby-identifier">data</span>, <span class="ruby-value">rsa_padding_mode:</span> <span class="ruby-string">&quot;oaep&quot;</span>)
+<span class="ruby-identifier">decrypted</span> = <span class="ruby-identifier">pkey</span>.<span class="ruby-identifier">decrypt</span>(<span class="ruby-identifier">data</span>, <span class="ruby-value">rsa_padding_mode:</span> <span class="ruby-string">&quot;oaep&quot;</span>)
+<span class="ruby-identifier">p</span> <span class="ruby-identifier">decrypted</span> <span class="ruby-comment">#=&gt; &quot;secret data&quot;</span>
+</pre>
+
+ <div class="method-source-code" id="encrypt-source">
+ <pre>static VALUE
+ossl_pkey_encrypt(int argc, VALUE *argv, VALUE self)
+{
+ EVP_PKEY *pkey;
+ EVP_PKEY_CTX *ctx;
+ VALUE data, options, str;
+ size_t outlen;
+ int state;
+
+ GetPKey(self, pkey);
+ rb_scan_args(argc, argv, &quot;11&quot;, &amp;data, &amp;options);
+ StringValue(data);
+
+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
+ if (!ctx)
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_CTX_new&quot;);
+ if (EVP_PKEY_encrypt_init(ctx) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_encrypt_init&quot;);
+ }
+ if (!NIL_P(options)) {
+ pkey_ctx_apply_options(ctx, options, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ }
+ if (EVP_PKEY_encrypt(ctx, NULL, &amp;outlen,
+ (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data)) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_encrypt&quot;);
+ }
+ if (outlen &gt; LONG_MAX) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_raise(ePKeyError, &quot;encrypted data would be too large&quot;);
+ }
+ str = ossl_str_new(NULL, (long)outlen, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ if (EVP_PKEY_encrypt(ctx, (unsigned char *)RSTRING_PTR(str), &amp;outlen,
+ (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data)) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_encrypt&quot;);
+ }
+ EVP_PKEY_CTX_free(ctx);
+ rb_str_set_len(str, outlen);
+ return str;
+}</pre>
+ </div>
+ </div>
+
+
+ </div>
+
+ <div id="method-i-initialize_copy" class="method-detail ">
+ <div class="method-heading">
+ <span class="method-name">initialize_copy</span><span
+ class="method-args">(p1)</span>
+ <span class="method-click-advice">click to toggle source</span>
+ </div>
+
+ <div class="method-description">
+
+
+ <div class="method-source-code" id="initialize_copy-source">
+ <pre>static VALUE
+ossl_pkey_initialize_copy(VALUE self, VALUE other)
+{
+ EVP_PKEY *pkey, *pkey_other;
+
+ TypedData_Get_Struct(self, EVP_PKEY, &amp;ossl_evp_pkey_type, pkey);
+ TypedData_Get_Struct(other, EVP_PKEY, &amp;ossl_evp_pkey_type, pkey_other);
+ if (pkey)
+ rb_raise(rb_eTypeError, &quot;pkey already initialized&quot;);
+ if (pkey_other) {
+ pkey = EVP_PKEY_dup(pkey_other);
+ if (!pkey)
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_dup&quot;);
+ RTYPEDDATA_DATA(self) = pkey;
+ }
+ return self;
+}</pre>
+ </div>
+ </div>
+
+
+ </div>
+
<div id="method-i-inspect" class="method-detail ">
<div class="method-heading">
<span class="method-callseq">
@@ -278,7 +597,7 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
<pre>static VALUE
ossl_pkey_public_to_der(VALUE self)
{
- return do_spki_export(self, 1);
+ return ossl_pkey_export_spki(self, 1);
}</pre>
</div>
</div>
@@ -301,7 +620,7 @@ ossl_pkey_public_to_der(VALUE self)
<pre>static VALUE
ossl_pkey_public_to_pem(VALUE self)
{
- return do_spki_export(self, 0);
+ return ossl_pkey_export_spki(self, 0);
}</pre>
</div>
</div>
@@ -312,56 +631,223 @@ ossl_pkey_public_to_pem(VALUE self)
<div id="method-i-sign" class="method-detail ">
<div class="method-heading">
<span class="method-callseq">
- sign(digest, data) &rarr; String
+ sign(digest, data [, options]) &rarr; string
</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
- <p>To sign the String <em>data</em>, <em>digest</em>, an instance of <a href="../Digest.html"><code>OpenSSL::Digest</code></a>, must be provided. The return value is again a String containing the signature. A <a href="PKeyError.html"><code>PKeyError</code></a> is raised should errors occur. Any previous state of the <a href="../Digest.html"><code>Digest</code></a> instance is irrelevant to the signature outcome, the digest instance is reset to its initial state during the operation.</p>
-
-<h2 id="method-i-sign-label-Example">Example<span><a href="#method-i-sign-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h2>
-
-<pre class="ruby"><span class="ruby-identifier">data</span> = <span class="ruby-string">&#39;Sign me!&#39;</span>
-<span class="ruby-identifier">digest</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">Digest</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">&#39;SHA256&#39;</span>)
-<span class="ruby-identifier">pkey</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">PKey</span><span class="ruby-operator">::</span><span class="ruby-constant">RSA</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">2048</span>)
-<span class="ruby-identifier">signature</span> = <span class="ruby-identifier">pkey</span>.<span class="ruby-identifier">sign</span>(<span class="ruby-identifier">digest</span>, <span class="ruby-identifier">data</span>)
+ <p>Hashes and signs the <code>data</code> using a message digest algorithm <code>digest</code> and a private key <code>pkey</code>.</p>
+
+<p>See <a href="PKey.html#method-i-verify"><code>verify</code></a> for the verification operation.</p>
+
+<p>See also the man page EVP_DigestSign(3).</p>
+<dl class="rdoc-list note-list"><dt><code>digest</code>
+<dd>
+<p>A String that represents the message digest algorithm name, or <code>nil</code> if the <a href="PKey.html"><code>PKey</code></a> type requires no digest algorithm. For backwards compatibility, this can be an instance of <a href="../Digest.html"><code>OpenSSL::Digest</code></a>. Its state will not affect the signature.</p>
+</dd><dt><code>data</code>
+<dd>
+<p>A String. The data to be hashed and signed.</p>
+</dd><dt><code>options</code>
+<dd>
+<p>A Hash that contains algorithm specific control operations to OpenSSL. See OpenSSL’s man page EVP_PKEY_CTX_ctrl_str(3) for details. <code>options</code> parameter was added in version 3.0.</p>
+</dd></dl>
+
+<p>Example:</p>
+
+<pre class="ruby"><span class="ruby-identifier">data</span> = <span class="ruby-string">&quot;Sign me!&quot;</span>
+<span class="ruby-identifier">pkey</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">PKey</span>.<span class="ruby-identifier">generate_key</span>(<span class="ruby-string">&quot;RSA&quot;</span>, <span class="ruby-value">rsa_keygen_bits:</span> <span class="ruby-value">2048</span>)
+<span class="ruby-identifier">signopts</span> = { <span class="ruby-value">rsa_padding_mode:</span> <span class="ruby-string">&quot;pss&quot;</span> }
+<span class="ruby-identifier">signature</span> = <span class="ruby-identifier">pkey</span>.<span class="ruby-identifier">sign</span>(<span class="ruby-string">&quot;SHA256&quot;</span>, <span class="ruby-identifier">data</span>, <span class="ruby-identifier">signopts</span>)
+
+<span class="ruby-comment"># Creates a copy of the RSA key pkey, but without the private components</span>
+<span class="ruby-identifier">pub_key</span> = <span class="ruby-identifier">pkey</span>.<span class="ruby-identifier">public_key</span>
+<span class="ruby-identifier">puts</span> <span class="ruby-identifier">pub_key</span>.<span class="ruby-identifier">verify</span>(<span class="ruby-string">&quot;SHA256&quot;</span>, <span class="ruby-identifier">signature</span>, <span class="ruby-identifier">data</span>, <span class="ruby-identifier">signopts</span>) <span class="ruby-comment"># =&gt; true</span>
</pre>
<div class="method-source-code" id="sign-source">
<pre>static VALUE
-ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
+ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
- const EVP_MD *md;
+ VALUE digest, data, options, sig;
+ const EVP_MD *md = NULL;
EVP_MD_CTX *ctx;
- unsigned int buf_len;
- VALUE str;
- int result;
+ EVP_PKEY_CTX *pctx;
+ size_t siglen;
+ int state;
pkey = GetPrivPKeyPtr(self);
- md = ossl_evp_get_digestbyname(digest);
+ rb_scan_args(argc, argv, &quot;21&quot;, &amp;digest, &amp;data, &amp;options);
+ if (!NIL_P(digest))
+ 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, &quot;EVP_MD_CTX_new&quot;);
- if (!EVP_SignInit_ex(ctx, md, NULL)) {
+ if (EVP_DigestSignInit(ctx, &amp;pctx, md, /* engine */NULL, pkey) &lt; 1) {
+ EVP_MD_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_DigestSignInit&quot;);
+ }
+ if (!NIL_P(options)) {
+ pkey_ctx_apply_options(pctx, options, &amp;state);
+ if (state) {
+ EVP_MD_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ }
+#if OPENSSL_VERSION_NUMBER &gt;= 0x10101000 &amp;&amp; !defined(LIBRESSL_VERSION_NUMBER)
+ if (EVP_DigestSign(ctx, NULL, &amp;siglen, (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data)) &lt; 1) {
+ EVP_MD_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_DigestSign&quot;);
+ }
+ if (siglen &gt; LONG_MAX) {
+ EVP_MD_CTX_free(ctx);
+ rb_raise(ePKeyError, &quot;signature would be too large&quot;);
+ }
+ sig = ossl_str_new(NULL, (long)siglen, &amp;state);
+ if (state) {
+ EVP_MD_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ if (EVP_DigestSign(ctx, (unsigned char *)RSTRING_PTR(sig), &amp;siglen,
+ (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data)) &lt; 1) {
+ EVP_MD_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_DigestSign&quot;);
+ }
+#else
+ if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) &lt; 1) {
EVP_MD_CTX_free(ctx);
- ossl_raise(ePKeyError, &quot;EVP_SignInit_ex&quot;);
+ ossl_raise(ePKeyError, &quot;EVP_DigestSignUpdate&quot;);
}
- if (!EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
+ if (EVP_DigestSignFinal(ctx, NULL, &amp;siglen) &lt; 1) {
EVP_MD_CTX_free(ctx);
- ossl_raise(ePKeyError, &quot;EVP_SignUpdate&quot;);
+ ossl_raise(ePKeyError, &quot;EVP_DigestSignFinal&quot;);
}
- result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &amp;buf_len, pkey);
+ if (siglen &gt; LONG_MAX) {
+ EVP_MD_CTX_free(ctx);
+ rb_raise(ePKeyError, &quot;signature would be too large&quot;);
+ }
+ sig = ossl_str_new(NULL, (long)siglen, &amp;state);
+ if (state) {
+ EVP_MD_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(sig),
+ &amp;siglen) &lt; 1) {
+ EVP_MD_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_DigestSignFinal&quot;);
+ }
+#endif
EVP_MD_CTX_free(ctx);
- if (!result)
- ossl_raise(ePKeyError, &quot;EVP_SignFinal&quot;);
- rb_str_set_len(str, buf_len);
+ rb_str_set_len(sig, siglen);
+ return sig;
+}</pre>
+ </div>
+ </div>
- return str;
+
+ </div>
+
+ <div id="method-i-sign_raw" class="method-detail ">
+ <div class="method-heading">
+ <span class="method-callseq">
+ sign_raw(digest, data [, options]) &rarr; string
+ </span>
+ <span class="method-click-advice">click to toggle source</span>
+ </div>
+
+ <div class="method-description">
+ <p>Signs <code>data</code> using a private key <code>pkey</code>. Unlike <a href="PKey.html#method-i-sign"><code>sign</code></a>, <code>data</code> will not be hashed by <code>digest</code> automatically.</p>
+
+<p>See <a href="PKey.html#method-i-verify_raw"><code>verify_raw</code></a> for the verification operation.</p>
+
+<p>Added in version 3.0. See also the man page EVP_PKEY_sign(3).</p>
+<dl class="rdoc-list note-list"><dt><code>digest</code>
+<dd>
+<p>A String that represents the message digest algorithm name, or <code>nil</code> if the <a href="PKey.html"><code>PKey</code></a> type requires no digest algorithm. Although this method will not hash <code>data</code> with it, this parameter may still be required depending on the signature algorithm.</p>
+</dd><dt><code>data</code>
+<dd>
+<p>A String. The data to be signed.</p>
+</dd><dt><code>options</code>
+<dd>
+<p>A Hash that contains algorithm specific control operations to OpenSSL. See OpenSSL’s man page EVP_PKEY_CTX_ctrl_str(3) for details.</p>
+</dd></dl>
+
+<p>Example:</p>
+
+<pre class="ruby"><span class="ruby-identifier">data</span> = <span class="ruby-string">&quot;Sign me!&quot;</span>
+<span class="ruby-identifier">hash</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">Digest</span>.<span class="ruby-identifier">digest</span>(<span class="ruby-string">&quot;SHA256&quot;</span>, <span class="ruby-identifier">data</span>)
+<span class="ruby-identifier">pkey</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">PKey</span>.<span class="ruby-identifier">generate_key</span>(<span class="ruby-string">&quot;RSA&quot;</span>, <span class="ruby-value">rsa_keygen_bits:</span> <span class="ruby-value">2048</span>)
+<span class="ruby-identifier">signopts</span> = { <span class="ruby-value">rsa_padding_mode:</span> <span class="ruby-string">&quot;pss&quot;</span> }
+<span class="ruby-identifier">signature</span> = <span class="ruby-identifier">pkey</span>.<span class="ruby-identifier">sign_raw</span>(<span class="ruby-string">&quot;SHA256&quot;</span>, <span class="ruby-identifier">hash</span>, <span class="ruby-identifier">signopts</span>)
+
+<span class="ruby-comment"># Creates a copy of the RSA key pkey, but without the private components</span>
+<span class="ruby-identifier">pub_key</span> = <span class="ruby-identifier">pkey</span>.<span class="ruby-identifier">public_key</span>
+<span class="ruby-identifier">puts</span> <span class="ruby-identifier">pub_key</span>.<span class="ruby-identifier">verify_raw</span>(<span class="ruby-string">&quot;SHA256&quot;</span>, <span class="ruby-identifier">signature</span>, <span class="ruby-identifier">hash</span>, <span class="ruby-identifier">signopts</span>) <span class="ruby-comment"># =&gt; true</span>
+</pre>
+
+ <div class="method-source-code" id="sign_raw-source">
+ <pre>static VALUE
+ossl_pkey_sign_raw(int argc, VALUE *argv, VALUE self)
+{
+ EVP_PKEY *pkey;
+ VALUE digest, data, options, sig;
+ const EVP_MD *md = NULL;
+ EVP_PKEY_CTX *ctx;
+ size_t outlen;
+ int state;
+
+ GetPKey(self, pkey);
+ rb_scan_args(argc, argv, &quot;21&quot;, &amp;digest, &amp;data, &amp;options);
+ if (!NIL_P(digest))
+ md = ossl_evp_get_digestbyname(digest);
+ StringValue(data);
+
+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
+ if (!ctx)
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_CTX_new&quot;);
+ if (EVP_PKEY_sign_init(ctx) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_sign_init&quot;);
+ }
+ if (md &amp;&amp; EVP_PKEY_CTX_set_signature_md(ctx, md) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_CTX_set_signature_md&quot;);
+ }
+ if (!NIL_P(options)) {
+ pkey_ctx_apply_options(ctx, options, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ }
+ if (EVP_PKEY_sign(ctx, NULL, &amp;outlen, (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data)) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_sign&quot;);
+ }
+ if (outlen &gt; LONG_MAX) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_raise(ePKeyError, &quot;signature would be too large&quot;);
+ }
+ sig = ossl_str_new(NULL, (long)outlen, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ if (EVP_PKEY_sign(ctx, (unsigned char *)RSTRING_PTR(sig), &amp;outlen,
+ (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data)) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_sign&quot;);
+ }
+ EVP_PKEY_CTX_free(ctx);
+ rb_str_set_len(sig, outlen);
+ return sig;
}</pre>
</div>
</div>
@@ -369,65 +855,298 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
</div>
- <div id="method-i-verify" class="method-detail ">
+ <div id="method-i-to_text" class="method-detail ">
<div class="method-heading">
<span class="method-callseq">
- verify(digest, signature, data) &rarr; String
+ to_text &rarr; string
</span>
<span class="method-click-advice">click to toggle source</span>
</div>
<div class="method-description">
- <p>To verify the String <em>signature</em>, <em>digest</em>, an instance of <a href="../Digest.html"><code>OpenSSL::Digest</code></a>, must be provided to re-compute the message digest of the original <em>data</em>, also a String. The return value is <code>true</code> if the signature is valid, <code>false</code> otherwise. A <a href="PKeyError.html"><code>PKeyError</code></a> is raised should errors occur. Any previous state of the <a href="../Digest.html"><code>Digest</code></a> instance is irrelevant to the validation outcome, the digest instance is reset to its initial state during the operation.</p>
+ <p>Dumps key parameters, public key, and private key components contained in the key into a human-readable text.</p>
-<h2 id="method-i-verify-label-Example">Example<span><a href="#method-i-verify-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h2>
+<p>This is intended for debugging purpose.</p>
-<pre class="ruby"><span class="ruby-identifier">data</span> = <span class="ruby-string">&#39;Sign me!&#39;</span>
-<span class="ruby-identifier">digest</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">Digest</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">&#39;SHA256&#39;</span>)
-<span class="ruby-identifier">pkey</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">PKey</span><span class="ruby-operator">::</span><span class="ruby-constant">RSA</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">2048</span>)
-<span class="ruby-identifier">signature</span> = <span class="ruby-identifier">pkey</span>.<span class="ruby-identifier">sign</span>(<span class="ruby-identifier">digest</span>, <span class="ruby-identifier">data</span>)
-<span class="ruby-identifier">pub_key</span> = <span class="ruby-identifier">pkey</span>.<span class="ruby-identifier">public_key</span>
-<span class="ruby-identifier">puts</span> <span class="ruby-identifier">pub_key</span>.<span class="ruby-identifier">verify</span>(<span class="ruby-identifier">digest</span>, <span class="ruby-identifier">signature</span>, <span class="ruby-identifier">data</span>) <span class="ruby-comment"># =&gt; true</span>
-</pre>
+<p>See also the man page EVP_PKEY_print_private(3).</p>
+
+ <div class="method-source-code" id="to_text-source">
+ <pre>static VALUE
+ossl_pkey_to_text(VALUE self)
+{
+ EVP_PKEY *pkey;
+ BIO *bio;
+
+ GetPKey(self, pkey);
+ if (!(bio = BIO_new(BIO_s_mem())))
+ ossl_raise(ePKeyError, &quot;BIO_new&quot;);
+
+ if (EVP_PKEY_print_private(bio, pkey, 0, NULL) == 1)
+ goto out;
+ OSSL_BIO_reset(bio);
+ if (EVP_PKEY_print_public(bio, pkey, 0, NULL) == 1)
+ goto out;
+ OSSL_BIO_reset(bio);
+ if (EVP_PKEY_print_params(bio, pkey, 0, NULL) == 1)
+ goto out;
+
+ BIO_free(bio);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_print_params&quot;);
+
+ out:
+ return ossl_membio2str(bio);
+}</pre>
+ </div>
+ </div>
+
+
+ </div>
+
+ <div id="method-i-verify" class="method-detail ">
+ <div class="method-heading">
+ <span class="method-callseq">
+ verify(digest, signature, data [, options]) &rarr; true or false
+ </span>
+ <span class="method-click-advice">click to toggle source</span>
+ </div>
+
+ <div class="method-description">
+ <p>Verifies the <code>signature</code> for the <code>data</code> using a message digest algorithm <code>digest</code> and a public key <code>pkey</code>.</p>
+
+<p>Returns <code>true</code> if the signature is successfully verified, <code>false</code> otherwise. The caller must check the return value.</p>
+
+<p>See <a href="PKey.html#method-i-sign"><code>sign</code></a> for the signing operation and an example.</p>
+
+<p>See also the man page EVP_DigestVerify(3).</p>
+<dl class="rdoc-list note-list"><dt><code>digest</code>
+<dd>
+<p>See <a href="PKey.html#method-i-sign"><code>sign</code></a>.</p>
+</dd><dt><code>signature</code>
+<dd>
+<p>A String containing the signature to be verified.</p>
+</dd><dt><code>data</code>
+<dd>
+<p>See <a href="PKey.html#method-i-sign"><code>sign</code></a>.</p>
+</dd><dt><code>options</code>
+<dd>
+<p>See <a href="PKey.html#method-i-sign"><code>sign</code></a>. <code>options</code> parameter was added in version 3.0.</p>
+</dd></dl>
<div class="method-source-code" id="verify-source">
<pre>static VALUE
-ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
+ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
- const EVP_MD *md;
+ VALUE digest, sig, data, options;
+ const EVP_MD *md = NULL;
EVP_MD_CTX *ctx;
- int siglen, result;
+ EVP_PKEY_CTX *pctx;
+ int state, ret;
GetPKey(self, pkey);
+ rb_scan_args(argc, argv, &quot;31&quot;, &amp;digest, &amp;sig, &amp;data, &amp;options);
ossl_pkey_check_public_key(pkey);
- md = ossl_evp_get_digestbyname(digest);
+ if (!NIL_P(digest))
+ md = ossl_evp_get_digestbyname(digest);
StringValue(sig);
- siglen = RSTRING_LENINT(sig);
StringValue(data);
ctx = EVP_MD_CTX_new();
if (!ctx)
ossl_raise(ePKeyError, &quot;EVP_MD_CTX_new&quot;);
- if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
+ if (EVP_DigestVerifyInit(ctx, &amp;pctx, md, /* engine */NULL, pkey) &lt; 1) {
EVP_MD_CTX_free(ctx);
- ossl_raise(ePKeyError, &quot;EVP_VerifyInit_ex&quot;);
+ ossl_raise(ePKeyError, &quot;EVP_DigestVerifyInit&quot;);
+ }
+ if (!NIL_P(options)) {
+ pkey_ctx_apply_options(pctx, options, &amp;state);
+ if (state) {
+ EVP_MD_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
}
- if (!EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
+#if OPENSSL_VERSION_NUMBER &gt;= 0x10101000 &amp;&amp; !defined(LIBRESSL_VERSION_NUMBER)
+ ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig),
+ RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data));
+ EVP_MD_CTX_free(ctx);
+ if (ret &lt; 0)
+ ossl_raise(ePKeyError, &quot;EVP_DigestVerify&quot;);
+#else
+ if (EVP_DigestVerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) &lt; 1) {
EVP_MD_CTX_free(ctx);
- ossl_raise(ePKeyError, &quot;EVP_VerifyUpdate&quot;);
+ ossl_raise(ePKeyError, &quot;EVP_DigestVerifyUpdate&quot;);
}
- result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), siglen, pkey);
+ ret = EVP_DigestVerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig),
+ RSTRING_LEN(sig));
EVP_MD_CTX_free(ctx);
- switch (result) {
- case 0:
+ if (ret &lt; 0)
+ ossl_raise(ePKeyError, &quot;EVP_DigestVerifyFinal&quot;);
+#endif
+ if (ret)
+ return Qtrue;
+ else {
ossl_clear_error();
return Qfalse;
- case 1:
+ }
+}</pre>
+ </div>
+ </div>
+
+
+ </div>
+
+ <div id="method-i-verify_raw" class="method-detail ">
+ <div class="method-heading">
+ <span class="method-callseq">
+ verify_raw(digest, signature, data [, options]) &rarr; true or false
+ </span>
+ <span class="method-click-advice">click to toggle source</span>
+ </div>
+
+ <div class="method-description">
+ <p>Verifies the <code>signature</code> for the <code>data</code> using a public key <code>pkey</code>. Unlike <a href="PKey.html#method-i-verify"><code>verify</code></a>, this method will not hash <code>data</code> with <code>digest</code> automatically.</p>
+
+<p>Returns <code>true</code> if the signature is successfully verified, <code>false</code> otherwise. The caller must check the return value.</p>
+
+<p>See <a href="PKey.html#method-i-sign_raw"><code>sign_raw</code></a> for the signing operation and an example code.</p>
+
+<p>Added in version 3.0. See also the man page EVP_PKEY_verify(3).</p>
+<dl class="rdoc-list note-list"><dt><code>signature</code>
+<dd>
+<p>A String containing the signature to be verified.</p>
+</dd></dl>
+
+ <div class="method-source-code" id="verify_raw-source">
+ <pre>static VALUE
+ossl_pkey_verify_raw(int argc, VALUE *argv, VALUE self)
+{
+ EVP_PKEY *pkey;
+ VALUE digest, sig, data, options;
+ const EVP_MD *md = NULL;
+ EVP_PKEY_CTX *ctx;
+ int state, ret;
+
+ GetPKey(self, pkey);
+ rb_scan_args(argc, argv, &quot;31&quot;, &amp;digest, &amp;sig, &amp;data, &amp;options);
+ ossl_pkey_check_public_key(pkey);
+ if (!NIL_P(digest))
+ md = ossl_evp_get_digestbyname(digest);
+ StringValue(sig);
+ StringValue(data);
+
+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
+ if (!ctx)
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_CTX_new&quot;);
+ if (EVP_PKEY_verify_init(ctx) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_verify_init&quot;);
+ }
+ if (md &amp;&amp; EVP_PKEY_CTX_set_signature_md(ctx, md) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_CTX_set_signature_md&quot;);
+ }
+ if (!NIL_P(options)) {
+ pkey_ctx_apply_options(ctx, options, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ }
+ ret = EVP_PKEY_verify(ctx, (unsigned char *)RSTRING_PTR(sig),
+ RSTRING_LEN(sig),
+ (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data));
+ EVP_PKEY_CTX_free(ctx);
+ if (ret &lt; 0)
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_verify&quot;);
+
+ if (ret)
return Qtrue;
- default:
- ossl_raise(ePKeyError, &quot;EVP_VerifyFinal&quot;);
+ else {
+ ossl_clear_error();
+ return Qfalse;
+ }
+}</pre>
+ </div>
+ </div>
+
+
+ </div>
+
+ <div id="method-i-verify_recover" class="method-detail ">
+ <div class="method-heading">
+ <span class="method-callseq">
+ verify_recover(digest, signature [, options]) &rarr; string
+ </span>
+ <span class="method-click-advice">click to toggle source</span>
+ </div>
+
+ <div class="method-description">
+ <p>Recovers the signed data from <code>signature</code> using a public key <code>pkey</code>. Not all signature algorithms support this operation.</p>
+
+<p>Added in version 3.0. See also the man page EVP_PKEY_verify_recover(3).</p>
+<dl class="rdoc-list note-list"><dt><code>signature</code>
+<dd>
+<p>A String containing the signature to be verified.</p>
+</dd></dl>
+
+ <div class="method-source-code" id="verify_recover-source">
+ <pre>static VALUE
+ossl_pkey_verify_recover(int argc, VALUE *argv, VALUE self)
+{
+ EVP_PKEY *pkey;
+ VALUE digest, sig, options, out;
+ const EVP_MD *md = NULL;
+ EVP_PKEY_CTX *ctx;
+ int state;
+ size_t outlen;
+
+ GetPKey(self, pkey);
+ rb_scan_args(argc, argv, &quot;21&quot;, &amp;digest, &amp;sig, &amp;options);
+ ossl_pkey_check_public_key(pkey);
+ if (!NIL_P(digest))
+ md = ossl_evp_get_digestbyname(digest);
+ StringValue(sig);
+
+ ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
+ if (!ctx)
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_CTX_new&quot;);
+ if (EVP_PKEY_verify_recover_init(ctx) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_verify_recover_init&quot;);
+ }
+ if (md &amp;&amp; EVP_PKEY_CTX_set_signature_md(ctx, md) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_CTX_set_signature_md&quot;);
+ }
+ if (!NIL_P(options)) {
+ pkey_ctx_apply_options(ctx, options, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ }
+ if (EVP_PKEY_verify_recover(ctx, NULL, &amp;outlen,
+ (unsigned char *)RSTRING_PTR(sig),
+ RSTRING_LEN(sig)) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_verify_recover&quot;);
+ }
+ out = ossl_str_new(NULL, (long)outlen, &amp;state);
+ if (state) {
+ EVP_PKEY_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ if (EVP_PKEY_verify_recover(ctx, (unsigned char *)RSTRING_PTR(out), &amp;outlen,
+ (unsigned char *)RSTRING_PTR(sig),
+ RSTRING_LEN(sig)) &lt;= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ ossl_raise(ePKeyError, &quot;EVP_PKEY_verify_recover&quot;);
}
+ EVP_PKEY_CTX_free(ctx);
+ rb_str_set_len(out, outlen);
+ return out;
}</pre>
</div>
</div>