]> git.sur5r.net Git - openldap/commitdiff
be liberal in accepting CL (ITS#6241)
authorPierangelo Masarati <ando@openldap.org>
Tue, 4 Aug 2009 14:14:17 +0000 (14:14 +0000)
committerPierangelo Masarati <ando@openldap.org>
Tue, 4 Aug 2009 14:14:17 +0000 (14:14 +0000)
servers/slapd/schema_init.c

index 95d108f6a5f294bd53777cfff0a7aa8d0742a708..b1e06e7b7f80dd82b991a7aaac7678b9cc27592c 100644 (file)
@@ -273,18 +273,25 @@ certificateValidate( Syntax *syntax, struct berval *in )
 }
 
 /* X.509 certificate list validation */
+static int
+checkTime( struct berval *in, struct berval *out );
+
 static int
 certificateListValidate( Syntax *syntax, struct berval *in )
 {
        BerElementBuffer berbuf;
        BerElement *ber = (BerElement *)&berbuf;
        ber_tag_t tag;
-       ber_len_t len;
+       ber_len_t len, wrapper_len;
+       char *wrapper_start;
+       int wrapper_ok = 0;
        ber_int_t version = SLAP_X509_V1;
+       struct berval bvdn, bvtu;
 
        ber_init2( ber, in, LBER_USE_DER );
-       tag = ber_skip_tag( ber, &len );        /* Signed wrapper */
+       tag = ber_skip_tag( ber, &wrapper_len );        /* Signed wrapper */
        if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
+       wrapper_start = ber->ber_ptr;
        tag = ber_skip_tag( ber, &len );        /* Sequence */
        if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
        tag = ber_peek_tag( ber, &len );
@@ -297,12 +304,18 @@ certificateListValidate( Syntax *syntax, struct berval *in )
        tag = ber_skip_tag( ber, &len );        /* Signature Algorithm */
        if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
        ber_skip_data( ber, len );
-       tag = ber_skip_tag( ber, &len );        /* Issuer DN */
+       tag = ber_peek_tag( ber, &len );        /* Issuer DN */
        if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
+       len = ber_ptrlen( ber );
+       bvdn.bv_val = in->bv_val + len;
+       bvdn.bv_len = in->bv_len - len;
+       tag = ber_skip_tag( ber, &len );
        ber_skip_data( ber, len );
        tag = ber_skip_tag( ber, &len );        /* thisUpdate */
        /* Time is a CHOICE { UTCTime, GeneralizedTime } */
        if ( tag != SLAP_TAG_UTCTIME && tag != SLAP_TAG_GENERALIZEDTIME ) return LDAP_INVALID_SYNTAX;
+       bvtu.bv_val = (char *)ber->ber_ptr;
+       bvtu.bv_len = len;
        ber_skip_data( ber, len );
        /* Optional nextUpdate */
        tag = ber_skip_tag( ber, &len );
@@ -335,10 +348,42 @@ certificateListValidate( Syntax *syntax, struct berval *in )
        /* Signature */
        if ( tag != LBER_BITSTRING ) return LDAP_INVALID_SYNTAX; 
        ber_skip_data( ber, len );
+       if ( ber->ber_ptr == wrapper_start + wrapper_len ) wrapper_ok = 1;
        tag = ber_skip_tag( ber, &len );
        /* Must be at end now */
        /* NOTE: OpenSSL tolerates CL with garbage past the end */
-       if ( len || tag != LBER_DEFAULT ) return LDAP_INVALID_SYNTAX;
+       if ( len || tag != LBER_DEFAULT ) {
+               struct berval issuer_dn, thisUpdate;
+               char tubuf[STRLENOF("YYYYmmddHHMMSSZ") + 1];
+               int rc;
+
+               if ( ! wrapper_ok ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               rc = dnX509normalize( &bvdn, &issuer_dn );
+               if ( rc != LDAP_SUCCESS ) {
+                       rc = LDAP_INVALID_SYNTAX;
+                       goto done;
+               }
+
+               thisUpdate.bv_val = tubuf;
+               thisUpdate.bv_len = sizeof(tubuf); 
+               if ( checkTime( &bvtu, &thisUpdate ) ) {
+                       rc = LDAP_INVALID_SYNTAX;
+                       goto done;
+               }
+
+               Debug( LDAP_DEBUG_ANY,
+                       "certificateListValidate issuer=\"%s\", thisUpdate=%s: extra cruft past end of certificateList\n",
+                       issuer_dn.bv_val, thisUpdate.bv_val, 0 );
+
+done:;
+               ber_memfree( issuer_dn.bv_val );
+
+               return rc;
+       }
+
        return LDAP_SUCCESS;
 }