123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- 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);
- ?>
|