I have 2 separate programs (spliced together below). The first generates the key pair and saves to files (works fine). The second opens the private key, decrypting with a pass phrase and then I need it to sign a string of text. The code below fails on the PEM_read_PrivateKey() (last) call (can't see why). Can anyone point me at what I am doing wrong and then what openssl calls I should make to use the private key to sign some text?
int main (int argc, char *argv[]) { char *priv_pem = "priv.pem"; char *pub_pem = "pub.pem"; char *pass = "Password"; FILE *fp; int bits = 4096; unsigned long exp = RSA_F4; RSA *rsa; EVP_PKEY *pkey; // GENERATE KEY rsa=RSA_generate_key(bits,exp,NULL,NULL); if (RSA_check_key(rsa)!=1) Exit(1,"Error whilst checking key",""); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, rsa); // WRITE ENCRYPTED PRIVATE KEY if (!(fp = fopen(priv_pem, "w"))) Exit(2,"Error opening PEM file",priv_pem); if (!PEM_write_PrivateKey(fp,pkey,EVP_aes_256_cbc(),NULL,0,NULL,pass)) Exit(3,"Error writing PEM file",priv_pem); fclose(fp); // WRITE PUBLIC KEY if (!(fp = fopen(pub_pem, "w"))) Exit(4,"Error opening PEM file",pub_pem); if (!PEM_write_PUBKEY(fp, pkey)) Exit(5,"Error writing PEM file",pub_pem); fclose(fp); // ------- End of key generation program ------- // ------- Start of text signing program ------- // READ IN ENCRYPTED PRIVATE KEY if (!(fp = fopen(priv_pem, "r"))) Exit(6,"Error reading encrypted private key file",priv_pem); if (!PEM_read_PrivateKey(fp,&pkey,NULL,pass)) Exit(7,"Error decrypting private key file",priv_pem); fclose(fp); // Sign some text using the private key.... // FREE RSA_free(rsa); return 0; } 2 Answers
Have you initialised pkey to NULL before you pass &pkey to PEM_read_PrivateKey()? If not, it will attempt to re-use the EVP_PKEY structure that pkey points to - and if pkey is uninitialised, it will be looking at a random spot in memory.
You can use ERR_print_errors_fp(stderr); to dump the OpenSSL error stack to stderr when an error occurs - this is often helpful in finding the problem.
Thanks @caf for your help. By trial and error I fixed PEM_read_PrivateKey() error by adding the following to the start:
if (EVP_get_cipherbyname("aes-256-cbc") == NULL) OpenSSL_add_all_algorithms(); However, I'm still looking for the best (practice) way of generating the keys and then using the private key for signing. From my limited understanding, I am looking for openssl methods that adhere to RSA's "PKCS #1 v2.0: RSA Cryptography Standard"
1