Skip to content

Commit

Permalink
Fix OpenSSL 3.0 deprecated warnings
Browse files Browse the repository at this point in the history
IB-7357

Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Apr 13, 2022
1 parent f052e8a commit f203fcb
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 48 deletions.
61 changes: 29 additions & 32 deletions src/crypto/PKCS12Signer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "crypto/X509Cert.h"
#include "log.h"

#include <algorithm>

using namespace digidoc;
using namespace std;

Expand Down Expand Up @@ -71,53 +73,48 @@ vector<unsigned char> PKCS12Signer::sign(const string &method, const vector<unsi

int result = 0;
vector<unsigned char> signature;
size_t size = 0;
SCOPE(EVP_PKEY_CTX, ctx, EVP_PKEY_CTX_new(d->key, nullptr));
if(!ctx || EVP_PKEY_sign_init(ctx.get()) <= 0)
THROW_OPENSSLEXCEPTION("Failed to sign the digest");
switch(EVP_PKEY_base_id(d->key))
{
case EVP_PKEY_RSA:
{
SCOPE(RSA, rsa, EVP_PKEY_get1_RSA(d->key));
signature.resize(size_t(RSA_size(rsa.get())));
int nid = Digest::toMethod(method);
if(Digest::isRsaPssUri(method)) {
vector<unsigned char> em(signature.size());
if(!RSA_padding_add_PKCS1_PSS_mgf1(rsa.get(), em.data(), digest.data(), EVP_get_digestbynid(nid), nullptr, RSA_PSS_SALTLEN_DIGEST))
if(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PSS_PADDING) <= 0 ||
EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(), RSA_PSS_SALTLEN_DIGEST) <= 0)
break;
if(RSA_private_encrypt(RSA_size(rsa.get()), em.data(), signature.data(), rsa.get(), RSA_NO_PADDING) == RSA_size(rsa.get()))
result = 1;
} else {
unsigned int size = (unsigned int)signature.size();
result = RSA_sign(nid, digest.data(), (unsigned int)digest.size(), signature.data(), &size, rsa.get());
}
} else if(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) <= 0)
break;
if(EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_get_digestbynid(Digest::toMethod(method))) <= 0 ||
EVP_PKEY_sign(ctx.get(), nullptr, &size, digest.data(), digest.size()) <= 0)
break;
signature.resize(size);
result = EVP_PKEY_sign(ctx.get(), signature.data(), &size, digest.data(), digest.size());
break;
}
#ifndef OPENSSL_NO_ECDSA
case EVP_PKEY_EC:
{
SCOPE(EC_KEY, ec, EVP_PKEY_get1_EC_KEY(d->key));
SCOPE(ECDSA_SIG, sig, ECDSA_do_sign(digest.data(), int(digest.size()), ec.get()));
if(!sig)
break;

size_t keyLen = 0;
if(const EC_GROUP *group = EC_KEY_get0_group(ec.get()))
{
BIGNUM *order = BN_new();
if (EC_GROUP_get_order(group, order, nullptr))
keyLen = size_t(BN_num_bytes(order));
BN_clear_free(order);
}
if(keyLen == 0)
THROW("Error caclulating signature size");
signature.resize(keyLen * 2);

if(EVP_PKEY_sign(ctx.get(), nullptr, &size, digest.data(), digest.size()) <= 0)
break;
vector<unsigned char> asn1(size);
result = EVP_PKEY_sign(ctx.get(), asn1.data(), &size, digest.data(), digest.size());
if(result <= 0)
break;
const unsigned char *p = asn1.data();
SCOPE(ECDSA_SIG, sig, d2i_ECDSA_SIG(nullptr, &p, long(asn1.size())));
const BIGNUM *r = nullptr, *s = nullptr;
ECDSA_SIG_get0(sig.get(), &r, &s);
if(BN_bn2bin(r, &signature[keyLen - size_t(BN_num_bytes(r))]) <= 0)
size_t r_len = size_t(BN_num_bytes(r));
size_t s_len = size_t(BN_num_bytes(s));
size_t keyLen = max(r_len, s_len);
signature.resize(keyLen * 2);
if(BN_bn2bin(r, &signature[keyLen - r_len]) <= 0)
THROW("Error copying signature 'r' value to buffer");
if(BN_bn2bin(s, &signature[keyLen*2 - size_t(BN_num_bytes(s))]) <= 0)
if(BN_bn2bin(s, &signature[keyLen*2 - s_len]) <= 0)
THROW("Error copying signature 's' value to buffer");

result = 1;
break;
}
#endif
Expand Down
38 changes: 22 additions & 16 deletions src/crypto/X509Crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,28 +211,33 @@ bool X509Crypto::verify(const string &method, const vector<unsigned char> &diges
if(!key)
THROW("Certificate does not have a public key, can not verify signature.");

SCOPE(EVP_PKEY_CTX, ctx, EVP_PKEY_CTX_new(key, nullptr));
int result = 0;
switch(EVP_PKEY_base_id(key))
{
case EVP_PKEY_RSA:
{
SCOPE(RSA, rsa, EVP_PKEY_get1_RSA(key));
auto decrypt = [&rsa, &signature](int padding) {
vector<unsigned char> decrypted(size_t(RSA_size(rsa.get())));
int size = RSA_public_decrypt(int(signature.size()), signature.data(), decrypted.data(), rsa.get(), padding);
if(size <= 0)
decrypted.clear();
return decrypted;
};
int nid = Digest::toMethod(method);

if(Digest::isRsaPssUri(method)) {
vector<unsigned char> decrypted = decrypt(RSA_NO_PADDING);
result = RSA_verify_PKCS1_PSS_mgf1(rsa.get(), digest.data(), EVP_get_digestbynid(nid), nullptr, decrypted.data(), RSA_PSS_SALTLEN_DIGEST);
if(ctx &&
EVP_PKEY_verify_init(ctx.get()) == 1 &&
EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PSS_PADDING) == 1 &&
EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(), RSA_PSS_SALTLEN_DIGEST) == 1 &&
EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_get_digestbynid(nid)) == 1)
result = EVP_PKEY_verify(ctx.get(), signature.data(), signature.size(), digest.data(), digest.size());
} else {
vector<unsigned char> out = decrypt(RSA_PKCS1_PADDING);
const unsigned char *p = out.data();
SCOPE(X509_SIG, sig, d2i_X509_SIG(nullptr, &p, long(out.size())));
size_t size = 0;
if(!ctx ||
EVP_PKEY_verify_recover_init(ctx.get()) <= 0 ||
EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING) <= 0 ||
EVP_PKEY_verify_recover(ctx.get(), nullptr, &size, signature.data(), signature.size()) <= 0)
break;
vector<unsigned char> decrypted(size);
if(EVP_PKEY_verify_recover(ctx.get(), decrypted.data(), &size, signature.data(), signature.size()) <= 0)
break;
decrypted.resize(size);
const unsigned char *p = decrypted.data();
SCOPE(X509_SIG, sig, d2i_X509_SIG(nullptr, &p, long(decrypted.size())));
if(!sig)
break;
const X509_ALGOR *algor = nullptr;
Expand All @@ -251,12 +256,13 @@ bool X509Crypto::verify(const string &method, const vector<unsigned char> &diges
#ifndef OPENSSL_NO_ECDSA
case EVP_PKEY_EC:
{
SCOPE(EC_KEY, ec, EVP_PKEY_get1_EC_KEY(key));
SCOPE(ECDSA_SIG, sig, ECDSA_SIG_new());
ECDSA_SIG_set0(sig.get(),
BN_bin2bn(signature.data(), int(signature.size()/2), nullptr),
BN_bin2bn(&signature[signature.size()/2], int(signature.size()/2), nullptr));
result = ECDSA_do_verify(digest.data(), int(digest.size()), sig.get(), ec.get());
vector<unsigned char> asn1 = i2d(sig.get(), i2d_ECDSA_SIG);
if(ctx && EVP_PKEY_verify_init(ctx.get()) == 1)
result = EVP_PKEY_verify(ctx.get(), asn1.data(), asn1.size(), digest.data(), digest.size());
break;
}
#endif
Expand Down

0 comments on commit f203fcb

Please sign in to comment.