Hi PHP folks,
Does anybody know a way to read the extension fields from a x509
certificate?
Maybe there is a better PHP module than openssl.
Until a better sollution came up, I did some changes to the openssl
PHP module,
I added the following lines, but here is still more to work (I hope
some developer from PHP hear me and give me a help):
Thanks in advance.
Sergiu.
/* {{{ proto array openssl_x509_parse(mixed x509 [, bool
shortnames=true])
Returns an array of the fields/values of the CERT */
PHP_FUNCTION(openssl_x509_parse)
{
zval * zcert;
X509 * cert = NULL;
long certresource = -1;
int i;
zend_bool useshortnames = 1;
char * tmpstr;
zval * subitem;
X509_EXTENSION *extension;
ASN1_OCTET_STRING *extdata;
char extstr[20];
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &zcert,
&useshortnames) == FAILURE)
return;
cert = php_openssl_x509_from_zval(&zcert, 0, &certresource
TSRMLS_CC);
if (cert == NULL)
RETURN_FALSE;
array_init(return_value);
if (cert->name)
add_assoc_string(return_value, "name", cert->name, 1);
/* add_assoc_bool(return_value, "valid", cert->valid); */
add_assoc_name_entry(return_value, "subject",
X509_get_subject_name(cert), useshortnames TSRMLS_CC);
/* hash as used in CA directories to lookup cert by subject name */
{
char buf[32];
snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert));
add_assoc_string(return_value, "hash", buf, 1);
}
add_assoc_name_entry(return_value, "issuer",
X509_get_issuer_name(cert), useshortnames TSRMLS_CC);
add_assoc_long(return_value, "version", X509_get_version(cert));
add_assoc_long(return_value, "serialNumber",
ASN1_INTEGER_get(X509_get_serialNumber(cert)));
add_assoc_asn1_string(return_value, "validFrom",
X509_get_notBefore(cert));
add_assoc_asn1_string(return_value, "validTo",
X509_get_notAfter(cert));
add_assoc_long(return_value, "validFrom_time_t",
asn1_time_to_time_t(X509_get_notBefore(cert) TSRMLS_CC));
add_assoc_long(return_value, "validTo_time_t",
asn1_time_to_time_t(X509_get_notAfter(cert) TSRMLS_CC));
tmpstr = X509_alias_get0(cert, NULL);
if (tmpstr)
add_assoc_string(return_value, "alias", tmpstr, 1);
/*
add_assoc_long(return_value, "signaturetypeLONG",
X509_get_signature_type(cert));
add_assoc_string(return_value, "signaturetype",
OBJ_nid2sn(X509_get_signature_type(cert)), 1);
add_assoc_string(return_value, "signaturetypeLN",
OBJ_nid2ln(X509_get_signature_type(cert)), 1);
*/
MAKE_STD_ZVAL(subitem);
array_init(subitem);
/* NOTE: the purposes are added as integer keys - the keys match up
to the X509_PURPOSE_SSL_XXX defines
in x509v3.h */
for (i = 0; i < X509_PURPOSE_get_count(); i++) {
int id, purpset;
char * pname;
X509_PURPOSE * purp;
zval * subsub;
MAKE_STD_ZVAL(subsub);
array_init(subsub);
purp = X509_PURPOSE_get0(i);
id = X509_PURPOSE_get_id(purp);
purpset = X509_check_purpose(cert, id, 0);
add_index_bool(subsub, 0, purpset);
purpset = X509_check_purpose(cert, id, 1);
add_index_bool(subsub, 1, purpset);
pname = useshortnames ? X509_PURPOSE_get0_sname(purp) :
X509_PURPOSE_get0_name(purp);
add_index_string(subsub, 2, pname, 1);
/* NOTE: if purpset > 1 then it's a warning - we should mention it ?
*/
add_index_zval(subitem, id, subsub);
}
add_assoc_zval(return_value, "purposes", subitem);
/* Adding extension support by Sergiu */
add_assoc_string(return_value, "extensions added", "true", 1);
for (i = 0; i < X509_get_ext_count(cert); i++) {
extension = X509_get_ext(cert, i);
extdata = X509_EXTENSION_get_data(extension);
sprintf(extstr, "ext%i", i);
add_assoc_asn1_string(return_value, extstr, extdata);
}
if (certresource == -1 && cert)
X509_free(cert);
}
/* }}} */