> I'm looking for an example of decoding the crlDistributionPoints
> extension; e.g. obtaining the specified URI (assuming that the value
> specifies a URI, that is). This seems like it should be easy. By
> digging around in the archives of this list, I've been able to
> figure out I can get the ASN.1-encoded value ... it seems like I
> want to go from ASN1_OCTET_STRING to a GENERAL_NAME structure, but I
> just can't seem to figure out how to get there.
>
Thanks to sbg for pointing out that I want d2i_CRL_DIST_POINTS. This
returns STACK_OF(DIST_POINT), and it all comes together from there.
Here's a working snippet that, for a CRL Distribution Point extension
that specifies a single URI-type distribution point name, extracts the
value of the URI. Hopefully, this will be helpful to the next soul
searching for details on how to do this.
int loc = X509_get_ext_by_NID(cert, NID_crl_distribution_points,
-1);
if (loc < 0) {
/* CRL Distribution Point extension not present... bail out */
}
X509_EXTENSION *ext = X509_get_ext(cert, loc);
assert(ext != NULL);
ASN1_STRING *s = X509_EXTENSION_get_data(ext);
const unsigned char *data = ASN1_STRING_data(s);
long length = ASN1_STRING_length(s);
STACK_OF(DIST_POINT) *dps = d2i_CRL_DIST_POINTS(NULL, &data,
length);
if (dps == NULL) {
/* some decoding error... bail out */
}
assert(sk_DIST_POINT_num(dps) > 0);
DIST_POINT *dp = sk_DIST_POINT_pop(dps);
STACK_OF(GENERAL_NAME) *names = dp->distpoint->name.fullname;
assert(sk_GENERAL_NAME_num(names) > 0);
GENERAL_NAME *name = sk_GENERAL_NAME_pop(names);
if (name->type == GEN_URI) {
ASN1_IA5STRING *uri = name->d.uniformResourceIdentifier;
/* do something with the URI value... */
}
else {
/* some other type of name... */
}
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org
> On Oct 25, 2009, at 2:57 PM, Carl Harris wrote:
>
>> I'm looking for an example of decoding the crlDistributionPoints
>> extension; e.g. obtaining the specified URI (assuming that the value
>> specifies a URI, that is). This seems like it should be easy. By digging
>> around in the archives of this list, I've been able to figure out I can
>> get the ASN.1-encoded value ... it seems like I want to go from
>> ASN1_OCTET_STRING to a GENERAL_NAME structure, but I just can't seem to
>> figure out how to get there.
>>
>
> Thanks to sbg for pointing out that I want d2i_CRL_DIST_POINTS. This
> returns STACK_OF(DIST_POINT), and it all comes together from there.
>
It is rather simpler than that. You can get the decoded structure for any
certificate extension using X509_get_ext_d2i(). You get additional checks that
way such as seeing if the extension occurs more than once.
There isn't a manual page for that function at present but some information is
in doc/openssl.txt
Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
True enough, this reduces the code snippet appreciably by eliminating
the rather tedious extension lookup fragment. My issue, of course,
was simply not knowing (and not being able to find any reference that
documents) the data type that would result from the d2i function for
this extension... but this is obviously simpler:
STACK_OF(DIST_POINT) *dps = X509_get_ext_d2i(cert,
NID_crl_distribution_points,
NULL, NULL);
/* extension not present or some decoding error... bail out */
}
assert(sk_DIST_POINT_num(dps) > 0);
DIST_POINT *dp = sk_DIST_POINT_pop(dps);
STACK_OF(GENERAL_NAME) *names = dp->distpoint->name.fullname;
assert(sk_GENERAL_NAME_num(names) > 0);
GENERAL_NAME *name = sk_GENERAL_NAME_pop(names);
if (name->type == GEN_URI) {
ASN1_IA5STRING *uri = name->d.uniformResourceIdentifier;
/* do something with the URI value... */
}
else {
/* some other type of name... */
}
______________________________________________________________________
> True enough, this reduces the code snippet appreciably by eliminating
> the rather tedious extension lookup fragment. My issue, of course, was
> simply not knowing (and not being able to find any reference that
> documents) the data type that would result from the d2i function for
> this extension... but this is obviously simpler:
>
> STACK_OF(DIST_POINT) *dps = X509_get_ext_d2i(cert,
> NID_crl_distribution_points,
> NULL, NULL);
> /* extension not present or some decoding error... bail out */
> }
>
> assert(sk_DIST_POINT_num(dps) > 0);
It is quite bad idea to use assert here. You are analyzing certificate.
External data which are passed to you by some other party, and you at
this moment cannot be sure that this party is trusted, because you've
not completed validation procedure yet.
If somebody would send you certificate without crlDistributionPoints
extension (perfectly valid by all other means), your program would
crash.
This should be runtime error, which can be handled by application, not
an assertion.
It is quite bad idea to use assert here. You are analyzing certificate.
External data which are passed to you by some other party, and you at
this moment cannot be sure that this party is trusted, because you've
not completed validation procedure yet.