Skip to content

Instantly share code, notes, and snippets.

@jas-
Created December 14, 2011 21:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jas-/1478742 to your computer and use it in GitHub Desktop.
Save jas-/1478742 to your computer and use it in GitHub Desktop.
PHP OpenSSL patch implementing SPKAC handling
#!/usr/local/bin/php
<?php
echo "Generating private key...";
$key = openssl_pkey_new(array('digest_alg' => 'sha512',
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'private_key_bits' => 2048));
echo "done\n";
echo "============================\n";
echo "Creating SPKAC using md5 signature...\n";
if (function_exists('openssl_spki_new')){
$spki = openssl_spki_new($key, _uuid(), 'md5');
echo $spki;
}
echo "\ndone\n";
echo "============================\n";
echo "Verifying SPKAC with md5 signature...\n";
if (function_exists('openssl_spki_verify')){
$w = openssl_spki_verify(preg_replace('/SPKAC=/', '', $spki));
var_dump($w);
}
echo "\n============================\n";
echo "Exporting challenge from SPKAC with md5 signature...\n";
if (function_exists('openssl_spki_export_challenge')){
$x = openssl_spki_export_challenge(preg_replace('/SPKAC=/', '', $spki));
echo $x;
}
echo "\ndone\n";
echo "============================\n";
echo "Exporting public key from SPKAC with md5 signature...\n";
if (function_exists('openssl_spki_export')){
$y = openssl_spki_export(preg_replace('/SPKAC=/', '', $spki));
print_r($y);
}
echo "\n============================\n";
echo "SPKAC details with md5 signature...\n";
if (function_exists('openssl_spki_details')){
$z = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
print_r($z);
}
echo "done\n";
echo "============================\n";
unset($w, $x, $y, $z);
echo "Creating SPKAC using sha1 signature...\n";
if (function_exists('openssl_spki_new')){
$spki = openssl_spki_new($key, _uuid(), 'sha1');
echo $spki;
}
echo "\ndone\n";
echo "============================\n";
echo "Verifying SPKAC with sha1 signature...\n";
if (function_exists('openssl_spki_verify')){
$w = openssl_spki_verify(preg_replace('/SPKAC=/', '', $spki));
var_dump($w);
}
echo "\n============================\n";
echo "Exporting challenge from SPKAC with sha1 signature...\n";
if (function_exists('openssl_spki_export_challenge')){
$x = openssl_spki_export_challenge(preg_replace('/SPKAC=/', '', $spki));
echo $x;
}
echo "\ndone\n";
echo "============================\n";
echo "Exporting public key from SPKAC with sha1 signature...\n";
if (function_exists('openssl_spki_export')){
$y = openssl_spki_export(preg_replace('/SPKAC=/', '', $spki));
print_r($y);
}
echo "\n============================\n";
echo "SPKAC details with sha1 signature...\n";
if (function_exists('openssl_spki_details')){
$z = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
print_r($z);
}
echo "done\n";
echo "============================\n";
unset($w, $x, $y, $z);
echo "Creating SPKAC using sha256 signature...\n";
if (function_exists('openssl_spki_new')){
$spki = openssl_spki_new($key, _uuid(), 'sha256');
echo $spki;
}
echo "\ndone\n";
echo "============================\n";
echo "Verifying SPKAC with sha256 signature...\n";
if (function_exists('openssl_spki_verify')){
$w = openssl_spki_verify(preg_replace('/SPKAC=/', '', $spki));
var_dump($w);
}
echo "\n============================\n";
echo "Exporting challenge from SPKAC with sha256 signature...\n";
if (function_exists('openssl_spki_export_challenge')){
$x = openssl_spki_export_challenge(preg_replace('/SPKAC=/', '', $spki));
echo $x;
}
echo "\ndone\n";
echo "============================\n";
echo "Exporting public key from SPKAC with sha256 signature...\n";
if (function_exists('openssl_spki_export')){
$y = openssl_spki_export(preg_replace('/SPKAC=/', '', $spki));
print_r($y);
}
echo "\n============================\n";
echo "SPKAC details with sha256 signature...\n";
if (function_exists('openssl_spki_details')){
$z = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
print_r($z);
}
echo "done\n";
echo "============================\n";
unset($w, $x, $y, $z);
echo "Creating SPKAC using sha512 signature...\n";
if (function_exists('openssl_spki_new')){
$spki = openssl_spki_new($key, _uuid(), 'md5');
echo $spki;
}
echo "\ndone\n";
echo "============================\n";
echo "Verifying SPKAC with sha512 signature...\n";
if (function_exists('openssl_spki_verify')){
$w = openssl_spki_verify(preg_replace('/SPKAC=/', '', $spki));
var_dump($w);
}
echo "\n============================\n";
echo "Exporting challenge from SPKAC with sha512 signature...\n";
if (function_exists('openssl_spki_export_challenge')){
$x = openssl_spki_export_challenge(preg_replace('/SPKAC=/', '', $spki));
echo $x;
}
echo "\ndone\n";
echo "============================\n";
echo "Exporting public key from SPKAC with sha512 signature...\n";
if (function_exists('openssl_spki_export')){
$y = openssl_spki_export(preg_replace('/SPKAC=/', '', $spki));
print_r($y);
}
echo "\n============================\n";
echo "SPKAC details with sha512 signature...\n";
if (function_exists('openssl_spki_details')){
$z = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
print_r($z);
}
echo "done\n";
echo "============================\n";
unset($w, $x, $y, $z);
openssl_free_key($key);
function _uuid()
{
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff),
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff),
mt_rand(0, 0xffff), mt_rand(0, 0xffff));
}
?>
--- php-5.3.8/ext/openssl/openssl.c 2011-07-25 05:42:53.000000000 -0600
+++ php-5.3.8/ext/openssl/openssl.c 2011-12-21 09:15:38.000000000 -0700
@@ -372,11 +372,40 @@
ZEND_ARG_INFO(0, length)
ZEND_ARG_INFO(1, result_is_strong)
ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_spki_new, 0, 0, 2)
+ ZEND_ARG_INFO(0, privkey)
+ ZEND_ARG_INFO(0, challenge)
+ ZEND_ARG_INFO(0, algo)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_verify, 0)
+ ZEND_ARG_INFO(0, spki)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_export, 0)
+ ZEND_ARG_INFO(0, spki)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_export_challenge, 0)
+ ZEND_ARG_INFO(0, spki)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_details, 0)
+ ZEND_ARG_INFO(0, spki)
+ZEND_END_ARG_INFO()
/* }}} */
/* {{{ openssl_functions[]
*/
const zend_function_entry openssl_functions[] = {
+/* spki functions */
+ PHP_FE(openssl_spki_new, arginfo_openssl_spki_new)
+ PHP_FE(openssl_spki_verify, arginfo_openssl_spki_verify)
+ PHP_FE(openssl_spki_export, arginfo_openssl_spki_export)
+ PHP_FE(openssl_spki_export_challenge, arginfo_openssl_spki_export_challenge)
+ PHP_FE(openssl_spki_details, arginfo_openssl_spki_details)
+
/* public/private key functions */
PHP_FE(openssl_pkey_free, arginfo_openssl_pkey_free)
PHP_FE(openssl_pkey_new, arginfo_openssl_pkey_new)
@@ -1252,6 +1281,291 @@
}
/* }}} */
+/* {{{ proto string openssl_spki_new(mixed zpkey, string challenge [, string algo='sha256'])
+ Creates new private key (or uses existing) and creates a new spki cert
+ outputting results to var */
+PHP_FUNCTION(openssl_spki_new)
+{
+ zval * zpkey = NULL;
+ EVP_PKEY * pkey = NULL;
+ NETSCAPE_SPKI *spki=NULL;
+ int challenge_len, algo_len;
+ char * challenge, * spkstr, *algo="sha256";
+ long keyresource = -1;
+ const char *spkac = "SPKAC=";
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s", &zpkey, &challenge, &challenge_len, &algo, &algo_len) == FAILURE) {
+ return;
+ }
+ RETVAL_FALSE;
+
+ pkey = php_openssl_evp_from_zval(&zpkey, 0, challenge, 1, &keyresource TSRMLS_CC);
+
+ if (pkey == NULL) {
+ goto cleanup;
+ }
+
+ if ((spki = NETSCAPE_SPKI_new()) == NULL) {
+ goto cleanup;
+ }
+
+ if (challenge) {
+ ASN1_STRING_set(spki->spkac->challenge, challenge, (int)strlen(challenge));
+ }
+
+ if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
+ goto cleanup;
+ }
+
+ if (strcmp(algo, "md5")==0){
+ if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_md5())) {
+ goto cleanup;
+ }
+ } else if(strcmp(algo, "sha1")==0){
+ if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_sha1())) {
+ goto cleanup;
+ }
+ } else if(strcmp(algo, "sha256")==0){
+ if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_sha256())) {
+ goto cleanup;
+ }
+ } else if (strcmp(algo, "sha512")==0){
+ if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_sha512())) {
+ goto cleanup;
+ }
+ }
+
+ spkstr = NETSCAPE_SPKI_b64_encode(spki);
+ if (!spkstr){
+ goto cleanup;
+ }
+
+ char * s = malloc(snprintf(NULL, 0, "%s%s", spkac, spkstr));
+ sprintf(s, "%s%s", spkac, spkstr);
+
+ if (strlen(s)<=0) {
+ goto cleanup;
+ }
+ RETURN_STRING(s, 1);
+
+cleanup:
+ if (keyresource == -1 && spki) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (keyresource == -1 && pkey) {
+ EVP_PKEY_free(pkey);
+ }
+ if (keyresource == -1 && s) {
+ free(s);
+ }
+ RETURN_NULL();
+}
+/* }}} */
+
+/* {{{ proto bool openssl_spki_verify(string spki)
+ Verifies spki returns boolean */
+PHP_FUNCTION(openssl_spki_verify)
+{
+ int spkstr_len, i, x=0;
+ char *spkstr = NULL;
+ EVP_PKEY *pkey = NULL;
+ NETSCAPE_SPKI *spki = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
+ return;
+ }
+
+ if (!spkstr) {
+ goto cleanup;
+ }
+
+ char * spkstr_cleaned = malloc(strlen(spkstr));
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (!spki) {
+ goto cleanup;
+ }
+
+ pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+ if (pkey == NULL) {
+ goto cleanup;
+ }
+
+ i = NETSCAPE_SPKI_verify(spki, pkey);
+
+ if (i > 0) {
+ x = 1;
+ }
+ goto cleanup;
+
+cleanup:
+ if (spki) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (pkey) {
+ EVP_PKEY_free(pkey);
+ }
+ RETURN_BOOL(x);
+}
+/* }}} */
+
+/* {{{ proto string openssl_spki_export(string spki)
+ Exports public key from existing spki to var */
+PHP_FUNCTION(openssl_spki_export)
+{
+ int spkstr_len;
+ EVP_PKEY *pkey = NULL;
+ NETSCAPE_SPKI *spki = NULL;
+ BIO *out = BIO_new(BIO_s_mem());
+ BUF_MEM *bio_buf;
+ char *spkstr;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
+ goto cleanup;
+ }
+
+ if (!spkstr) {
+ goto cleanup;
+ }
+
+ char * spkstr_cleaned = malloc(strlen(spkstr));
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (!spki) {
+ goto cleanup;
+ }
+
+ pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+ if (!pkey) {
+ goto cleanup;
+ }
+
+ PEM_write_bio_PUBKEY(out, pkey);
+ BIO_get_mem_ptr(out, &bio_buf);
+
+ if ((!bio_buf->data)&&(bio_buf->length<=0)) {
+ goto cleanup;
+ }
+
+ char * s = malloc(bio_buf->length);
+ BIO_read(out, s, bio_buf->length);
+ RETURN_STRING(s, 1);
+
+cleanup:
+ if (spki) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (out) {
+ BIO_free_all(out);
+ }
+ if (pkey) {
+ EVP_PKEY_free(pkey);
+ }
+}
+/* }}} */
+
+/* {{{ proto string openssl_spki_export_challenge(string spki)
+ Exports spkac challenge from existing spki to var */
+PHP_FUNCTION(openssl_spki_export_challenge)
+{
+ int spkstr_len;
+ NETSCAPE_SPKI *spki = NULL;
+ char *spkstr;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
+ goto cleanup;
+ }
+
+ if (!spkstr) {
+ goto cleanup;
+ }
+
+ char * spkstr_cleaned = malloc(strlen(spkstr));
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (!spki) {
+ goto cleanup;
+ }
+
+ RETURN_STRING(ASN1_STRING_data(spki->spkac->challenge), 1);
+
+cleanup:
+ if (spki) {
+ NETSCAPE_SPKI_free(spki);
+ }
+}
+/* }}} */
+
+/* {{{ proto string openssl_spki_details(string spki)
+ Provides details from existing spki to var */
+PHP_FUNCTION(openssl_spki_details)
+{
+ int spkstr_len;
+ NETSCAPE_SPKI *spki = NULL;
+ BIO *out = BIO_new(BIO_s_mem());
+ BUF_MEM *bio_buf;
+ zval *zout;
+ char *spkstr;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
+ return;
+ }
+ RETVAL_FALSE;
+
+ if (!spkstr) {
+ goto cleanup;
+ }
+
+ char * spkstr_cleaned = malloc(strlen(spkstr));
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (!spki) {
+ goto cleanup;
+ }
+
+ NETSCAPE_SPKI_print(out, spki);
+ BIO_get_mem_ptr(out, &bio_buf);
+
+ if ((!bio_buf->data)&&(bio_buf->length<=0)) {
+ goto cleanup;
+ }
+
+ char * s = malloc(bio_buf->length);
+ BIO_read(out, s, bio_buf->length);
+ RETURN_STRING(s, 1);
+
+cleanup:
+ if (spki) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ BIO_free_all(out);
+}
+/* }}} */
+
+/* {{{ proto int openssl_spki_cleanup(const char *src, char *results)
+ This will help remove new line chars in the SPKAC sent from the
+ browser */
+int openssl_spki_cleanup(const char *src, char *dest)
+{
+ int removed=0;
+
+ while (*src) {
+ if (*src!='\n'&&*src!='\r') {
+ *dest++=*src;
+ } else {
+ ++removed;
+ }
+ ++src;
+ }
+ *dest=0;
+ return removed;
+}
+/* }}} */
+
/* {{{ proto bool openssl_x509_export(mixed x509, string &out [, bool notext = true])
Exports a CERT to file or a var */
PHP_FUNCTION(openssl_x509_export)
--- php-5.3.8/ext/openssl/php_openssl.h 2010-12-31 19:19:59.000000000 -0700
+++ php-5.3.8/ext/openssl/php_openssl.h 2011-12-21 09:15:38.000000000 -0700
@@ -74,6 +74,12 @@
PHP_FUNCTION(openssl_csr_sign);
PHP_FUNCTION(openssl_csr_get_subject);
PHP_FUNCTION(openssl_csr_get_public_key);
+
+PHP_FUNCTION(openssl_spki_new);
+PHP_FUNCTION(openssl_spki_verify);
+PHP_FUNCTION(openssl_spki_export);
+PHP_FUNCTION(openssl_spki_export_challenge);
+PHP_FUNCTION(openssl_spki_details);
#else
#define phpext_openssl_ptr NULL
--- php-5.3.8/ext/openssl/tests/026.phpt 1969-12-31 17:00:00.000000000 -0700
+++ php-5.3.8/ext/openssl/tests/026.phpt 2011-12-21 12:45:39.000000000 -0700
@@ -0,0 +1,208 @@
+--TEST--
+openssl_spki_new(), openssl_spki_verify(), openssl_spki_export(), openssl_spki_export_challenge(), openssl_spki_details()
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (!@openssl_pkey_new()) die("skip cannot create private key");
+?>
+--FILE--
+<?php
+
+echo "Creating private key\n";
+$key = openssl_pkey_new();
+if ($key === false)
+ die("failed to create private key\n");
+
+echo "Creating new SPKAC with defaults\n";
+if (!function_exists("openssl_spki_new"))
+ die("openssl_spki_new() does not exist\n");
+
+$spki = openssl_spki_new($key, "sample_challenge_string");
+if ($spki === false)
+ die("could not create spkac\n");
+
+echo "Verifying SPKAC using defaults\n";
+if (!function_exists("openssl_spki_verify"))
+ die("openssl_spki_verify() does not exist\n");
+
+$a = openssl_spki_verify(preg_replace("/SPKAC=/", "", $spki));
+if ($a === false)
+ die("could not verify spkac\n");
+
+echo "Exporting challenge using defaults\n";
+if (!function_exists("openssl_spki_export_challenge"))
+ die("openssl_spki_export_challenge() does not exist\n");
+
+$b = openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki));
+if ($b !== "sample_challenge_string")
+ die("could not verify challenge string from spkac\n");
+
+echo "Exporting public key from SPKAC using defaults\n";
+if (!function_exists("openssl_spki_export"))
+ die("openssl_spki_export() does not exist\n");
+
+$c = openssl_spki_export(preg_replace("/SPKAC=/", '', $spki));
+if ($c === "")
+ die("could not export public key from spkac\n");
+
+echo "Generating details of SPKAC structure using defaults\n";
+if (!function_exists("openssl_spki_details"))
+ die("openssl_spki_details() does not exist\n");
+
+$d = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
+if ($d === "")
+ die("could not obtain details from spkac\n");
+
+unset($spki, $a, $b, $c, $d);
+
+echo "Creating new SPKAC using md5 signature\n";
+if (!function_exists("openssl_spki_new"))
+ die("openssl_spki_new() does not exist\n");
+
+$spki = openssl_spki_new($key, "sample_challenge_string", "md5");
+if ($spki === false)
+ die("could not create spkac\n");
+
+echo "Verifying SPKAC using md5 signature\n";
+if (!function_exists("openssl_spki_verify"))
+ die("openssl_spki_verify() does not exist\n");
+
+$a = openssl_spki_verify(preg_replace("/SPKAC=/", "", $spki));
+if ($a === false)
+ die("could not verify spkac\n");
+
+echo "Exporting challenge using md5 signature\n";
+if (!function_exists("openssl_spki_export_challenge"))
+ die("openssl_spki_export_challenge() does not exist\n");
+
+$b = openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki));
+if ($b !== "sample_challenge_string")
+ die("could not verify challenge string from spkac\n");
+
+echo "Exporting public key from SPKAC using md5 signature\n";
+if (!function_exists("openssl_spki_export"))
+ die("openssl_spki_export() does not exist\n");
+
+$c = openssl_spki_export(preg_replace("/SPKAC=/", '', $spki));
+if ($c === "")
+ die("could not export public key from spkac\n");
+
+echo "Generating details of SPKAC structure using md5 signature\n";
+if (!function_exists("openssl_spki_details"))
+ die("openssl_spki_details() does not exist\n");
+
+$d = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
+if ($d === "")
+ die("could not obtain details from spkac\n");
+
+unset($spki, $a, $b, $c, $d);
+
+echo "Creating new SPKAC using sha1 signature\n";
+if (!function_exists("openssl_spki_new"))
+ die("openssl_spki_new() does not exist\n");
+
+$spki = openssl_spki_new($key, "sample_challenge_string", "sha1");
+if ($spki === false)
+ die("could not create spkac\n");
+
+echo "Verifying SPKAC using sha1 signature\n";
+if (!function_exists("openssl_spki_verify"))
+ die("openssl_spki_verify() does not exist\n");
+
+$a = openssl_spki_verify(preg_replace("/SPKAC=/", "", $spki));
+if ($a === false)
+ die("could not verify spkac\n");
+
+echo "Exporting challenge using sha1 signature\n";
+if (!function_exists("openssl_spki_export_challenge"))
+ die("openssl_spki_export_challenge() does not exist\n");
+
+$b = openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki));
+if ($b !== "sample_challenge_string")
+ die("could not verify challenge string from spkac\n");
+
+echo "Exporting public key from SPKAC using sha1 signature\n";
+if (!function_exists("openssl_spki_export"))
+ die("openssl_spki_export() does not exist\n");
+
+$c = openssl_spki_export(preg_replace("/SPKAC=/", '', $spki));
+if ($c === "")
+ die("could not export public key from spkac\n");
+
+echo "Generating details of SPKAC structure using sha1 signature\n";
+if (!function_exists("openssl_spki_details"))
+ die("openssl_spki_details() does not exist\n");
+
+$d = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
+if ($d === "")
+ die("could not obtain details from spkac\n");
+
+unset($spki, $a, $b, $c, $d);
+
+echo "Creating new SPKAC using sha512 signature\n";
+if (!function_exists("openssl_spki_new"))
+ die("openssl_spki_new() does not exist\n");
+
+$spki = openssl_spki_new($key, "sample_challenge_string", "sha512");
+if ($spki === false)
+ die("could not create spkac\n");
+
+echo "Verifying SPKAC using sha512 signature\n";
+if (!function_exists("openssl_spki_verify"))
+ die("openssl_spki_verify() does not exist\n");
+
+$a = openssl_spki_verify(preg_replace("/SPKAC=/", "", $spki));
+if ($a === false)
+ die("could not verify spkac\n");
+
+echo "Exporting challenge using sha512 signature\n";
+if (!function_exists("openssl_spki_export_challenge"))
+ die("openssl_spki_export_challenge() does not exist\n");
+
+$b = openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki));
+if ($b !== "sample_challenge_string")
+ die("could not verify challenge string from spkac\n");
+
+echo "Exporting public key from SPKAC using sha512 signature\n";
+if (!function_exists("openssl_spki_export"))
+ die("openssl_spki_export() does not exist\n");
+
+$c = openssl_spki_export(preg_replace("/SPKAC=/", '', $spki));
+if ($c === "")
+ die("could not export public key from spkac\n");
+
+echo "Generating details of SPKAC structure using sha512 signature\n";
+if (!function_exists("openssl_spki_details"))
+ die("openssl_spki_details() does not exist\n");
+
+$d = openssl_spki_details(preg_replace('/SPKAC=/', '', $spki));
+if ($d === "")
+ die("could not obtain details from spkac\n");
+
+echo "OK!\n";
+
+openssl_free_key($key);
+?>
+--EXPECT--
+Creating private key
+Creating new SPKAC with defaults
+Verifying SPKAC using defaults
+Exporting challenge using defaults
+Exporting public key from SPKAC using defaults
+Generating details of SPKAC structure using defaults
+Creating new SPKAC using md5 signature
+Verifying SPKAC using md5 signature
+Exporting challenge using md5 signature
+Exporting public key from SPKAC using md5 signature
+Generating details of SPKAC structure using md5 signature
+Creating new SPKAC using sha1 signature
+Verifying SPKAC using sha1 signature
+Exporting challenge using sha1 signature
+Exporting public key from SPKAC using sha1 signature
+Generating details of SPKAC structure using sha1 signature
+Creating new SPKAC using sha512 signature
+Verifying SPKAC using sha512 signature
+Exporting challenge using sha512 signature
+Exporting public key from SPKAC using sha512 signature
+Generating details of SPKAC structure using sha512 signature
+OK!
<?php
@date_default_timezone_set(@date_default_timezone_get());
$settings['opts'] = array('digest_alg' => 'sha1',
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'private_key_bits' => 2048);
$settings['dn'] = array('commonName' => 'Jas-',
'emailAddress' => 'jason.gerfen@gmail.com',
'countryName' => 'US',
'stateOrProvinceName' => 'Utah',
'localityName' => 'Roy',
'organizationName' => 'University Of Utah',
'organizationalUnitName' => 'Marriott Library');
if (!empty($_POST['spki-key'])){
if ((!empty($_POST['commonName']))&&
(!empty($_POST['emailAddress']))&&
(!empty($_POST['countryName']))&&
(!empty($_POST['stateOrProvinceName']))&&
(!empty($_POST['localityName']))&&
(!empty($_POST['organizationName']))&&
(!empty($_POST['organizationalUnitName']))){
$settings['dn']['countryName'] = $_POST['countryName'];
$settings['dn']['stateOrProvinceName'] = $_POST['stateOrProvinceName'];
$settings['dn']['localityName'] = $_POST['localityName'];
$settings['dn']['organizationName'] = $_POST['organizationName'];
$settings['dn']['organizationalUnitName'] = $_POST['organizationalUnitName'];
$settings['dn']['commonName'] = $_POST['commonName'];
$settings['dn']['emailAddress'] = $_POST['emailAddress'];
$settings['dn']['SPKAC'] = $_POST['spki-key'];
$key = openssl_pkey_new($settings['opts']);
if (!empty($_POST['spki-key'])){
if (function_exists('openssl_spki_export_challenge')){
$pwd = openssl_spki_export_challenge($_POST['spki-key']);
}
if (function_exists('openssl_spki_export')){
$pkey = openssl_spki_export($_POST['spki-key']);
}
openssl_pkey_export($key, $pkey, $pwd);
}
$a = openssl_pkey_get_private($pkey, $pwd);
$b = openssl_csr_new($settings['dn'], $a, $settings['opts']);
openssl_csr_export($b, $c);
$d = openssl_csr_sign($c, NULL, $a, 365);
//$c = openssl_spki_export_cert($a, $_POST['spki-key'], $settings['dn'], $settings['opts']);
//openssl_csr_export($c, $d);
echo '<pre>'; print_r($c); echo '</pre>';
/*
$length = sizeof($d);
header('Last-Modified: '.date('r+b'));
header('Accept-Ranges: bytes');
header('Content-Length: '.$length);
header('Content-Type: application/x-x509-user-cert');
readfile('/tmp/'.$_POST['emailAddress'].'-cert');
exit;
*/
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>PHP OpenSSL SPKI functionality</title>
<link rel="stylesheet" href="styles.css" type="text/css" media="screen" />
</head>
<body>
<div id="contact-form" class="clearfix">
<h2>SPKAC to PKCS#7 certificate generator</h2>
<p>This form is to demo the HTML5 KeyGen tag and the new PHP OpenSSL SPKI family of functions</p>
<form id="spkac" name="spkac" method="post" action="openssl-spki.php">
<div>
<label for="emailAddress">Email:</label>
<input type="email" name="emailAddress">
</div>
<div>
<label for="commonName">Name:</label>
<input type="text" name="commonName">
</div>
<div>
<label for="countryName">Country:</label>
<select name="countryName">
<optgroup label="North America">
<option value="US">United States</option>
<option value="AI">Anguilla</option>
<option value="AG">Antigua and Barbuda</option>
<option value="ABC">Aruba</option>
<option value="BS">Bahamas</option>
<option value="BB">Barbados</option>
<option value="BZ">Belize</option>
<option value="BM">Bermuda</option>
<option value="VG">Virgin Islands, British</option>
<option value="CA">Canada</option>
<option value="KY">Cayman Islands</option>
<option value="CR">Costa Rica</option>
<option value="CU">Cuba</option>
<option value="DM">Dominica</option>
<option value="DO">Dominican Republic</option>
<option value="SV">El Salvador</option>
<option value="FK">Falkland Islands (Malvinas)</option>
<option value="GL">Greenland</option>
<option value="GD">Grenada</option>
<option value="GP">Guadeloupe</option>
<option value="GT">Guatemala</option>
<option value="HT">Haiti</option>
<option value="HN">Honduras</option>
<option value="JM">Jamaica</option>
<option value="MQ">Martinique</option>
<option value="MX">Mexico</option>
<option value="MS">Montserrat</option>
<option value="AN">Netherlands Antilles</option>
<option value="NI">Nicaragua</option>
<option value="PA">Panama</option>
<option value="PR">Puerto Rico</option>
<option value="KN">Saint Kitts and Nevis</option>
<option value="LC">Saint Lucia</option>
<option value="PM">Saint Pierre and Miquelon</option>
<option value="VC">Saint Vincent and The Grenadines</option>
<option value="TT">Trinidad and Tobago</option>
<option value="TC">Turks and Caicos Islands</option>
<option value="UM">United States Minor Outlying Islands</option>
<option value="VI">Virgin Islands, U.S.</option>
</optgroup>
<optgroup label="South America">
<option value="010">Argentina</option>
<option value="026">Bolivia</option>
<option value="030">Brazil</option>
<option value="043">Chile</option>
<option value="047">Colombia</option>
<option value="062">Ecuador</option>
<option value="074">French Guiana</option>
<option value="091">Guyana</option>
<option value="167">Paraguay</option>
<option value="168">Peru</option>
<option value="202">Suriname</option>
<option value="228">Uruguay</option>
<option value="231">Venezuela</option>
</optgroup>
<optgroup label="Antarctica">
<option value="008">Antarctica</option>
<option value="029">Bouvet Island</option>
<option value="076">French Southern Territories</option>
<option value="093">Heard Island and Mcdonald Islands</option>
<option value="198">South Georgia and The South Sandwich Islands</option>
</optgroup>
<optgroup label="Africa">
<option value="003">Algeria</option>
<option value="006">Angola</option>
<option value="023">Benin</option>
<option value="028">Botswana</option>
<option value="034">Burkina Faso</option>
<option value="035">Burundi</option>
<option value="037">Cameroon</option>
<option value="039">Cape Verde</option>
<option value="041">Central African Republic</option>
<option value="042">Chad</option>
<option value="048">Comoros</option>
<option value="049">Congo</option>
<option value="050">Congo, The Democratic Republic of The</option>
<option value="053">Cote D'ivoire</option>
<option value="059">Djibouti</option>
<option value="063">Egypt</option>
<option value="065">Equatorial Guinea</option>
<option value="066">Eritrea</option>
<option value="068">Ethiopia</option>
<option value="077">Gabon</option>
<option value="078">Gambia</option>
<option value="081">Ghana</option>
<option value="089">Guinea</option>
<option value="090">Guinea-bissau</option>
<option value="110">Kenya</option>
<option value="119">Lesotho</option>
<option value="120">Liberia</option>
<option value="121">Libyan Arab Jamahiriya</option>
<option value="235">Wallis and Futuna</option>
<option value="236">Western Sahara</option>
<option value="237">Yemen</option>
<option value="127">Madagascar</option>
<option value="128">Malawi</option>
<option value="131">Mali</option>
<option value="135">Mauritania</option>
<option value="136">Mauritius</option>
<option value="137">Mayotte</option>
<option value="144">Morocco</option>
<option value="145">Mozambique</option>
<option value="147">Namibia</option>
<option value="155">Niger</option>
<option value="156">Nigeria</option>
<option value="175">Reunion</option>
<option value="178">Rwanda</option>
<option value="179">Saint Helena</option>
<option value="186">Sao Tome and Principe</option>
<option value="188">Senegal</option>
<option value="190">Seychelles</option>
<option value="191">Sierra Leone</option>
<option value="196">Somalia</option>
<option value="197">South Africa</option>
<option value="201">Sudan</option>
<option value="204">Swaziland</option>
<option value="210">Tanzania, United Republic of</option>
<option value="213">Togo</option>
<option value="217">Tunisia</option>
<option value="222">Uganda</option>
<option value="238">Zambia</option>
<option value="239">Zimbabwe</option>
</optgroup>
<optgroup label="Europe">
<option value="002">Albania</option>
<option value="005">Andorra</option>
<option value="011">Armenia</option>
<option value="014">Austria</option>
<option value="015">Azerbaijan</option>
<option value="020">Belarus</option>
<option value="021">Belgium</option>
<option value="027">Bosnia and Herzegovina</option>
<option value="033">Bulgaria</option>
<option value="054">Croatia</option>
<option value="056">Cyprus</option>
<option value="057">Czech Republic</option>
<option value="058">Denmark</option>
<option value="067">Estonia</option>
<option value="070">Faroe Islands</option>
<option value="072">Finland</option>
<option value="073">France</option>
<option value="079">Georgia</option>
<option value="080">Germany</option>
<option value="082">Gibraltar</option>
<option value="083">Greece</option>
<option value="084">Greenland</option>
<option value="097">Hungary</option>
<option value="098">Iceland</option>
<option value="103">Ireland</option>
<option value="105">Italy</option>
<option value="109">Kazakhstan</option>
<option value="300">Kosovo</option>
<option value="117">Latvia</option>
<option value="122">Liechtenstein</option>
<option value="123">Lithuania</option>
<option value="124">Luxembourg</option>
<option value="126">Macedonia</option>
<option value="132">Malta</option>
<option value="140">Moldova, Republic of</option>
<option value="141">Monaco</option>
<option value="301">Montenegro</option>
<option value="150">Netherlands</option>
<option value="160">Norway</option>
<option value="171">Poland</option>
<option value="172">Portugal</option>
<option value="176">Romania</option>
<option value="177">Russia</option>
<option value="185">San Marino</option>
<option value="189">Serbia and Montenegro</option>
<option value="193">Slovakia</option>
<option value="194">Slovenia</option>
<option value="199">Spain</option>
<option value="203">Svalbard and Jan Mayen</option>
<option value="205">Sweden</option>
<option value="206">Switzerland</option>
<option value="218">Turkey</option>
<option value="223">Ukraine</option>
<option value="225">United Kingdom</option>
<option value="094">Vatican City</option>
</optgroup>
<optgroup label="Asia">
<option value="001">Afghanistan</option>
<option value="011">Armenia</option>
<option value="015">Azerbaijan</option>
<option value="017">Bahrain</option>
<option value="018">Bangladesh</option>
<option value="025">Bhutan</option>
<option value="031">British Indian Ocean Territory</option>
<option value="032">Brunei Darussalam</option>
<option value="036">Cambodia</option>
<option value="044">China</option>
<option value="056">Cyprus</option>
<option value="079">Georgia</option>
<option value="096">Hong Kong</option>
<option value="099">India</option>
<option value="100">Indonesia</option>
<option value="101">Iran</option>
<option value="102">Iraq</option>
<option value="104">Israel</option>
<option value="107">Japan</option>
<option value="108">Jordan</option>
<option value="109">Kazakhstan</option>
<option value="112">Korea, North</option>
<option value="113">Korea, South</option>
<option value="114">Kuwait</option>
<option value="115">Kyrgyzstan</option>
<option value="116">Laos</option>
<option value="118">Lebanon</option>
<option value="125">Macau</option>
<option value="129">Malaysia</option>
<option value="130">Maldives</option>
<option value="142">Mongolia</option>
<option value="146">Myanmar</option>
<option value="149">Nepal</option>
<option value="161">Oman</option>
<option value="162">Pakistan</option>
<option value="164">Palestinian Territory</option>
<option value="169">Philippines</option>
<option value="174">Qatar</option>
<option value="177">Russia</option>
<option value="187">Saudi Arabia</option>
<option value="192">Singapore</option>
<option value="200">Sri Lanka</option>
<option value="207">Syria</option>
<option value="208">Taiwan</option>
<option value="209">Tajikistan</option>
<option value="211">Thailand</option>
<option value="212">Timor-leste</option>
<option value="218">Turkey</option>
<option value="219">Turkmenistan</option>
<option value="224">United Arab Emirates</option>
<option value="229">Uzbekistan</option>
<option value="232">Vietnam</option>
<option value="237">Yemen</option>
</optgroup>
<optgroup label="Oceania">
<option value="004">American Samoa</option>
<option value="013">Australia</option>
<option value="045">Christmas Island</option>
<option value="046">Cocos (Keeling) Islands</option>
<option value="051">Cook Islands</option>
<option value="302">Easter Island</option>
<option value="071">Fiji</option>
<option value="087">Guam</option>
<option value="100">Indonesia</option>
<option value="111">Kiribati</option>
<option value="133">Marshall Islands</option>
<option value="139">Micronesia, Federated States of</option>
<option value="148">Nauru</option>
<option value="152">New Caledonia</option>
<option value="153">New Zealand</option>
<option value="157">Niue</option>
<option value="158">Norfolk Island</option>
<option value="159">Northern Mariana Islands</option>
<option value="163">Palau</option>
<option value="166">Papua New Guinea</option>
<option value="170">Pitcairn</option>
<option value="075">French Polynesia</option>
<option value="184">Samoa</option>
<option value="195">Solomon Islands</option>
<option value="214">Tokelau</option>
<option value="215">Tonga</option>
<option value="221">Tuvalu</option>
<option value="230">Vanuatu</option>
</optgroup>
</select>
</div>
<div>
<label for="stateOrProvinceName">State:</label>
<select name="stateOrProvinceName">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="DC">District Of Columbia</option>
<option value="FL">Florida</option>
<option value="GA">Georgia</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
</select>
</div>
<div>
<label for="localityName">City:</label>
<input type="text" name="localityName">
</div>
<div>
<label for="organizationalName">Organization:</label>
<input type="text" name="organizationName">
</div>
<div>
<label for="organizationalUnitName">Department:</label>
<input type="text" name="organizationalUnitName">
</div>
<div>
<label for="spki-key">Key strength:</label>
<keygen name="spki-key" keytype="rsa" challenge="testing"></keygen>
</div>
<input type="submit">
</form>
</div>
<div id="contact-form" class="clearfix" style="word-wrap:break-word; font-size: 12px">
<?php
if (empty($_POST['spki-key'])){
echo "Generating private key...";
$key = openssl_pkey_new(array('digest_alg' => 'sha512',
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'private_key_bits' => 2048));
echo "done<br/>";
echo "============================<br/>";
}
if (empty($_POST['spki-key'])){
echo "Creating SPKAC...<br/>";
if (function_exists('openssl_spki_new')){
$spki = openssl_spki_new($key, 'wtfd00d', 'sha512');
echo $spki;
}
echo "<br/>done<br/>";
echo "============================<br/>";
}
if (!empty($_POST['spki-key'])){
echo "Recieved SPKAC...<br/>";
echo $_POST['spki-key']."<br/>";
echo "done<br/>";
echo "============================<br/>";
}
echo "Verifying SPKAC...<br/>";
if (function_exists('openssl_spki_verify')){
$y = (empty($_POST['spki-key'])) ?
openssl_spki_verify(preg_replace('/SPKAC=/', '', $spki)) :
openssl_spki_verify($_POST['spki-key']);
var_dump($y);
}
echo "<br/>============================<br/>";
echo "Exporting challenge from SPKAC...<br/>";
if (function_exists('openssl_spki_export_challenge')){
$x = (empty($_POST['spki-key'])) ?
openssl_spki_export_challenge(preg_replace('/SPKAC=/', '', $spki)) :
openssl_spki_export_challenge($_POST['spki-key']);
echo $x;
}
echo "<br/>done<br/>";
echo "============================<br/>";
echo "Exporting public key from SPKAC...<br/>";
if (function_exists('openssl_spki_export')){
$z = (empty($_POST['spki-key'])) ?
openssl_spki_export(preg_replace('/SPKAC=/', '', $spki)) :
openssl_spki_export($_POST['spki-key']);
echo '<pre>'; print_r($z); echo '</pre>';
}
echo "<br/>============================<br/>";
echo "SPKAC details...<br/>";
if (function_exists('openssl_spki_details')){
$w = (empty($_POST['spki-key'])) ?
openssl_spki_details(preg_replace('/SPKAC=/', '', $spki)) :
openssl_spki_details($_POST['spki-key']);
echo '<pre>'; print_r($w); echo '</pre>';
}
echo "done<br/>";
echo "============================<br/>";
if (empty($_POST['spki-key'])){
openssl_free_key($key);
}
?>
</div>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment