ByteBuffer AsymmetricCipherOpenssl::Decrypt()

in sdk/src/encryption/CipherOpenssl.cc [285:390]


ByteBuffer AsymmetricCipherOpenssl::Decrypt(const ByteBuffer& data)
{
#if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 30000
    BIO* bio = NULL;
    EVP_PKEY* pkey = NULL;
    EVP_PKEY_CTX* ctx = NULL;
    ByteBuffer dec;

    do {

        if (data.empty()) {
            break;
        }

        bio = BIO_new(BIO_s_mem());
        BIO_puts(bio, PrivateKey().c_str());

        pkey = PEM_read_bio_PrivateKey(bio, &pkey, NULL, NULL);

        ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
        if (ctx == NULL) {
            break;
        }

        if (EVP_PKEY_decrypt_init_ex(ctx, NULL) <= 0) {
            break;
        }

        if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) {
            break;
        }

        size_t dec_len = 0;
        if (EVP_PKEY_decrypt(ctx, NULL, &dec_len, (unsigned char*)data.data(), data.size()) <= 0) {
            break;
        }
        dec.resize(dec_len, 0);
        
        if (EVP_PKEY_decrypt(ctx, (unsigned char*)dec.data(), &dec_len, (unsigned char*)data.data(), data.size()) <= 0) {
            dec_len = 0;
        }
        dec.resize(dec_len);

    } while (0);

    if (bio) {
        BIO_free(bio);
    }

    if (pkey) {
        EVP_PKEY_free(pkey);
    }

    if (ctx != NULL) {
        EVP_PKEY_CTX_free(ctx);
    }

    return dec;
#else
    RSA* rsa = NULL;
    BIO* bio = NULL;
    EVP_PKEY* pkey = NULL;
    ByteBuffer dec;
    do {
        if (data.empty()) {
            break;
        }

        bio = BIO_new(BIO_s_mem());
        BIO_puts(bio, PrivateKey().c_str());

        if (strncmp("-----BEGIN RSA", PublicKey().c_str(), 14) == 0) {
            rsa = PEM_read_bio_RSAPrivateKey(bio, &rsa, NULL, NULL);
        }
        else {
            pkey = PEM_read_bio_PrivateKey(bio, &pkey, NULL, NULL);
            rsa = pkey ? EVP_PKEY_get1_RSA(pkey) : NULL;
        }

        if (rsa == NULL) {
            break;
        }

        int rsa_len = RSA_size(rsa);
        dec.resize(rsa_len, 0);

        auto dec_len = RSA_private_decrypt(rsa_len, (unsigned char*)data.data(), (unsigned char*)dec.data(), rsa, RSA_PKCS1_PADDING);
        dec.resize(dec_len < 0 ? 0 : static_cast<size_t>(dec_len));

    } while (0);

    if (bio) {
        BIO_free(bio);
    }

    if (pkey) {
        EVP_PKEY_free(pkey);
    }

    if (rsa) {
        RSA_free(rsa);
    }

    return dec;
#endif
}