Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

SPKAC functionality per feature request #38917 (part deux) #37

Closed
wants to merge 5 commits into from

5 participants

@jas-

Per bug id https://bugs.php.net/bug.php?id=38917, a patch to implement missing SPKAC functionality within the OpenSSL extension.

I have made recommended modifications per closed pull request id #21.

ext/openssl/openssl.c
((60 lines not shown))
+
+ if (!NETSCAPE_SPKI_sign(spki, pkey, mdtype)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to sign with %l algorithm", method);
+ RETURN_NULL();
+ }
+
+ spkstr = NETSCAPE_SPKI_b64_encode(spki);
+ if (!spkstr){
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable encode SPKAC");
+ RETURN_NULL();
+ }
+
+ s = emalloc(strlen(spkac) + strlen(spkstr) + 1);
+ sprintf(s, "%s%s", spkac, spkstr);
+
+ if (sizeof(s)<=0) {
@smalyshev Owner

what this code is for? emalloc never returns NULL and sizeof(s) is a constant and you used s for sprintf anyway earlier.

@jas-
jas- added a note

Perhaps I don't understand the question. sprintf() gets used after emalloc

@smalyshev Owner

What is this code for: if (sizeof(s)<=0) {

@jas-
jas- added a note

To ensure an SPKAC is created, I should modify that to be

if (sizeof(s)!=8) {
@nikic Owner
nikic added a note

@jas- In which occasions would it not be created? As @smalyshev mentioned, emalloc is infallible. If it can't allocate the memory the program will terminate.

@jas-
jas- added a note

Didn't think of that, over engineering it. WIll remove thanks @smalyshev & @nikic

@smalyshev Owner

Also, sizeof(s) is always the same, it is a constant operation. It does not depend on anything, just returns size of char * type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
ext/openssl/openssl.c
((72 lines not shown))
+ s = emalloc(strlen(spkac) + strlen(spkstr) + 1);
+ sprintf(s, "%s%s", spkac, spkstr);
+
+ if (sizeof(s)<=0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate memory for SPKAC");
+ RETURN_NULL();
+ }
+
+ if (keyresource == -1 && spki != NULL) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (keyresource == -1 && pkey != NULL) {
+ EVP_PKEY_free(pkey);
+ }
+
+ RETURN_STRINGL(s, strlen(s), 1);
@smalyshev Owner

Why s is allocated and then copied? Can't you avoid the copy and return s as is? Also, s is never freed.

@jas-
jas- added a note

I suppose because the remainder of the functions in the openssl.c file contain similar methods of allocating memory for pointers prior to copying contents although most of them deal with the BIO_* family of functions provided by the ssl libs.

According to the documentation on the RETURN_STRINGL() macro it will actually perform the free/efree operations unless I am missing something

@smalyshev Owner

I don't know what documentation you are referring to, I don't see RETURN_STRINGL doing any free or efree. What documentation says it does?

@jas-
jas- added a note

I am mistaken. The last argument was to copy not free the string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
ext/openssl/openssl.c
((111 lines not shown))
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ if (strlen(spkstr_cleaned)<=0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate memory for SPKAC");
+ RETURN_FALSE;
+ }
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (spki == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to decode supplied SPKAC");
+ RETURN_FALSE;
+ }
+
+ pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+ if (pkey == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to aquire signed public key");
@smalyshev Owner

Wouldn't this leak spki?

@jas-
jas- added a note

Fix is on the way, just performing tests to ensure leaks are no longer applicable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
ext/openssl/openssl.c
((172 lines not shown))
+ if (spki == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to decode supplied SPKAC");
+ RETURN_NULL();
+ }
+
+ pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+ if (pkey == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to aquire signed public key");
+ RETURN_NULL();
+ }
+
+ PEM_write_bio_PUBKEY(out, pkey);
+ BIO_get_mem_ptr(out, &bio_buf);
+
+ if ((!bio_buf->data)&&(bio_buf->length<=0)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate memory for public key");
@smalyshev Owner

here we would leak pkey, spki, spkstr_cleaned

@jas-
jas- added a note

So would you rather it worked like this?

PEM_write_bio(out, X509_PUBKEY_get(spki->spkac->pubkey));
@smalyshev Owner

PEM_write_bio call doesn't matter, what matters you are returning without freeing structures that you have allocated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
ext/openssl/openssl.c
((189 lines not shown))
+ }
+
+ s = emalloc(bio_buf->length);
+ BIO_read(out, s, bio_buf->length);
+
+ if (spki != NULL) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (out != NULL) {
+ BIO_free_all(out);
+ }
+ if (pkey != NULL) {
+ EVP_PKEY_free(pkey);
+ }
+
+ RETURN_STRINGL(s, strlen(s), 1);
@smalyshev Owner

Is s and spkstr_cleaned ever freed?

@jas-
jas- added a note

Apparently not but upon review of other functions in the openssl.c file there are resources that are similar, openssl_x509_parse() for example doesn't free a few items. Could you be specific in what the problem is?

@smalyshev Owner

The problem is that you allocate s but do not free it. It creates memory leak. It should be fixed.

@jas-
jas- added a note

No worries, my dyslexia rears its ugly head. I misread the docs on RETURN_STRINGL. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
ext/openssl/openssl.c
((220 lines not shown))
+
+ if (spkstr == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to use supplied SPKAC");
+ RETURN_NULL();
+ }
+
+ spkstr_cleaned = emalloc(spkstr_len + 1);
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (spki == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate memory for public key");
+ RETURN_NULL();
+ }
+
+ RETURN_STRINGL(ASN1_STRING_data(spki->spkac->challenge), strlen(ASN1_STRING_data(spki->spkac->challenge)), 1);
@smalyshev Owner

Is spkstr_cleaned ever freed?

@jas-
jas- added a note

@smalyshev Could you confirm that the document I am referencing here (http://docstore.mik.ua/orelly/webprog/php/ch14_08.htm) is correct?

PHP_FUNCTION(test) {
    char *str = emalloc(5);
    strcpy(str, "newb");
    RETURN_STRINGL(str, strlen(str), 0);
}

By setting the last argument of RETURN_STRINGL to 0 anything emalloc'd will get efree'd internally or no?

@smalyshev Owner

The last argument of RETURN_STRING[L] says if the argument string should be duplicated or not. If the string is already allocated with emalloc (IMPORTANT: not malloc!) then you can pass 0 zero and you don't have to free the string and there's no duplication.

If you pass 1, the string will be duplicated and if you allocated the original you have the responsibility to free it.

If you use strlen, recommended way would be to do RETURN_STRING(str, 0); as RETURN_STRING automatically says length to strlen of the string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@smalyshev smalyshev commented on the diff
ext/openssl/openssl.c
((43 lines not shown))
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm");
+ RETURN_NULL();
+ }
+
+ if ((spki = NETSCAPE_SPKI_new()) == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create new SPKAC");
+ RETURN_NULL();
+ }
+
+ if (challenge) {
+ ASN1_STRING_set(spki->spkac->challenge, challenge, (int)strlen(challenge));
+ }
+
+ if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to embed public key");
+ RETURN_NULL();
@smalyshev Owner

Wouldn't this RETURN leave spki and pkey not freed?

@jas-
jas- added a note

I would much rather use a macro as I did in my original patch submission to free everything.

if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
    goto cleanup;

I was however told I should move away from using those

@smalyshev Owner

You can use macro, you can use goto if you're really careful (comment on it!) but you have to free stuff you allocated one way or another.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@smalyshev smalyshev commented on the diff
ext/openssl/openssl.c
((107 lines not shown))
+
+ if (strlen(spkstr_cleaned)<=0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate memory for SPKAC");
+ RETURN_FALSE;
+ }
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (spki == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode supplied SPKAC");
+ RETURN_FALSE;
+ }
+
+ pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+ if (pkey == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to aquire signed public key");
+ RETURN_FALSE;
@smalyshev Owner

This RETURN seems not to free all temp structured previously allocated.

@jas-
jas- added a note

Again, move to a macro to perform all free'ing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@smalyshev smalyshev commented on the diff
ext/openssl/openssl.c
((236 lines not shown))
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (spki == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate memory for public key");
+ RETURN_NULL();
+ }
+ /*
+ if (spkstr != NULL) {
+ efree(spkstr);
+ }
+ if (spkstr_cleaned != NULL) {
+ efree(spkstr_cleaned);
+ }
+ */
+ RETURN_STRING(ASN1_STRING_data(spki->spkac->challenge), 0);
@smalyshev Owner

aren't you supposed to free spki data structure?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@smalyshev smalyshev commented on the diff
ext/openssl/tests/openssl_spki_export_challenge.phpt
((14 lines not shown))
+echo ($pkey !== false) ?
+ "ok!\n\n" : "error creating private key\n\n";
+
+/* testing all signing algorithms */
+$algos = array('MD5'=>OPENSSL_ALGO_MD5,
+ 'SHA1'=>OPENSSL_ALGO_SHA1,
+ 'SHA256'=>OPENSSL_ALGO_SHA256,
+ 'SHA512'=>OPENSSL_ALGO_SHA512);
+
+/* loop to create, export challenge and verify */
+foreach($algos as $key => $value){
+ echo "Exporting challenge from SPKAC with ".$key."...";
+ $spki = openssl_spki_new($pkey, "sample_challenge_string", $value);
+ if ((!empty($spki)) && (preg_match('/SPKAC=[a-zA-Z0-9\/\+]/', $spki)))
+ $r = openssl_spki_export_challenge(preg_replace('/SPKAC=/', '', $spki));
+ if ($r === "sample_challenge_string")
@smalyshev Owner

I think it is better to do var_dump($r) here and then have the string in the EXPECT. This way if $r is something else it is immediately seen in the test diff.

@jas-
jas- added a note

Noted. I will make adjustments hopefully over the weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@lstrojny

@jas- ping again

@jas-

Closing this request. Please refer to branch "issue-38917-spkac" and pull request #267 (#267)

@jas- jas- closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 3, 2012
  1. @invalid-email-address
  2. @jas-

    Tue Apr 3 14:41:40 MDT 2012 - SPKI functions, recommended changes and…

    jas- authored
    … patch for bug id #61421
Commits on Apr 4, 2012
  1. @jas-
  2. @jas-

    Tue Apr 3 22:27:41 MDT 2012 - Split SPKI family of test cases into in…

    jas- authored
    …dividual files as requested
Commits on Apr 8, 2012
  1. @jas-

    Sat Apr 7 21:02:37 MDT 2012 - Fixed segfaults and should just need to…

    jas- authored
    … clean up any memory leaks
This page is out of date. Refresh to see the latest.
View
579 ext/openssl/openssl.c
@@ -16,7 +16,7 @@
| Wez Furlong <wez@thebrainroom.com> |
| Sascha Kettler <kettler@gmx.net> |
| Pierre-Alain Joye <pierre@php.net> |
- | Marc Delling <delling@silpion.de> (PKCS12 functions) |
+ | Marc Delling <delling@silpion.de> (PKCS12 functions) |
+----------------------------------------------------------------------+
*/
@@ -66,6 +66,14 @@
#endif
#define OPENSSL_ALGO_DSS1 5
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+#define OPENSSL_ALGO_SHA224 6
+#define OPENSSL_ALGO_SHA256 7
+#define OPENSSL_ALGO_SHA384 8
+#define OPENSSL_ALGO_SHA512 9
+#define OPENSSL_ALGO_RIPEMD160 10
+#endif
+
#define DEBUG_SMIME 0
/* FIXME: Use the openssl constants instead of
@@ -375,11 +383,35 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_random_pseudo_bytes, 0, 0, 1)
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()
/* }}} */
/* {{{ 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)
+
/* public/private key functions */
PHP_FE(openssl_pkey_free, arginfo_openssl_pkey_free)
PHP_FE(openssl_pkey_new, arginfo_openssl_pkey_new)
@@ -506,7 +538,7 @@ inline static int php_openssl_open_base_dir_chk(char *filename TSRMLS_DC)
if (php_check_open_basedir(filename TSRMLS_CC)) {
return -1;
}
-
+
return 0;
}
/* }}} */
@@ -565,7 +597,7 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s
} else {
subitem = val;
}
-
+
for (i = 0; i < X509_NAME_entry_count(name); i++) {
unsigned char *to_add;
int to_add_len;
@@ -608,7 +640,7 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s
last = j;
}
i = last;
-
+
if (obj_cnt > 1) {
add_assoc_zval_ex(subitem, sname, strlen(sname) + 1, subentries);
} else {
@@ -708,7 +740,7 @@ static inline int php_openssl_config_check_syntax(const char * section_label, co
#endif
{
X509V3_CTX ctx;
-
+
X509V3_set_ctx_test(&ctx);
X509V3_set_conf_lhash(&ctx, config);
if (!X509V3_EXT_add_conf(config, &ctx, (char *)section, NULL)) {
@@ -770,6 +802,7 @@ static int add_oid_section(struct php_x509_request * req TSRMLS_DC) /* {{{ */
static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(long algo);
+int openssl_spki_cleanup(const char *src, char *dest);
static int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args TSRMLS_DC) /* {{{ */
{
@@ -836,7 +869,7 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
}
-
+
/* digest alg */
if (req->digest_name == NULL) {
req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md");
@@ -858,7 +891,7 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
}
PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section);
-
+
return SUCCESS;
}
/* }}} */
@@ -950,6 +983,23 @@ static EVP_MD * php_openssl_get_evp_md_from_algo(long algo) { /* {{{ */
case OPENSSL_ALGO_DSS1:
mdtype = (EVP_MD *) EVP_dss1();
break;
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+ case OPENSSL_ALGO_SHA224:
+ mdtype = (EVP_MD *) EVP_sha224();
+ break;
+ case OPENSSL_ALGO_SHA256:
+ mdtype = (EVP_MD *) EVP_sha256();
+ break;
+ case OPENSSL_ALGO_SHA384:
+ mdtype = (EVP_MD *) EVP_sha384();
+ break;
+ case OPENSSL_ALGO_SHA512:
+ mdtype = (EVP_MD *) EVP_sha512();
+ break;
+ case OPENSSL_ALGO_RIPEMD160:
+ mdtype = (EVP_MD *) EVP_ripemd160();
+ break;
+#endif
default:
return NULL;
break;
@@ -1021,10 +1071,10 @@ PHP_MINIT_FUNCTION(openssl)
/* register a resource id number with OpenSSL so that we can map SSL -> stream structures in
* OpenSSL callbacks */
ssl_stream_data_index = SSL_get_ex_new_index(0, "PHP stream index", NULL, NULL, NULL);
-
+
REGISTER_STRING_CONSTANT("OPENSSL_VERSION_TEXT", OPENSSL_VERSION_TEXT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER, CONST_CS|CONST_PERSISTENT);
-
+
/* purposes for cert purpose checking */
REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_CLIENT", X509_PURPOSE_SSL_CLIENT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_SERVER", X509_PURPOSE_SSL_SERVER, CONST_CS|CONST_PERSISTENT);
@@ -1045,6 +1095,14 @@ PHP_MINIT_FUNCTION(openssl)
#endif
REGISTER_LONG_CONSTANT("OPENSSL_ALGO_DSS1", OPENSSL_ALGO_DSS1, CONST_CS|CONST_PERSISTENT);
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA224", OPENSSL_ALGO_SHA224, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA256", OPENSSL_ALGO_SHA256, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA384", OPENSSL_ALGO_SHA384, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA512", OPENSSL_ALGO_SHA512, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_RIPEMD160", OPENSSL_ALGO_RIPEMD160, CONST_CS|CONST_PERSISTENT);
+#endif
+
/* flags for S/MIME */
REGISTER_LONG_CONSTANT("PKCS7_DETACHED", PKCS7_DETACHED, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PKCS7_TEXT", PKCS7_TEXT, CONST_CS|CONST_PERSISTENT);
@@ -1076,7 +1134,7 @@ PHP_MINIT_FUNCTION(openssl)
REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_192_CBC", PHP_OPENSSL_CIPHER_AES_192_CBC, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_256_CBC", PHP_OPENSSL_CIPHER_AES_256_CBC, CONST_CS|CONST_PERSISTENT);
#endif
-
+
/* Values for key types */
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_RSA", OPENSSL_KEYTYPE_RSA, CONST_CS|CONST_PERSISTENT);
#ifndef NO_DSA
@@ -1122,7 +1180,7 @@ PHP_MINIT_FUNCTION(openssl)
php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC);
php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC);
-
+
return SUCCESS;
}
/* }}} */
@@ -1290,6 +1348,277 @@ PHP_FUNCTION(openssl_x509_export_to_file)
}
/* }}} */
+/* {{{ proto string openssl_spki_new(mixed zpkey, string challenge [, mixed method])
+ Creates new private key (or uses existing) and creates a new spki cert
+ outputting results to var */
+PHP_FUNCTION(openssl_spki_new)
+{
+ int challenge_len;
+ char * challenge, * spkstr, * s;
+ long keyresource = -1;
+ const char *spkac = "SPKAC=";
+ long algo = OPENSSL_ALGO_MD5;
+
+ zval *method = NULL;
+ zval * zpkey = NULL;
+ EVP_PKEY * pkey = NULL;
+ NETSCAPE_SPKI *spki=NULL;
+ const EVP_MD *mdtype;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z", &zpkey, &challenge, &challenge_len, &method) == FAILURE) {
+ return;
+ }
+
+ pkey = php_openssl_evp_from_zval(&zpkey, 0, challenge, 1, &keyresource TSRMLS_CC);
+
+ if (pkey == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied private key");
+ RETURN_NULL();
+ }
+
+ if (method != NULL) {
+ if (Z_TYPE_P(method) == IS_LONG) {
+ algo = Z_LVAL_P(method);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Algorithm must be of supported type");
+ RETURN_NULL();
+ }
+ }
+ mdtype = php_openssl_get_evp_md_from_algo(algo);
+
+ if (!mdtype) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm");
+ RETURN_NULL();
+ }
+
+ if ((spki = NETSCAPE_SPKI_new()) == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create new SPKAC");
+ RETURN_NULL();
+ }
+
+ if (challenge) {
+ ASN1_STRING_set(spki->spkac->challenge, challenge, (int)strlen(challenge));
+ }
+
+ if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to embed public key");
+ RETURN_NULL();
@smalyshev Owner

Wouldn't this RETURN leave spki and pkey not freed?

@jas-
jas- added a note

I would much rather use a macro as I did in my original patch submission to free everything.

if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
    goto cleanup;

I was however told I should move away from using those

@smalyshev Owner

You can use macro, you can use goto if you're really careful (comment on it!) but you have to free stuff you allocated one way or another.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+
+ if (!NETSCAPE_SPKI_sign(spki, pkey, mdtype)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to sign with specified algorithm");
+ RETURN_NULL();
+ }
+
+ spkstr = NETSCAPE_SPKI_b64_encode(spki);
+ if (!spkstr){
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable encode SPKAC");
+ RETURN_NULL();
+ }
+
+ s = emalloc(strlen(spkac) + strlen(spkstr) + 1);
+ sprintf(s, "%s%s", spkac, spkstr);
+
+ if (keyresource == -1 && spki != NULL) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (keyresource == -1 && pkey != NULL) {
+ EVP_PKEY_free(pkey);
+ }
+
+ RETURN_STRINGL(s, strlen(s), 0);
+}
+/* }}} */
+
+/* {{{ proto bool openssl_spki_verify(string spki)
+ Verifies spki returns boolean */
+PHP_FUNCTION(openssl_spki_verify)
+{
+ int spkstr_len, i;
+ char *spkstr = NULL, * spkstr_cleaned;
+
+ 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 == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied SPKAC");
+ RETURN_FALSE;
+ }
+
+ spkstr_cleaned = emalloc(spkstr_len + 1);
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ if (strlen(spkstr_cleaned)<=0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate memory for SPKAC");
+ RETURN_FALSE;
+ }
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (spki == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode supplied SPKAC");
+ RETURN_FALSE;
+ }
+
+ pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+ if (pkey == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to aquire signed public key");
+ RETURN_FALSE;
@smalyshev Owner

This RETURN seems not to free all temp structured previously allocated.

@jas-
jas- added a note

Again, move to a macro to perform all free'ing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+
+ i = NETSCAPE_SPKI_verify(spki, pkey);
+
+ if (spki != NULL) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (pkey != NULL) {
+ EVP_PKEY_free(pkey);
+ }
+ /*
+ if (spkstr != NULL) {
+ efree(spkstr);
+ }
+ if (spkstr_cleaned != NULL) {
+ efree(spkstr_cleaned);
+ }
+ */
+ if (i > 0) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto string openssl_spki_export(string spki)
+ Exports public key from existing spki to var */
+PHP_FUNCTION(openssl_spki_export)
+{
+ int spkstr_len;
+ char *spkstr, * spkstr_cleaned, * s;
+
+ EVP_PKEY *pkey = NULL;
+ NETSCAPE_SPKI *spki = NULL;
+ BIO *out = BIO_new(BIO_s_mem());
+ BUF_MEM *bio_buf;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
+ return;
+ }
+
+ if (spkstr == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied SPKAC");
+ RETURN_NULL();
+ }
+
+ spkstr_cleaned = emalloc(spkstr_len + 1);
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (spki == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode supplied SPKAC");
+ RETURN_NULL();
+ }
+
+ pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+ if (pkey == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to aquire signed public key");
+ RETURN_NULL();
+ }
+
+ PEM_write_bio_PUBKEY(out, pkey);
+ BIO_get_mem_ptr(out, &bio_buf);
+
+ if ((!bio_buf->data)&&(bio_buf->length<=0)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate memory for public key");
+ RETURN_NULL();
+ }
+
+ s = emalloc(bio_buf->length);
+ BIO_read(out, s, bio_buf->length);
+
+ if (spki != NULL) {
+ NETSCAPE_SPKI_free(spki);
+ }
+ if (out != NULL) {
+ BIO_free_all(out);
+ }
+ if (pkey != NULL) {
+ EVP_PKEY_free(pkey);
+ }
+ /*
+ if (spkstr != NULL) {
+ efree(spkstr);
+ }
+ if (spkstr_cleaned != NULL) {
+ efree(spkstr_cleaned);
+ }
+ */
+ RETURN_STRINGL(s, strlen(s), 1);
+}
+/* }}} */
+
+/* {{{ 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;
+ char *spkstr, * spkstr_cleaned;
+
+ NETSCAPE_SPKI *spki = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
+ return;
+ }
+
+ if (spkstr == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied SPKAC");
+ RETURN_NULL();
+ }
+
+ spkstr_cleaned = emalloc(spkstr_len + 1);
+ openssl_spki_cleanup(spkstr, spkstr_cleaned);
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (spki == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate memory for public key");
+ RETURN_NULL();
+ }
+ /*
+ if (spkstr != NULL) {
+ efree(spkstr);
+ }
+ if (spkstr_cleaned != NULL) {
+ efree(spkstr_cleaned);
+ }
+ */
+ RETURN_STRING(ASN1_STRING_data(spki->spkac->challenge), 0);
@smalyshev Owner

aren't you supposed to free spki data structure?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+}
+/* }}} */
+
+/* {{{ 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)
@@ -1342,14 +1671,14 @@ PHP_FUNCTION(openssl_x509_check_private_key)
long certresource = -1, keyresource = -1;
RETVAL_FALSE;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &zcert, &zkey) == FAILURE) {
return;
}
cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
RETURN_FALSE;
- }
+ }
key = php_openssl_evp_from_zval(zkey, 0, "", 1, &keyresource TSRMLS_CC);
if (key) {
RETVAL_BOOL(X509_check_private_key(cert, key));
@@ -1402,11 +1731,11 @@ PHP_FUNCTION(openssl_x509_parse)
snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert));
add_assoc_string(return_value, "hash", buf, 1);
}
-
+
add_assoc_name_entry(return_value, "issuer", X509_get_issuer_name(cert), useshortnames TSRMLS_CC);
add_assoc_long(return_value, "version", X509_get_version(cert));
- add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1);
+ add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1);
add_assoc_asn1_string(return_value, "validFrom", X509_get_notBefore(cert));
add_assoc_asn1_string(return_value, "validTo", X509_get_notAfter(cert));
@@ -1608,8 +1937,8 @@ PHP_FUNCTION(openssl_x509_checkpurpose)
if (certresource == 1 && cert) {
X509_free(cert);
}
- if (cainfo) {
- X509_STORE_free(cainfo);
+ if (cainfo) {
+ X509_STORE_free(cainfo);
}
if (untrustedchain) {
sk_X509_pop_free(untrustedchain, X509_free);
@@ -1662,7 +1991,7 @@ static X509_STORE * setup_verify(zval * calist TSRMLS_DC)
dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, Z_STRVAL_PP(item), X509_FILETYPE_PEM)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading directory %s", Z_STRVAL_PP(item));
- } else {
+ } else {
ndirs++;
}
dir_lookup = NULL;
@@ -1756,11 +2085,11 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */
if (certresource != -1) {
cert = X509_dup(cert);
-
+
if (cert == NULL) {
goto clean_exit;
}
-
+
}
sk_X509_push(sk, cert);
@@ -1769,7 +2098,7 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */
} else {
/* a single certificate */
cert = php_openssl_x509_from_zval(zcerts, 0, &certresource TSRMLS_CC);
-
+
if (cert == NULL) {
goto clean_exit;
}
@@ -1810,7 +2139,7 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
return;
RETVAL_FALSE;
-
+
cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
@@ -1846,9 +2175,9 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
- bio_out = BIO_new_file(filename, "w");
+ bio_out = BIO_new_file(filename, "w");
if (bio_out) {
-
+
i2d_PKCS12_bio(bio_out, p12);
RETVAL_TRUE;
@@ -1859,13 +2188,13 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
BIO_free(bio_out);
PKCS12_free(p12);
php_sk_X509_free(ca);
-
+
cleanup:
if (keyresource == -1 && priv_key) {
EVP_PKEY_free(priv_key);
}
- if (certresource == -1 && cert) {
+ if (certresource == -1 && cert) {
X509_free(cert);
}
}
@@ -1891,7 +2220,7 @@ PHP_FUNCTION(openssl_pkcs12_export)
return;
RETVAL_FALSE;
-
+
cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
@@ -1914,7 +2243,7 @@ PHP_FUNCTION(openssl_pkcs12_export)
if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)
ca = php_array_to_X509_sk(item TSRMLS_CC);
/* end parse extra config */
-
+
p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
bio_out = BIO_new(BIO_s_mem());
@@ -1931,13 +2260,13 @@ PHP_FUNCTION(openssl_pkcs12_export)
BIO_free(bio_out);
PKCS12_free(p12);
php_sk_X509_free(ca);
-
+
cleanup:
if (keyresource == -1 && priv_key) {
EVP_PKEY_free(priv_key);
}
- if (certresource == -1 && cert) {
+ if (certresource == -1 && cert) {
X509_free(cert);
}
}
@@ -1961,12 +2290,12 @@ PHP_FUNCTION(openssl_pkcs12_read)
return;
RETVAL_FALSE;
-
+
bio_in = BIO_new(BIO_s_mem());
-
+
if(!BIO_write(bio_in, zp12, zp12_len))
goto cleanup;
-
+
if(d2i_PKCS12_bio(bio_in, &p12)) {
if(PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
BIO * bio_out;
@@ -1996,12 +2325,12 @@ PHP_FUNCTION(openssl_pkcs12_read)
MAKE_STD_ZVAL(zextracerts);
array_init(zextracerts);
-
+
for (i=0;;i++) {
zval * zextracert;
X509* aCA = sk_X509_pop(ca);
if (!aCA) break;
-
+
bio_out = BIO_new(BIO_s_mem());
if (PEM_write_bio_X509(bio_out, aCA)) {
BUF_MEM *bio_buf;
@@ -2009,7 +2338,7 @@ PHP_FUNCTION(openssl_pkcs12_read)
MAKE_STD_ZVAL(zextracert);
ZVAL_STRINGL(zextracert, bio_buf->data, bio_buf->length, 1);
add_index_zval(zextracerts, i, zextracert);
-
+
}
BIO_free(bio_out);
@@ -2021,13 +2350,13 @@ PHP_FUNCTION(openssl_pkcs12_read)
} else {
zval_dtor(zextracerts);
}
-
+
RETVAL_TRUE;
-
+
PKCS12_free(p12);
}
}
-
+
cleanup:
if (bio_in) {
BIO_free(bio_in);
@@ -2035,7 +2364,7 @@ PHP_FUNCTION(openssl_pkcs12_read)
if (pkey) {
EVP_PKEY_free(pkey);
}
- if (cert) {
+ if (cert) {
X509_free(cert);
}
}
@@ -2054,7 +2383,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
return FAILURE;
}
dn_sk = CONF_get_section(req->req_config, dn_sect);
- if (dn_sk == NULL) {
+ if (dn_sk == NULL) {
return FAILURE;
}
attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes");
@@ -2074,15 +2403,15 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
X509_NAME * subj;
HashPosition hpos;
zval ** item;
-
+
subj = X509_REQ_get_subject_name(csr);
/* apply values from the dn hash */
zend_hash_internal_pointer_reset_ex(HASH_OF(dn), &hpos);
while(zend_hash_get_current_data_ex(HASH_OF(dn), (void**)&item, &hpos) == SUCCESS) {
- char * strindex = NULL;
+ char * strindex = NULL;
uint strindexlen = 0;
ulong intindex;
-
+
zend_hash_get_current_key_ex(HASH_OF(dn), &strindex, &strindexlen, &intindex, 0, &hpos);
convert_to_string_ex(item);
@@ -2092,7 +2421,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
nid = OBJ_txt2nid(strindex);
if (nid != NID_undef) {
- if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8,
+ if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8,
(unsigned char*)Z_STRVAL_PP(item), -1, -1, 0))
{
php_error_docref(NULL TSRMLS_CC, E_WARNING,
@@ -2113,10 +2442,10 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
int len;
char buffer[200 + 1]; /*200 + \0 !*/
-
+
v = sk_CONF_VALUE_value(dn_sk, i);
type = v->name;
-
+
len = strlen(type);
if (len < sizeof("_default")) {
continue;
@@ -2131,7 +2460,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
memcpy(buffer, type, len);
buffer[len] = '\0';
type = buffer;
-
+
/* Skip past any leading X. X: X, etc to allow for multiple
* instances */
for (str = type; *str; str++) {
@@ -2212,7 +2541,7 @@ static X509_REQ * php_openssl_csr_from_zval(zval ** val, int makeresource, long
X509_REQ * csr = NULL;
char * filename = NULL;
BIO * in;
-
+
if (resourceval) {
*resourceval = -1;
}
@@ -2353,13 +2682,13 @@ PHP_FUNCTION(openssl_csr_sign)
long csr_resource, certresource = 0, keyresource = -1;
int i;
struct php_x509_request req;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ!Zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE)
return;
RETVAL_FALSE;
PHP_SSL_REQ_INIT(&req);
-
+
csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
if (csr == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
@@ -2381,7 +2710,7 @@ PHP_FUNCTION(openssl_csr_sign)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to signing cert");
goto cleanup;
}
-
+
if (PHP_SSL_REQ_PARSE(&req, args) == FAILURE) {
goto cleanup;
}
@@ -2401,9 +2730,9 @@ PHP_FUNCTION(openssl_csr_sign)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature did not match the certificate request");
goto cleanup;
}
-
+
/* Now we can get on with it */
-
+
new_cert = X509_new();
if (new_cert == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory");
@@ -2414,7 +2743,7 @@ PHP_FUNCTION(openssl_csr_sign)
goto cleanup;
ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);
-
+
X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));
if (cert == NULL) {
@@ -2431,7 +2760,7 @@ PHP_FUNCTION(openssl_csr_sign)
}
if (req.extensions_section) {
X509V3_CTX ctx;
-
+
X509V3_set_ctx(&ctx, cert, new_cert, csr, NULL, 0);
X509V3_set_conf_lhash(&ctx, req.req_config);
if (!X509V3_EXT_add_conf(req.req_config, &ctx, req.extensions_section, new_cert)) {
@@ -2444,11 +2773,11 @@ PHP_FUNCTION(openssl_csr_sign)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to sign it");
goto cleanup;
}
-
+
/* Succeeded; lets return the cert */
RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509 TSRMLS_CC));
new_cert = NULL;
-
+
cleanup:
if (cert == new_cert) {
@@ -2465,7 +2794,7 @@ PHP_FUNCTION(openssl_csr_sign)
if (csr_resource == -1 && csr) {
X509_REQ_free(csr);
}
- if (certresource == -1 && cert) {
+ if (certresource == -1 && cert) {
X509_free(cert);
}
if (new_cert) {
@@ -2484,12 +2813,12 @@ PHP_FUNCTION(openssl_csr_new)
X509_REQ * csr = NULL;
int we_made_the_key = 1;
long key_resource;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {
return;
}
RETVAL_FALSE;
-
+
PHP_SSL_REQ_INIT(&req);
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
@@ -2521,10 +2850,10 @@ PHP_FUNCTION(openssl_csr_new)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading extension section %s", req.request_extensions_section);
} else {
RETVAL_TRUE;
-
+
if (X509_REQ_sign(csr, req.priv_key, req.digest)) {
RETVAL_RESOURCE(zend_list_insert(csr, le_csr TSRMLS_CC));
- csr = NULL;
+ csr = NULL;
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request");
}
@@ -2649,14 +2978,14 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
}
if (Z_TYPE_PP(val) == IS_ARRAY) {
zval ** zphrase;
-
+
/* get passphrase */
if (zend_hash_index_find(HASH_OF(*val), 1, (void **)&zphrase) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");
return NULL;
}
-
+
if (Z_TYPE_PP(zphrase) == IS_STRING) {
passphrase = Z_STRVAL_PP(zphrase);
} else {
@@ -2681,7 +3010,7 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
if (!what) {
TMP_CLEAN;
}
- if (resourceval) {
+ if (resourceval) {
*resourceval = Z_LVAL_PP(val);
}
if (type == le_x509) {
@@ -2715,8 +3044,8 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
}
} else {
/* force it to be a string and check if it refers to a file */
- /* passing non string values leaks, object uses toString, it returns NULL
- * See bug38255.phpt
+ /* passing non string values leaks, object uses toString, it returns NULL
+ * See bug38255.phpt
*/
if (!(Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_OBJECT)) {
TMP_CLEAN;
@@ -2790,7 +3119,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
char * randfile = NULL;
int egdsocket, seeded;
EVP_PKEY * return_val = NULL;
-
+
if (req->priv_key_bits < MIN_KEY_LENGTH) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key length is too short; it needs to be at least %d bits, not %d",
MIN_KEY_LENGTH, req->priv_key_bits);
@@ -2799,7 +3128,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");
php_openssl_load_rand_file(randfile, &egdsocket, &seeded TSRMLS_CC);
-
+
if ((req->priv_key = EVP_PKEY_new()) != NULL) {
switch(req->priv_key_type) {
case OPENSSL_KEYTYPE_RSA:
@@ -2849,13 +3178,13 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
}
php_openssl_write_rand_file(randfile, egdsocket, seeded);
-
+
if (return_val == NULL) {
EVP_PKEY_free(req->priv_key);
req->priv_key = NULL;
return NULL;
}
-
+
return return_val;
}
/* }}} */
@@ -2884,7 +3213,7 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
case EVP_PKEY_DSA4:
assert(pkey->pkey.dsa != NULL);
- if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
+ if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
return 0;
}
break;
@@ -3015,7 +3344,7 @@ PHP_FUNCTION(openssl_pkey_new)
}
RETURN_FALSE;
}
- }
+ }
PHP_SSL_REQ_INIT(&req);
@@ -3044,7 +3373,7 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
EVP_PKEY * key;
BIO * bio_out = NULL;
const EVP_CIPHER * cipher;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zp|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {
return;
}
@@ -3056,11 +3385,11 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
RETURN_FALSE;
}
-
+
if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
RETURN_FALSE;
}
-
+
PHP_SSL_REQ_INIT(&req);
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
@@ -3103,7 +3432,7 @@ PHP_FUNCTION(openssl_pkey_export)
EVP_PKEY * key;
BIO * bio_out = NULL;
const EVP_CIPHER * cipher;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zz|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) {
return;
}
@@ -3115,7 +3444,7 @@ PHP_FUNCTION(openssl_pkey_export)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
RETURN_FALSE;
}
-
+
PHP_SSL_REQ_INIT(&req);
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
@@ -3235,7 +3564,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
array_init(return_value);
add_assoc_long(return_value, "bits", EVP_PKEY_bits(pkey));
add_assoc_stringl(return_value, "key", pbio, pbio_len, 1);
- /*TODO: Use the real values once the openssl constants are used
+ /*TODO: Use the real values once the openssl constants are used
* See the enum at the top of this file
*/
switch (EVP_PKEY_type(pkey->type)) {
@@ -3259,7 +3588,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
add_assoc_zval(return_value, "rsa", rsa);
}
- break;
+ break;
case EVP_PKEY_DSA:
case EVP_PKEY_DSA2:
case EVP_PKEY_DSA3:
@@ -3280,7 +3609,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
}
break;
case EVP_PKEY_DH:
-
+
ktype = OPENSSL_KEYTYPE_DH;
if (pkey->pkey.dh != NULL) {
@@ -3296,7 +3625,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
}
break;
-#ifdef EVP_PKEY_EC
+#ifdef EVP_PKEY_EC
case EVP_PKEY_EC:
ktype = OPENSSL_KEYTYPE_EC;
break;
@@ -3330,7 +3659,7 @@ PHP_FUNCTION(openssl_pkcs7_verify)
char * extracerts = NULL; int extracerts_len = 0;
char * signersfilename = NULL; int signersfilename_len = 0;
char * datafilename = NULL; int datafilename_len = 0;
-
+
RETVAL_LONG(-1);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pl|papp", &filename, &filename_len,
@@ -3338,7 +3667,7 @@ PHP_FUNCTION(openssl_pkcs7_verify)
&extracerts, &extracerts_len, &datafilename, &datafilename_len) == FAILURE) {
return;
}
-
+
if (extracerts) {
others = load_all_certs_from_file(extracerts);
if (others == NULL) {
@@ -3390,11 +3719,11 @@ PHP_FUNCTION(openssl_pkcs7_verify)
if (signersfilename) {
BIO *certout;
-
+
if (php_openssl_open_base_dir_chk(signersfilename TSRMLS_CC)) {
goto clean_exit;
}
-
+
certout = BIO_new_file(signersfilename, "w");
if (certout) {
int i;
@@ -3443,14 +3772,14 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
char * strindex;
char * infilename = NULL; int infilename_len;
char * outfilename = NULL; int outfilename_len;
-
+
RETVAL_FALSE;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZa!|ll", &infilename, &infilename_len,
&outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE)
return;
-
+
if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
return;
}
@@ -3461,7 +3790,7 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
}
outfile = BIO_new_file(outfilename, "w");
- if (outfile == NULL) {
+ if (outfile == NULL) {
goto clean_exit;
}
@@ -3588,12 +3917,12 @@ PHP_FUNCTION(openssl_pkcs7_sign)
&extracertsfilename_len) == FAILURE) {
return;
}
-
+
RETVAL_FALSE;
if (extracertsfilename) {
others = load_all_certs_from_file(extracertsfilename);
- if (others == NULL) {
+ if (others == NULL) {
goto clean_exit;
}
}
@@ -3704,7 +4033,7 @@ PHP_FUNCTION(openssl_pkcs7_decrypt)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get private key");
goto clean_exit;
}
-
+
if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
goto clean_exit;
}
@@ -3723,7 +4052,7 @@ PHP_FUNCTION(openssl_pkcs7_decrypt)
if (p7 == NULL) {
goto clean_exit;
}
- if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {
+ if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {
RETVAL_TRUE;
}
clean_exit:
@@ -3756,7 +4085,7 @@ PHP_FUNCTION(openssl_private_encrypt)
int data_len;
long padding = RSA_PKCS1_PADDING;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -3774,10 +4103,10 @@ PHP_FUNCTION(openssl_private_encrypt)
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- successful = (RSA_private_encrypt(data_len,
- (unsigned char *)data,
- cryptedbuf,
- pkey->pkey.rsa,
+ successful = (RSA_private_encrypt(data_len,
+ (unsigned char *)data,
+ cryptedbuf,
+ pkey->pkey.rsa,
padding) == cryptedlen);
break;
default:
@@ -3794,7 +4123,7 @@ PHP_FUNCTION(openssl_private_encrypt)
if (cryptedbuf) {
efree(cryptedbuf);
}
- if (keyresource == -1) {
+ if (keyresource == -1) {
EVP_PKEY_free(pkey);
}
}
@@ -3832,10 +4161,10 @@ PHP_FUNCTION(openssl_private_decrypt)
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- cryptedlen = RSA_private_decrypt(data_len,
- (unsigned char *)data,
- crypttemp,
- pkey->pkey.rsa,
+ cryptedlen = RSA_private_decrypt(data_len,
+ (unsigned char *)data,
+ crypttemp,
+ pkey->pkey.rsa,
padding);
if (cryptedlen != -1) {
cryptedbuf = emalloc(cryptedlen + 1);
@@ -3860,7 +4189,7 @@ PHP_FUNCTION(openssl_private_decrypt)
if (keyresource == -1) {
EVP_PKEY_free(pkey);
}
- if (cryptedbuf) {
+ if (cryptedbuf) {
efree(cryptedbuf);
}
}
@@ -3884,7 +4213,7 @@ PHP_FUNCTION(openssl_public_encrypt)
return;
RETVAL_FALSE;
-
+
pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
if (pkey == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
@@ -3897,10 +4226,10 @@ PHP_FUNCTION(openssl_public_encrypt)
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- successful = (RSA_public_encrypt(data_len,
- (unsigned char *)data,
- cryptedbuf,
- pkey->pkey.rsa,
+ successful = (RSA_public_encrypt(data_len,
+ (unsigned char *)data,
+ cryptedbuf,
+ pkey->pkey.rsa,
padding) == cryptedlen);
break;
default:
@@ -3943,7 +4272,7 @@ PHP_FUNCTION(openssl_public_decrypt)
return;
}
RETVAL_FALSE;
-
+
pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
if (pkey == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
@@ -3956,10 +4285,10 @@ PHP_FUNCTION(openssl_public_decrypt)
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- cryptedlen = RSA_public_decrypt(data_len,
- (unsigned char *)data,
- crypttemp,
- pkey->pkey.rsa,
+ cryptedlen = RSA_public_decrypt(data_len,
+ (unsigned char *)data,
+ crypttemp,
+ pkey->pkey.rsa,
padding);
if (cryptedlen != -1) {
cryptedbuf = emalloc(cryptedlen + 1);
@@ -3967,10 +4296,10 @@ PHP_FUNCTION(openssl_public_decrypt)
successful = 1;
}
break;
-
+
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
-
+
}
efree(crypttemp);
@@ -4088,7 +4417,7 @@ PHP_FUNCTION(openssl_verify)
char * signature; int signature_len;
zval *method = NULL;
long signature_algo = OPENSSL_ALGO_SHA1;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) {
return;
}
@@ -4147,7 +4476,7 @@ PHP_FUNCTION(openssl_seal)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
return;
}
-
+
pubkeysht = HASH_OF(pubkeys);
nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;
if (!nkeys) {
@@ -4242,7 +4571,7 @@ PHP_FUNCTION(openssl_seal)
if (key_resources[i] == -1) {
EVP_PKEY_free(pkeys[i]);
}
- if (eks[i]) {
+ if (eks[i]) {
efree(eks[i]);
}
}
@@ -4288,13 +4617,13 @@ PHP_FUNCTION(openssl_open)
} else {
cipher = EVP_rc4();
}
-
+
buf = emalloc(data_len + 1);
if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
efree(buf);
- if (keyresource == -1) {
+ if (keyresource == -1) {
EVP_PKEY_free(pkey);
}
RETURN_FALSE;
@@ -4531,7 +4860,7 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{
if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
return NULL;
- }
+ }
}
tmpssl = SSL_new(ctx);
@@ -4588,7 +4917,7 @@ PHP_FUNCTION(openssl_get_md_methods)
}
array_init(return_value);
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH,
- aliases ? openssl_add_method_or_alias: openssl_add_method,
+ aliases ? openssl_add_method_or_alias: openssl_add_method,
return_value);
}
/* }}} */
@@ -4604,7 +4933,7 @@ PHP_FUNCTION(openssl_get_cipher_methods)
}
array_init(return_value);
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
- aliases ? openssl_add_method_or_alias: openssl_add_method,
+ aliases ? openssl_add_method_or_alias: openssl_add_method,
return_value);
}
/* }}} */
View
5 ext/openssl/php_openssl.h
@@ -77,6 +77,11 @@ PHP_FUNCTION(openssl_csr_export_to_file);
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);
#else
#define phpext_openssl_ptr NULL
View
41 ext/openssl/tests/openssl_spki_export.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Testing openssl_spki_export()
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (!@openssl_pkey_new()) die("skip cannot create private key");
+?>
+--FILE--
+<?php
+
+/* private key creation */
+echo "Creating private key...";
+$pkey = openssl_pkey_new();
+echo ($pkey !== false) ?
+ "ok!\n\n" : "error creating private key\n\n";
+
+/* testing all signing algorithms */
+$algos = array('MD5'=>OPENSSL_ALGO_MD5,
+ 'SHA1'=>OPENSSL_ALGO_SHA1,
+ 'SHA256'=>OPENSSL_ALGO_SHA256,
+ 'SHA512'=>OPENSSL_ALGO_SHA512);
+
+/* loop to create, export public keys and verify */
+foreach($algos as $key => $value){
+ echo "Exporting public key from SPKAC with ".$key."...";
+ $spki = openssl_spki_new($pkey, "sample_challenge_string", $value);
+ if ((!empty($spki)) && (preg_match('/SPKAC=[a-zA-Z0-9\/\+]/', $spki)))
+ $r = openssl_spki_export(preg_replace('/SPKAC=/', '', $spki));
+ if (preg_match("/-----BEGIN PUBLIC KEY-----/", $r))
+ echo "ok!\n";
+}
+
+openssl_free_key($pkey);
+?>
+--EXPECT--
+Creating private key...ok!
+
+Exporting public key from SPKAC with MD5...ok!
+Exporting public key from SPKAC with SHA1...ok!
+Exporting public key from SPKAC with SHA256...ok!
+Exporting public key from SPKAC with SHA512...ok!
View
41 ext/openssl/tests/openssl_spki_export_challenge.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Testing openssl_spki_export_challenge()
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (!@openssl_pkey_new()) die("skip cannot create private key");
+?>
+--FILE--
+<?php
+
+/* private key creation */
+echo "Creating private key...";
+$pkey = openssl_pkey_new();
+echo ($pkey !== false) ?
+ "ok!\n\n" : "error creating private key\n\n";
+
+/* testing all signing algorithms */
+$algos = array('MD5'=>OPENSSL_ALGO_MD5,
+ 'SHA1'=>OPENSSL_ALGO_SHA1,
+ 'SHA256'=>OPENSSL_ALGO_SHA256,
+ 'SHA512'=>OPENSSL_ALGO_SHA512);
+
+/* loop to create, export challenge and verify */
+foreach($algos as $key => $value){
+ echo "Exporting challenge from SPKAC with ".$key."...";
+ $spki = openssl_spki_new($pkey, "sample_challenge_string", $value);
+ if ((!empty($spki)) && (preg_match('/SPKAC=[a-zA-Z0-9\/\+]/', $spki)))
+ $r = openssl_spki_export_challenge(preg_replace('/SPKAC=/', '', $spki));
+ if ($r === "sample_challenge_string")
@smalyshev Owner

I think it is better to do var_dump($r) here and then have the string in the EXPECT. This way if $r is something else it is immediately seen in the test diff.

@jas-
jas- added a note

Noted. I will make adjustments hopefully over the weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ echo "ok!\n";
+}
+
+openssl_free_key($pkey);
+?>
+--EXPECT--
+Creating private key...ok!
+
+Exporting challenge from SPKAC with MD5...ok!
+Exporting challenge from SPKAC with SHA1...ok!
+Exporting challenge from SPKAC with SHA256...ok!
+Exporting challenge from SPKAC with SHA512...ok!
View
39 ext/openssl/tests/openssl_spki_new.phpt
@@ -0,0 +1,39 @@
+--TEST--
+Testing openssl_spki_new()
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (!@openssl_pkey_new()) die("skip cannot create private key");
+?>
+--FILE--
+<?php
+
+/* private key creation */
+echo "Creating private key...";
+$pkey = openssl_pkey_new();
+echo ($pkey !== false) ?
+ "ok!\n\n" : "error creating private key\n\n";
+
+/* testing all signing algorithms */
+$algos = array('MD5'=>OPENSSL_ALGO_MD5,
+ 'SHA1'=>OPENSSL_ALGO_SHA1,
+ 'SHA256'=>OPENSSL_ALGO_SHA256,
+ 'SHA512'=>OPENSSL_ALGO_SHA512);
+
+/* loop to create and verify results */
+foreach($algos as $key => $value){
+ echo "Creating new SPKAC with ".$key."...";
+ $spki = openssl_spki_new($pkey, "sample_challenge_string", $value);
+ if ((!empty($spki)) && (preg_match('/SPKAC=[a-zA-Z0-9\/\+]/', $spki)))
+ echo "ok!\n";
+}
+
+openssl_free_key($pkey);
+?>
+--EXPECT--
+Creating private key...ok!
+
+Creating new SPKAC with MD5...ok!
+Creating new SPKAC with SHA1...ok!
+Creating new SPKAC with SHA256...ok!
+Creating new SPKAC with SHA512...ok!
View
40 ext/openssl/tests/openssl_spki_verify.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Testing openssl_spki_verify()
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (!@openssl_pkey_new()) die("skip cannot create private key");
+?>
+--FILE--
+<?php
+
+/* private key creation */
+echo "Creating private key...";
+$pkey = openssl_pkey_new();
+echo ($pkey !== false) ?
+ "ok!\n\n" : "error creating private key\n\n";
+
+/* testing all signing algorithms */
+$algos = array('MD5'=>OPENSSL_ALGO_MD5,
+ 'SHA1'=>OPENSSL_ALGO_SHA1,
+ 'SHA256'=>OPENSSL_ALGO_SHA256,
+ 'SHA512'=>OPENSSL_ALGO_SHA512);
+
+/* loop to create and verify results */
+foreach($algos as $key => $value){
+ echo "Performing verification of SPKAC with ".$key."...";
+ $spki = openssl_spki_new($pkey, "sample_challenge_string", $value);
+ if ((!empty($spki)) && (preg_match('/SPKAC=[a-zA-Z0-9\/\+]/', $spki)))
+ if (openssl_spki_verify(preg_replace('/SPKAC=/', '', $spki)))
+ echo "ok!\n";
+}
+
+openssl_free_key($pkey);
+?>
+--EXPECT--
+Creating private key...ok!
+
+Performing verification of SPKAC with MD5...ok!
+Performing verification of SPKAC with SHA1...ok!
+Performing verification of SPKAC with SHA256...ok!
+Performing verification of SPKAC with SHA512...ok!
Something went wrong with that request. Please try again.