title: OpenSSL not working on Windows, errors 0x02001003 0x2006D080 0x0E064002
body: <p><strong>Problem:</strong> OpenSSL is not working in my Windows environment. OpenSSL repeatedly reports errors 0x02001003, 0x2006D080 and 0x0E064002.</p>
  
  <p><strong>Environment:</strong></p>
  
  <pre><code>Windows NT x 6.1 build 7601 (Windows 7 Business Edition Service Pack 1) i586
  Apache/2.4.4 (Win32)
  PHP/5.4.13 x86
  PHP Directory: E:\wamp\php\
  Virtual Host Directory: E:\Projects\1\public_html
  </code></pre>
  
  <p><strong>What I've Attempted:</strong></p>
  
  <ul>
  <li><strong>Installation Instructions</strong> <a href="http://www.php.net/manual/en/openssl.installation.php" rel="noreferrer">http://www.php.net/manual/en/openssl.installation.php</a></li>
  <li><strong>PHP.ini</strong> <code>extension=php_openssl.dll</code></li>
  <li><strong>Openssl.cnf</strong> <code>E:\wamp\php\extras\openssl.cnf</code></li>
  <li><strong>%PATH%</strong> <code>E:\wamp\php</code></li>
  <li><strong>Rebooted</strong></li>
  <li><strong>phpinfo:</strong><br>
  ----OpenSSL support enabled<br>
  ----OpenSSL Library Version OpenSSL 1.0.1e 11 Feb 2013<br>
  ----OpenSSL Header Version  OpenSSL 0.9.8y 5 Feb 2013  </li>
  <li>With and without specifying <strong>config</strong> in <code>configargs</code></li>
  <li>With and without specifying <code>&lt;Directory E:\wamp\php\extras&gt;</code> in apache config</li>
  <li>Copied <code>openssl.cnf</code> to virtualhost public_html, pointed to that and still get same errors</li>
  <li>Nothing logged in <strong>error_log</strong></li>
  <li><strong>Researched:</strong> I've spent the last 2 days researching this, surprised there isn't more info on it so I'm posting here. Seems to be problem with OpenSSL config or apache/php not reading config properly.</li>
  </ul>
  
  <p><strong>Code:</strong>  </p>
  
  <pre><code>$privateKey = openssl_pkey_new();
  while($message = openssl_error_string()){
      echo $message.'&lt;br /&gt;'.PHP_EOL;
  }
  </code></pre>
  
  <p><strong>Results:</strong></p>
  
  <pre><code>error:02001003:system library:fopen:No such process
  error:2006D080:BIO routines:BIO_new_file:no such file
  error:0E064002:configuration file routines:CONF_load:system lib
  error:02001003:system library:fopen:No such process
  error:2006D080:BIO routines:BIO_new_file:no such file
  error:0E064002:configuration file routines:CONF_load:system lib
  </code></pre>
  
  <p><strong>OpenSSL Manually:</strong></p>
  
  <pre><code>E:\wamp\apache\bin&gt;openssl.exe pkey
  WARNING: can't open config file: c:/openssl-1.0.1e/ssl/openssl.cnf
  
  E:\wamp\apache\bin&gt;set OPENSSL_CONF="E:\wamp\php\extras\openssl.cnf"
  
  E:\wamp\apache\bin&gt;openssl.exe pkey
  3484:error:0200107B:system library:fopen:Unknown error:.\crypto\bio\bss_file.c:169:fopen('"E:\wamp\php\extras\openssl.cnf"','rb')
  3484:error:2006D002:BIO routines:BIO_new_file:system lib:.\crypto\bio\bss_file.c:174:
  3484:error:0E078002:configuration file routines:DEF_LOAD:system lib:.\crypto\conf\conf_def.c:199:
  </code></pre>
  
  <p><strong>EDIT:</strong></p>
  
  <ol>
  <li>Thanks to @Gordon I can now see open_ssl errors using <code>openssl_error_string</code></li>
  <li>Completely uninstall EasyPHP. Manually installed stable versions of PHP/Apache. Same results! Definitely something I'm doing wrong with implementing openssl on windows.</li>
  <li>OpenSSL Manually section... additional error info</li>
  </ol>
  
  <p><strong>FINAL THOUGHTS:</strong><br>
  I set up a linux box and I'm getting the same errors. After some playing around I see that even though it's throwing errors at the openssl_pkey_new it does eventually create my test p12 file. Long story short, the errors are misleading and it has to deal more with <strong>how</strong> you are using openssl functions not so much server-side configuration.</p>
  
  <p>Final code:</p>
  
  <pre><code>// Create the keypair
  $res=openssl_pkey_new();
  
  // Get private key
  openssl_pkey_export($res, $privkey);
  
  // Get public key
  $pubkey=openssl_pkey_get_details($res);
  $pubkey=$pubkey["key"];
  
  // Actual file
  $Private_Key = null;
  $Unsigned_Cert = openssl_csr_new($Info,$Private_Key,$Configs);
  $Signed_Cert = openssl_csr_sign($Unsigned_Cert,null,$Private_Key,365,$Configs);
  openssl_pkcs12_export_to_file($Signed_Cert,"test.p12",$Private_Key,"123456");
  </code></pre>
  
  <p><strong>Close away.</strong></p>
  
  <p><strong>A year later...</strong></p>
  
  <p>So I found myself doing this again a year later, and regardless of whatever PATH variables I set on the computer or during the script execution, it kept erroring about file not found. I was able to resolve it by passing in the <code>config</code> parameter in the <code>config_args</code> array in <code>openssl_pkey_new</code>. Here is a function that tests the ability to successfully use OpenSSL:</p>
  
  <pre><code>    /**
       * Tests the ability to 1) create pub/priv key pair 2) extract pub/priv keys 3) encrypt plaintext using keys 4) decrypt using keys
       * 
       * @return boolean|string False if fails, string if success
       */
      function testOpenSSL($opensslConfigPath = NULL)
      {
          if ($opensslConfigPath == NULL)
          {
              $opensslConfigPath = "E:/Services/Apache/httpd-2.4.9-win32-VC11/conf/openssl.cnf";
          }
          $config = array(
              "config" =&gt; $opensslConfigPath,
              "digest_alg" =&gt; "sha512",
              "private_key_bits" =&gt; 4096,
              "private_key_type" =&gt; OPENSSL_KEYTYPE_RSA,
          );
  
          $res = openssl_pkey_new($config); // &lt;-- CONFIG ARRAY
          if (empty($res)) {return false;}
  
          // Extract the private key from $res to $privKey
          openssl_pkey_export($res, $privKey, NULL, $config); // &lt;-- CONFIG ARRAY
  
          // Extract the public key from $res to $pubKey
          $pubKey = openssl_pkey_get_details($res);
          if ($pubKey === FALSE){return false;}
  
          $pubKey = $pubKey["key"];
  
          $data = 'plaintext data goes here';
  
          // Encrypt the data to $encrypted using the public key
          $res = openssl_public_encrypt($data, $encrypted, $pubKey);
          if ($res === FALSE){return false;}
  
          // Decrypt the data using the private key and store the results in $decrypted
          $res = openssl_private_decrypt($encrypted, $decrypted, $privKey);
          if ($res === FALSE){return false;}
  
          return $decrypted;
      }
  
      // Example usage:
      $res = testOpenSSL();
      if ($res === FALSE)
      {
          echo "&lt;span style='background-color: red;'&gt;Fail&lt;/span&gt;";
      } else {
          echo "&lt;span style='background-color: green;'&gt;Pass: ".$res."&lt;/span&gt;";
      }
  </code></pre>