ByteBuffer AsymmetricCipherOpenssl::Encrypt()

in sdk/src/encryption/CipherOpenssl.cc [164:283]


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

    do {

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

        dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, "RSA", EVP_PKEY_PUBLIC_KEY, NULL, NULL);

        if (dctx == NULL) {
            break;
        }

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

        if (OSSL_DECODER_from_bio(dctx, bio) == 0) {
            break;
        }

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

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

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

        size_t enc_len = 0;
        if (EVP_PKEY_encrypt(ctx, NULL, &enc_len, (unsigned char*)data.data(), data.size()) <= 0) {
            break;
        }
        enc.resize(enc_len, 0);
        
        if (EVP_PKEY_encrypt(ctx, (unsigned char*)enc.data(), &enc_len, (unsigned char*)data.data(), data.size()) <= 0) {
            enc.resize(0);
            break;
        }
    } while (0);

    if (bio) {
        BIO_free(bio);
    }

    if (dctx != NULL) {
        OSSL_DECODER_CTX_free(dctx);
    }

    if (pkey) {
        EVP_PKEY_free(pkey);
    }

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

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

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

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

        if (rsa == NULL) {
            break;
        }

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

        if (RSA_public_encrypt(data.size(), (unsigned char*)data.data(), (unsigned char*)enc.data(), rsa, RSA_PKCS1_PADDING) < 0) {
            enc.resize(0);
        }

    } while (0);

    if (bio) {
        BIO_free(bio);
    }

    if (pkey) {
        EVP_PKEY_free(pkey);
    }

    if (rsa) {
        RSA_free(rsa);
    }

    return enc;

#endif
}