【OpenSSL】Access PEM

Test code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

# include <openssl/e_os2.h>
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/bn.h>
# include <openssl/rsa.h>
# include <openssl/evp.h>
# include <openssl/ssl.h>
# include <openssl/x509.h>
# include <openssl/pem.h>
# include <openssl/rand.h>

static 
void 
loadRsaPrivateKey(const char * file, const char * passphrase);

static 
void 
genRsaPrivateKey(const char * file, const char * passphrase);


int 
main(int argc, char * argv[])
{
    // initialize openssl library
    // Notice, if not initialized, 
    // some decryption routine will fail.
    // but, if links in all algos, prog will grow large.
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ERR_load_crypto_strings();

    // generate test rsa key into local file.
    genRsaPrivateKey("bobkey.pem", "passphrase");

    // load tes ras key from local file.
    loadRsaPrivateKey("bobkey.pem","passphrase");

    // cleanup library
    EVP_cleanup();

    return 0;
}

static 
void 
loadRsaPrivateKey(const char * file, const char * passphrase)
{
    BIO * in = BIO_new(BIO_s_file());
    if (!in) return ;

    if (BIO_read_filename(in, (char*)file) <= 0)
        return ;

    RSA * x = PEM_read_bio_RSAPrivateKey(in \
                                , NULL /*or, &x */
                                , NULL /*void callback*/
                                , (void *)passphrase);

    if (!x) return ;

    BIO * bio_err = NULL;
    if ((bio_err = BIO_new(BIO_s_file())) != NULL)
       BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    //RSA_print_fp(stdout, x, 0);
    RSA_print(bio_err, x, 0);

    if (x) RSA_free(x);
    else{
        /*Error*/
        ERR_print_errors_fp(stdout);
    }
    x = NULL;

    if (in) BIO_free(in);
    in = NULL;

    return ;
}

static 
void 
genRsaPrivateKey(const char * file, const char * passphrase)
{

    BIO *out = BIO_new(BIO_s_file());
    BIO_write_filename(out, (char*)file);

    BIGNUM *bn = BN_new();
    BN_set_word(bn, RSA_F4);

    RSA *rsa = RSA_new();
    RSA_generate_key_ex(rsa, 2048 /*key bits*/, bn, NULL);

    PEM_write_bio_RSAPrivateKey(out
                                , rsa
                                , EVP_des_ede3_cbc()
                                , NULL, 0
                                , NULL, (void*)passphrase);

    if (rsa) RSA_free(rsa);

    if (bn)  BN_free(bn);

    if (out) BIO_free(out);
}

Notice:

  • For the PEM write routines if the kstr parameter is not NULL then klen bytes at kstr are used as the passphrase and cb is ignored.

  • If the cb parameters is set to NULL and the u parameter is not NULL then the u parameter is interpreted as a null terminated string to use as the passphrase.

  • If both cb and u are NULL then the default callback routine is used which will typically prompt for the passphrase on the current terminal with echoing turned off.

  • Default pass phrase callback definition, as following:

int cb(char *buf, int size, int rwflag, void *u);

Error

  • Failed to call PEM_read_bio_RSAPrivateKey()
$ ./genrsa.exe
7040:error:0906B072:lib(9):func(107):reason(114):pem_lib.c:537:

check error code with openssl errstr utility

$ openssl errstr 0906b027
error:0906B027:PEM routines:PEM_get_EVP_CIPHER_INFO:OCSP lib

Reason

  • crypt algorithms is neither initialized nor loaded.

check these following links about openssl library initialization routines.

  • https://wiki.openssl.org/index.php/Library_Initialization

  • https://www.openssl.org/docs/crypto/OpenSSL_add_all_algorithms.html

 // initially
 OpenSSL_add_all_algorithms()
 // or, OpenSSL_add_all_digests() && OpenSSL_add_all_ciphers()
 // 
 // finally
 EVP_cleanup()

你可能感兴趣的:(OpenSSL,pem)