mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-23 16:56:28 +08:00
Add PHP Extension for GmSSL
View http://gmssl.org/docs/php-api.html for more info.
This commit is contained in:
322
php/ext/openssl/README
Normal file
322
php/ext/openssl/README
Normal file
@@ -0,0 +1,322 @@
|
||||
OpenSSL extension for PHP
|
||||
|
||||
$Id$
|
||||
|
||||
The functions implemented so far make it possible to seal and open data, and
|
||||
also create and verify signatures.
|
||||
|
||||
NEW: support for S/MIME encrypt/decrypt/sign/verify, as well as more
|
||||
flexibility for specifying certificates/keys.
|
||||
|
||||
To enable the extension, configure PHP with --with-openssl.
|
||||
|
||||
Specifying keys/certificates
|
||||
----------------------------
|
||||
|
||||
Most of the functions require a key or a certificate as a parameter; to make
|
||||
things easy for you to use openssl, this extension allows you
|
||||
to specify certificates in the following way:
|
||||
|
||||
1. As an X.509 resource returned from openssl_x509_read
|
||||
2. As a string in the format file://filename, where filename is the path to the
|
||||
certificate file (it will be opened and read automatically)
|
||||
3. As a string containing the data from the certificate file
|
||||
|
||||
Similarly, you can use the following methods of specifying a public key:
|
||||
|
||||
1. As a key resource returned from openssl_get_publickey
|
||||
2. An X509 resource - public key only
|
||||
3. As a string in the format file://filename
|
||||
4. As a string containing the data from the key file
|
||||
|
||||
Additionally, for a private key, when the openssl extension function does not
|
||||
allow you to enter the passphrase as a parameter you may use the syntax
|
||||
array($key, "passphrase") where $key can be a key specified using one of the
|
||||
methods listed above.
|
||||
|
||||
Certificate Verification
|
||||
------------------------
|
||||
When calling a function that will verify a signature/certificate, the cainfo
|
||||
parameter is an array containing file and directory names that specifiy the
|
||||
locations of trusted CA files. If a directory is specified, then it must be a
|
||||
correctly hashed directory.
|
||||
|
||||
Misc:
|
||||
-----
|
||||
|
||||
mixed openssl_error_string()
|
||||
|
||||
returns the message from the last error that the OpenSSL library encountered
|
||||
and moves it's internal error pointer to the next message. If there are no
|
||||
more error messages, returns false.
|
||||
|
||||
General Key/Cert Functions:
|
||||
---------------------------
|
||||
|
||||
resource openssl_get_privatekey(mixed key [, string passphrase])
|
||||
|
||||
Parses the key data and returns a key resource identifier. If the key is
|
||||
encrypted a passphrase is needed. This can be supplied as second argument.
|
||||
|
||||
|
||||
resource openssl_get_publickey(mixed cert)
|
||||
|
||||
Extracts the public key from the given certificate or public key and returns
|
||||
a key resource identifier.
|
||||
|
||||
|
||||
void openssl_free_key(resource key)
|
||||
|
||||
Frees the resource given by the key resource identifier.
|
||||
Note that this function does not accept the extended key specification
|
||||
syntax mentioned above, as it doesn't make sense in this case!
|
||||
|
||||
array openssl_x509_parse(mixed x509[, bool shortnames=true])
|
||||
|
||||
Parses the certificate data and returns an array containing information
|
||||
about the certificate, it's intended purposes, subject, issuer, validity
|
||||
etc. etc. If shortnames is true (the default) then the fields will be
|
||||
keyed by the shortname forms eg: CN as opposed to commonName (shortnames
|
||||
= false).
|
||||
|
||||
|
||||
bool openssl_x509_checkpurpose(mixed x509cert, int purpose,
|
||||
array cainfo[, string untrustedfile])
|
||||
|
||||
Verifies if the certificate can be used for a specific purpose.
|
||||
Purpose can be one of the following values:
|
||||
X509_PURPOSE_SSL_CLIENT
|
||||
X509_PURPOSE_SSL_SERVER
|
||||
X509_PURPOSE_NS_SSL_SERVER
|
||||
X509_PURPOSE_SMIME_SIGN
|
||||
X509_PURPOSE_SMIME_ENCRYPT
|
||||
X509_PURPOSE_CRL_SIGN
|
||||
X509_PURPOSE_ANY
|
||||
|
||||
cainfo is an array of CA information (as mentioned above).
|
||||
untrusted file specifies a file containing a bunch of certs that
|
||||
are not trusted but may be useful in validating the certificate.
|
||||
|
||||
|
||||
resource openssl_read_x509(mixed cert)
|
||||
|
||||
Parses the cert and returns a resource that can be used with the
|
||||
other openssl functions
|
||||
|
||||
|
||||
void openssl_free_x509(resource x509)
|
||||
|
||||
Frees the resource given by the x509 resource identifier.
|
||||
Note that this function does not accept the extended cert specification
|
||||
syntax mentioned above, as it doesn't make sense in this case!
|
||||
|
||||
|
||||
PKCS7 (S/MIME) Sign/Verify/Encrypt/Decrypt Functions:
|
||||
-----------------------------------------------------
|
||||
|
||||
These functions allow you to manipulate S/MIME messages!
|
||||
|
||||
They are based on apps/smime.c from the openssl dist, so for information,
|
||||
see the documentation for openssl.
|
||||
|
||||
You may pass in some flags that affect how these functions work using
|
||||
and array containing the following values:
|
||||
"detached", "nodetached", "text", "nointern", "noverify", "nochain",
|
||||
"nocerts", "noattr", "binary", "nosigs".
|
||||
The options correspond to the options of the same name for the
|
||||
"openssl smime" command (smime(1)).
|
||||
|
||||
|
||||
bool openssl_pkcs7_verify(string filename, array flags[, string signerscerts][,
|
||||
array cainfo])
|
||||
|
||||
Verifies that the signature on the MIME message contained in the file
|
||||
named by filename is valid. If signerscerts is passed in, it holds the
|
||||
name of a file into which the certificates of those that signed the
|
||||
message will be stored.
|
||||
cainfo and flags are CA information and flag information as described
|
||||
above.
|
||||
|
||||
|
||||
bool openssl_pkcs7_encrypt(string infile, string outfile, array recipcerts,
|
||||
array headers[, array flags])
|
||||
|
||||
Encrypts the MIME message contained in the file named by infile using
|
||||
the certificates held in recipcerts. The result is place in the file
|
||||
named outfile.
|
||||
recipcerts is an array of certificate identifiers representing the certs
|
||||
of the intended recipients of the message.
|
||||
headers is an array of headers to prepend to the message: they will
|
||||
not be included in the encoded section.
|
||||
flags is flag information as described above.
|
||||
Hint: you will want to put "To", "From", and "Subject" headers in headers.
|
||||
Headers can be either an assoc array keyed by header named, or can be
|
||||
and indexed array containing a single header line per value.
|
||||
The message will be encoded using a RC2-40 bit cipher.
|
||||
TODO: allow user to specify cipher.
|
||||
|
||||
bool openssl_pkcs7_sign(string infile, string outfile, mixed signcert, mixed
|
||||
signkey, array headers[, array flags][, string extracertsfilename])
|
||||
|
||||
Signs the MIME message contained in the file named by infile using the
|
||||
certificate and key pair identified by signcert/signkey.
|
||||
Signkey must be the private key corresponding to signcert.
|
||||
The result is placed in the file named by outfile.
|
||||
Headers and flags have the same effects as mentioned above.
|
||||
extracertsfilename names a file containing a bunch of additional certificates
|
||||
to include in the signature, in order to aid the recipient in verifying the
|
||||
message.
|
||||
|
||||
|
||||
bool openssl_pkcs7_decrypt(string infilename, string outfilename, mixed
|
||||
recipcert, mixed recipkey)
|
||||
|
||||
Decrypts the MIME message contained in the file named by infilename
|
||||
using the certificate and private key pair recipcert/recipkey.
|
||||
The descrypted result is placed in outfilename.
|
||||
TODO: add flags parameter, if needed?
|
||||
|
||||
|
||||
EVP Sign/Verify/Encrypt/Decrypt Functions:
|
||||
------------------------------------------
|
||||
|
||||
bool openssl_sign(string data, &string signature, mixed key)
|
||||
|
||||
Uses key to create signature for data, returns true on success and false
|
||||
on failure. signature is passed by reference and contains the newly created
|
||||
signature on success.
|
||||
|
||||
|
||||
int openssl_verify(string data, string signature, mixed key)
|
||||
|
||||
Uses key to verify that the signature is correct for the given data.
|
||||
Returns 1 if correct, 0 if incorrect, and -1 on error.
|
||||
|
||||
|
||||
int openssl_seal(string data, &string sealdata, &array ekeys, array pubkeys)
|
||||
|
||||
Encrypts data using pubkeys, so that only owners of the respective private
|
||||
keys and ekeys can decrypt and read the data. Returns the length of the
|
||||
sealed data on success, else false. On success, sealdata and ekeys hold
|
||||
the sealed data and envelope keys.
|
||||
|
||||
|
||||
bool openssl_open(string data, &string opendata, string ekey, int privkey)
|
||||
|
||||
Opens (decrypts) sealed data using a private key and the corresponding
|
||||
envelope key. Returns true on success and false on failure. On success,
|
||||
opendata will hold the descypted data.
|
||||
|
||||
|
||||
See below for more details on usage. Also feel free to mail me at
|
||||
venaas@php.net if you have questions. The OpenSSL documentation,
|
||||
especially the EVP documentation at
|
||||
http://www.openssl.org/docs/crypto/evp.html, might also be of help.
|
||||
|
||||
|
||||
HOWTO:
|
||||
|
||||
To do anything you need a private key and a certificate containing the
|
||||
corresponding public key. This is similar to what you have using say an
|
||||
Apache webserver with OpenSSL. For testing you could try keys that come
|
||||
with OpenSSL, that's what the sample scripts below do. You can also get
|
||||
keys from some CA, or you can create them yourself.
|
||||
|
||||
|
||||
Creating private key
|
||||
|
||||
To generate an unprotected 1024 bit RSA private key you can do
|
||||
|
||||
openssl genrsa -out /tmp/test.key 1024
|
||||
|
||||
Private keys should be protected by a passphrase though.
|
||||
|
||||
|
||||
Creating a self signed certificate
|
||||
|
||||
To generate a self signed certificate from the key that is valid for
|
||||
365 days, do
|
||||
|
||||
openssl req -new -key /tmp/test.key -out /tmp/test.crt -days 365 -x509
|
||||
|
||||
|
||||
Example usage
|
||||
|
||||
These examples use keys that come with OpenSSL, you should perhaps test with
|
||||
those first.
|
||||
|
||||
|
||||
Seal and open
|
||||
|
||||
<?php
|
||||
$data = "Follow the white rabbit";
|
||||
|
||||
// Get certificate into a string
|
||||
// this file comes with OpenSSL 0.9.6
|
||||
$fp = fopen("/src/openssl-0.9.6/demos/maurice/cert.pem", "r");
|
||||
$cert = fread($fp, 8192);
|
||||
fclose($fp);
|
||||
// get public key from certificate
|
||||
$pk1 = openssl_get_publickey($cert);
|
||||
// $pk1 is an encryption key resource id if success, else false
|
||||
// Repeat if want public keys for multiple parties
|
||||
|
||||
$fp = fopen("/src/openssl-0.9.6/demos/sign/cert.pem", "r");
|
||||
$cert = fread($fp, 8192);
|
||||
fclose($fp);
|
||||
$pk2 = openssl_get_publickey($cert);
|
||||
|
||||
// seal data, only owners of $pk1 and $pk2 can decrypt $sealed with keys
|
||||
// $ekeys[0] and $ekeys[1] respectively.
|
||||
openssl_seal($data, $sealed, $ekeys, array($pk1,$pk2));
|
||||
openssl_free_key($pk1);
|
||||
openssl_free_key($pk2);
|
||||
|
||||
// now we try to decrypt data for one of the recipients
|
||||
$fp = fopen("/src/openssl-0.9.6/demos/sign/key.pem", "r");
|
||||
// Get PEM coded key into $pkey
|
||||
$pkey = fread($fp, 8192);
|
||||
fclose($fp);
|
||||
// $key will be resource id for unpacked $pkey
|
||||
$key = openssl_get_privatekey($pkey);
|
||||
|
||||
openssl_open($sealed, $open, $ekeys[1], $key);
|
||||
openssl_free_key($key);
|
||||
echo "$open\n";
|
||||
?>
|
||||
|
||||
|
||||
Sign and verify
|
||||
|
||||
<?php
|
||||
$data = "Follow the white rabbit";
|
||||
|
||||
// First we need to have a string containing the private key in PEM format
|
||||
// this file comes with OpenSSL 0.9.6
|
||||
$fp = fopen("/src/openssl-0.9.6/demos/sign/key.pem", "r");
|
||||
$pkey = fread($fp, 8192);
|
||||
fclose($fp);
|
||||
|
||||
// get private key from the PEM format
|
||||
// $key is an encr key resource id if success, else false
|
||||
$key = openssl_get_privatekey($pkey);
|
||||
|
||||
// calculate signature
|
||||
openssl_sign($data, $signature, $key);
|
||||
openssl_free_key($key);
|
||||
|
||||
// recipient verifies signature
|
||||
// read certificate
|
||||
$fp = fopen("/src/openssl-0.9.6/demos/sign/cert.pem", "r");
|
||||
$cert = fread($fp, 8192);
|
||||
fclose($fp);
|
||||
|
||||
// Get public key from the certificate
|
||||
$pubkey = openssl_get_publickey($cert);
|
||||
|
||||
// state whether signature is okay or not
|
||||
echo openssl_verify($data, $signature, $pubkey) == 1 ? "ok\n" : "bad\n";
|
||||
|
||||
// free key
|
||||
openssl_free_key($pubkey);
|
||||
?>
|
||||
Reference in New Issue
Block a user