* \brief Base class for PSS-RSA family of algorithms */
| 1934 | * \brief Base class for PSS-RSA family of algorithms |
| 1935 | */ |
| 1936 | struct pss { |
| 1937 | /** |
| 1938 | * Construct new pss algorithm |
| 1939 | * \param public_key RSA public key in PEM format |
| 1940 | * \param private_key RSA private key or empty string if not available. If empty, signing will always fail. |
| 1941 | * \param public_key_password Password to decrypt public key pem. |
| 1942 | * \param private_key_password Password to decrypt private key pem. |
| 1943 | * \param md Pointer to hash function |
| 1944 | * \param name Name of the algorithm |
| 1945 | */ |
| 1946 | pss(const std::string& public_key, const std::string& private_key, const std::string& public_key_password, |
| 1947 | const std::string& private_key_password, const EVP_MD* (*md)(), std::string name) |
| 1948 | : md(md), alg_name(std::move(name)) { |
| 1949 | if (!private_key.empty()) { |
| 1950 | pkey = helper::load_private_key_from_string(private_key, private_key_password); |
| 1951 | } else if (!public_key.empty()) { |
| 1952 | pkey = helper::load_public_key_from_string(public_key, public_key_password); |
| 1953 | } else |
| 1954 | throw error::rsa_exception(error::rsa_error::no_key_provided); |
| 1955 | } |
| 1956 | |
| 1957 | /** |
| 1958 | * Sign jwt data |
| 1959 | * \param data The data to sign |
| 1960 | * \param ec error_code filled with details on error |
| 1961 | * \return ECDSA signature for the given data |
| 1962 | */ |
| 1963 | std::string sign(const std::string& data, std::error_code& ec) const { |
| 1964 | ec.clear(); |
| 1965 | auto md_ctx = helper::make_evp_md_ctx(); |
| 1966 | if (!md_ctx) { |
| 1967 | ec = error::signature_generation_error::create_context_failed; |
| 1968 | return {}; |
| 1969 | } |
| 1970 | EVP_PKEY_CTX* ctx = nullptr; |
| 1971 | if (EVP_DigestSignInit(md_ctx.get(), &ctx, md(), nullptr, pkey.get()) != 1) { |
| 1972 | ec = error::signature_generation_error::signinit_failed; |
| 1973 | return {}; |
| 1974 | } |
| 1975 | if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) { |
| 1976 | ec = error::signature_generation_error::rsa_padding_failed; |
| 1977 | return {}; |
| 1978 | } |
| 1979 | // wolfSSL does not require EVP_PKEY_CTX_set_rsa_pss_saltlen. The default behavior |
| 1980 | // sets the salt length to the hash length. Unlike OpenSSL which exposes this functionality. |
| 1981 | #ifndef LIBWOLFSSL_VERSION_HEX |
| 1982 | if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0) { |
| 1983 | ec = error::signature_generation_error::set_rsa_pss_saltlen_failed; |
| 1984 | return {}; |
| 1985 | } |
| 1986 | #endif |
| 1987 | if (EVP_DigestUpdate(md_ctx.get(), data.data(), data.size()) != 1) { |
| 1988 | ec = error::signature_generation_error::digestupdate_failed; |
| 1989 | return {}; |
| 1990 | } |
| 1991 | |
| 1992 | size_t size = EVP_PKEY_size(pkey.get()); |
| 1993 | std::string res(size, 0x00); |
nothing calls this directly
no outgoing calls
no test coverage detected