title: C++ openssl - Generate RSA Keypair and read
body: <p>I am trying to generate RSA keypair using openssl library and then read the same keys later. However, it fails. Sometimes it gives me this error:                 </p>
  
  <blockquote>
    <p>error:0906D06C:PEM routines:PEM_read_bio:no start line   </p>
  </blockquote>
  
  <p>And sometimes, it gives me this error:</p>
  
  <blockquote>
    <p>error:0906D06C:lib(9):func(109):reason(108)</p>
  </blockquote>
  
  <p>What is the correct way to generate the keypair and later be able to read it ? Here is my code. If you run it, you will find that it correctly generates the RSA key pair but not able read them later.</p>
  
  <pre><code>    #include &lt;stdio.h&gt;
      #include &lt;iostream&gt;
      #include &lt;openssl/rsa.h&gt;
      #include &lt;openssl/pem.h&gt;
      #include &lt;openssl/err.h&gt;
      #include &lt;exception&gt;
  
      bool generate_key() {
          size_t pri_len;            // Length of private key
          size_t pub_len;            // Length of public key
          char *pri_key;           // Private key in PEM
          char *pub_key;           // Public key in PEM
  
          int ret = 0;
          RSA *r = NULL;
          BIGNUM *bne = NULL;
          BIO *bp_public = NULL, *bp_private = NULL;
          int bits = 2048;
          unsigned long e = RSA_F4;
  
          EVP_PKEY *evp_pbkey = NULL;
          EVP_PKEY *evp_pkey = NULL;
  
          BIO *pbkeybio = NULL;
          BIO *pkeybio = NULL;
  
          // 1. generate rsa key
          bne = BN_new();
          ret = BN_set_word(bne, e);
          if (ret != 1) {
              goto free_all;
          }
  
          r = RSA_new();
          ret = RSA_generate_key_ex(r, bits, bne, NULL);
          if (ret != 1) {
              goto free_all;
          }
  
          // 2. save public key
          //bp_public = BIO_new_file("public.pem", "w+");
          bp_public = BIO_new(BIO_s_mem());
          ret = PEM_write_bio_RSAPublicKey(bp_public, r);
          if (ret != 1) {
              goto free_all;
          }
  
          // 3. save private key
          //bp_private = BIO_new_file("private.pem", "w+");
          bp_private = BIO_new(BIO_s_mem());
          ret = PEM_write_bio_RSAPrivateKey(bp_private, r, NULL, NULL, 0, NULL, NULL);
  
          //4. Get the keys are PEM formatted strings
          pri_len = BIO_pending(bp_private);
          pub_len = BIO_pending(bp_public);
  
          pri_key = (char*) malloc(pri_len + 1);
          pub_key = (char*) malloc(pub_len + 1);
  
          BIO_read(bp_private, pri_key, pri_len);
          BIO_read(bp_public, pub_key, pub_len);
  
          pri_key[pri_len] = '\0';
          pub_key[pub_len] = '\0';
  
          printf("\n%s\n%s\n", pri_key, pub_key);
  
          //verify if you are able to re-construct the keys
          pbkeybio = BIO_new_mem_buf((void*) pub_key, -1);
          if (pbkeybio == NULL) {
              return -1;
          }
          evp_pbkey = PEM_read_bio_PUBKEY(pbkeybio, &amp;evp_pbkey, NULL, NULL);
          if (evp_pbkey == NULL) {
              char buffer[120];
              ERR_error_string(ERR_get_error(), buffer);
              printf("Error reading public key:%s\n", buffer);
          }
  
          pkeybio = BIO_new_mem_buf((void*) pri_key, -1);
          if (pkeybio == NULL) {
              return -1;
          }
          evp_pkey = PEM_read_bio_PrivateKey(pkeybio, &amp;evp_pkey, NULL, NULL);
          if (evp_pbkey == NULL) {
              char buffer[120];
              ERR_error_string(ERR_get_error(), buffer);
              printf("Error reading private key:%s\n", buffer);
          }
  
          BIO_free(pbkeybio);
          BIO_free(pkeybio);
  
          // 4. free
          free_all:
  
          BIO_free_all(bp_public);
          BIO_free_all(bp_private);
          RSA_free(r);
          BN_free(bne);
  
          return (ret == 1);
      }
  
      int main(int argc, char* argv[]) {
          generate_key();
          return 0;
      }
  </code></pre>