Maybe one for the FAQ (openssl_pkcs7_decrypt problem)
"Roger H?kansson" <[email protected]> Mon, 21 Apr 2003 02:05:12 +0200
| Newsgroups | gmane.comp.horde.imp,gmane.comp.horde.documentation,gmane.comp.horde.user |
|---|---|
| Message-ID | <004401c30799$ae44efd0$9b0aa8c0@bop> |
I don't recall seeing this problem on any of the mailinglists, but since I ran into trouble because of it(and had a little hell finding it) I thought I'll send a mail about it. There is a problem with all PHP versions(up to and including 4.3.1, it is fixed in 4.3.2RC1) if you have OpenSSL 0.9.7. (more info at http://bugs.php.net/bug.php?id=22809 ) The problem is that if you try to use openssl_pkcs7_decrypt() or openssl_get_privatekey() and pass the privatekey stored in a variable instead of a filereference, PHP will fail to get the private key. In your php_error.log you will see something like this if you try to open an encrypted mail in IMP. ---- [18-Apr-2003 23:48:40] PHP Warning: openssl_pkcs7_decrypt(): unable to get private key in /var/apache/htdocs_8080/horde/lib/Crypt/smime.php on line 492 ---- In order to determine if you have this problem you can use the attached testprogram. Change the path to the private and public key-files, the emailaddres and the passphrase If you get an output looking like this you have a problem: ---- PHP Warning: openssl_pkcs7_decrypt() [http://www.php.net/function.openssl-pkcs7-decrypt]: unable to get private key in /tmp/openssl_test3.php on line 19 Source: The test string unencrypted Error decrypting Decrypted: ---- But if it looks like this your PHP works. ---- Source: The test string unencrypted Decrypted: The test string unencrypted ---- Solution: You have three options Downgrade OpenSSL to 0.9.6 (bad idea since it has a number of security problems) Upgrade to PHP-stable (or 4.3.2 when its relased) http://snaps.php.net/php4-STABLE-latest.tar.gz Patch your PHP: You need to patch $php_build_dirg/ext/openssl/openssl.c, take a look at the attached files(one is for 4.3.1 and the other for 4.2.3) and apply it to your openssl.c. -- Roger HÃ¥kansson -- IMP mailing list Frequently Asked Questions: http://horde.org/faq/ To unsubscribe, mail: [email protected]
openssl_test3.php
(application/octet-stream, 1 KB)
<?php $email = "[email protected]"; $passphrase = "private"; $text = "The test string unencrypted"; $pubkey = implode('',file("/path/to/certificate.crt")); $privkey_pem = implode('',file("/path/to/certificate.key")); //$privkey = openssl_get_privatekey("file:///path/to/certificate.key",$passphrase); $privkey = openssl_get_privatekey($privkey_pem,$passphrase); $input = tempnam('/tmp','openssl-test1-in'); $output1 = tempnam('/tmp','openssl-test1-out'); $fp1 = fopen($input, 'w+'); fputs($fp1, $text); fclose($fp1); echo "Source: $text\n"; $res = openssl_pkcs7_encrypt($input, $output1, $pubkey, array("To" => $email)); $result = file($output1); if (!$res || empty($result)) echo "Error encrypting\n"; $output2 = tempnam('/tmp','openssl-test2-out'); $res = openssl_pkcs7_decrypt($output1, $output2, $pubkey, $privkey ); $result = file($output2); if (!$res || empty($result)) echo "Error decrypting\n"; $result = file($output2); $tmp_txt = implode('',file($output2)); echo "Decrypted: $tmp_txt\n"; unlink($input); unlink($output1); unlink($output2); ?>
php-4.2.3_openssl.c.patch
(application/octet-stream, 1.7 KB)
*** ext/openssl/openssl.c.orig Fri Jul 12 23:47:33 2002
--- ext/openssl/openssl.c Sat Apr 19 04:47:43 2003
***************
*** 1661,1686 ****
cert = php_openssl_x509_from_zval(val, 0, &cert_res TSRMLS_CC);
free_cert = (cert_res == -1);
/* actual extraction done later */
}
else {
/* we want the private key */
if (filename) {
! BIO *in = BIO_new_file(filename, "r");
! if (in == NULL)
! return NULL;
! key = PEM_read_bio_PrivateKey(in, NULL,NULL, passphrase);
! BIO_free(in);
}
else {
! BIO * b = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
! if (b == NULL)
! return NULL;
!
! key = (EVP_PKEY *) PEM_ASN1_read_bio((char *(*)())d2i_PrivateKey,
! PEM_STRING_EVP_PKEY, b,
! NULL, NULL, passphrase);
! BIO_free(b);
}
}
}
--- 1661,1701 ----
cert = php_openssl_x509_from_zval(val, 0, &cert_res TSRMLS_CC);
free_cert = (cert_res == -1);
/* actual extraction done later */
+ if (!cert) {
+ /* not a X509 certificate, try to retrieve public key */
+ BIO *in;
+
+ if (filename) {
+ in = BIO_new_file(filename, "r");
+ }
+ else {
+ in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
+ }
+ if (in == NULL) {
+ return NULL;
+ }
+
+ key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL);
+ BIO_free(in);
+ }
+
}
else {
/* we want the private key */
+ BIO *in;
+
if (filename) {
! in = BIO_new_file(filename, "r");
}
else {
! in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
}
+ if (in == NULL) {
+ return NULL;
+ }
+
+ key = PEM_read_bio_PrivateKey(in, NULL,NULL, passphrase);
+ BIO_free(in);
}
}
php-4.3.1_openssl.c.patch
(application/octet-stream, 1.2 KB)
*** ext/openssl/openssl.c.orig Thu Dec 12 19:36:38 2002
--- ext/openssl/openssl.c Mon Apr 21 01:19:38 2003
***************
*** 1728,1754 ****
}
else {
/* we want the private key */
if (filename) {
- BIO *in;
if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
return NULL;
}
in = BIO_new_file(filename, "r");
- if (in == NULL)
- return NULL;
- key = PEM_read_bio_PrivateKey(in, NULL,NULL, passphrase);
- BIO_free(in);
}
else {
! BIO * b = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
! if (b == NULL)
! return NULL;
!
! key = (EVP_PKEY *) PEM_ASN1_read_bio((char *(*)())d2i_PrivateKey,
! PEM_STRING_EVP_PKEY, b,
! NULL, NULL, passphrase);
! BIO_free(b);
}
}
}
--- 1728,1747 ----
}
else {
/* we want the private key */
+ BIO *in;
if (filename) {
if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
return NULL;
}
in = BIO_new_file(filename, "r");
}
else {
! in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
}
+ if (in == NULL)
+ return NULL;
+ key = PEM_read_bio_PrivateKey(in, NULL,NULL, passphrase);
+ BIO_free(in);
}
}