README 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. OpenSSL extension for PHP
  2. $Id$
  3. The functions implemented so far make it possible to seal and open data, and
  4. also create and verify signatures.
  5. NEW: support for S/MIME encrypt/decrypt/sign/verify, as well as more
  6. flexibility for specifying certificates/keys.
  7. To enable the extension, configure PHP with --with-openssl.
  8. Specifying keys/certificates
  9. ----------------------------
  10. Most of the functions require a key or a certificate as a parameter; to make
  11. things easy for you to use openssl, this extension allows you
  12. to specify certificates in the following way:
  13. 1. As an X.509 resource returned from openssl_x509_read
  14. 2. As a string in the format file://filename, where filename is the path to the
  15. certificate file (it will be opened and read automatically)
  16. 3. As a string containing the data from the certificate file
  17. Similarly, you can use the following methods of specifying a public key:
  18. 1. As a key resource returned from openssl_get_publickey
  19. 2. An X509 resource - public key only
  20. 3. As a string in the format file://filename
  21. 4. As a string containing the data from the key file
  22. Additionally, for a private key, when the openssl extension function does not
  23. allow you to enter the passphrase as a parameter you may use the syntax
  24. array($key, "passphrase") where $key can be a key specified using one of the
  25. methods listed above.
  26. Certificate Verification
  27. ------------------------
  28. When calling a function that will verify a signature/certificate, the cainfo
  29. parameter is an array containing file and directory names that specifiy the
  30. locations of trusted CA files. If a directory is specified, then it must be a
  31. correctly hashed directory.
  32. Misc:
  33. -----
  34. mixed openssl_error_string()
  35. returns the message from the last error that the OpenSSL library encountered
  36. and moves it's internal error pointer to the next message. If there are no
  37. more error messages, returns false.
  38. General Key/Cert Functions:
  39. ---------------------------
  40. resource openssl_get_privatekey(mixed key [, string passphrase])
  41. Parses the key data and returns a key resource identifier. If the key is
  42. encrypted a passphrase is needed. This can be supplied as second argument.
  43. resource openssl_get_publickey(mixed cert)
  44. Extracts the public key from the given certificate or public key and returns
  45. a key resource identifier.
  46. void openssl_free_key(resource key)
  47. Frees the resource given by the key resource identifier.
  48. Note that this function does not accept the extended key specification
  49. syntax mentioned above, as it doesn't make sense in this case!
  50. array openssl_x509_parse(mixed x509[, bool shortnames=true])
  51. Parses the certificate data and returns an array containing information
  52. about the certificate, it's intended purposes, subject, issuer, validity
  53. etc. etc. If shortnames is true (the default) then the fields will be
  54. keyed by the shortname forms eg: CN as opposed to commonName (shortnames
  55. = false).
  56. bool openssl_x509_checkpurpose(mixed x509cert, int purpose,
  57. array cainfo[, string untrustedfile])
  58. Verifies if the certificate can be used for a specific purpose.
  59. Purpose can be one of the following values:
  60. X509_PURPOSE_SSL_CLIENT
  61. X509_PURPOSE_SSL_SERVER
  62. X509_PURPOSE_NS_SSL_SERVER
  63. X509_PURPOSE_SMIME_SIGN
  64. X509_PURPOSE_SMIME_ENCRYPT
  65. X509_PURPOSE_CRL_SIGN
  66. X509_PURPOSE_ANY
  67. cainfo is an array of CA information (as mentioned above).
  68. untrusted file specifies a file containing a bunch of certs that
  69. are not trusted but may be useful in validating the certificate.
  70. resource openssl_read_x509(mixed cert)
  71. Parses the cert and returns a resource that can be used with the
  72. other openssl functions
  73. void openssl_free_x509(resource x509)
  74. Frees the resource given by the x509 resource identifier.
  75. Note that this function does not accept the extended cert specification
  76. syntax mentioned above, as it doesn't make sense in this case!
  77. PKCS7 (S/MIME) Sign/Verify/Encrypt/Decrypt Functions:
  78. -----------------------------------------------------
  79. These functions allow you to manipulate S/MIME messages!
  80. They are based on apps/smime.c from the openssl dist, so for information,
  81. see the documentation for openssl.
  82. You may pass in some flags that affect how these functions work using
  83. and array containing the following values:
  84. "detached", "nodetached", "text", "nointern", "noverify", "nochain",
  85. "nocerts", "noattr", "binary", "nosigs".
  86. The options correspond to the options of the same name for the
  87. "openssl smime" command (smime(1)).
  88. bool openssl_pkcs7_verify(string filename, array flags[, string signerscerts][,
  89. array cainfo])
  90. Verifies that the signature on the MIME message contained in the file
  91. named by filename is valid. If signerscerts is passed in, it holds the
  92. name of a file into which the certificates of those that signed the
  93. message will be stored.
  94. cainfo and flags are CA information and flag information as described
  95. above.
  96. bool openssl_pkcs7_encrypt(string infile, string outfile, array recipcerts,
  97. array headers[, array flags])
  98. Encrypts the MIME message contained in the file named by infile using
  99. the certificates held in recipcerts. The result is place in the file
  100. named outfile.
  101. recipcerts is an array of certificate identifiers representing the certs
  102. of the intended recipients of the message.
  103. headers is an array of headers to prepend to the message: they will
  104. not be included in the encoded section.
  105. flags is flag information as described above.
  106. Hint: you will want to put "To", "From", and "Subject" headers in headers.
  107. Headers can be either an assoc array keyed by header named, or can be
  108. and indexed array containing a single header line per value.
  109. The message will be encoded using a RC2-40 bit cipher.
  110. TODO: allow user to specify cipher.
  111. bool openssl_pkcs7_sign(string infile, string outfile, mixed signcert, mixed
  112. signkey, array headers[, array flags][, string extracertsfilename])
  113. Signs the MIME message contained in the file named by infile using the
  114. certificate and key pair identified by signcert/signkey.
  115. Signkey must be the private key corresponding to signcert.
  116. The result is placed in the file named by outfile.
  117. Headers and flags have the same effects as mentioned above.
  118. extracertsfilename names a file containing a bunch of additional certificates
  119. to include in the signature, in order to aid the recipient in verifying the
  120. message.
  121. bool openssl_pkcs7_decrypt(string infilename, string outfilename, mixed
  122. recipcert, mixed recipkey)
  123. Decrypts the MIME message contained in the file named by infilename
  124. using the certificate and private key pair recipcert/recipkey.
  125. The descrypted result is placed in outfilename.
  126. TODO: add flags parameter, if needed?
  127. EVP Sign/Verify/Encrypt/Decrypt Functions:
  128. ------------------------------------------
  129. bool openssl_sign(string data, &string signature, mixed key)
  130. Uses key to create signature for data, returns true on success and false
  131. on failure. signature is passed by reference and contains the newly created
  132. signature on success.
  133. int openssl_verify(string data, string signature, mixed key)
  134. Uses key to verify that the signature is correct for the given data.
  135. Returns 1 if correct, 0 if incorrect, and -1 on error.
  136. int openssl_seal(string data, &string sealdata, &array ekeys, array pubkeys)
  137. Encrypts data using pubkeys, so that only owners of the respective private
  138. keys and ekeys can decrypt and read the data. Returns the length of the
  139. sealed data on success, else false. On success, sealdata and ekeys hold
  140. the sealed data and envelope keys.
  141. bool openssl_open(string data, &string opendata, string ekey, int privkey)
  142. Opens (decrypts) sealed data using a private key and the corresponding
  143. envelope key. Returns true on success and false on failure. On success,
  144. opendata will hold the descypted data.
  145. See below for more details on usage. Also feel free to mail me at
  146. venaas@php.net if you have questions. The OpenSSL documentation,
  147. especially the EVP documentation at
  148. http://www.openssl.org/docs/crypto/evp.html, might also be of help.
  149. HOWTO:
  150. To do anything you need a private key and a certificate containing the
  151. corresponding public key. This is similar to what you have using say an
  152. Apache webserver with OpenSSL. For testing you could try keys that come
  153. with OpenSSL, that's what the sample scripts below do. You can also get
  154. keys from some CA, or you can create them yourself.
  155. Creating private key
  156. To generate an unprotected 1024 bit RSA private key you can do
  157. openssl genrsa -out /tmp/test.key 1024
  158. Private keys should be protected by a passphrase though.
  159. Creating a self signed certificate
  160. To generate a self signed certificate from the key that is valid for
  161. 365 days, do
  162. openssl req -new -key /tmp/test.key -out /tmp/test.crt -days 365 -x509
  163. Example usage
  164. These examples use keys that come with OpenSSL, you should perhaps test with
  165. those first.
  166. Seal and open
  167. <?php
  168. $data = "Follow the white rabbit";
  169. // Get certificate into a string
  170. // this file comes with OpenSSL 0.9.6
  171. $fp = fopen("/src/openssl-0.9.6/demos/maurice/cert.pem", "r");
  172. $cert = fread($fp, 8192);
  173. fclose($fp);
  174. // get public key from certificate
  175. $pk1 = openssl_get_publickey($cert);
  176. // $pk1 is an encryption key resource id if success, else false
  177. // Repeat if want public keys for multiple parties
  178. $fp = fopen("/src/openssl-0.9.6/demos/sign/cert.pem", "r");
  179. $cert = fread($fp, 8192);
  180. fclose($fp);
  181. $pk2 = openssl_get_publickey($cert);
  182. // seal data, only owners of $pk1 and $pk2 can decrypt $sealed with keys
  183. // $ekeys[0] and $ekeys[1] respectively.
  184. openssl_seal($data, $sealed, $ekeys, array($pk1,$pk2));
  185. openssl_free_key($pk1);
  186. openssl_free_key($pk2);
  187. // now we try to decrypt data for one of the recipients
  188. $fp = fopen("/src/openssl-0.9.6/demos/sign/key.pem", "r");
  189. // Get PEM coded key into $pkey
  190. $pkey = fread($fp, 8192);
  191. fclose($fp);
  192. // $key will be resource id for unpacked $pkey
  193. $key = openssl_get_privatekey($pkey);
  194. openssl_open($sealed, $open, $ekeys[1], $key);
  195. openssl_free_key($key);
  196. echo "$open\n";
  197. ?>
  198. Sign and verify
  199. <?php
  200. $data = "Follow the white rabbit";
  201. // First we need to have a string containing the private key in PEM format
  202. // this file comes with OpenSSL 0.9.6
  203. $fp = fopen("/src/openssl-0.9.6/demos/sign/key.pem", "r");
  204. $pkey = fread($fp, 8192);
  205. fclose($fp);
  206. // get private key from the PEM format
  207. // $key is an encr key resource id if success, else false
  208. $key = openssl_get_privatekey($pkey);
  209. // calculate signature
  210. openssl_sign($data, $signature, $key);
  211. openssl_free_key($key);
  212. // recipient verifies signature
  213. // read certificate
  214. $fp = fopen("/src/openssl-0.9.6/demos/sign/cert.pem", "r");
  215. $cert = fread($fp, 8192);
  216. fclose($fp);
  217. // Get public key from the certificate
  218. $pubkey = openssl_get_publickey($cert);
  219. // state whether signature is okay or not
  220. echo openssl_verify($data, $signature, $pubkey) == 1 ? "ok\n" : "bad\n";
  221. // free key
  222. openssl_free_key($pubkey);
  223. ?>