]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_init.c
ITS#8778 Fix telephoneNumberNormalize("-" or " ")
[openldap] / servers / slapd / schema_init.c
index d177795925d03b6c41389b98669f9d4a53b9f282..b51ce53e3c0f2ea0bb3bc4ab5c2f21ec25222915 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2013 The OpenLDAP Foundation.
+ * Copyright 1998-2017 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -593,6 +593,41 @@ attributeCertificateValidate( Syntax *syntax, struct berval *in )
        return LDAP_SUCCESS;
 }
 
+/* accept a PKCS#8 private key */
+static int
+privateKeyValidate(
+       Syntax          *syntax,
+       struct berval   *val )
+{
+       BerElementBuffer berbuf;
+       BerElement *ber = (BerElement *)&berbuf;
+       ber_tag_t tag;
+       ber_len_t len;
+       ber_int_t version;
+
+       ber_init2( ber, val, LBER_USE_DER );
+       tag = ber_skip_tag( ber, &len );        /* Sequence */
+       if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
+       tag = ber_peek_tag( ber, &len );
+       if ( tag != LBER_INTEGER ) return LDAP_INVALID_SYNTAX;
+       tag = ber_get_int( ber, &version );
+       tag = ber_skip_tag( ber, &len );        /* AlgorithmIdentifier */
+       if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
+       ber_skip_data( ber, len );
+       tag = ber_skip_tag( ber, &len );        /* PrivateKey */
+       if ( tag != LBER_OCTETSTRING ) return LDAP_INVALID_SYNTAX;
+       ber_skip_data( ber, len );
+       tag = ber_skip_tag( ber, &len );
+       if ( tag == LBER_SET ) {                        /* Optional Attributes */
+               ber_skip_data( ber, len );
+               tag = ber_skip_tag( ber, &len );
+       }
+
+       /* Must be at end now */
+       if ( len || tag != LBER_DEFAULT ) return LDAP_INVALID_SYNTAX;
+       return LDAP_SUCCESS;
+}
+
 int
 octetStringMatch(
        int *matchp,
@@ -686,7 +721,6 @@ int octetStringIndexer(
        void *ctx )
 {
        int i;
-       size_t slen, mlen;
        BerVarray keys;
        HASH_CONTEXT HASHcontext;
        unsigned char HASHdigest[HASH_BYTES];
@@ -703,9 +737,6 @@ int octetStringIndexer(
 
        keys = slap_sl_malloc( sizeof( struct berval ) * (i+1), ctx );
 
-       slen = syntax->ssyn_oidlen;
-       mlen = mr->smr_oidlen;
-
        hashPreset( &HASHcontext, prefix, 0, syntax, mr);
        for( i=0; !BER_BVISNULL( &values[i] ); i++ ) {
                hashIter( &HASHcontext, HASHdigest,
@@ -731,7 +762,6 @@ int octetStringFilter(
        BerVarray *keysp,
        void *ctx )
 {
-       size_t slen, mlen;
        BerVarray keys;
        HASH_CONTEXT HASHcontext;
        unsigned char HASHdigest[HASH_BYTES];
@@ -740,9 +770,6 @@ int octetStringFilter(
        digest.bv_val = (char *)HASHdigest;
        digest.bv_len = HASH_LEN;
 
-       slen = syntax->ssyn_oidlen;
-       mlen = mr->smr_oidlen;
-
        keys = slap_sl_malloc( sizeof( struct berval ) * 2, ctx );
 
        hashPreset( &HASHcontext, prefix, 0, syntax, mr );
@@ -894,7 +921,6 @@ octetStringSubstringsIndexer(
        void *ctx )
 {
        ber_len_t i, nkeys;
-       size_t slen, mlen;
        BerVarray keys;
 
        HASH_CONTEXT HCany, HCini, HCfin;
@@ -940,9 +966,6 @@ octetStringSubstringsIndexer(
 
        keys = slap_sl_malloc( sizeof( struct berval ) * (nkeys+1), ctx );
 
-       slen = syntax->ssyn_oidlen;
-       mlen = mr->smr_oidlen;
-
        if ( flags & SLAP_INDEX_SUBSTR_ANY )
                hashPreset( &HCany, prefix, SLAP_INDEX_SUBSTR_PREFIX, syntax, mr );
        if( flags & SLAP_INDEX_SUBSTR_INITIAL )
@@ -1016,7 +1039,7 @@ octetStringSubstringsFilter (
        SubstringsAssertion *sa;
        char pre;
        ber_len_t nkeys = 0;
-       size_t slen, mlen, klen;
+       size_t klen;
        BerVarray keys;
        HASH_CONTEXT HASHcontext;
        unsigned char HASHdigest[HASH_BYTES];
@@ -1068,9 +1091,6 @@ octetStringSubstringsFilter (
        digest.bv_val = (char *)HASHdigest;
        digest.bv_len = HASH_LEN;
 
-       slen = syntax->ssyn_oidlen;
-       mlen = mr->smr_oidlen;
-
        keys = slap_sl_malloc( sizeof( struct berval ) * (nkeys+1), ctx );
        nkeys = 0;
 
@@ -1780,16 +1800,15 @@ UTF8StringValidate(
        Syntax *syntax,
        struct berval *in )
 {
-       ber_len_t count;
        int len;
-       unsigned char *u = (unsigned char *)in->bv_val;
+       unsigned char *u = (unsigned char *)in->bv_val, *end = (unsigned char *)in->bv_val + in->bv_len;
 
        if( BER_BVISEMPTY( in ) && syntax == slap_schema.si_syn_directoryString ) {
                /* directory strings cannot be empty */
                return LDAP_INVALID_SYNTAX;
        }
 
-       for( count = in->bv_len; count > 0; count -= len, u += len ) {
+       for( ; u < end; u += len ) {
                /* get the length indicated by the first byte */
                len = LDAP_UTF8_CHARLEN2( u, len );
 
@@ -1827,7 +1846,7 @@ UTF8StringValidate(
                if( LDAP_UTF8_OFFSET( (char *)u ) != len ) return LDAP_INVALID_SYNTAX;
        }
 
-       if( count != 0 ) {
+       if( u > end ) {
                return LDAP_INVALID_SYNTAX;
        }
 
@@ -2271,7 +2290,7 @@ approxFilter(
        return LDAP_SUCCESS;
 }
 
-/* Remove all spaces and '-' characters */
+/* Remove all spaces and '-' characters, unless the result would be empty */
 static int
 telephoneNumberNormalize(
        slap_mask_t usage,
@@ -2285,8 +2304,11 @@ telephoneNumberNormalize(
 
        assert( SLAP_MR_IS_VALUE_OF_SYNTAX( usage ) != 0 );
 
-       /* validator should have refused an empty string */
-       assert( !BER_BVISEMPTY( val ) );
+       /* Ensure q is big enough, though validator should have caught this */
+       if ( BER_BVISEMPTY( val )) {
+               BER_BVZERO( normalized );
+               return LDAP_INVALID_SYNTAX;
+       }
 
        q = normalized->bv_val = slap_sl_malloc( val->bv_len + 1, ctx );
 
@@ -2295,16 +2317,13 @@ telephoneNumberNormalize(
                        *q++ = *p;
                }
        }
+       if ( q == normalized->bv_val ) {
+               *q++ = ' ';
+       }
        *q = '\0';
 
        normalized->bv_len = q - normalized->bv_val;
 
-       if( BER_BVISEMPTY( normalized ) ) {
-               slap_sl_free( normalized->bv_val, ctx );
-               BER_BVZERO( normalized );
-               return LDAP_INVALID_SYNTAX;
-       }
-
        return LDAP_SUCCESS;
 }
 
@@ -2681,8 +2700,10 @@ integerIndexer(
                                itmp.bv_len = maxstrlen;
                }
                rc = integerVal2Key( &values[i], &keys[i], &itmp, ctx );
-               if ( rc )
+               if ( rc ) {
+                       slap_sl_free( keys, ctx );
                        goto func_leave;
+               }
        }
        *keysp = keys;
 func_leave:
@@ -2729,12 +2750,16 @@ integerFilter(
        }
 
        rc = integerVal2Key( value, keys, &iv, ctx );
-       if ( rc == 0 )
-               *keysp = keys;
 
        if ( iv.bv_val != ibuf ) {
                slap_sl_free( iv.bv_val, ctx );
        }
+
+       if ( rc == 0 )
+               *keysp = keys;
+       else
+               slap_sl_free( keys, ctx );
+
        return rc;
 }
 
@@ -3310,6 +3335,7 @@ serialNumberAndIssuerCheck(
                                        }
                                        if ( is->bv_val[is->bv_len+1] == '"' ) {
                                                /* double dquote */
+                                               numdquotes++;
                                                is->bv_len += 2;
                                                continue;
                                        }
@@ -3713,12 +3739,14 @@ certificateExactNormalize(
        tag = ber_skip_tag( ber, &len );        /* SignatureAlg */
        ber_skip_data( ber, len );
        tag = ber_peek_tag( ber, &len );        /* IssuerDN */
-       len = ber_ptrlen( ber );
-       bvdn.bv_val = val->bv_val + len;
-       bvdn.bv_len = val->bv_len - len;
+       if ( len ) {
+               len = ber_ptrlen( ber );
+               bvdn.bv_val = val->bv_val + len;
+               bvdn.bv_len = val->bv_len - len;
 
-       rc = dnX509normalize( &bvdn, &issuer_dn );
-       if ( rc != LDAP_SUCCESS ) goto done;
+               rc = dnX509normalize( &bvdn, &issuer_dn );
+               if ( rc != LDAP_SUCCESS ) goto done;
+       }
 
        normalized->bv_len = STRLENOF( "{ serialNumber , issuer rdnSequence:\"\" }" )
                + sn2.bv_len + issuer_dn.bv_len;
@@ -3885,6 +3913,7 @@ issuerAndThisUpdateCheck(
                                }
                                if ( is->bv_val[is->bv_len+1] == '"' ) {
                                        /* double dquote */
+                                       numdquotes++;
                                        is->bv_len += 2;
                                        continue;
                                }
@@ -4427,6 +4456,7 @@ serialNumberAndIssuerSerialCheck(
                                                }
                                                if ( is->bv_val[is->bv_len + 1] == '"' ) {
                                                        /* double dquote */
+                                                       numdquotes++;
                                                        is->bv_len += 2;
                                                        continue;
                                                }
@@ -6354,6 +6384,9 @@ static slap_syntax_defs_rec syntax_defs[] = {
        {"( 1.3.6.1.4.1.4203.666.2.7 DESC 'OpenLDAP authz' )",
                SLAP_SYNTAX_HIDE, NULL, authzValidate, authzPretty},
 
+       /* PKCS#8 Private Keys for X.509 certificates */
+       {"( 1.3.6.1.4.1.4203.666.2.13 DESC 'OpenLDAP privateKey' )",
+               SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, privateKeyValidate, NULL},
        {NULL, 0, NULL, NULL, NULL}
 };
 
@@ -6841,6 +6874,13 @@ static slap_mrule_defs_rec mrule_defs[] = {
                NULL, NULL,
                NULL},
 
+       {"( 1.3.6.1.4.1.4203.666.4.13 NAME 'privateKeyMatch' "
+               "SYNTAX 1.3.6.1.4.1.4203.666.2.13 )", /* OpenLDAP privateKey */
+               SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
+               NULL, NULL, octetStringMatch,
+               NULL, NULL,
+               NULL},
+
        {NULL, SLAP_MR_NONE, NULL,
                NULL, NULL, NULL, NULL, NULL,
                NULL }