As per X.690, "the end-of-contents octets shall be present if the length is
encoded as specified in 8.1.3.6, otherwise they shall not be present", i.e.
only used with indefinite length encoding. Since we do not support indefinite
length encoding, I thought it may make sense to remove some corresponding code
from the ber api.

The end-of-content type under the universal class has a special meaning; if
applications wish to make use of a similar, non-universal content value they
are free to do so without assistance from the ber api. It would appear that
ldap still wants to use the "eoc" functions, but I believe simply checking for
a ber element length of zero should suffice in these cases (i.e. aldap.c).

I think the RFC 2411 comment referenced in usr.sbin/ldapd/modify.c below should
be referring to RFC 4511, but I will send a separate diff proposal for that.

The ldapd and snmpd regression tests pass for me with these changes.

I am only looking for feedback and testing at this time. I may be wrong with
this approach, so feel free to correct me if you feel this is a misguided
change.

All such (DER like) restrictions enforced by the ber api will be clarified in
an upcoming ber.3 diff.

Regards,

Rob

Index: usr.bin/ldap/aldap.c
===================================================================
RCS file: /cvs/src/usr.bin/ldap/aldap.c,v
retrieving revision 1.4
diff -u -p -r1.4 aldap.c
--- usr.bin/ldap/aldap.c        31 Jul 2018 11:37:18 -0000      1.4
+++ usr.bin/ldap/aldap.c        12 Aug 2018 17:39:52 -0000
@@ -568,7 +568,7 @@ aldap_count_attrs(struct aldap_message *
                return (-1);
 
        for (i = 0, a = msg->body.search.attrs;
-           a != NULL && ber_get_eoc(a) != 0;
+           a != NULL && a->be_len != 0;
            i++, a = a->be_next)
                ;
 
@@ -616,7 +616,7 @@ aldap_next_attr(struct aldap_message *ms
 
        LDAP_DEBUG("attr", msg->body.search.iter);
 
-       if (ber_get_eoc(msg->body.search.iter) == 0)
+       if (msg->body.search.iter->be_len == 0)
                goto notfound;
 
        if (ber_scanf_elements(msg->body.search.iter, "{s(e)}e", &key, &a, &b)
@@ -654,7 +654,7 @@ aldap_match_attr(struct aldap_message *m
        for (a = msg->body.search.attrs;;) {
                if (a == NULL)
                        goto notfound;
-               if (ber_get_eoc(a) == 0)
+               if (a->be_len == 0)
                        goto notfound;
                if (ber_scanf_elements(a, "{s(e", &descr, &b) != 0)
                        goto fail;
Index: usr.bin/ldap/ber.c
===================================================================
RCS file: /cvs/src/usr.bin/ldap/ber.c,v
retrieving revision 1.18
diff -u -p -r1.18 ber.c
--- usr.bin/ldap/ber.c  3 Aug 2018 01:51:28 -0000       1.18
+++ usr.bin/ldap/ber.c  12 Aug 2018 17:39:52 -0000
@@ -359,28 +359,6 @@ ber_get_null(struct ber_element *elm)
        return 0;
 }
 
-struct ber_element *
-ber_add_eoc(struct ber_element *prev)
-{
-       struct ber_element *elm;
-
-       if ((elm = ber_get_element(BER_TYPE_EOC)) == NULL)
-               return NULL;
-
-       ber_link_elements(prev, elm);
-
-       return elm;
-}
-
-int
-ber_get_eoc(struct ber_element *elm)
-{
-       if (elm->be_encoding != BER_TYPE_EOC)
-               return -1;
-
-       return 0;
-}
-
 size_t
 ber_oid2ber(struct ber_oid *o, u_int8_t *buf, size_t len)
 {
@@ -629,11 +607,6 @@ ber_printf_elements(struct ber_element *
                case ')':
                        ber = sub;
                        break;
-               case '.':
-                       if ((e = ber_add_eoc(ber)) == NULL)
-                               goto fail;
-                       ber = e;
-                       break;
                default:
                        break;
                }
@@ -737,11 +710,6 @@ ber_scanf_elements(struct ber_element *b
                                goto fail;
                        ret++;
                        break;
-               case '.':
-                       if (ber->be_encoding != BER_TYPE_EOC)
-                               goto fail;
-                       ret++;
-                       break;
                case 'p':
                        pos = va_arg(ap, off_t *);
                        *pos = ber_getpos(ber);
@@ -990,7 +958,10 @@ ber_dump_element(struct ber *ber, struct
                ber_write(ber, root->be_val, root->be_len);
                break;
        case BER_TYPE_NULL:     /* no payload */
+               break;
        case BER_TYPE_EOC:
+               if (root->be_class == BER_CLASS_UNIVERSAL)
+                       return -1;
                break;
        case BER_TYPE_SEQUENCE:
        case BER_TYPE_SET:
@@ -1202,6 +1173,8 @@ ber_read_element(struct ber *ber, struct
 
        switch (elm->be_encoding) {
        case BER_TYPE_EOC:      /* End-Of-Content */
+               if (class == BER_CLASS_UNIVERSAL)
+                       return -1;
                break;
        case BER_TYPE_BOOLEAN:
        case BER_TYPE_INTEGER:
Index: usr.bin/ldap/ber.h
===================================================================
RCS file: /cvs/src/usr.bin/ldap/ber.h,v
retrieving revision 1.6
diff -u -p -r1.6 ber.h
--- usr.bin/ldap/ber.h  3 Aug 2018 01:51:28 -0000       1.6
+++ usr.bin/ldap/ber.h  12 Aug 2018 17:39:52 -0000
@@ -113,8 +113,6 @@ int                  ber_get_bitstring(struct ber_elem
                            size_t *);
 struct ber_element     *ber_add_null(struct ber_element *);
 int                     ber_get_null(struct ber_element *);
-struct ber_element     *ber_add_eoc(struct ber_element *);
-int                     ber_get_eoc(struct ber_element *);
 struct ber_element     *ber_add_oid(struct ber_element *, struct ber_oid *);
 struct ber_element     *ber_add_noid(struct ber_element *, struct ber_oid *, 
int);
 struct ber_element     *ber_add_oidstring(struct ber_element *, const char *);
cvs server: Diffing usr.sbin
cvs server: Diffing usr.sbin/ldapctl
cvs server: Diffing usr.sbin/ldapd
Index: usr.sbin/ldapd/ber.c
===================================================================
RCS file: /cvs/src/usr.sbin/ldapd/ber.c,v
retrieving revision 1.28
diff -u -p -r1.28 ber.c
--- usr.sbin/ldapd/ber.c        3 Aug 2018 01:51:28 -0000       1.28
+++ usr.sbin/ldapd/ber.c        12 Aug 2018 17:39:53 -0000
@@ -359,28 +359,6 @@ ber_get_null(struct ber_element *elm)
        return 0;
 }
 
-struct ber_element *
-ber_add_eoc(struct ber_element *prev)
-{
-       struct ber_element *elm;
-
-       if ((elm = ber_get_element(BER_TYPE_EOC)) == NULL)
-               return NULL;
-
-       ber_link_elements(prev, elm);
-
-       return elm;
-}
-
-int
-ber_get_eoc(struct ber_element *elm)
-{
-       if (elm->be_encoding != BER_TYPE_EOC)
-               return -1;
-
-       return 0;
-}
-
 size_t
 ber_oid2ber(struct ber_oid *o, u_int8_t *buf, size_t len)
 {
@@ -629,11 +607,6 @@ ber_printf_elements(struct ber_element *
                case ')':
                        ber = sub;
                        break;
-               case '.':
-                       if ((e = ber_add_eoc(ber)) == NULL)
-                               goto fail;
-                       ber = e;
-                       break;
                default:
                        break;
                }
@@ -737,11 +710,6 @@ ber_scanf_elements(struct ber_element *b
                                goto fail;
                        ret++;
                        break;
-               case '.':
-                       if (ber->be_encoding != BER_TYPE_EOC)
-                               goto fail;
-                       ret++;
-                       break;
                case 'p':
                        pos = va_arg(ap, off_t *);
                        *pos = ber_getpos(ber);
@@ -990,7 +958,10 @@ ber_dump_element(struct ber *ber, struct
                ber_write(ber, root->be_val, root->be_len);
                break;
        case BER_TYPE_NULL:     /* no payload */
+               break;
        case BER_TYPE_EOC:
+               if (root->be_class == BER_CLASS_UNIVERSAL)
+                       return -1;
                break;
        case BER_TYPE_SEQUENCE:
        case BER_TYPE_SET:
@@ -1202,6 +1173,8 @@ ber_read_element(struct ber *ber, struct
 
        switch (elm->be_encoding) {
        case BER_TYPE_EOC:      /* End-Of-Content */
+               if (class == BER_CLASS_UNIVERSAL)
+                       return -1;
                break;
        case BER_TYPE_BOOLEAN:
        case BER_TYPE_INTEGER:
Index: usr.sbin/ldapd/ber.h
===================================================================
RCS file: /cvs/src/usr.sbin/ldapd/ber.h,v
retrieving revision 1.7
diff -u -p -r1.7 ber.h
--- usr.sbin/ldapd/ber.h        3 Aug 2018 01:51:28 -0000       1.7
+++ usr.sbin/ldapd/ber.h        12 Aug 2018 17:39:53 -0000
@@ -113,8 +113,6 @@ int                  ber_get_bitstring(struct ber_elem
                            size_t *);
 struct ber_element     *ber_add_null(struct ber_element *);
 int                     ber_get_null(struct ber_element *);
-struct ber_element     *ber_add_eoc(struct ber_element *);
-int                     ber_get_eoc(struct ber_element *);
 struct ber_element     *ber_add_oid(struct ber_element *, struct ber_oid *);
 struct ber_element     *ber_add_noid(struct ber_element *, struct ber_oid *, 
int);
 struct ber_element     *ber_add_oidstring(struct ber_element *, const char *);
Index: usr.sbin/ldapd/modify.c
===================================================================
RCS file: /cvs/src/usr.sbin/ldapd/modify.c,v
retrieving revision 1.21
diff -u -p -r1.21 modify.c
--- usr.sbin/ldapd/modify.c     14 May 2018 07:53:47 -0000      1.21
+++ usr.sbin/ldapd/modify.c     12 Aug 2018 17:39:53 -0000
@@ -327,7 +327,7 @@ ldap_modify(struct request *req)
                        /*
                         * We're already in the "SET OF value
                         * AttributeValue" (see RFC2411 section
-                        * 4.1.7) have either EOC, so all values
+                        * 4.1.7) have either no content, so all values
                         * for the attribute gets deleted, or we
                         * have a (first) octetstring (there is one
                         * for each AttributeValue to be deleted)
@@ -340,8 +340,8 @@ ldap_modify(struct request *req)
                        }
                        break;
                case LDAP_MOD_REPLACE:
-                       if (vals->be_sub != NULL &&
-                           vals->be_sub->be_type != BER_TYPE_EOC) {
+                       if (vals->be_sub &&
+                           vals->be_sub->be_len != 0) {
                                if (a == NULL) {
                                        if (ldap_add_attribute(entry, attr, 
vals) != NULL)
                                                vals = NULL;
Index: usr.sbin/ldapd/search.c
===================================================================
RCS file: /cvs/src/usr.sbin/ldapd/search.c,v
retrieving revision 1.23
diff -u -p -r1.23 search.c
--- usr.sbin/ldapd/search.c     31 Jul 2018 11:01:00 -0000      1.23
+++ usr.sbin/ldapd/search.c     12 Aug 2018 17:39:54 -0000
@@ -72,7 +72,7 @@ should_include_attribute(char *adesc, st
        struct ber_element      *elm;
 
        if (search->attrlist->be_sub == NULL ||
-           search->attrlist->be_sub->be_encoding == BER_TYPE_EOC) {
+           search->attrlist->be_sub->be_len == 0) {
                /* An empty list with no attributes requests the return of
                 * all user attributes. */
                return !is_operational(adesc);
cvs server: Diffing usr.sbin/ldapd/schema
cvs server: Diffing usr.sbin/snmpctl
cvs server: Diffing usr.sbin/snmpd
Index: usr.sbin/snmpd/ber.3
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/ber.3,v
retrieving revision 1.17
diff -u -p -r1.17 ber.3
--- usr.sbin/snmpd/ber.3        31 Jul 2018 11:01:29 -0000      1.17
+++ usr.sbin/snmpd/ber.3        12 Aug 2018 17:39:54 -0000
@@ -39,8 +39,6 @@
 .Nm ber_get_bitstring ,
 .Nm ber_add_null ,
 .Nm ber_get_null ,
-.Nm ber_add_eoc ,
-.Nm ber_get_eoc ,
 .Nm ber_add_oid ,
 .Nm ber_add_noid ,
 .Nm ber_add_oidstring ,
@@ -107,10 +105,6 @@
 .Ft "int"
 .Fn "ber_get_null" "struct ber_element *root"
 .Ft "struct ber_element *"
-.Fn "ber_add_eoc" "struct ber_element *prev"
-.Ft "int"
-.Fn "ber_get_eoc" "struct ber_element *root"
-.Ft "struct ber_element *"
 .Fn "ber_add_oid" "struct ber_element *prev" "struct ber_oid *oid"
 .Ft "struct ber_element *"
 .Fn "ber_add_noid" "struct ber_element *prev" "struct ber_oid *oid" "int n"
@@ -180,8 +174,6 @@ using the
 .Fn ber_get_bitstring ,
 .Fn ber_add_null ,
 .Fn ber_get_null ,
-.Fn ber_add_eoc ,
-.Fn ber_get_eoc
 .Sh OBJECT IDS
 Object Identifiers are commonly used in ASN.1-based protocols.
 These functions provide an interface to parse OIDs.
@@ -228,7 +220,6 @@ Upon successful completion
 .Fn ber_get_nstring ,
 .Fn ber_get_bitstring ,
 .Fn ber_get_null ,
-.Fn ber_get_eoc ,
 .Fn ber_get_oid ,
 .Fn ber_string2oid
 and
Index: usr.sbin/snmpd/ber.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/ber.c,v
retrieving revision 1.47
diff -u -p -r1.47 ber.c
--- usr.sbin/snmpd/ber.c        3 Aug 2018 01:51:28 -0000       1.47
+++ usr.sbin/snmpd/ber.c        12 Aug 2018 17:39:56 -0000
@@ -359,28 +359,6 @@ ber_get_null(struct ber_element *elm)
        return 0;
 }
 
-struct ber_element *
-ber_add_eoc(struct ber_element *prev)
-{
-       struct ber_element *elm;
-
-       if ((elm = ber_get_element(BER_TYPE_EOC)) == NULL)
-               return NULL;
-
-       ber_link_elements(prev, elm);
-
-       return elm;
-}
-
-int
-ber_get_eoc(struct ber_element *elm)
-{
-       if (elm->be_encoding != BER_TYPE_EOC)
-               return -1;
-
-       return 0;
-}
-
 size_t
 ber_oid2ber(struct ber_oid *o, u_int8_t *buf, size_t len)
 {
@@ -629,11 +607,6 @@ ber_printf_elements(struct ber_element *
                case ')':
                        ber = sub;
                        break;
-               case '.':
-                       if ((e = ber_add_eoc(ber)) == NULL)
-                               goto fail;
-                       ber = e;
-                       break;
                default:
                        break;
                }
@@ -737,11 +710,6 @@ ber_scanf_elements(struct ber_element *b
                                goto fail;
                        ret++;
                        break;
-               case '.':
-                       if (ber->be_encoding != BER_TYPE_EOC)
-                               goto fail;
-                       ret++;
-                       break;
                case 'p':
                        pos = va_arg(ap, off_t *);
                        *pos = ber_getpos(ber);
@@ -990,7 +958,10 @@ ber_dump_element(struct ber *ber, struct
                ber_write(ber, root->be_val, root->be_len);
                break;
        case BER_TYPE_NULL:     /* no payload */
+               break;
        case BER_TYPE_EOC:
+               if (root->be_class == BER_CLASS_UNIVERSAL)
+                       return -1;
                break;
        case BER_TYPE_SEQUENCE:
        case BER_TYPE_SET:
@@ -1202,6 +1173,8 @@ ber_read_element(struct ber *ber, struct
 
        switch (elm->be_encoding) {
        case BER_TYPE_EOC:      /* End-Of-Content */
+               if (class == BER_CLASS_UNIVERSAL)
+                       return -1;
                break;
        case BER_TYPE_BOOLEAN:
        case BER_TYPE_INTEGER:
Index: usr.sbin/snmpd/ber.h
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/ber.h,v
retrieving revision 1.13
diff -u -p -r1.13 ber.h
--- usr.sbin/snmpd/ber.h        3 Aug 2018 01:51:28 -0000       1.13
+++ usr.sbin/snmpd/ber.h        12 Aug 2018 17:39:56 -0000
@@ -113,8 +113,6 @@ int                  ber_get_bitstring(struct ber_elem
                            size_t *);
 struct ber_element     *ber_add_null(struct ber_element *);
 int                     ber_get_null(struct ber_element *);
-struct ber_element     *ber_add_eoc(struct ber_element *);
-int                     ber_get_eoc(struct ber_element *);
 struct ber_element     *ber_add_oid(struct ber_element *, struct ber_oid *);
 struct ber_element     *ber_add_noid(struct ber_element *, struct ber_oid *, 
int);
 struct ber_element     *ber_add_oidstring(struct ber_element *, const char *);
cvs server: Diffing usr.sbin/ypldap
Index: usr.sbin/ypldap/aldap.c
===================================================================
RCS file: /cvs/src/usr.sbin/ypldap/aldap.c,v
retrieving revision 1.42
diff -u -p -r1.42 aldap.c
--- usr.sbin/ypldap/aldap.c     31 Jul 2018 11:37:18 -0000      1.42
+++ usr.sbin/ypldap/aldap.c     12 Aug 2018 17:40:03 -0000
@@ -568,7 +568,7 @@ aldap_count_attrs(struct aldap_message *
                return (-1);
 
        for (i = 0, a = msg->body.search.attrs;
-           a != NULL && ber_get_eoc(a) != 0;
+           a != NULL && a->be_len != 0;
            i++, a = a->be_next)
                ;
 
@@ -616,7 +616,7 @@ aldap_next_attr(struct aldap_message *ms
 
        LDAP_DEBUG("attr", msg->body.search.iter);
 
-       if (ber_get_eoc(msg->body.search.iter) == 0)
+       if (msg->body.search.iter->be_len == 0)
                goto notfound;
 
        if (ber_scanf_elements(msg->body.search.iter, "{s(e)}e", &key, &a, &b)
@@ -654,7 +654,7 @@ aldap_match_attr(struct aldap_message *m
        for (a = msg->body.search.attrs;;) {
                if (a == NULL)
                        goto notfound;
-               if (ber_get_eoc(a) == 0)
+               if (a->be_len == 0)
                        goto notfound;
                if (ber_scanf_elements(a, "{s(e", &descr, &b) != 0)
                        goto fail;
Index: usr.sbin/ypldap/ber.c
===================================================================
RCS file: /cvs/src/usr.sbin/ypldap/ber.c,v
retrieving revision 1.30
diff -u -p -r1.30 ber.c
--- usr.sbin/ypldap/ber.c       3 Aug 2018 01:51:28 -0000       1.30
+++ usr.sbin/ypldap/ber.c       12 Aug 2018 17:40:03 -0000
@@ -359,28 +359,6 @@ ber_get_null(struct ber_element *elm)
        return 0;
 }
 
-struct ber_element *
-ber_add_eoc(struct ber_element *prev)
-{
-       struct ber_element *elm;
-
-       if ((elm = ber_get_element(BER_TYPE_EOC)) == NULL)
-               return NULL;
-
-       ber_link_elements(prev, elm);
-
-       return elm;
-}
-
-int
-ber_get_eoc(struct ber_element *elm)
-{
-       if (elm->be_encoding != BER_TYPE_EOC)
-               return -1;
-
-       return 0;
-}
-
 size_t
 ber_oid2ber(struct ber_oid *o, u_int8_t *buf, size_t len)
 {
@@ -629,11 +607,6 @@ ber_printf_elements(struct ber_element *
                case ')':
                        ber = sub;
                        break;
-               case '.':
-                       if ((e = ber_add_eoc(ber)) == NULL)
-                               goto fail;
-                       ber = e;
-                       break;
                default:
                        break;
                }
@@ -737,11 +710,6 @@ ber_scanf_elements(struct ber_element *b
                                goto fail;
                        ret++;
                        break;
-               case '.':
-                       if (ber->be_encoding != BER_TYPE_EOC)
-                               goto fail;
-                       ret++;
-                       break;
                case 'p':
                        pos = va_arg(ap, off_t *);
                        *pos = ber_getpos(ber);
@@ -990,7 +958,10 @@ ber_dump_element(struct ber *ber, struct
                ber_write(ber, root->be_val, root->be_len);
                break;
        case BER_TYPE_NULL:     /* no payload */
+               break;
        case BER_TYPE_EOC:
+               if (root->be_class == BER_CLASS_UNIVERSAL)
+                       return -1;
                break;
        case BER_TYPE_SEQUENCE:
        case BER_TYPE_SET:
@@ -1202,6 +1173,8 @@ ber_read_element(struct ber *ber, struct
 
        switch (elm->be_encoding) {
        case BER_TYPE_EOC:      /* End-Of-Content */
+               if (class == BER_CLASS_UNIVERSAL)
+                       return -1;
                break;
        case BER_TYPE_BOOLEAN:
        case BER_TYPE_INTEGER:
Index: usr.sbin/ypldap/ber.h
===================================================================
RCS file: /cvs/src/usr.sbin/ypldap/ber.h,v
retrieving revision 1.8
diff -u -p -r1.8 ber.h
--- usr.sbin/ypldap/ber.h       3 Aug 2018 01:51:28 -0000       1.8
+++ usr.sbin/ypldap/ber.h       12 Aug 2018 17:40:05 -0000
@@ -113,8 +113,6 @@ int                  ber_get_bitstring(struct ber_elem
                            size_t *);
 struct ber_element     *ber_add_null(struct ber_element *);
 int                     ber_get_null(struct ber_element *);
-struct ber_element     *ber_add_eoc(struct ber_element *);
-int                     ber_get_eoc(struct ber_element *);
 struct ber_element     *ber_add_oid(struct ber_element *, struct ber_oid *);
 struct ber_element     *ber_add_noid(struct ber_element *, struct ber_oid *, 
int);
 struct ber_element     *ber_add_oidstring(struct ber_element *, const char *);

Reply via email to