5

PHPを使用して、証明書と秘密鍵を証明書チェーン(ルート証明書および/または中間)とともにopenssl_pkcs12_export().pfxにエクスポートすることは可能ですか?

更新:php openssl拡張機能のソースを調べたところ、ドキュメントにあるもの以外の2つの引数をサポートしていることがわかりましopenssl_pkcs12_export()た。これは、1914年から1920年(PHP-5.4.0)の行を確認してください。friendly_nameextracertsext/openssl/openssl.c

1878 /* {{{ proto bool openssl_pkcs12_export(mixed x509, string &out, mixed priv_key, string pass[, array args])
1879    Creates and exports a PKCS12 to a var */
1880 PHP_FUNCTION(openssl_pkcs12_export)
1881 {
1882         X509 * cert = NULL;                                                                                                                                                
1883         BIO * bio_out;
1884         PKCS12 * p12 = NULL;
1885         zval * zcert = NULL, *zout = NULL, *zpkey, *args = NULL;
1886         EVP_PKEY *priv_key = NULL;
1887         long certresource, keyresource;
1888         char * pass;
1889         int pass_len;
1890         char * friendly_name = NULL;
1891         zval ** item;
1892         STACK_OF(X509) *ca = NULL;
1893 
1894         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzzs|a", &zcert, &zout, &zpkey, &pass, &pass_len, &args) == FAILURE)
1895                 return;
1896 
1897         RETVAL_FALSE;
1898 
1899         cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC);
1900         if (cert == NULL) {
1901                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
1902                 return;
1903         }
1904         priv_key = php_openssl_evp_from_zval(&zpkey, 0, "", 1, &keyresource TSRMLS_CC);
1905         if (priv_key == NULL) {
1906                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get private key from parameter 3");
1907                 goto cleanup;
1908         }
1909         if (cert && !X509_check_private_key(cert, priv_key)) {
1910                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to cert");
1911                 goto cleanup;
1912         }
1913 
1914         /* parse extra config from args array, promote this to an extra function */
1915         if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS)
1916                 friendly_name = Z_STRVAL_PP(item);
1917 
1918         if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)
1919                 ca = php_array_to_X509_sk(item TSRMLS_CC);
1920         /* end parse extra config */
1921 
1922         p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
1923 
1924         bio_out = BIO_new(BIO_s_mem());
1925         if (i2d_PKCS12_bio(bio_out, p12))  {
1926                 BUF_MEM *bio_buf;
1927 
1928                 zval_dtor(zout);
1929                 BIO_get_mem_ptr(bio_out, &bio_buf);
1930                 ZVAL_STRINGL(zout, bio_buf->data, bio_buf->length, 1);
1931 
1932                 RETVAL_TRUE;
1933         }
1934 
1935         BIO_free(bio_out);
1936         PKCS12_free(p12);
1937         php_sk_X509_free(ca);
1938 
1939 cleanup:
1940 
1941         if (keyresource == -1 && priv_key) {
1942                 EVP_PKEY_free(priv_key);
1943         }
1944         if (certresource == -1 && cert) {
1945                 X509_free(cert);
1946         }
1947 }
1948 /* }}} */

ただし、追加の証明書を引数として渡す方法がよくわかりません...手がかりはありますか?

行番号がなくても読みやすいかどうか教えてください

4

1 に答える 1

5

これは、 2か月近く前に発生したバグです。

ありがたいことに、彼はドキュメントのサンプルパッチを提供しています。

$args = array(
               'extracerts' => $CAcert,
               'friendly_name' => 'My signed cert by CA certificate'
              );
openssl_pkcs12_export($signed_csr, $cerificate_out, $private_key_resource, $passphrase, $args);

$CAcertですか?内部的には、配列を取得してx509に変換する関数に渡され、その関数は、それが証明書の配列であるか単一の証明書であるかも検出します。配列を渡す場合は、各要素をx509リソースにする必要があります。配列を渡さない場合は、$CAcertを単一のリソースにする必要があります。openssl_x509_readで期待されるx509リソースタイプを返すため、ここで使用したいものである可能性があります$CAcert

ドキュメントを最新の状態に保つことは、PHPプロジェクトの最も難しい部分の1つであると言う人もいます。Cが苦手で、PHPの改善を支援したい場合は、ここから始めるのがよいでしょう。

于 2012-04-08T12:54:21.717 に答える