title: Export public key and private key from iOS to OpenSSL
body: <p>I'm working on app in which I need to create CSR, by using objective c or Swift this doesn't easy. So I choosed OpenSSL to created CSR and I created successfully code is shown following, but my one more core requirement is to store keys in secure enclave but this not possible in OpenSSL as I searched online. 
  Now I want to create keypair in objective c in secure enclave and then export these public key (with data) and private key (with reference) to openSSL (<code>EC_KEY</code>) and then create CSR from. I found this <a href="https://digitalleaves.com/blog/2015/10/sharing-public-keys-between-ios-and-the-rest-of-the-world/" rel="nofollow noreferrer">this link</a> to export key but there is no way to export private key (not possible with data but with reference).</p>
  
  <p>I need some guidance how to do that.</p>
  
  <pre><code>    - (void)genCSRX509ForEC
  {
      int             ret = 0;
      DSA             *r = NULL;
      BIGNUM          *bne = NULL;
  
  
  int             nVersion = 1;
  
  unsigned long   e = RSA_F4;
  
  X509_REQ        *x509_req = NULL;
  X509_NAME       *x509_name = NULL;
  EVP_PKEY        *pKey = NULL;
  BIO             *out = NULL;
  
  const char      *szCountry = "USA";
  const char      *szProvince = "MA";
  const char      *szCity = "Boston";
  const char      *szOrganization = "MyComp";
  const char      *szCommon = "MYC";
  
  const char      *szPath = "x509Req.pem";
  
  // 1. generate rsa key
  bne = BN_new();
  ret = BN_set_word(bne,e);
  if(ret != 1){
      goto free_all;
  }
  
  r = DSA_new();
  //    
  //    EC_KEY* _ec_key = EC_KEY_new();
  //    EC_GROUP* ec_group_new = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
  //    const EC_GROUP* ec_group = ec_group_new;
  //    if (!EC_KEY_set_group(_ec_key,ec_group))
  //        NSLog(@"Error in initializeCrypto, EC_KEY_set_group failed!");
  
      // Segfault at this position
  
  
      //////////////////////////// CREATE KEYPAIR /////////////////////////////////////
  
      EC_KEY* _ec_key = EC_KEY_new();
      EC_GROUP* ec_group_new = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
      const EC_GROUP* ec_group = ec_group_new;
      if (!EC_KEY_set_group(_ec_key,ec_group))
          NSLog(@"Error in initializeCrypto, EC_KEY_set_group failed!");
  
      EC_KEY_generate_key(_ec_key);
  
      ret = EC_KEY_check_key(_ec_key);
      if (ret != 1){
          goto free_all;
      }
  
        const BIGNUM *privateKey = EC_KEY_get0_private_key(_ec_key);
        const EC_POINT *publicKey = EC_KEY_get0_public_key(_ec_key);
  
        privateKeySize = i2d_ECPrivateKey(_ec_key,NULL);
        unsigned char *privateKeyBuf = OPENSSL_malloc(privateKeySize);
        memset(privateKeyBuf, 0, privateKeySize);
        int status = i2d_ECPrivateKey(_ec_key,&amp;privateKeyBuf);
        if (!ret){
          NSLog(@"Private key to DER failed\n");
          return;
        }
        else {
          NSLog(@"Private key %s",privateKeyBuf);
        }
      privateKeyUnsignedChar = privateKeyBuf;
  
        publicKeySize = i2o_ECPublicKey(_ec_key,NULL);
        unsigned char *publicKeyBuf = OPENSSL_malloc(privateKeySize);
        memset(publicKeyBuf, 0, privateKeySize);
        ret = i2o_ECPublicKey(_ec_key,&amp;publicKeyBuf);
        if (!ret){
          NSLog(@"Public key to octed failed\n");
          return;
        }
        else {
          NSLog(@"Public key %s",publicKeyBuf);
        }
      publicKeyUnsignedChar = publicKeyBuf;
      NSLog(@"key generation generated");
  
      //////////////////////////// CREATE KEYPAIR END /////////////////////////////////////
  
  
      // 2. set version of x509 req
      x509_req = X509_REQ_new();
      ret = X509_REQ_set_version(x509_req, nVersion);
      if (ret != 1){
          goto free_all;
      }
  
      // 3. set subject of x509 req
      x509_name = X509_REQ_get_subject_name(x509_req);
  
      ret = X509_NAME_add_entry_by_txt(x509_name,"C", MBSTRING_ASC, (const unsigned char*)szCountry, -1, -1, 0);
      if (ret != 1){
          goto free_all;
      }
  
      ret = X509_NAME_add_entry_by_txt(x509_name,"ST", MBSTRING_ASC, (const unsigned char*)szProvince, -1, -1, 0);
      if (ret != 1){
          goto free_all;
      }
  
      ret = X509_NAME_add_entry_by_txt(x509_name,"L", MBSTRING_ASC, (const unsigned char*)szCity, -1, -1, 0);
      if (ret != 1){
          goto free_all;
      }
  
      ret = X509_NAME_add_entry_by_txt(x509_name,"O", MBSTRING_ASC, (const unsigned char*)szOrganization, -1, -1, 0);
      if (ret != 1){
          goto free_all;
      }
  
      ret = X509_NAME_add_entry_by_txt(x509_name,"CN", MBSTRING_ASC, (const unsigned char*)szCommon, -1, -1, 0);
      if (ret != 1){
          goto free_all;
      }
  
      // 4. set public key of x509 req
      pKey = EVP_PKEY_new();
      EVP_PKEY_assign_EC_KEY(pKey, _ec_key);
      r = NULL;   // will be free rsa when EVP_PKEY_free(pKey)
  
      ret = X509_REQ_set_pubkey(x509_req, pKey);
      if (ret != 1){
          goto free_all;
      }
  
      // 5. set sign key of x509 req
      ret = X509_REQ_sign(x509_req, pKey, EVP_sha256());    // return x509_req-&gt;signature-&gt;length
      if (ret &lt;= 0){
          goto free_all;
      }
  
      out = BIO_new_file(szPath,"w");
      ret = PEM_write_bio_X509_REQ(out, x509_req);
      X509_REQ_print_fp(stdout, x509_req);
  
  
      [self createFileForPEM:x509_req];
  
      //    PEM_write_X509_REQ(pemFile, certSigningRequest);
      // 6. free
  free_all:
      X509_REQ_free(x509_req);
      BIO_free_all(out);
  
      EVP_PKEY_free(pKey);
  //    BN_free(bne);
  
  
  }
  </code></pre>