2012-04-05 6 views
5

Ist es möglich, ein Zertifikat und einen privaten Schlüssel zu einer .pfx zusammen mit der Zertifikatskette (Root-Zertifikat und/oder Zwischenzertifikat) openssl_pkcs12_export() über zu exportieren?Exportkette mit openssl_pkcs12_export in PHP

UPDATE: Ich habe einen Blick auf die Quelle für die PHP-Erweiterung openssl genommen und festgestellt, dass openssl_pkcs12_export() unterstützt 2 args andere als die, die in der Dokumentation, friendly_name und extracerts. Dies ist von ext/openssl/openssl.c Besuche Linien 1914-1920 (PHP-5.4.0):

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 /* }}} */ 

aber ich bin mir nicht ganz sicher, wie die zusätzlichen Zertifikate als Argumente zu übergeben ... irgendwelche Hinweise?

Lassen Sie mich wissen, ob es ohne die Zeilennummern leichter lesbar ist

Antwort

5

Diese a bug that has been brought up vor fast zwei Monate.

Zum Glück bietet er eine Probe Patch für die Dokumentation:

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

Was $CAcert ist? Intern wird es an eine Funktion takes an array and turns it into a x509 übergeben und diese Funktion erkennt auch, ob es sich um ein Array von Zertifikaten oder ein einzelnes Zertifikat handelt. Jedes Element sollte eine x509-Ressource sein, wenn Sie ein Array übergeben, oder $ CAcert sollte eine einzelne Ressource sein, wenn Sie kein Array übergeben. openssl_x509_read ist wahrscheinlich, was Sie hier verwenden möchten, da es den x509-Ressourcentyp zurückgibt, der in $CAcert erwartet wird.

Einige Leute sagen, dass die Aktualisierung von Dokumenten einer der schwierigsten Teile von PHP ist. Wenn du nicht gut mit C bist und PHP helfen willst, besser zu werden, ist das ein guter Anfang.

+0

Schön, danke. Welcher Variablentyp wäre $ CAcert in diesem Kontext? Nur ein String oder die Ausgabe von einem PEM gelesen mit openssl_x509_read() oder was? Bitte geben Sie ein Beispiel, wenn Sie können –

+0

@ MathiasR.Jessen Intern '$ CAcert' wird an http://lxr.php.net/opengrok/xref/PHP_5_4/ext/openssl/openssl.c#1741 übergeben und dies erkennt, ob es ist ein Array von Zertifikaten oder ein einzelnes Zertifikat, jedes Element sollte eine 'x509 Resource' sein. Ich habe das vorher nicht implementiert, aber ich vermute sehr, dass Ihre Annahme von "openssl_x509_read" korrekt ist, da sie diesen Ressourcentyp zurückgibt. – Incognito

+1

Cool, ich werde versuchen, mit diesem Ansatz zu implementieren und zurück, danke –