Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPKAC functionality per feature request #38917 #21

Closed
wants to merge 8 commits into from
Closed

SPKAC functionality per feature request #38917 #21

wants to merge 8 commits into from

Conversation

jas-
Copy link
Contributor

@jas- jas- commented Mar 26, 2012

ORIGINAL BUG:

https://bugs.php.net/bug.php?id=38917

FEATURES:

  • Generate and sign SPKAC's (signture algorithms; md5, sha1, sha256 & sha512)
  • Verify SPKAC (returns boolean)
  • Extract challenge from SPKAC
  • Extract public key form SPKAC
  • Print formatted details of SPKAC

INSTALLATION:

  • Download & install latest OpenSSL stable (0.9.8x or 1.0.x)
  • Download & install latest PHP stable (5.3.x)
  • Clone this repo into root of extracted PHP source code
  • Run these commands:
%> patch -p0 < php-openssl-spki.patch
%> cd php-5.3.x
%> ./configure --with-openssl
%> make
%> make test | grep spki
%> make install

Once it is installed you can use either test case provided to test. The CLI
version might be easier for immediate testing of applied patch.

/path/to/php ./openssl-spki-cli.php

USAGE EXAMPLES:

Here is a complete list of the functions this patch implements as well as
usage examples of how ot use them.

Creating new SPKAC's

Creating a new SPKAC with defaults (sha256 signature)

Returns SPKAC string

openssl_spki_new($private_key, $challenge);

Creating a new SPKAC using MD5 signature

Returns SPKAC string

openssl_spki_new($private_key, $challenge, 'md5');

Creating new SPKAC using sha1 signature

Returns SPKAC string

openssl_spki_new($private_key, $challenge, 'sha1');

Creating new SPKAC using sha512 signature

Returns SPKAC string

openssl_spki_new($private_key, $challgen, 'sha512');

Verification

You can verify an existing SPKAC (possibly one generated from the HTML5
KeyGen element)

Verifying an existing SPKAC

Returns boolean true/false value

openssl_spki_verify($spkac);

Extracting from SPKAC

You may wish use the SPKAC for more then just generating certificate
signing requests. The next two functions will allow you retrieve the
formatted public key as well as the associated challenge from the SPKAC.

Extracting the challenge

Returns challenge string

openssl_spki_export_challenge($spkac);

Extracting the public key

Returns a formatted string containing the public key

openssl_spki_export($spkac);

SPKAC details

This next function may be unnecessary but will provide a formatted copy of the
details of the SPKAC (the signature algorithm, the associated challenge string,
the public key modulus etc.)

Providing details of SPKAC

openssl_spki_details($spkac);

EXAMPLE OUTPUT

Here are the output examples if you would like to know what type of information
you can retrieve from a signed public key and challenge.

A signed public key and challenge string

SPKAC=MIICRzCCAS8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkehFnCJLB2cdqQCVdpaK/0pWVXSCJy+fEypQGGbOyG2ufHNdgU4CVwlgJn+pvr0Yk4txALP2W5OJOUcVVYHCdT52nerm2U4BrWD5TYOTHgbH5y33yro8bsEYDK+mp8xQlfBfIse8P1899hJ6t1mt0VWHPC3P6IxaE2j7CDJJ8p0J1JqfzqkOpy1hCw9sjQQOlMk6oBGqOwnCtqsjBczYiq/Tr/UCGfIzJoBdBap+ez/RR/o4qYF3h1iAGLmQ8FNpIZdFWi3iwts/Kjk+UC4ZMuiqDy+3JEXfrzm7y6YEUhFkSIScPZ9h4Z/99wpzsAwj9XF/yT6qzQhdxdbCGqprFAgMBAAEWB3d0ZmQwMGQwDQYJKoZIhvcNAQENBQADggEBAH5SWT6AyVuhdjVmJr0GkdU18jS6TBNt3lyp8Zh1Mc/99TGzKxOtaP02v9JZcvX4PnWV0XBiqUQjdl7exFkP3IudVp6OyxwpA7e/y94U9WVOwMr6U9qTSlQ3rozNNO01lrl++yc/RTEGmV/UDiImeAALhh7FfDrbgDQcjttmk8LbIfy11aMmzmtk01juWDnjInHFgNvkrcnfsKl9ejau0Vhn2W0NOplZC+nE8rdHStt/m6Bc6E66XF7T5E3v/mZFR8bihCPy0a0ujYj3cf1Ak+ySGanobqJ3SC3aqY+3fUiUZDOFwwUQ56oK79jV5lcb6LW3JLcBi7xxSu2IQntfwes=

Extracting the associated public key

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5HoRZwiSwdnHakAlXaWi
v9KVlV0gicvnxMqUBhmzshtrnxzXYFOAlcJYCZ/qb69GJOLcQCz9luTiTlHFVWBw
nU+dp3q5tlOAa1g+U2Dkx4Gx+ct98q6PG7BGAyvpqfMUJXwXyLHvD9fPfYSerdZr
dFVhzwtz+iMWhNo+wgySfKdCdSan86pDqctYQsPbI0EDpTJOqARqjsJwrarIwXM2
Iqv06/1AhnyMyaAXQWqfns/0Uf6OKmBd4dYgBi5kPBTaSGXRVot4sLbPyo5PlAuG
TLoqg8vtyRF3685u8umBFIRZEiEnD2fYeGf/fcKc7AMI/Vxf8k+qs0IXcXWwhqqa
xQIDAQAB
-----END PUBLIC KEY-----

Providing details of the SPKAC

Netscape SPKI:
  Public Key Algorithm: rsaEncryption
  RSA Public Key: (2048 bit)
  Modulus (2048 bit):
      00:e4:7a:11:67:08:92:c1:d9:c7:6a:40:25:5d:a5:
      a2:bf:d2:95:95:5d:20:89:cb:e7:c4:ca:94:06:19:
      b3:b2:1b:6b:9f:1c:d7:60:53:80:95:c2:58:09:9f:
      ea:6f:af:46:24:e2:dc:40:2c:fd:96:e4:e2:4e:51:
      c5:55:60:70:9d:4f:9d:a7:7a:b9:b6:53:80:6b:58:
      3e:53:60:e4:c7:81:b1:f9:cb:7d:f2:ae:8f:1b:b0:
      46:03:2b:e9:a9:f3:14:25:7c:17:c8:b1:ef:0f:d7:
      cf:7d:84:9e:ad:d6:6b:74:55:61:cf:0b:73:fa:23:
      16:84:da:3e:c2:0c:92:7c:a7:42:75:26:a7:f3:aa:
      43:a9:cb:58:42:c3:db:23:41:03:a5:32:4e:a8:04:
      6a:8e:c2:70:ad:aa:c8:c1:73:36:22:ab:f4:eb:fd:
      40:86:7c:8c:c9:a0:17:41:6a:9f:9e:cf:f4:51:fe:
      8e:2a:60:5d:e1:d6:20:06:2e:64:3c:14:da:48:65:
      d1:56:8b:78:b0:b6:cf:ca:8e:4f:94:0b:86:4c:ba:
      2a:83:cb:ed:c9:11:77:eb:ce:6e:f2:e9:81:14:84:
      59:12:21:27:0f:67:d8:78:67:ff:7d:c2:9c:ec:03:
      08:fd:5c:5f:f2:4f:aa:b3:42:17:71:75:b0:86:aa:
      9a:c5
  Exponent: 65537 (0x10001)
  Challenge String: wtfd00d
  Signature Algorithm: sha512WithRSAEncryption
      7e:52:59:3e:80:c9:5b:a1:76:35:66:26:bd:06:91:d5:35:f2:
      34:ba:4c:13:6d:de:5c:a9:f1:98:75:31:cf:fd:f5:31:b3:2b:
      13:ad:68:fd:36:bf:d2:59:72:f5:f8:3e:75:95:d1:70:62:a9:
      44:23:76:5e:de:c4:59:0f:dc:8b:9d:56:9e:8e:cb:1c:29:03:
      b7:bf:cb:de:14:f5:65:4e:c0:ca:fa:53:da:93:4a:54:37:ae:
      8c:cd:34:ed:35:96:b9:7e:fb:27:3f:45:31:06:99:5f:d4:0e:
      22:26:78:00:0b:86:1e:c5:7c:3a:db:80:34:1c:8e:db:66:93:
      c2:db:21:fc:b5:d5:a3:26:ce:6b:64:d3:58:ee:58:39:e3:22:
      71:c5:80:db:e4:ad:c9:df:b0:a9:7d:7a:36:ae:d1:58:67:d9:
      6d:0d:3a:99:59:0b:e9:c4:f2:b7:47:4a:db:7f:9b:a0:5c:e8:
      4e:ba:5c:5e:d3:e4:4d:ef:fe:66:45:47:c6:e2:84:23:f2:d1:
      ad:2e:8d:88:f7:71:fd:40:93:ec:92:19:a9:e8:6e:a2:77:48:
      2d:da:a9:8f:b7:7d:48:94:64:33:85:c3:05:10:e7:aa:0a:ef:
      d8:d5:e6:57:1b:e8:b5:b7:24:b7:01:8b:bc:71:4a:ed:88:42:
      7b:5f:c1:eb

@smalyshev
Copy link
Contributor

This needs some tests. The tests attached does not really test anything except function existence. It should actually test the functions doing what they are supposed to do.

Also, it would be nice if whole code structure was not built around goto's.

@jas-
Copy link
Contributor Author

jas- commented Mar 26, 2012

Perhaps you could elaborate on the tests which do nothing more then test for the function existing? If you review the test cases again you will see that after each function is shown to exist it will halt script execution if the desired value is not what the various test cases expect therefore causing it to fail.

As well; propose a consistent return value for each of the five implemented functions and I will move away from GOTO's which (IMO) are the best way to go in these cases.

@andrejpavlovic
Copy link

I would use a multli-exit loop instead of goto, which is usually a much cleaner strategy.

"A Case for Teaching Multi-exit Loops to Beginning Programmers" would be useful to read.

Basically, do something like:

while(true) {
    if(..) break;

    if(...) break;

    return ...;
}

// clean up code goes here

Replace all goto's with break and put the entire chunk of code in a loop of your choice (for, while, etc.).

@smalyshev
Copy link
Contributor

@jas- sorry, I was wrong on the test. If doesn't use the usual way phpt tests work - by outputting the data and comparing it to test output, which is the recommended way since if something goes wrong you can see what exactly was expected and returned without having to parse the code. I'll review the test again this evening and see if anything is missing.

@cataphract
Copy link
Contributor

A quick glance shows a few problems:

  • Usage of a malloc instead of emalloc to allocate the arrays for the string zvals returned.
  • This statement has no effect.
  • The test should definitely be split up.
  • Declarations should be on top, this was only relaxed on C99 (PHP's codebase follows C89).
  • snprintf(NULL, 0, ...) is not portable (though C99 guarantees the behavior you rely on).

@php-pulls
Copy link

Comment on behalf of yohgaki at php.net:

Could you use the "CODING STANDARD"? Indent should be TAG, not spaces.

@jas-
Copy link
Contributor Author

jas- commented Apr 3, 2012

Modifications have been made per the comments. First patch so should I ask for a discussion on internals?

It has been tested against OpenSSL libraries 0.9.8, 1.0.0, 1.0.1 and Fips versions

@smalyshev
Copy link
Contributor

I would drop a note to internals, yes.

RETURN_NULL();
}

s = emalloc(strlen(spkac) + strlen(spkstr) + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this one definitely leaked on errors, and probably also leaked on normal return.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi:

On Tue, Apr 3, 2012 at 3:39 PM, Stanislav Malyshev
[email protected]
wrote:

  •            RETURN_NULL();
  •        }
  •    } else if (strcmp(algo, "sha512")==0){
  •        if (!NETSCAPE_SPKI_sign(spki, pkey, EVP_sha512())) {
  •            php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to sign with sha512 algorithm");

should we make an RFC, that the error message should be in ucfirst
form, or lower case ?

I see there are both ucfirst warnig message and lowercase messages
in php-src.

thanks

  •            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);

Looks like this one definitely leaked on errors, and probably also leaked on normal return.


Reply to this email directly or view it on GitHub:
https://github.com/php/php-src/pull/21/files#r637678

Git Pull Requests Mailing List (https://github.com/php)
To unsubscribe, visit: http://www.php.net/unsub.php

Laruence  Xinchen Hui
http://www.laruence.com/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used all lc due to additional functions in etc/openssl/openssl.c using all lc for warnings

@smalyshev
Copy link
Contributor

Looks like in the patch multiple structures are allocated but never freed on error conditions, and some buffers also are not deallocated in normal return too. Please fix.

Also, in the tests, in PHP sources it is usually custom to print the output and compare it to template in EXPECT results, not compare it in the code. So instead of:

$b = openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki)); if ($b !== "sample_challenge_string") die("could not verify challenge string from spkac\n");

You would do just:

echo openssl_spki_export_challenge(preg_replace("/SPKAC=/", "", $spki));

and then put "sample_challenge_string" in result. This would allow if it fails to see not only the expected but the actual result and thus more easily be able to see what went wrong. Of course, when it is not possible code checks are still OK.

@pierrejoye
Copy link
Contributor

Please use constants for the hash methods (md5&co).

See https://bugs.php.net/bug.php?id=61421 for some of the new contants

@jas-
Copy link
Contributor Author

jas- commented Apr 3, 2012

Wouldn't use of the newer constants for sha256, sha512 etc break compatibility with 5.3? Or should I be patching for the 5.4 branch? At the moment I have been and am working on the 5.3 branch as per https://wiki.php.net/vcs/gitworkflow

If I were to manually patch without the referenced patch I feel it might mess up the workflow preservation. Also, I feel like I should close this patch request due to problems with the latest pull request due to incorrect indentation settings within my editor that I was unable to revert. Suggestions?

jas- added 2 commits April 3, 2012 08:21
…thms to requested algorithm constants (does not contain patch specified @ https://bugs.php.net/bug.php?id=61421 due to it being upstream)
…thms to requested algorithm constants (does not contain patch specified @ https://bugs.php.net/bug.php?id=61421 due to it being upstream)
@jas- jas- closed this Apr 3, 2012
@pierrejoye
Copy link
Contributor

@jas- not really, as this patch can only make it to master. 5.3 and 5.4 are not open to feature additions

@pierrejoye
Copy link
Contributor

@jas- no worry btw, php-next come in a year or so :)

@jas-
Copy link
Contributor Author

jas- commented Apr 3, 2012

@pierrejoye I plan on resubmitting to master but the last push (because of my editors indenting problems) added unnecessary bits.

I am also going to remove the openssl_spki_details() function as it's not needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants