]> git.sur5r.net Git - openldap/commitdiff
It now sort of works, but needs some normalization work and proper
authorJulio Sánchez Fernández <jsanchez@openldap.org>
Mon, 22 Oct 2001 06:54:30 +0000 (06:54 +0000)
committerJulio Sánchez Fernández <jsanchez@openldap.org>
Mon, 22 Oct 2001 06:54:30 +0000 (06:54 +0000)
error reporting to client and syslog. And indexing, of course.

Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is.  When doing
a modify, a full certificate value is passed (to verify it isn't
already there).  When doing a search or compare, the passed value is
in the syntax of the matching rule.

Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match.  It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).

Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.

servers/slapd/schema_init.c

index 11e85cae16ac9f843e3c000d06939564c23a861f..77521254582596b8d5136424a2e0e78c39800585 100644 (file)
@@ -3497,6 +3497,7 @@ asn1_integer2str(ASN1_INTEGER *a)
        return ber_bvstrdup(p);
 }
 
+/* Get a DN in RFC2253 format from a X509_NAME internal struct */
 static struct berval *
 dn_openssl2ldap(X509_NAME *name)
 {
@@ -3517,6 +3518,61 @@ dn_openssl2ldap(X509_NAME *name)
        return ber_bvstrdup(issuer_dn);
 }
 
+/*
+ * Given a certificate in DER format, extract the corresponding
+ * assertion value for certificateExactMatch
+ */
+static int
+certificateExactConvert(
+       struct berval * in,
+       struct berval ** out )
+{
+       X509 *xcert;
+       unsigned char *p = in->bv_val;
+       struct berval *serial;
+       struct berval *issuer_dn;
+       struct berval *bv_tmp;
+       int ret;
+
+       xcert = d2i_X509(NULL, &p, in->bv_len);
+       if ( !xcert ) {
+               ERR_error_string(ERR_get_error(),NULL);
+               return LDAP_INVALID_SYNTAX;
+       }
+
+       serial = asn1_integer2str(xcert->cert_info->serialNumber);
+       issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
+
+       X509_free(xcert);
+
+       *out = ch_malloc(sizeof(struct berval));
+       (*out)->bv_len = serial->bv_len + 3 + issuer_dn->bv_len + 1;
+       (*out)->bv_val = ch_malloc((*out)->bv_len);
+       p = (*out)->bv_val;
+       AC_MEMCPY(p, serial->bv_val, serial->bv_len);
+       p += serial->bv_len;
+       AC_MEMCPY(p, " $ ", 3);
+       p += 3;
+       AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
+       p += issuer_dn->bv_len;
+       *p++ = '\0';
+
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
+                  "certificateExactConvert: \n %s\n",
+                  (*out)->bv_val));
+#else
+       Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
+               "\n\t\"%s\"\n",
+               (*out)->bv_val, NULL, NULL );
+#endif
+
+       ber_bvfree(serial);
+       ber_bvfree(issuer_dn);
+
+       return LDAP_SUCCESS;
+}
+
 static int
 serial_and_issuer_parse(
        struct berval *assertion,
@@ -3538,11 +3594,11 @@ serial_and_issuer_parse(
 
        /* p now points at the $ sign, now use begin and end to delimit the
           serial number */
-       while (ASCII_SPACE(*begin++))
-               ;
-       end = p;
-       while (ASCII_SPACE(*end--))
-               ;
+       while (ASCII_SPACE(*begin))
+               begin++;
+       end = p-1;
+       while (ASCII_SPACE(*end))
+               end--;
 
        q = ch_malloc( (end-begin+1)+1 );
        AC_MEMCPY( q, begin, end-begin+1 );
@@ -3552,8 +3608,8 @@ serial_and_issuer_parse(
        /* now extract the issuer, remember p was at the dollar sign */
        begin = p+1;
        end = assertion->bv_val+assertion->bv_len-1;
-       while (ASCII_SPACE(*begin++))
-               ;
+       while (ASCII_SPACE(*begin))
+               begin++;
        /* should we trim spaces at the end too? is it safe always? */
 
        q = ch_malloc( (end-begin+1)+1 );
@@ -3584,6 +3640,7 @@ certificateExactMatch(
        xcert = d2i_X509(NULL, &p, value->bv_len);
        if ( !xcert ) {
                ERR_error_string(ERR_get_error(),NULL);
+               return LDAP_INVALID_SYNTAX;
        }
 
        serial = asn1_integer2str(xcert->cert_info->serialNumber);
@@ -3604,6 +3661,7 @@ certificateExactMatch(
                asserted_serial);
        if ( ret == LDAP_SUCCESS ) {
                if ( *matchp == 0 ) {
+                       /* We need to normalize everything for dnMatch */
                        ret = dnMatch(
                                matchp,
                                flags,
@@ -3614,6 +3672,20 @@ certificateExactMatch(
                }
        }
 
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
+                  "certificateExactMatch: %d\n  %s $ %s\n       %s $   %s\n",
+                  *matchp, serial->bv_val, issuer_dn->bv_val,
+                  asserted->serial->bv_val, asserted_issuer_dn->bv_val));
+#else
+       Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
+               "%d\n\t\"%s $ %s\"\n",
+               *matchp, serial->bv_val, issuer_dn->bv_val );
+       Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
+               asserted_serial->bv_val, asserted_issuer_dn->bv_val,
+               NULL );
+#endif
+
        ber_bvfree(serial);
        ber_bvfree(issuer_dn);
        ber_bvfree(asserted_serial);
@@ -4378,7 +4450,7 @@ struct mrule_defs_rec mrule_defs[] = {
        {"( 2.5.13.34 NAME 'certificateExactMatch' "
                "SYNTAX 1.2.826.0.1.3344810.7.1 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT,
-               NULL, NULL,
+               certificateExactConvert, NULL,
                certificateExactMatch, NULL, NULL,
                NULL},
 #endif