neubert
neubert

Reputation: 16782

segfault with EVP_PKEY_decrypt()

I'm getting a segfault when running this code and idk why. Any ideas?:

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <string.h>

#include <openssl/err.h>

int main (void)
{
    char privateKey[] = "-----BEGIN RSA PRIVATE KEY-----\n"\
"MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu\n"\
"KUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQJAIJLixBy2qpFoS4DSmoEm\n"\
"o3qGy0t6z09AIJtH+5OeRV1be+N4cDYJKffGzDa88vQENZiRm0GRq6a+HPGQMd2k\n"\
"TQIhAKMSvzIBnni7ot/OSie2TmJLY4SwTQAevXysE2RbFDYdAiEBCUEaRQnMnbp7\n"\
"9mxDXDf6AU0cN/RPBjb9qSHDcWZHGzUCIG2Es59z8ugGrDY+pxLQnwfotadxd+Uy\n"\
"v/Ow5T0q5gIJAiEAyS4RaI9YG8EWx/2w0T67ZUVAw8eOMB6BIUg0Xcu+3okCIBOs\n"\
"/5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00\n"\
"-----END RSA PRIVATE KEY-----\n";
    char ciphertext[] = "h3j3zLT2jXCaZuwF7cgUE/Zmc/5IsIfKbaTiBhpCJo86AiyuoA3Yvni+Lrm5wu2OGv2h5R7Zu3voFcHugiystw==";
    // base64 decode ciphertext
    EVP_DecodeBlock(ciphertext, ciphertext, strlen(ciphertext));

    BIO* bo = BIO_new(BIO_s_mem());
    BIO_write(bo, privateKey, strlen(privateKey));
    EVP_PKEY* pkey = 0;
    PEM_read_bio_PrivateKey(bo, &pkey, 0, 0);
    BIO_free(bo);

    EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
    EVP_PKEY_decrypt_init(ctx);
    EVP_PKEY_CTX_ctrl_str(ctx, "rsa_padding_mode", "oaep");
    EVP_PKEY_CTX_ctrl_str(ctx, "rsa_oaep_md", "sha256");
    EVP_PKEY_CTX_ctrl_str(ctx, "rsa_mgf1_md", "sha256");

    size_t plaintext_len;
    unsigned char* plaintext;

    EVP_PKEY_decrypt(ctx, plaintext, &plaintext_len, ciphertext, strlen(ciphertext));
    //plaintext[plaintext_len] = '\0';

    printf("%s\n", plaintext);
}

Upvotes: 0

Views: 934

Answers (1)

MikeCAT
MikeCAT

Reputation: 75062

You forgot to initialize plaintext before passing that to EVP_PKEY_decrypt.

Refering evp_pkey_decrypt(3) - Linux man page, the part

    unsigned char* plaintext;

    EVP_PKEY_decrypt(ctx, plaintext, &plaintext_len, ciphertext, strlen(ciphertext));
    //plaintext[plaintext_len] = '\0';

should be

    unsigned char* plaintext;

    /* determine output size */
    EVP_PKEY_decrypt(ctx, NULL, &plaintext_len, ciphertext, strlen(ciphertext));

    /* allocate memory (+1 for terminating null-character) */
    plaintext = OPENSSL_malloc(plaintext_len + 1);
    if (plaintext == NULL) {
        /* allocation failed */
        return 1;
    } else {
        EVP_PKEY_decrypt(ctx, plaintext, &plaintext_len, ciphertext, strlen(ciphertext));
        plaintext[plaintext_len] = '\0'; /* required for %s */
    }

Upvotes: 2

Related Questions