Method: OpenSSL::PKey::RSA#verify_pss

Defined in:
ossl_pkey_rsa.c

#verify_pss(digest, signature, data, salt_length: , mgf1_hash: ) ⇒ Object

Verifies data using the Probabilistic Signature Scheme (RSA-PSS).

The return value is true if the signature is valid, false otherwise. RSAError will be raised if an error occurs.

See #sign_pss for the signing operation and an example code.

Parameters

digest

A String containing the message digest algorithm name.

data

A String. The data to be signed.

salt_length

The length in octets of the salt. Two special values are reserved: :digest means the digest length, and :auto means automatically determining the length based on the signature.

mgf1_hash

The hash algorithm used in MGF1.



427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
# File 'ossl_pkey_rsa.c', line 427

static VALUE
ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self)
{
    VALUE digest, signature, data, options, kwargs[2];
    static ID kwargs_ids[2];
    EVP_PKEY *pkey;
    EVP_PKEY_CTX *pkey_ctx;
    const EVP_MD *md, *mgf1md;
    EVP_MD_CTX *md_ctx;
    int result, salt_len;

    if (!kwargs_ids[0]) {
	kwargs_ids[0] = rb_intern_const("salt_length");
	kwargs_ids[1] = rb_intern_const("mgf1_hash");
    }
    rb_scan_args(argc, argv, "3:", &digest, &signature, &data, &options);
    rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
    if (kwargs[0] == ID2SYM(rb_intern("auto")))
	salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */
    else if (kwargs[0] == ID2SYM(rb_intern("digest")))
	salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
    else
	salt_len = NUM2INT(kwargs[0]);
    mgf1md = ossl_evp_get_digestbyname(kwargs[1]);

    GetPKey(self, pkey);
    md = ossl_evp_get_digestbyname(digest);
    StringValue(signature);
    StringValue(data);

    md_ctx = EVP_MD_CTX_new();
    if (!md_ctx)
	goto err;

    if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
	goto err;

    if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
	goto err;

    if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
	goto err;

    if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
	goto err;

    if (EVP_DigestVerifyUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
	goto err;

    result = EVP_DigestVerifyFinal(md_ctx,
				   (unsigned char *)RSTRING_PTR(signature),
				   RSTRING_LEN(signature));

    switch (result) {
      case 0:
	ossl_clear_error();
	EVP_MD_CTX_free(md_ctx);
	return Qfalse;
      case 1:
	EVP_MD_CTX_free(md_ctx);
	return Qtrue;
      default:
	goto err;
    }

  err:
    EVP_MD_CTX_free(md_ctx);
    ossl_raise(eRSAError, NULL);
}