Use ldap-prep (with libwind) to compare names
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@22583 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
2008-02-11 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||||
|
|
||||||
|
* Use ldap-prep (with libwind) to compare names
|
||||||
|
|
||||||
2008-01-27 Love H<>rnquist <20>strand <lha@it.su.se>
|
2008-01-27 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||||
|
|
||||||
* cert.c (hx509_query_match_eku): update to support the NULL
|
* cert.c (hx509_query_match_eku): update to support the NULL
|
||||||
|
@@ -85,6 +85,7 @@ libhx509_la_LIBADD = \
|
|||||||
$(LIB_com_err) \
|
$(LIB_com_err) \
|
||||||
$(LIB_hcrypto) \
|
$(LIB_hcrypto) \
|
||||||
$(top_builddir)/lib/asn1/libasn1.la \
|
$(top_builddir)/lib/asn1/libasn1.la \
|
||||||
|
$(top_builddir)/lib/wind/libwind.la \
|
||||||
$(LIBADD_roken) \
|
$(LIBADD_roken) \
|
||||||
$(LIB_dlopen)
|
$(LIB_dlopen)
|
||||||
|
|
||||||
|
115
lib/hx509/cert.c
115
lib/hx509/cert.c
@@ -893,10 +893,13 @@ _hx509_cert_is_parent_cmp(const Certificate *subject,
|
|||||||
int diff;
|
int diff;
|
||||||
AuthorityKeyIdentifier ai;
|
AuthorityKeyIdentifier ai;
|
||||||
SubjectKeyIdentifier si;
|
SubjectKeyIdentifier si;
|
||||||
int ret_ai, ret_si;
|
int ret_ai, ret_si, ret;
|
||||||
|
|
||||||
diff = _hx509_name_cmp(&issuer->tbsCertificate.subject,
|
ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
|
||||||
&subject->tbsCertificate.issuer);
|
&subject->tbsCertificate.issuer,
|
||||||
|
&diff);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
if (diff)
|
if (diff)
|
||||||
return diff;
|
return diff;
|
||||||
|
|
||||||
@@ -951,8 +954,11 @@ _hx509_cert_is_parent_cmp(const Certificate *subject,
|
|||||||
name.u.rdnSequence =
|
name.u.rdnSequence =
|
||||||
ai.authorityCertIssuer->val[0].u.directoryName.u.rdnSequence;
|
ai.authorityCertIssuer->val[0].u.directoryName.u.rdnSequence;
|
||||||
|
|
||||||
diff = _hx509_name_cmp(&issuer->tbsCertificate.subject,
|
ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
|
||||||
&name);
|
&name,
|
||||||
|
&diff);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
if (diff)
|
if (diff)
|
||||||
return diff;
|
return diff;
|
||||||
diff = 0;
|
diff = 0;
|
||||||
@@ -991,10 +997,18 @@ certificate_is_anchor(hx509_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
certificate_is_self_signed(const Certificate *cert)
|
certificate_is_self_signed(hx509_context context,
|
||||||
|
const Certificate *cert,
|
||||||
|
int *self_signed)
|
||||||
{
|
{
|
||||||
return _hx509_name_cmp(&cert->tbsCertificate.subject,
|
int ret, diff;
|
||||||
&cert->tbsCertificate.issuer) == 0;
|
ret = _hx509_name_cmp(&cert->tbsCertificate.subject,
|
||||||
|
&cert->tbsCertificate.issuer, &diff);
|
||||||
|
*self_signed = (diff == 0);
|
||||||
|
if (ret)
|
||||||
|
hx509_set_error_string(context, 0, ret,
|
||||||
|
"Failed to check if self signed");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1605,9 +1619,14 @@ match_RDN(const RelativeDistinguishedName *c,
|
|||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
|
|
||||||
for (i = 0; i < n->len; i++) {
|
for (i = 0; i < n->len; i++) {
|
||||||
|
int diff, ret;
|
||||||
|
|
||||||
if (der_heim_oid_cmp(&c->val[i].type, &n->val[i].type) != 0)
|
if (der_heim_oid_cmp(&c->val[i].type, &n->val[i].type) != 0)
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
if (_hx509_name_ds_cmp(&c->val[i].value, &n->val[i].value) != 0)
|
ret = _hx509_name_ds_cmp(&c->val[i].value, &n->val[i].value, &diff);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
if (diff != 0)
|
||||||
return HX509_NAME_CONSTRAINT_ERROR;
|
return HX509_NAME_CONSTRAINT_ERROR;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1867,10 +1886,7 @@ hx509_verify_path(hx509_context context,
|
|||||||
{
|
{
|
||||||
hx509_name_constraints nc;
|
hx509_name_constraints nc;
|
||||||
hx509_path path;
|
hx509_path path;
|
||||||
#if 0
|
int ret, i, proxy_cert_depth, selfsigned_depth, diff;
|
||||||
const AlgorithmIdentifier *alg_id;
|
|
||||||
#endif
|
|
||||||
int ret, i, proxy_cert_depth, selfsigned_depth;
|
|
||||||
enum certtype type;
|
enum certtype type;
|
||||||
Name proxy_issuer;
|
Name proxy_issuer;
|
||||||
hx509_certs anchors = NULL;
|
hx509_certs anchors = NULL;
|
||||||
@@ -1910,10 +1926,6 @@ hx509_verify_path(hx509_context context,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
#if 0
|
|
||||||
alg_id = path.val[path->len - 1]->data->tbsCertificate.signature;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check CA and proxy certificate chain from the top of the
|
* Check CA and proxy certificate chain from the top of the
|
||||||
* certificate chain. Also check certificate is valid with respect
|
* certificate chain. Also check certificate is valid with respect
|
||||||
@@ -1943,6 +1955,7 @@ hx509_verify_path(hx509_context context,
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CA_CERT:
|
case CA_CERT:
|
||||||
|
|
||||||
/* XXX make constants for keyusage */
|
/* XXX make constants for keyusage */
|
||||||
ret = check_key_usage(context, c, 1 << 5,
|
ret = check_key_usage(context, c, 1 << 5,
|
||||||
REQUIRE_RFC3280(ctx) ? TRUE : FALSE);
|
REQUIRE_RFC3280(ctx) ? TRUE : FALSE);
|
||||||
@@ -1952,8 +1965,16 @@ hx509_verify_path(hx509_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i + 1 != path.len && certificate_is_self_signed(c))
|
/* self signed cert doesn't add to path length */
|
||||||
selfsigned_depth++;
|
if (i + 1 != path.len) {
|
||||||
|
int selfsigned;
|
||||||
|
|
||||||
|
ret = certificate_is_self_signed(context, c, &selfsigned);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
if (selfsigned)
|
||||||
|
selfsigned_depth++;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PROXY_CERT: {
|
case PROXY_CERT: {
|
||||||
@@ -2001,8 +2022,12 @@ hx509_verify_path(hx509_context context,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (proxy_cert_depth) {
|
if (proxy_cert_depth) {
|
||||||
ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.subject);
|
ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.subject, &diff);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
hx509_set_error_string(context, 0, ret, "Out of memory");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (diff) {
|
||||||
ret = HX509_PROXY_CERT_NAME_WRONG;
|
ret = HX509_PROXY_CERT_NAME_WRONG;
|
||||||
hx509_set_error_string(context, 0, ret,
|
hx509_set_error_string(context, 0, ret,
|
||||||
"Base proxy name not right");
|
"Base proxy name not right");
|
||||||
@@ -2035,8 +2060,12 @@ hx509_verify_path(hx509_context context,
|
|||||||
free_RelativeDistinguishedName(&proxy_issuer.u.rdnSequence.val[j - 1]);
|
free_RelativeDistinguishedName(&proxy_issuer.u.rdnSequence.val[j - 1]);
|
||||||
proxy_issuer.u.rdnSequence.len -= 1;
|
proxy_issuer.u.rdnSequence.len -= 1;
|
||||||
|
|
||||||
ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.issuer);
|
ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.issuer, &diff);
|
||||||
if (ret != 0) {
|
if (ret) {
|
||||||
|
hx509_set_error_string(context, 0, ret, "Out of memory");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (diff != 0) {
|
||||||
ret = HX509_PROXY_CERT_NAME_WRONG;
|
ret = HX509_PROXY_CERT_NAME_WRONG;
|
||||||
hx509_set_error_string(context, 0, ret,
|
hx509_set_error_string(context, 0, ret,
|
||||||
"Proxy issuer name not as expected");
|
"Proxy issuer name not as expected");
|
||||||
@@ -2063,8 +2092,12 @@ hx509_verify_path(hx509_context context,
|
|||||||
if (proxy_cert_depth) {
|
if (proxy_cert_depth) {
|
||||||
|
|
||||||
ret = _hx509_name_cmp(&proxy_issuer,
|
ret = _hx509_name_cmp(&proxy_issuer,
|
||||||
&c->tbsCertificate.subject);
|
&c->tbsCertificate.subject, &diff);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
hx509_set_error_string(context, 0, ret, "out of memory");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (diff) {
|
||||||
ret = HX509_PROXY_CERT_NAME_WRONG;
|
ret = HX509_PROXY_CERT_NAME_WRONG;
|
||||||
hx509_clear_error_string(context);
|
hx509_clear_error_string(context);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -2120,11 +2153,16 @@ hx509_verify_path(hx509_context context,
|
|||||||
|
|
||||||
for (ret = 0, i = path.len - 1; i >= 0; i--) {
|
for (ret = 0, i = path.len - 1; i >= 0; i--) {
|
||||||
Certificate *c;
|
Certificate *c;
|
||||||
|
int selfsigned;
|
||||||
|
|
||||||
c = _hx509_get_cert(path.val[i]);
|
c = _hx509_get_cert(path.val[i]);
|
||||||
|
|
||||||
|
ret = certificate_is_self_signed(context, c, &selfsigned);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* verify name constraints, not for selfsigned and anchor */
|
/* verify name constraints, not for selfsigned and anchor */
|
||||||
if (!certificate_is_self_signed(c) || i + 1 != path.len) {
|
if (!selfsigned || i + 1 != path.len) {
|
||||||
ret = check_name_constraints(context, &nc, c);
|
ret = check_name_constraints(context, &nc, c);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
goto out;
|
goto out;
|
||||||
@@ -2192,10 +2230,16 @@ hx509_verify_path(hx509_context context,
|
|||||||
|
|
||||||
/* is last in chain (trust anchor) */
|
/* is last in chain (trust anchor) */
|
||||||
if (i + 1 == path.len) {
|
if (i + 1 == path.len) {
|
||||||
|
int selfsigned;
|
||||||
|
|
||||||
signer = path.val[i]->data;
|
signer = path.val[i]->data;
|
||||||
|
|
||||||
|
ret = certificate_is_self_signed(context, signer, &selfsigned);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* if trust anchor is not self signed, don't check sig */
|
/* if trust anchor is not self signed, don't check sig */
|
||||||
if (!certificate_is_self_signed(signer))
|
if (!selfsigned)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
/* take next certificate in chain */
|
/* take next certificate in chain */
|
||||||
@@ -2717,6 +2761,7 @@ int
|
|||||||
_hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert cert)
|
_hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert cert)
|
||||||
{
|
{
|
||||||
Certificate *c = _hx509_get_cert(cert);
|
Certificate *c = _hx509_get_cert(cert);
|
||||||
|
int ret, diff;
|
||||||
|
|
||||||
_hx509_query_statistic(context, 1, q);
|
_hx509_query_statistic(context, 1, q);
|
||||||
|
|
||||||
@@ -2732,17 +2777,20 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
|
|||||||
&& der_heim_integer_cmp(&c->tbsCertificate.serialNumber, q->serial) != 0)
|
&& der_heim_integer_cmp(&c->tbsCertificate.serialNumber, q->serial) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((q->match & HX509_QUERY_MATCH_ISSUER_NAME)
|
if (q->match & HX509_QUERY_MATCH_ISSUER_NAME) {
|
||||||
&& _hx509_name_cmp(&c->tbsCertificate.issuer, q->issuer_name) != 0)
|
ret = _hx509_name_cmp(&c->tbsCertificate.issuer, q->issuer_name, &diff);
|
||||||
return 0;
|
if (ret || diff)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((q->match & HX509_QUERY_MATCH_SUBJECT_NAME)
|
if (q->match & HX509_QUERY_MATCH_SUBJECT_NAME) {
|
||||||
&& _hx509_name_cmp(&c->tbsCertificate.subject, q->subject_name) != 0)
|
ret = _hx509_name_cmp(&c->tbsCertificate.subject, q->subject_name, &diff);
|
||||||
return 0;
|
if (ret || diff)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (q->match & HX509_QUERY_MATCH_SUBJECT_KEY_ID) {
|
if (q->match & HX509_QUERY_MATCH_SUBJECT_KEY_ID) {
|
||||||
SubjectKeyIdentifier si;
|
SubjectKeyIdentifier si;
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = _hx509_find_extension_subject_key_id(c, &si);
|
ret = _hx509_find_extension_subject_key_id(c, &si);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@@ -2806,14 +2854,13 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (q->match & HX509_QUERY_MATCH_FUNCTION) {
|
if (q->match & HX509_QUERY_MATCH_FUNCTION) {
|
||||||
int ret = (*q->cmp_func)(q->cmp_func_ctx, cert);
|
ret = (*q->cmp_func)(q->cmp_func_ctx, cert);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->match & HX509_QUERY_MATCH_KEY_HASH_SHA1) {
|
if (q->match & HX509_QUERY_MATCH_KEY_HASH_SHA1) {
|
||||||
heim_octet_string os;
|
heim_octet_string os;
|
||||||
int ret;
|
|
||||||
|
|
||||||
os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
|
os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
|
||||||
os.length =
|
os.length =
|
||||||
|
205
lib/hx509/name.c
205
lib/hx509/name.c
@@ -32,6 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hx_locl.h"
|
#include "hx_locl.h"
|
||||||
|
#include <wind.h>
|
||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,6 +64,7 @@ RCSID("$Id$");
|
|||||||
static const struct {
|
static const struct {
|
||||||
const char *n;
|
const char *n;
|
||||||
const heim_oid *(*o)(void);
|
const heim_oid *(*o)(void);
|
||||||
|
wind_profile_flags flags;
|
||||||
} no[] = {
|
} no[] = {
|
||||||
{ "C", oid_id_at_countryName },
|
{ "C", oid_id_at_countryName },
|
||||||
{ "CN", oid_id_at_commonName },
|
{ "CN", oid_id_at_commonName },
|
||||||
@@ -279,95 +281,162 @@ _hx509_Name_to_string(const Name *n, char **str)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#define COPYCHARARRAY(_ds,_el,_l,_n) \
|
||||||
* XXX this function is broken, it needs to compare code points, not
|
(_l) = strlen(_ds->u._el); \
|
||||||
* bytes.
|
(_n) = malloc((_l) * sizeof((_n)[0])); \
|
||||||
*/
|
if ((_n) == NULL) \
|
||||||
|
return ENOMEM; \
|
||||||
|
for (i = 0; i < (_l); i++) \
|
||||||
|
(_n)[i] = _ds->u._el[i]
|
||||||
|
|
||||||
static void
|
|
||||||
prune_space(const unsigned char **s)
|
#define COPYVALARRAY(_ds,_el,_l,_n) \
|
||||||
|
(_l) = _ds->u._el.length; \
|
||||||
|
(_n) = malloc((_l) * sizeof((_n)[0])); \
|
||||||
|
if ((_n) == NULL) \
|
||||||
|
return ENOMEM; \
|
||||||
|
for (i = 0; i < (_l); i++) \
|
||||||
|
(_n)[i] = _ds->u._el.data[i]
|
||||||
|
|
||||||
|
#define COPYVOIDARRAY(_ds,_el,_l,_n) \
|
||||||
|
(_l) = _ds->u._el.length; \
|
||||||
|
(_n) = malloc((_l) * sizeof((_n)[0])); \
|
||||||
|
if ((_n) == NULL) \
|
||||||
|
return ENOMEM; \
|
||||||
|
for (i = 0; i < (_l); i++) \
|
||||||
|
(_n)[i] = ((unsigned char *)_ds->u._el.data)[i]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
|
||||||
{
|
{
|
||||||
while (**s == ' ')
|
wind_profile_flags flags = 0;
|
||||||
(*s)++;
|
size_t i, len;
|
||||||
}
|
int ret;
|
||||||
|
uint32_t *name;
|
||||||
|
|
||||||
int
|
*rname = NULL;
|
||||||
_hx509_name_ds_cmp(const DirectoryString *ds1, const DirectoryString *ds2)
|
*rlen = 0;
|
||||||
{
|
|
||||||
int c;
|
|
||||||
|
|
||||||
c = ds1->element - ds2->element;
|
switch(ds->element) {
|
||||||
if (c)
|
|
||||||
return c;
|
|
||||||
|
|
||||||
switch(ds1->element) {
|
|
||||||
case choice_DirectoryString_ia5String:
|
case choice_DirectoryString_ia5String:
|
||||||
c = strcmp(ds1->u.ia5String, ds2->u.ia5String);
|
COPYCHARARRAY(ds, ia5String, len, name);
|
||||||
|
break;
|
||||||
|
case choice_DirectoryString_printableString:
|
||||||
|
flags = WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE;
|
||||||
|
COPYCHARARRAY(ds, printableString, len, name);
|
||||||
break;
|
break;
|
||||||
case choice_DirectoryString_teletexString:
|
case choice_DirectoryString_teletexString:
|
||||||
c = der_heim_octet_string_cmp(&ds1->u.teletexString,
|
COPYVOIDARRAY(ds, teletexString, len, name);
|
||||||
&ds2->u.teletexString);
|
|
||||||
break;
|
|
||||||
case choice_DirectoryString_printableString: {
|
|
||||||
const unsigned char *s1 = (unsigned char*)ds1->u.printableString;
|
|
||||||
const unsigned char *s2 = (unsigned char*)ds2->u.printableString;
|
|
||||||
prune_space(&s1); prune_space(&s2);
|
|
||||||
while (*s1 && *s2) {
|
|
||||||
if (toupper(*s1) != toupper(*s2)) {
|
|
||||||
c = toupper(*s1) - toupper(*s2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (*s1 == ' ') { prune_space(&s1); prune_space(&s2); }
|
|
||||||
else { s1++; s2++; }
|
|
||||||
}
|
|
||||||
prune_space(&s1); prune_space(&s2);
|
|
||||||
c = *s1 - *s2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case choice_DirectoryString_utf8String:
|
|
||||||
c = strcmp(ds1->u.utf8String, ds2->u.utf8String);
|
|
||||||
break;
|
|
||||||
case choice_DirectoryString_universalString:
|
|
||||||
c = der_heim_universal_string_cmp(&ds1->u.universalString,
|
|
||||||
&ds2->u.universalString);
|
|
||||||
break;
|
break;
|
||||||
case choice_DirectoryString_bmpString:
|
case choice_DirectoryString_bmpString:
|
||||||
c = der_heim_bmp_string_cmp(&ds1->u.bmpString,
|
COPYVALARRAY(ds, bmpString, len, name);
|
||||||
&ds2->u.bmpString);
|
break;
|
||||||
|
case choice_DirectoryString_universalString:
|
||||||
|
COPYVALARRAY(ds, universalString, len, name);
|
||||||
|
break;
|
||||||
|
case choice_DirectoryString_utf8String:
|
||||||
|
ret = wind_utf8ucs4_length(ds->u.utf8String, &len);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
name = malloc(len * sizeof(name[0]));
|
||||||
|
if (name == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
ret = wind_utf8ucs4(ds->u.utf8String, name, &len);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
c = 1;
|
_hx509_abort("unknown directory type: %d", ds->element);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return c;
|
|
||||||
|
*rlen = len;
|
||||||
|
/* try a couple of times to get the length right, XXX gross */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
*rlen = *rlen * 2;
|
||||||
|
*rname = malloc(*rlen * sizeof((*rname)[0]));
|
||||||
|
|
||||||
|
ret = wind_stringprep(name, len, *rname, rlen,
|
||||||
|
WIND_PROFILE_LDAP|flags);
|
||||||
|
if (ret == WIND_ERR_OVERRUN) {
|
||||||
|
free(*rname);
|
||||||
|
*rname = NULL;
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(name);
|
||||||
|
if (ret) {
|
||||||
|
if (*rname)
|
||||||
|
free(*rname);
|
||||||
|
*rname = NULL;
|
||||||
|
*rlen = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_hx509_name_cmp(const Name *n1, const Name *n2)
|
_hx509_name_ds_cmp(const DirectoryString *ds1,
|
||||||
|
const DirectoryString *ds2,
|
||||||
|
int *diff)
|
||||||
{
|
{
|
||||||
int i, j, c;
|
uint32_t *ds1lp, *ds2lp;
|
||||||
|
size_t ds1len, ds2len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;
|
ret = dsstringprep(ds1, &ds1lp, &ds1len);
|
||||||
if (c)
|
if (ret)
|
||||||
return c;
|
return ret;
|
||||||
|
ret = dsstringprep(ds2, &ds2lp, &ds2len);
|
||||||
|
if (ret) {
|
||||||
|
free(ds1lp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ds1len != ds2len)
|
||||||
|
*diff = ds1len - ds2len;
|
||||||
|
else
|
||||||
|
*diff = memcmp(ds1lp, ds2lp, ds1len * sizeof(ds1lp[0]));
|
||||||
|
|
||||||
|
free(ds1lp);
|
||||||
|
free(ds2lp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_hx509_name_cmp(const Name *n1, const Name *n2, int *c)
|
||||||
|
{
|
||||||
|
int ret, i, j;
|
||||||
|
|
||||||
|
*c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;
|
||||||
|
if (*c)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (i = 0 ; i < n1->u.rdnSequence.len; i++) {
|
for (i = 0 ; i < n1->u.rdnSequence.len; i++) {
|
||||||
c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;
|
*c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;
|
||||||
if (c)
|
if (*c)
|
||||||
return c;
|
return 0;
|
||||||
|
|
||||||
for (j = 0; j < n1->u.rdnSequence.val[i].len; j++) {
|
for (j = 0; j < n1->u.rdnSequence.val[i].len; j++) {
|
||||||
c = der_heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,
|
*c = der_heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,
|
||||||
&n1->u.rdnSequence.val[i].val[j].type);
|
&n1->u.rdnSequence.val[i].val[j].type);
|
||||||
if (c)
|
if (*c)
|
||||||
return c;
|
return 0;
|
||||||
|
|
||||||
c = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,
|
ret = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,
|
||||||
&n2->u.rdnSequence.val[i].val[j].value);
|
&n2->u.rdnSequence.val[i].val[j].value,
|
||||||
if (c)
|
c);
|
||||||
return c;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
if (*c)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*c = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +455,11 @@ _hx509_name_cmp(const Name *n1, const Name *n2)
|
|||||||
int
|
int
|
||||||
hx509_name_cmp(hx509_name n1, hx509_name n2)
|
hx509_name_cmp(hx509_name n1, hx509_name n2)
|
||||||
{
|
{
|
||||||
return _hx509_name_cmp(&n1->der_name, &n2->der_name);
|
int ret, diff;
|
||||||
|
ret = _hx509_name_cmp(&n1->der_name, &n2->der_name, &diff);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -763,11 +763,12 @@ hx509_revoke_verify(hx509_context context,
|
|||||||
for (i = 0; i < ctx->crls.len; i++) {
|
for (i = 0; i < ctx->crls.len; i++) {
|
||||||
struct revoke_crl *crl = &ctx->crls.val[i];
|
struct revoke_crl *crl = &ctx->crls.val[i];
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
int diff;
|
||||||
|
|
||||||
/* check if cert.issuer == crls.val[i].crl.issuer */
|
/* check if cert.issuer == crls.val[i].crl.issuer */
|
||||||
ret = _hx509_name_cmp(&c->tbsCertificate.issuer,
|
ret = _hx509_name_cmp(&c->tbsCertificate.issuer,
|
||||||
&crl->crl.tbsCertList.issuer);
|
&crl->crl.tbsCertList.issuer, &diff);
|
||||||
if (ret)
|
if (ret || diff)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = stat(crl->path, &sb);
|
ret = stat(crl->path, &sb);
|
||||||
|
Reference in New Issue
Block a user