From 6a56c8b4bbb5f0ca576797a892ae7e1a9c940479 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 23 Aug 2000 01:15:32 +0000 Subject: [PATCH] Import latest changes from devel include substrings indexing support --- doc/devel/asn-layman.txt | 1855 --------------------- doc/devel/guidelines | 110 -- libraries/liblutil/signal.c | 1 + servers/slapd/back-ldbm/attr.c | 8 +- servers/slapd/back-ldbm/back-ldbm.h | 2 +- servers/slapd/back-ldbm/filterindex.c | 172 +- servers/slapd/back-ldbm/index.c | 19 +- servers/slapd/back-ldbm/proto-back-ldbm.h | 4 +- servers/slapd/index.c | 2 +- servers/slapd/proto-slap.h | 2 +- servers/slapd/schema/core.schema | 2 +- servers/slapd/schema/openldap.schema | 8 +- servers/slapd/schema_init.c | 350 +++- servers/slapd/slap.h | 22 +- tests/data/slapd.conf | 3 +- 15 files changed, 480 insertions(+), 2080 deletions(-) delete mode 100644 doc/devel/asn-layman.txt delete mode 100644 doc/devel/guidelines diff --git a/doc/devel/asn-layman.txt b/doc/devel/asn-layman.txt deleted file mode 100644 index d4fbe64be9..0000000000 --- a/doc/devel/asn-layman.txt +++ /dev/null @@ -1,1855 +0,0 @@ -A Layman's Guide to a Subset of ASN.1, BER, and DER - -An RSA Laboratories Technical Note -Burton S. Kaliski Jr. -Revised November 1, 1993 - - -Supersedes June 3, 1991 version, which was also published as -NIST/OSI Implementors' Workshop document SEC-SIG-91-17. -PKCS documents are available by electronic mail to -. - -Copyright (C) 1991-1993 RSA Laboratories, a division of RSA -Data Security, Inc. License to copy this document is granted -provided that it is identified as "RSA Data Security, Inc. -Public-Key Cryptography Standards (PKCS)" in all material -mentioning or referencing this document. -003-903015-110-000-000 - - -Abstract. This note gives a layman's introduction to a -subset of OSI's Abstract Syntax Notation One (ASN.1), Basic -Encoding Rules (BER), and Distinguished Encoding Rules -(DER). The particular purpose of this note is to provide -background material sufficient for understanding and -implementing the PKCS family of standards. - - -1. Introduction - -It is a generally accepted design principle that abstraction -is a key to managing software development. With abstraction, -a designer can specify a part of a system without concern -for how the part is actually implemented or represented. -Such a practice leaves the implementation open; it -simplifies the specification; and it makes it possible to -state "axioms" about the part that can be proved when the -part is implemented, and assumed when the part is employed -in another, higher-level part. Abstraction is the hallmark -of most modern software specifications. - -One of the most complex systems today, and one that also -involves a great deal of abstraction, is Open Systems -Interconnection (OSI, described in X.200). OSI is an -internationally standardized architecture that governs the -interconnection of computers from the physical layer up to -the user application layer. Objects at higher layers are -defined abstractly and intended to be implemented with -objects at lower layers. For instance, a service at one -layer may require transfer of certain abstract objects -between computers; a lower layer may provide transfer -services for strings of ones and zeroes, using encoding -rules to transform the abstract objects into such strings. -OSI is called an open system because it supports many -different implementations of the services at each layer. - -OSI's method of specifying abstract objects is called ASN.1 -(Abstract Syntax Notation One, defined in X.208), and one -set of rules for representing such objects as strings of -ones and zeros is called the BER (Basic Encoding Rules, -defined in X.209). ASN.1 is a flexible notation that allows -one to define a variety data types, from simple types such -as integers and bit strings to structured types such as sets -and sequences, as well as complex types defined in terms of -others. BER describes how to represent or encode values of -each ASN.1 type as a string of eight-bit octets. There is -generally more than one way to BER-encode a given value. -Another set of rules, called the Distinguished Encoding -Rules (DER), which is a subset of BER, gives a unique -encoding to each ASN.1 value. - -The purpose of this note is to describe a subset of ASN.1, -BER and DER sufficient to understand and implement one OSI- -based application, RSA Data Security, Inc.'s Public-Key -Cryptography Standards. The features described include an -overview of ASN.1, BER, and DER and an abridged list of -ASN.1 types and their BER and DER encodings. Sections 2-4 -give an overview of ASN.1, BER, and DER, in that order. -Section 5 lists some ASN.1 types, giving their notation, -specific encoding rules, examples, and comments about their -application to PKCS. Section 6 concludes with an example, -X.500 distinguished names. - -Advanced features of ASN.1, such as macros, are not -described in this note, as they are not needed to implement -PKCS. For information on the other features, and for more -detail generally, the reader is referred to CCITT -Recommendations X.208 and X.209, which define ASN.1 and BER. - -Terminology and notation. In this note, an octet is an eight- -bit unsigned integer. Bit 8 of the octet is the most -significant and bit 1 is the least significant. - -The following meta-syntax is used for in describing ASN.1 -notation: - - BIT monospace denotes literal characters in the type - and value notation; in examples, it generally - denotes an octet value in hexadecimal - - n1 bold italics denotes a variable - - [] bold square brackets indicate that a term is - optional - - {} bold braces group related terms - - | bold vertical bar delimits alternatives with a - group - - ... bold ellipsis indicates repeated occurrences - - = bold equals sign expresses terms as subterms - - -2. Abstract Syntax Notation One - -Abstract Syntax Notation One, abbreviated ASN.1, is a -notation for describing abstract types and values. - -In ASN.1, a type is a set of values. For some types, there -are a finite number of values, and for other types there are -an infinite number. A value of a given ASN.1 type is an -element of the type's set. ASN.1 has four kinds of type: -simple types, which are "atomic" and have no components; -structured types, which have components; tagged types, which -are derived from other types; and other types, which include -the CHOICE type and the ANY type. Types and values can be -given names with the ASN.1 assignment operator (::=) , and -those names can be used in defining other types and values. - -Every ASN.1 type other than CHOICE and ANY has a tag, which -consists of a class and a nonnegative tag number. ASN.1 -types are abstractly the same if and only if their tag -numbers are the same. In other words, the name of an ASN.1 -type does not affect its abstract meaning, only the tag -does. There are four classes of tag: - - Universal, for types whose meaning is the same in all - applications; these types are only defined in - X.208. - - Application, for types whose meaning is specific to an - application, such as X.500 directory services; - types in two different applications may have the - same application-specific tag and different - meanings. - - Private, for types whose meaning is specific to a given - enterprise. - - Context-specific, for types whose meaning is specific - to a given structured type; context-specific tags - are used to distinguish between component types - with the same underlying tag within the context of - a given structured type, and component types in - two different structured types may have the same - tag and different meanings. - -The types with universal tags are defined in X.208, which -also gives the types' universal tag numbers. Types with -other tags are defined in many places, and are always -obtained by implicit or explicit tagging (see Section 2.3). -Table 1 lists some ASN.1 types and their universal-class -tags. - - Type Tag number Tag number - (decimal) (hexadecimal) - INTEGER 2 02 - BIT STRING 3 03 - OCTET STRING 4 04 - NULL 5 05 - OBJECT IDENTIFIER 6 06 - SEQUENCE and SEQUENCE OF 16 10 - SET and SET OF 17 11 - PrintableString 19 13 - T61String 20 14 - IA5String 22 16 - UTCTime 23 17 - - Table 1. Some types and their universal-class tags. - -ASN.1 types and values are expressed in a flexible, -programming-language-like notation, with the following -special rules: - - o Layout is not significant; multiple spaces and - line breaks can be considered as a single space. - - o Comments are delimited by pairs of hyphens (--), - or a pair of hyphens and a line break. - - o Identifiers (names of values and fields) and type - references (names of types) consist of upper- and - lower-case letters, digits, hyphens, and spaces; - identifiers begin with lower-case letters; type - references begin with upper-case letters. - -The following four subsections give an overview of simple -types, structured types, implicitly and explicitly tagged -types, and other types. Section 5 describes specific types -in more detail. - - -2.1 Simple types - -Simple types are those not consisting of components; they -are the "atomic" types. ASN.1 defines several; the types -that are relevant to the PKCS standards are the following: - - BIT STRING, an arbitrary string of bits (ones and - zeroes). - - IA5String, an arbitrary string of IA5 (ASCII) - characters. - - INTEGER, an arbitrary integer. - - NULL, a null value. - - OBJECT IDENTIFIER, an object identifier, which is a - sequence of integer components that identify an - object such as an algorithm or attribute type. - - OCTET STRING, an arbitrary string of octets (eight-bit - values). - - PrintableString, an arbitrary string of printable - characters. - - T61String, an arbitrary string of T.61 (eight-bit) - characters. - - UTCTime, a "coordinated universal time" or Greenwich - Mean Time (GMT) value. - -Simple types fall into two categories: string types and non- -string types. BIT STRING, IA5String, OCTET STRING, -PrintableString, T61String, and UTCTime are string types. - -String types can be viewed, for the purposes of encoding, as -consisting of components, where the components are -substrings. This view allows one to encode a value whose -length is not known in advance (e.g., an octet string value -input from a file stream) with a constructed, indefinite- -length encoding (see Section 3). - -The string types can be given size constraints limiting the -length of values. - - -2.2 Structured types - -Structured types are those consisting of components. ASN.1 -defines four, all of which are relevant to the PKCS -standards: - - SEQUENCE, an ordered collection of one or more types. - - SEQUENCE OF, an ordered collection of zero or more - occurrences of a given type. - - SET, an unordered collection of one or more types. - - SET OF, an unordered collection of zero or more - occurrences of a given type. - -The structured types can have optional components, possibly -with default values. - - -2.3 Implicitly and explicitly tagged types - -Tagging is useful to distinguish types within an -application; it is also commonly used to distinguish -component types within a structured type. For instance, -optional components of a SET or SEQUENCE type are typically -given distinct context-specific tags to avoid ambiguity. - -There are two ways to tag a type: implicitly and explicitly. - -Implicitly tagged types are derived from other types by -changing the tag of the underlying type. Implicit tagging is -denoted by the ASN.1 keywords [class number] IMPLICIT (see -Section 5.1). - -Explicitly tagged types are derived from other types by -adding an outer tag to the underlying type. In effect, -explicitly tagged types are structured types consisting of -one component, the underlying type. Explicit tagging is -denoted by the ASN.1 keywords [class number] EXPLICIT (see -Section 5.2). - -The keyword [class number] alone is the same as explicit -tagging, except when the "module" in which the ASN.1 type is -defined has implicit tagging by default. ("Modules" are -among the advanced features not described in this note.) - -For purposes of encoding, an implicitly tagged type is -considered the same as the underlying type, except that the -tag is different. An explicitly tagged type is considered -like a structured type with one component, the underlying -type. Implicit tags result in shorter encodings, but -explicit tags may be necessary to avoid ambiguity if the tag -of the underlying type is indeterminate (e.g., the -underlying type is CHOICE or ANY). - - -2.4 Other types - -Other types in ASN.1 include the CHOICE and ANY types. The -CHOICE type denotes a union of one or more alternatives; the -ANY type denotes an arbitrary value of an arbitrary type, -where the arbitrary type is possibly defined in the -registration of an object identifier or integer value. - - -3. Basic Encoding Rules - -The Basic Encoding Rules for ASN.1, abbreviated BER, give -one or more ways to represent any ASN.1 value as an octet -string. (There are certainly other ways to represent ASN.1 -values, but BER is the standard for interchanging such -values in OSI.) - -There are three methods to encode an ASN.1 value under BER, -the choice of which depends on the type of value and whether -the length of the value is known. The three methods are -primitive, definite-length encoding; constructed, definite- -length encoding; and constructed, indefinite-length -encoding. Simple non-string types employ the primitive, -definite-length method; structured types employ either of -the constructed methods; and simple string types employ any -of the methods, depending on whether the length of the value -is known. Types derived by implicit tagging employ the -method of the underlying type and types derived by explicit -tagging employ the constructed methods. - -In each method, the BER encoding has three or four parts: - - Identifier octets. These identify the class and tag - number of the ASN.1 value, and indicate whether - the method is primitive or constructed. - - Length octets. For the definite-length methods, these - give the number of contents octets. For the - constructed, indefinite-length method, these - indicate that the length is indefinite. - - Contents octets. For the primitive, definite-length - method, these give a concrete representation of - the value. For the constructed methods, these - give the concatenation of the BER encodings of the - components of the value. - - End-of-contents octets. For the constructed, indefinite- - length method, these denote the end of the - contents. For the other methods, these are absent. - -The three methods of encoding are described in the following -sections. - - -3.1 Primitive, definite-length method - -This method applies to simple types and types derived from -simple types by implicit tagging. It requires that the -length of the value be known in advance. The parts of the -BER encoding are as follows: - -Identifier octets. There are two forms: low tag number (for -tag numbers between 0 and 30) and high tag number (for tag -numbers 31 and greater). - - Low-tag-number form. One octet. Bits 8 and 7 specify - the class (see Table 2), bit 6 has value "0," - indicating that the encoding is primitive, and - bits 5-1 give the tag number. - - Class Bit Bit - 8 7 - universal 0 0 - application 0 1 - context-specific 1 0 - private 1 1 - - Table 2. Class encoding in identifier octets. - - High-tag-number form. Two or more octets. First octet - is as in low-tag-number form, except that bits 5-1 - all have value "1." Second and following octets - give the tag number, base 128, most significant - digit first, with as few digits as possible, and - with the bit 8 of each octet except the last set - to "1." - -Length octets. There are two forms: short (for lengths -between 0 and 127), and long definite (for lengths between 0 -and 21008-1). - - Short form. One octet. Bit 8 has value "0" and bits 7-1 - give the length. - - Long form. Two to 127 octets. Bit 8 of first octet has - value "1" and bits 7-1 give the number of - additional length octets. Second and following - octets give the length, base 256, most significant - digit first. - -Contents octets. These give a concrete representation of the -value (or the value of the underlying type, if the type is -derived by implicit tagging). Details for particular types -are given in Section 5. - - -3.2 Constructed, definite-length method - -This method applies to simple string types, structured -types, types derived simple string types and structured -types by implicit tagging, and types derived from anything -by explicit tagging. It requires that the length of the -value be known in advance. The parts of the BER encoding are -as follows: - -Identifier octets. As described in Section 3.1, except that -bit 6 has value "1," indicating that the encoding is -constructed. - -Length octets. As described in Section 3.1. - -Contents octets. The concatenation of the BER encodings of -the components of the value: - - o For simple string types and types derived from - them by implicit tagging, the concatenation of the - BER encodings of consecutive substrings of the - value (underlying value for implicit tagging). - - o For structured types and types derived from them - by implicit tagging, the concatenation of the BER - encodings of components of the value (underlying - value for implicit tagging). - - o For types derived from anything by explicit - tagging, the BER encoding of the underlying value. - -Details for particular types are given in Section 5. - - -3.3 Constructed, indefinite-length method - -This method applies to simple string types, structured -types, types derived simple string types and structured -types by implicit tagging, and types derived from anything -by explicit tagging. It does not require that the length of -the value be known in advance. The parts of the BER encoding -are as follows: - -Identifier octets. As described in Section 3.2. - -Length octets. One octet, 80. - -Contents octets. As described in Section 3.2. - -End-of-contents octets. Two octets, 00 00. - -Since the end-of-contents octets appear where an ordinary -BER encoding might be expected (e.g., in the contents octets -of a sequence value), the 00 and 00 appear as identifier and -length octets, respectively. Thus the end-of-contents octets -is really the primitive, definite-length encoding of a value -with universal class, tag number 0, and length 0. - - -4. Distinguished Encoding Rules - -The Distinguished Encoding Rules for ASN.1, abbreviated DER, -are a subset of BER, and give exactly one way to represent -any ASN.1 value as an octet string. DER is intended for -applications in which a unique octet string encoding is -needed, as is the case when a digital signature is computed -on an ASN.1 value. DER is defined in Section 8.7 of X.509. - -DER adds the following restrictions to the rules given in -Section 3: - - 1. When the length is between 0 and 127, the short - form of length must be used - - 2. When the length is 128 or greater, the long form - of length must be used, and the length must be - encoded in the minimum number of octets. - - 3. For simple string types and implicitly tagged - types derived from simple string types, the - primitive, definite-length method must be - employed. - - 4. For structured types, implicitly tagged types - derived from structured types, and explicitly - tagged types derived from anything, the - constructed, definite-length method must be - employed. - -Other restrictions are defined for particular types (such as -BIT STRING, SEQUENCE, SET, and SET OF), and can be found in -Section 5. - - -5. Notation and encodings for some types - -This section gives the notation for some ASN.1 types and -describes how to encode values of those types under both BER -and DER. - -The types described are those presented in Section 2. They -are listed alphabetically here. - -Each description includes ASN.1 notation, BER encoding, and -DER encoding. The focus of the encodings is primarily on the -contents octets; the tag and length octets follow Sections 3 -and 4. The descriptions also explain where each type is used -in PKCS and related standards. ASN.1 notation is generally -only for types, although for the type OBJECT IDENTIFIER, -value notation is given as well. - - -5.1 Implicitly tagged types - -An implicitly tagged type is a type derived from another -type by changing the tag of the underlying type. - -Implicit tagging is used for optional SEQUENCE components -with underlying type other than ANY throughout PKCS, and for -the extendedCertificate alternative of PKCS #7's -ExtendedCertificateOrCertificate type. - -ASN.1 notation: - -[[class] number] IMPLICIT Type - -class = UNIVERSAL | APPLICATION | PRIVATE - -where Type is a type, class is an optional class name, and -number is the tag number within the class, a nonnegative -integer. - -In ASN.1 "modules" whose default tagging method is implicit -tagging, the notation [[class] number] Type is also -acceptable, and the keyword IMPLICIT is implied. (See -Section 2.3.) For definitions stated outside a module, the -explicit inclusion of the keyword IMPLICIT is preferable to -prevent ambiguity. - -If the class name is absent, then the tag is context- -specific. Context-specific tags can only appear in a -component of a structured or CHOICE type. - -Example: PKCS #8's PrivateKeyInfo type has an optional -attributes component with an implicit, context-specific tag: - -PrivateKeyInfo ::= SEQUENCE { - version Version, - privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - privateKey PrivateKey, - attributes [0] IMPLICIT Attributes OPTIONAL } - -Here the underlying type is Attributes, the class is absent -(i.e., context-specific), and the tag number within the -class is 0. - -BER encoding. Primitive or constructed, depending on the -underlying type. Contents octets are as for the BER encoding -of the underlying value. - -Example: The BER encoding of the attributes component of a -PrivateKeyInfo value is as follows: - - o the identifier octets are 80 if the underlying - Attributes value has a primitive BER encoding and - a0 if the underlying Attributes value has a - constructed BER encoding - - o the length and contents octets are the same as the - length and contents octets of the BER encoding of - the underlying Attributes value - -DER encoding. Primitive or constructed, depending on the -underlying type. Contents octets are as for the DER encoding -of the underlying value. - - -5.2 Explicitly tagged types - -Explicit tagging denotes a type derived from another type by -adding an outer tag to the underlying type. - -Explicit tagging is used for optional SEQUENCE components -with underlying type ANY throughout PKCS, and for the -version component of X.509's Certificate type. - -ASN.1 notation: - -[[class] number] EXPLICIT Type - -class = UNIVERSAL | APPLICATION | PRIVATE - -where Type is a type, class is an optional class name, and -number is the tag number within the class, a nonnegative -integer. - -If the class name is absent, then the tag is context- -specific. Context-specific tags can only appear in a -component of a SEQUENCE, SET or CHOICE type. - -In ASN.1 "modules" whose default tagging method is explicit -tagging, the notation [[class] number] Type is also -acceptable, and the keyword EXPLICIT is implied. (See -Section 2.3.) For definitions stated outside a module, the -explicit inclusion of the keyword EXPLICIT is preferable to -prevent ambiguity. - -Example 1: PKCS #7's ContentInfo type has an optional -content component with an explicit, context-specific tag: - -ContentInfo ::= SEQUENCE { - contentType ContentType, - content - [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } - -Here the underlying type is ANY DEFINED BY contentType, the -class is absent (i.e., context-specific), and the tag number -within the class is 0. - -Example 2: X.509's Certificate type has a version component -with an explicit, context-specific tag, where the EXPLICIT -keyword is omitted: - -Certificate ::= ... - version [0] Version DEFAULT v1988, -... - -The tag is explicit because the default tagging method for -the ASN.1 "module" in X.509 that defines the Certificate -type is explicit tagging. - -BER encoding. Constructed. Contents octets are the BER -encoding of the underlying value. - -Example: the BER encoding of the content component of a -ContentInfo value is as follows: - - o identifier octets are a0 - - o length octets represent the length of the BER - encoding of the underlying ANY DEFINED BY - contentType value - - o contents octets are the BER encoding of the - underlying ANY DEFINED BY contentType value - -DER encoding. Constructed. Contents octets are the DER -encoding of the underlying value. - - -5.3 ANY - -The ANY type denotes an arbitrary value of an arbitrary -type, where the arbitrary type is possibly defined in the -registration of an object identifier or associated with an -integer index. - -The ANY type is used for content of a particular content -type in PKCS #7's ContentInfo type, for parameters of a -particular algorithm in X.509's AlgorithmIdentifier type, -and for attribute values in X.501's Attribute and -AttributeValueAssertion types. The Attribute type is used by -PKCS #6, #7, #8, #9 and #10, and the AttributeValueAssertion -type is used in X.501 distinguished names. - -ASN.1 notation: - -ANY [DEFINED BY identifier] - -where identifier is an optional identifier. - -In the ANY form, the actual type is indeterminate. - -The ANY DEFINED BY identifier form can only appear in a -component of a SEQUENCE or SET type for which identifier -identifies some other component, and that other component -has type INTEGER or OBJECT IDENTIFIER (or a type derived -from either of those by tagging). In that form, the actual -type is determined by the value of the other component, -either in the registration of the object identifier value, -or in a table of integer values. - -Example: X.509's AlgorithmIdentifier type has a component of -type ANY: - -AlgorithmIdentifier ::= SEQUENCE { - algorithm OBJECT IDENTIFIER, - parameters ANY DEFINED BY algorithm OPTIONAL } - -Here the actual type of the parameter component depends on -the value of the algorithm component. The actual type would -be defined in the registration of object identifier values -for the algorithm component. - -BER encoding. Same as the BER encoding of the actual value. - -Example: The BER encoding of the value of the parameter -component is the BER encoding of the value of the actual -type as defined in the registration of object identifier -values for the algorithm component. - -DER encoding. Same as the DER encoding of the actual value. - - -5.4 BIT STRING - -The BIT STRING type denotes an arbitrary string of bits -(ones and zeroes). A BIT STRING value can have any length, -including zero. This type is a string type. - -The BIT STRING type is used for digital signatures on -extended certificates in PKCS #6's ExtendedCertificate type, -for digital signatures on certificates in X.509's -Certificate type, and for public keys in certificates in -X.509's SubjectPublicKeyInfo type. - -ASN.1 notation: - -BIT STRING - -Example: X.509's SubjectPublicKeyInfo type has a component -of type BIT STRING: - -SubjectPublicKeyInfo ::= SEQUENCE { - algorithm AlgorithmIdentifier, - publicKey BIT STRING } - -BER encoding. Primitive or constructed. In a primitive -encoding, the first contents octet gives the number of bits -by which the length of the bit string is less than the next -multiple of eight (this is called the "number of unused -bits"). The second and following contents octets give the -value of the bit string, converted to an octet string. The -conversion process is as follows: - - 1. The bit string is padded after the last bit with - zero to seven bits of any value to make the length - of the bit string a multiple of eight. If the - length of the bit string is a multiple of eight - already, no padding is done. - - 2. The padded bit string is divided into octets. The - first eight bits of the padded bit string become - the first octet, bit 8 to bit 1, and so on through - the last eight bits of the padded bit string. - -In a constructed encoding, the contents octets give the -concatenation of the BER encodings of consecutive substrings -of the bit string, where each substring except the last has -a length that is a multiple of eight bits. - -Example: The BER encoding of the BIT STRING value -"011011100101110111" can be any of the following, among -others, depending on the choice of padding bits, the form of -length octets, and whether the encoding is primitive or -constructed: - -03 04 06 6e 5d c0 DER encoding - -03 04 06 6e 5d e0 padded with "100000" - -03 81 04 06 6e 5d c0 long form of length octets - -23 09 constructed encoding: "0110111001011101" + "11" - 03 03 00 6e 5d - 03 02 06 c0 - -DER encoding. Primitive. The contents octects are as for a -primitive BER encoding, except that the bit string is padded -with zero-valued bits. - -Example: The DER encoding of the BIT STRING value -"011011100101110111" is - -03 04 06 6e 5d c0 - - -5.5 CHOICE - -The CHOICE type denotes a union of one or more alternatives. - -The CHOICE type is used to represent the union of an -extended certificate and an X.509 certificate in PKCS #7's -ExtendedCertificateOrCertificate type. - -ASN.1 notation: - -CHOICE { - [identifier1] Type1, - ..., - [identifiern] Typen } - -where identifier1 , ..., identifiern are optional, distinct -identifiers for the alternatives, and Type1, ..., Typen are -the types of the alternatives. The identifiers are primarily -for documentation; they do not affect values of the type or -their encodings in any way. - -The types must have distinct tags. This requirement is -typically satisfied with explicit or implicit tagging on -some of the alternatives. - -Example: PKCS #7's ExtendedCertificateOrCertificate type is -a CHOICE type: - -ExtendedCertificateOrCertificate ::= CHOICE { - certificate Certificate, -- X.509 - extendedCertificate [0] IMPLICIT ExtendedCertificate -} - -Here the identifiers for the alternatives are certificate -and extendedCertificate, and the types of the alternatives -are Certificate and [0] IMPLICIT ExtendedCertificate. - -BER encoding. Same as the BER encoding of the chosen -alternative. The fact that the alternatives have distinct -tags makes it possible to distinguish between their BER -encodings. - -Example: The identifier octets for the BER encoding are 30 -if the chosen alternative is certificate, and a0 if the -chosen alternative is extendedCertificate. - -DER encoding. Same as the DER encoding of the chosen -alternative. - - -5.6 IA5String - -The IA5String type denotes an arbtrary string of IA5 -characters. IA5 stands for International Alphabet 5, which -is the same as ASCII. The character set includes non- -printing control characters. An IA5String value can have any -length, including zero. This type is a string type. - -The IA5String type is used in PKCS #9's electronic-mail -address, unstructured-name, and unstructured-address -attributes. - -ASN.1 notation: - -IA5String - -BER encoding. Primitive or constructed. In a primitive -encoding, the contents octets give the characters in the IA5 -string, encoded in ASCII. In a constructed encoding, the -contents octets give the concatenation of the BER encodings -of consecutive substrings of the IA5 string. - -Example: The BER encoding of the IA5String value -"test1@rsa.com" can be any of the following, among others, -depending on the form of length octets and whether the -encoding is primitive or constructed: - -16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d DER encoding - -16 81 0d long form of length octets - 74 65 73 74 31 40 72 73 61 2e 63 6f 6d - -36 13 constructed encoding: "test1" + "@" + "rsa.com" - 16 05 74 65 73 74 31 - 16 01 40 - 16 07 72 73 61 2e 63 6f 6d - -DER encoding. Primitive. Contents octets are as for a -primitive BER encoding. - -Example: The DER encoding of the IA5String value -"test1@rsa.com" is - -16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d - - -5.7 INTEGER - -The INTEGER type denotes an arbitrary integer. INTEGER -values can be positive, negative, or zero, and can have any -magnitude. - -The INTEGER type is used for version numbers throughout -PKCS, cryptographic values such as modulus, exponent, and -primes in PKCS #1's RSAPublicKey and RSAPrivateKey types and -PKCS #3's DHParameter type, a message-digest iteration count -in PKCS #5's PBEParameter type, and version numbers and -serial numbers in X.509's Certificate type. - -ASN.1 notation: - -INTEGER [{ identifier1(value1) ... identifiern(valuen) }] - -where identifier1, ..., identifiern are optional distinct -identifiers and value1, ..., valuen are optional integer -values. The identifiers, when present, are associated with -values of the type. - -Example: X.509's Version type is an INTEGER type with -identified values: - -Version ::= INTEGER { v1988(0) } - -The identifier v1988 is associated with the value 0. X.509's -Certificate type uses the identifier v1988 to give a default -value of 0 for the version component: - -Certificate ::= ... - version Version DEFAULT v1988, -... - -BER encoding. Primitive. Contents octets give the value of -the integer, base 256, in two's complement form, most -significant digit first, with the minimum number of octets. -The value 0 is encoded as a single 00 octet. - -Some example BER encodings (which also happen to be DER -encodings) are given in Table 3. - - Integer BER encoding - value - 0 02 01 00 - 127 02 01 7F - 128 02 02 00 80 - 256 02 02 01 00 - -128 02 01 80 - -129 02 02 FF 7F - - Table 3. Example BER encodings of INTEGER values. - -DER encoding. Primitive. Contents octets are as for a -primitive BER encoding. - - -5.8 NULL - -The NULL type denotes a null value. - -The NULL type is used for algorithm parameters in several -places in PKCS. - -ASN.1 notation: - -NULL - -BER encoding. Primitive. Contents octets are empty. - -Example: The BER encoding of a NULL value can be either of -the following, as well as others, depending on the form of -the length octets: - -05 00 - -05 81 00 - -DER encoding. Primitive. Contents octets are empty; the DER -encoding of a NULL value is always 05 00. - - -5.9 OBJECT IDENTIFIER - -The OBJECT IDENTIFIER type denotes an object identifier, a -sequence of integer components that identifies an object -such as an algorithm, an attribute type, or perhaps a -registration authority that defines other object -identifiers. An OBJECT IDENTIFIER value can have any number -of components, and components can generally have any -nonnegative value. This type is a non-string type. - -OBJECT IDENTIFIER values are given meanings by registration -authorities. Each registration authority is responsible for -all sequences of components beginning with a given sequence. -A registration authority typically delegates responsibility -for subsets of the sequences in its domain to other -registration authorities, or for particular types of object. -There are always at least two components. - -The OBJECT IDENTIFIER type is used to identify content in -PKCS #7's ContentInfo type, to identify algorithms in -X.509's AlgorithmIdentifier type, and to identify attributes -in X.501's Attribute and AttributeValueAssertion types. The -Attribute type is used by PKCS #6, #7, #8, #9, and #10, and -the AttributeValueAssertion type is used in X.501 -distinguished names. OBJECT IDENTIFIER values are defined -throughout PKCS. - -ASN.1 notation: - -OBJECT IDENTIFIER - -The ASN.1 notation for values of the OBJECT IDENTIFIER type -is - -{ [identifier] component1 ... componentn } - -componenti = identifieri | identifieri (valuei) | valuei - -where identifier, identifier1, ..., identifiern are -identifiers, and value1, ..., valuen are optional integer -values. - -The form without identifier is the "complete" value with all -its components; the form with identifier abbreviates the -beginning components with another object identifier value. -The identifiers identifier1, ..., identifiern are intended -primarily for documentation, but they must correspond to the -integer value when both are present. These identifiers can -appear without integer values only if they are among a small -set of identifiers defined in X.208. - -Example: The following values both refer to the object -identifier assigned to RSA Data Security, Inc.: - -{ iso(1) member-body(2) 840 113549 } -{ 1 2 840 113549 } - -(In this example, which gives ASN.1 value notation, the -object identifier values are decimal, not hexadecimal.) -Table 4 gives some other object identifier values and their -meanings. - - Object identifier value Meaning - { 1 2 } ISO member bodies - { 1 2 840 } US (ANSI) - { 1 2 840 113549 } RSA Data Security, Inc. - { 1 2 840 113549 1 } RSA Data Security, Inc. PKCS - { 2 5 } directory services (X.500) - { 2 5 8 } directory services-algorithms - - Table 4. Some object identifier values and their meanings. - -BER encoding. Primitive. Contents octets are as follows, -where value1, ..., valuen denote the integer values of the -components in the complete object identifier: - - 1. The first octet has value 40 * value1 + value2. - (This is unambiguous, since value1 is limited to - values 0, 1, and 2; value2 is limited to the range - 0 to 39 when value1 is 0 or 1; and, according to - X.208, n is always at least 2.) - - 2. The following octets, if any, encode value3, ..., - valuen. Each value is encoded base 128, most - significant digit first, with as few digits as - possible, and the most significant bit of each - octet except the last in the value's encoding set - to "1." - -Example: The first octet of the BER encoding of RSA Data -Security, Inc.'s object identifier is 40 * 1 + 2 = 42 = -2a16. The encoding of 840 = 6 * 128 + 4816 is 86 48 and the -encoding of 113549 = 6 * 1282 + 7716 * 128 + d16 is 86 f7 -0d. This leads to the following BER encoding: - -06 06 2a 86 48 86 f7 0d - -DER encoding. Primitive. Contents octets are as for a -primitive BER encoding. - - -5.10 OCTET STRING - -The OCTET STRING type denotes an arbitrary string of octets -(eight-bit values). An OCTET STRING value can have any -length, including zero. This type is a string type. - -The OCTET STRING type is used for salt values in PKCS #5's -PBEParameter type, for message digests, encrypted message -digests, and encrypted content in PKCS #7, and for private -keys and encrypted private keys in PKCS #8. - -ASN.1 notation: - -OCTET STRING [SIZE ({size | size1..size2})] - -where size, size1, and size2 are optional size constraints. -In the OCTET STRING SIZE (size) form, the octet string must -have size octets. In the OCTET STRING SIZE (size1..size2) -form, the octet string must have between size1 and size2 -octets. In the OCTET STRING form, the octet string can have -any size. - -Example: PKCS #5's PBEParameter type has a component of type -OCTET STRING: - -PBEParameter ::= SEQUENCE { - salt OCTET STRING SIZE(8), - iterationCount INTEGER } - -Here the size of the salt component is always eight octets. - -BER encoding. Primitive or constructed. In a primitive -encoding, the contents octets give the value of the octet -string, first octet to last octet. In a constructed -encoding, the contents octets give the concatenation of the -BER encodings of substrings of the OCTET STRING value. - -Example: The BER encoding of the OCTET STRING value 01 23 45 -67 89 ab cd ef can be any of the following, among others, -depending on the form of length octets and whether the -encoding is primitive or constructed: - -04 08 01 23 45 67 89 ab cd ef DER encoding - -04 81 08 01 23 45 67 89 ab cd ef long form of length octets - -24 0c constructed encoding: 01 ... 67 + 89 ... ef - 04 04 01 23 45 67 - 04 04 89 ab cd ef - -DER encoding. Primitive. Contents octets are as for a -primitive BER encoding. - -Example: The BER encoding of the OCTET STRING value 01 23 45 -67 89 ab cd ef is - -04 08 01 23 45 67 89 ab cd ef - - -5.11 PrintableString - -The PrintableString type denotes an arbitrary string of -printable characters from the following character set: - - A, B, ..., Z - a, b, ..., z - 0, 1, ..., 9 - (space) ' ( ) + , - . / : = ? - -This type is a string type. - -The PrintableString type is used in PKCS #9's challenge- -password and unstructuerd-address attributes, and in several -X.521 distinguished names attributes. - -ASN.1 notation: - -PrintableString - -BER encoding. Primitive or constructed. In a primitive -encoding, the contents octets give the characters in the -printable string, encoded in ASCII. In a constructed -encoding, the contents octets give the concatenation of the -BER encodings of consecutive substrings of the string. - -Example: The BER encoding of the PrintableString value "Test -User 1" can be any of the following, among others, depending -on the form of length octets and whether the encoding is -primitive or constructed: - -13 0b 54 65 73 74 20 55 73 65 72 20 31 DER encoding - -13 81 0b long form of length octets - 54 65 73 74 20 55 73 65 72 20 31 - -33 0f constructed encoding: "Test " + "User 1" - 13 05 54 65 73 74 20 - 13 06 55 73 65 72 20 31 - -DER encoding. Primitive. Contents octets are as for a -primitive BER encoding. - -Example: The DER encoding of the PrintableString value "Test -User 1" is - -13 0b 54 65 73 74 20 55 73 65 72 20 31 - - -5.12 SEQUENCE - -The SEQUENCE type denotes an ordered collection of one or -more types. - -The SEQUENCE type is used throughout PKCS and related -standards. - -ASN.1 notation: - -SEQUENCE { - [identifier1] Type1 [{OPTIONAL | DEFAULT value1}], - ..., - [identifiern] Typen [{OPTIONAL | DEFAULT valuen}]} - -where identifier1 , ..., identifiern are optional, distinct -identifiers for the components, Type1, ..., Typen are the -types of the components, and value1, ..., valuen are optional -default values for the components. The identifiers are -primarily for documentation; they do not affect values of -the type or their encodings in any way. - -The OPTIONAL qualifier indicates that the value of a -component is optional and need not be present in the -sequence. The DEFAULT qualifier also indicates that the -value of a component is optional, and assigns a default -value to the component when the component is absent. - -The types of any consecutive series of components with the -OPTIONAL or DEFAULT qualifier, as well as of any component -immediately following that series, must have distinct tags. -This requirement is typically satisfied with explicit or -implicit tagging on some of the components. - -Example: X.509's Validity type is a SEQUENCE type with two -components: - -Validity ::= SEQUENCE { - start UTCTime, - end UTCTime } - -Here the identifiers for the components are start and end, -and the types of the components are both UTCTime. - -BER encoding. Constructed. Contents octets are the -concatenation of the BER encodings of the values of the -components of the sequence, in order of definition, with the -following rules for components with the OPTIONAL and DEFAULT -qualifiers: - - o if the value of a component with the OPTIONAL or - DEFAULT qualifier is absent from the sequence, - then the encoding of that component is not - included in the contents octets - - o if the value of a component with the DEFAULT - qualifier is the default value, then the encoding - of that component may or may not be included in - the contents octets - -DER encoding. Constructed. Contents octets are the same as -the BER encoding, except that if the value of a component -with the DEFAULT qualifier is the default value, the -encoding of that component is not included in the contents -octets. - - -5.13 SEQUENCE OF - -The SEQUENCE OF type denotes an ordered collection of zero -or more occurrences of a given type. - -The SEQUENCE OF type is used in X.501 distinguished names. - -ASN.1 notation: - -SEQUENCE OF Type - -where Type is a type. - -Example: X.501's RDNSequence type consists of zero or more -occurences of the RelativeDistinguishedName type, most -significant occurrence first: - -RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - -BER encoding. Constructed. Contents octets are the -concatenation of the BER encodings of the values of the -occurrences in the collection, in order of occurence. - -DER encoding. Constructed. Contents octets are the -concatenation of the DER encodings of the values of the -occurrences in the collection, in order of occurence. - - -5.14 SET - -The SET type denotes an unordered collection of one or more -types. - -The SET type is not used in PKCS. - -ASN.1 notation: - -SET { - [identifier1] Type1 [{OPTIONAL | DEFAULT value1}], - ..., - [identifiern] Typen [{OPTIONAL | DEFAULT valuen}]} - -where identifier1, ..., identifiern are optional, distinct -identifiers for the components, Type1, ..., Typen are the -types of the components, and value1, ..., valuen are -optional default values for the components. The identifiers -are primarily for documentation; they do not affect values -of the type or their encodings in any way. - -The OPTIONAL qualifier indicates that the value of a -component is optional and need not be present in the set. -The DEFAULT qualifier also indicates that the value of a -component is optional, and assigns a default value to the -component when the component is absent. - -The types must have distinct tags. This requirement is -typically satisfied with explicit or implicit tagging on -some of the components. - -BER encoding. Constructed. Contents octets are the -concatenation of the BER encodings of the values of the -components of the set, in any order, with the following -rules for components with the OPTIONAL and DEFAULT -qualifiers: - - o if the value of a component with the OPTIONAL or - DEFAULT qualifier is absent from the set, then the - encoding of that component is not included in the - contents octets - - o if the value of a component with the DEFAULT - qualifier is the default value, then the encoding - of that component may or may not be included in - the contents octets - -DER encoding. Constructed. Contents octets are the same as -for the BER encoding, except that: - - 1. If the value of a component with the DEFAULT - qualifier is the default value, the encoding of - that component is not included. - - 2. There is an order to the components, namely - ascending order by tag. - - -5.15 SET OF - -The SET OF type denotes an unordered collection of zero or -more occurrences of a given type. - -The SET OF type is used for sets of attributes in PKCS #6, -#7, #8, #9 and #10, for sets of message-digest algorithm -identifiers, signer information, and recipient information -in PKCS #7, and in X.501 distinguished names. - -ASN.1 notation: - -SET OF Type - -where Type is a type. - -Example: X.501's RelativeDistinguishedName type consists of -zero or more occurrences of the AttributeValueAssertion -type, where the order is unimportant: - -RelativeDistinguishedName ::= - SET OF AttributeValueAssertion - -BER encoding. Constructed. Contents octets are the -concatenation of the BER encodings of the values of the -occurrences in the collection, in any order. - -DER encoding. Constructed. Contents octets are the same as -for the BER encoding, except that there is an order, namely -ascending lexicographic order of BER encoding. Lexicographic -comparison of two different BER encodings is done as -follows: Logically pad the shorter BER encoding after the -last octet with dummy octets that are smaller in value than -any normal octet. Scan the BER encodings from left to right -until a difference is found. The smaller-valued BER encoding -is the one with the smaller-valued octet at the point of -difference. - - -5.16 T61String - -The T61String type denotes an arbtrary string of T.61 -characters. T.61 is an eight-bit extension to the ASCII -character set. Special "escape" sequences specify the -interpretation of subsequent character values as, for -example, Japanese; the initial interpretation is Latin. The -character set includes non-printing control characters. The -T61String type allows only the Latin and Japanese character -interepretations, and implementors' agreements for directory -names exclude control characters [NIST92]. A T61String value -can have any length, including zero. This type is a string -type. - -The T61String type is used in PKCS #9's unstructured-address -and challenge-password attributes, and in several X.521 -attributes. - -ASN.1 notation: - -T61String - -BER encoding. Primitive or constructed. In a primitive -encoding, the contents octets give the characters in the -T.61 string, encoded in ASCII. In a constructed encoding, -the contents octets give the concatenation of the BER -encodings of consecutive substrings of the T.61 string. - -Example: The BER encoding of the T61String value "cl'es -publiques" (French for "public keys") can be any of the -following, among others, depending on the form of length -octets and whether the encoding is primitive or constructed: - -14 0f DER encoding - 63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73 - -14 81 0f long form of length octets - 63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73 - -34 15 constructed encoding: "cl'es" + " " + "publiques" - 14 05 63 6c c2 65 73 - 14 01 20 - 14 09 70 75 62 6c 69 71 75 65 73 - -The eight-bit character c2 is a T.61 prefix that adds an -acute accent (') to the next character. - -DER encoding. Primitive. Contents octets are as for a -primitive BER encoding. - -Example: The DER encoding of the T61String value "cl'es -publiques" is - -14 0f 63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73 - - -5.17 UTCTime - -The UTCTime type denotes a "coordinated universal time" or -Greenwich Mean Time (GMT) value. A UTCTime value includes -the local time precise to either minutes or seconds, and an -offset from GMT in hours and minutes. It takes any of the -following forms: - -YYMMDDhhmmZ -YYMMDDhhmm+hh'mm' -YYMMDDhhmm-hh'mm' -YYMMDDhhmmssZ -YYMMDDhhmmss+hh'mm' -YYMMDDhhmmss-hh'mm' - -where: - - YY is the least significant two digits of the year - - MM is the month (01 to 12) - - DD is the day (01 to 31) - - hh is the hour (00 to 23) - - mm are the minutes (00 to 59) - - ss are the seconds (00 to 59) - - Z indicates that local time is GMT, + indicates that - local time is later than GMT, and - indicates that - local time is earlier than GMT - - hh' is the absolute value of the offset from GMT in - hours - - mm' is the absolute value of the offset from GMT in - minutes - -This type is a string type. - -The UTCTime type is used for signing times in PKCS #9's -signing-time attribute and for certificate validity periods -in X.509's Validity type. - -ASN.1 notation: - -UTCTime - -BER encoding. Primitive or constructed. In a primitive -encoding, the contents octets give the characters in the -string, encoded in ASCII. In a constructed encoding, the -contents octets give the concatenation of the BER encodings -of consecutive substrings of the string. (The constructed -encoding is not particularly interesting, since UTCTime -values are so short, but the constructed encoding is -permitted.) - -Example: The time this sentence was originally written was -4:45:40 p.m. Pacific Daylight Time on May 6, 1991, which can -be represented with either of the following UTCTime values, -among others: - -"910506164540-0700" - -"910506234540Z" - -These values have the following BER encodings, among others: - -17 0d 39 31 30 35 30 36 32 33 34 35 34 30 5a - -17 11 39 31 30 35 30 36 31 36 34 35 34 30 2D 30 37 30 - 30 - -DER encoding. Primitive. Contents octets are as for a -primitive BER encoding. - - -6. An example - -This section gives an example of ASN.1 notation and DER -encoding: the X.501 type Name. - - -6.1 Abstract notation - -This section gives the ASN.1 notation for the X.501 type -Name. - -Name ::= CHOICE { - RDNSequence } - -RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - -RelativeDistinguishedName ::= - SET OF AttributeValueAssertion - -AttributeValueAssertion ::= SEQUENCE { - AttributeType, - AttributeValue } - -AttributeType ::= OBJECT IDENTIFIER - -AttributeValue ::= ANY - -The Name type identifies an object in an X.500 directory. -Name is a CHOICE type consisting of one alternative: -RDNSequence. (Future revisions of X.500 may have other -alternatives.) - -The RDNSequence type gives a path through an X.500 directory -tree starting at the root. RDNSequence is a SEQUENCE OF type -consisting of zero or more occurences of -RelativeDistinguishedName. - -The RelativeDistinguishedName type gives a unique name to an -object relative to the object superior to it in the -directory tree. RelativeDistinguishedName is a SET OF type -consisting of zero or more occurrences of -AttributeValueAssertion. - -The AttributeValueAssertion type assigns a value to some -attribute of a relative distinguished name, such as country -name or common name. AttributeValueAssertion is a SEQUENCE -type consisting of two components, an AttributeType type and -an AttributeValue type. - -The AttributeType type identifies an attribute by object -identifier. The AttributeValue type gives an arbitrary -attribute value. The actual type of the attribute value is -determined by the attribute type. - - -6.2 DER encoding - -This section gives an example of a DER encoding of a value -of type Name, working from the bottom up. - -The name is that of the Test User 1 from the PKCS examples -[Kal93]. The name is represented by the following path: - - (root) - | - countryName = "US" - | - organizationName = "Example Organization" - | - commonName = "Test User 1" - -Each level corresponds to one RelativeDistinguishedName -value, each of which happens for this name to consist of one -AttributeValueAssertion value. The AttributeType value is -before the equals sign, and the AttributeValue value (a -printable string for the given attribute types) is after the -equals sign. - -The countryName, organizationName, and commonUnitName are -attribute types defined in X.520 as: - -attributeType OBJECT IDENTIFIER ::= - { joint-iso-ccitt(2) ds(5) 4 } - -countryName OBJECT IDENTIFIER ::= { attributeType 6 } -organizationName OBJECT IDENTIFIER ::= - { attributeType 10 } -commonUnitName OBJECT IDENTIFIER ::= - { attributeType 3 } - - -6.2.1 AttributeType - -The three AttributeType values are OCTET STRING values, so -their DER encoding follows the primitive, definite-length -method: - -06 03 55 04 06 countryName - -06 03 55 04 0a organizationName - -06 03 55 04 03 commonName - -The identifier octets follow the low-tag form, since the tag -is 6 for OBJECT IDENTIFIER. Bits 8 and 7 have value "0," -indicating universal class, and bit 6 has value "0," -indicating that the encoding is primitive. The length octets -follow the short form. The contents octets are the -concatenation of three octet strings derived from -subidentifiers (in decimal): 40 * 2 + 5 = 85 = 5516; 4; and -6, 10, or 3. - - -6.2.2 AttributeValue - -The three AttributeValue values are PrintableString values, -so their encodings follow the primitive, definite-length -method: - -13 02 55 53 "US" - -13 14 "Example Organization" - 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 - 74 69 6f 6e - -13 0b "Test User 1" - 54 65 73 74 20 55 73 65 72 20 31 - -The identifier octets follow the low-tag-number form, since -the tag for PrintableString, 19 (decimal), is between 0 and -30. Bits 8 and 7 have value "0" since PrintableString is in -the universal class. Bit 6 has value "0" since the encoding -is primitive. The length octets follow the short form, and -the contents octets are the ASCII representation of the -attribute value. - - -6.2.3 AttributeValueAssertion - -The three AttributeValueAssertion values are SEQUENCE -values, so their DER encodings follow the constructed, -definite-length method: - -30 09 countryName = "US" - 06 03 55 04 06 - 13 02 55 53 - -30 1b organizationName = "Example Organizaiton" - 06 03 55 04 0a - 13 14 ... 6f 6e - -30 12 commonName = "Test User 1" - 06 03 55 04 0b - 13 0b ... 20 31 - -The identifier octets follow the low-tag-number form, since -the tag for SEQUENCE, 16 (decimal), is between 0 and 30. -Bits 8 and 7 have value "0" since SEQUENCE is in the -universal class. Bit 6 has value "1" since the encoding is -constructed. The length octets follow the short form, and -the contents octets are the concatenation of the DER -encodings of the attributeType and attributeValue -components. - - -6.2.4 RelativeDistinguishedName - -The three RelativeDistinguishedName values are SET OF -values, so their DER encodings follow the constructed, -definite-length method: - -31 0b - 30 09 ... 55 53 - -31 1d - 30 1b ... 6f 6e - -31 14 - 30 12 ... 20 31 - -The identifier octets follow the low-tag-number form, since -the tag for SET OF, 17 (decimal), is between 0 and 30. Bits -8 and 7 have value "0" since SET OF is in the universal -class Bit 6 has value "1" since the encoding is constructed. -The lengths octets follow the short form, and the contents -octets are the DER encodings of the respective -AttributeValueAssertion values, since there is only one -value in each set. - - -6.2.5 RDNSequence - -The RDNSequence value is a SEQUENCE OF value, so its DER -encoding follows the constructed, definite-length method: - -30 42 - 31 0b ... 55 53 - 31 1d ... 6f 6e - 31 14 ... 20 31 - -The identifier octets follow the low-tag-number form, since -the tag for SEQUENCE OF, 16 (decimal), is between 0 and 30. -Bits 8 and 7 have value "0" since SEQUENCE OF is in the -universal class. Bit 6 has value "1" since the encoding is -constructed. The lengths octets follow the short form, and -the contents octets are the concatenation of the DER -encodings of the three RelativeDistinguishedName values, in -order of occurrence. - - -6.2.6 Name - -The Name value is a CHOICE value, so its DER encoding is the -same as that of the RDNSequence value: - -30 42 - 31 0b - 30 09 - 06 03 55 04 06 attributeType = countryName - 13 02 55 53 attributeValue = "US" - 31 1d - 30 1b - 06 03 55 04 0a attributeType = organizationName - 13 14 attributeValue = "Example Organization" - 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 - 74 69 6f 6e - - 31 14 - 30 12 - 06 03 55 04 03 attributeType = commonName - 13 0b attributeValue = "Test User 1" - 54 65 73 74 20 55 73 65 72 20 31 - - -References - -PKCS #1 RSA Laboratories. PKCS #1: RSA Encryption - Standard. Version 1.5, November 1993. - -PKCS #3 RSA Laboratories. PKCS #3: Diffie-Hellman Key- - Agreement Standard. Version 1.4, November 1993. - -PKCS #5 RSA Laboratories. PKCS #5: Password-Based - Encryption Standard. Version 1.5, November 1993. - -PKCS #6 RSA Laboratories. PKCS #6: Extended-Certificate - Syntax Standard. Version 1.5, November 1993. - -PKCS #7 RSA Laboratories. PKCS #7: Cryptographic Message - Syntax Standard. Version 1.5, November 1993. - -PKCS #8 RSA Laboratories. PKCS #8: Private-Key Information - Syntax Standard. Version 1.2, November 1993. - -PKCS #9 RSA Laboratories. PKCS #9: Selected Attribute - Types. Version 1.1, November 1993. - -PKCS #10 RSA Laboratories. PKCS #10: Certification Request - Syntax Standard. Version 1.0, November 1993. - -X.200 CCITT. Recommendation X.200: Reference Model of - Open Systems Interconnection for CCITT - Applications. 1984. - -X.208 CCITT. Recommendation X.208: Specification of - Abstract Syntax Notation One (ASN.1). 1988. - -X.209 CCITT. Recommendation X.209: Specification of - Basic Encoding Rules for Abstract Syntax Notation - One (ASN.1). 1988. - -X.500 CCITT. Recommendation X.500: The - Directory--Overview of Concepts, Models and - Services. 1988. - -X.501 CCITT. Recommendation X.501: The Directory-- - Models. 1988. - -X.509 CCITT. Recommendation X.509: The Directory-- - Authentication Framework. 1988. - -X.520 CCITT. Recommendation X.520: The Directory-- - Selected Attribute Types. 1988. - -[Kal93] Burton S. Kaliski Jr. Some Examples of the PKCS - Standards. RSA Laboratories, November 1993. - -[NIST92] NIST. Special Publication 500-202: Stable - Implementation Agreements for Open Systems - Interconnection Protocols. Part 11 (Directory - Services Protocols). December 1992. - - -Revision history - - -June 3, 1991 version - -The June 3, 1991 version is part of the initial public -release of PKCS. It was published as NIST/OSI Implementors' -Workshop document SEC-SIG-91-17. - - -November 1, 1993 version - -The November 1, 1993 version incorporates several editorial -changes, including the addition of a revision history. It is -updated to be consistent with the following versions of the -PKCS documents: - - PKCS #1: RSA Encryption Standard. Version 1.5, November - 1993. - - PKCS #3: Diffie-Hellman Key-Agreement Standard. Version - 1.4, November 1993. - - PKCS #5: Password-Based Encryption Standard. Version - 1.5, November 1993. - - PKCS #6: Extended-Certificate Syntax Standard. Version - 1.5, November 1993. - - PKCS #7: Cryptographic Message Syntax Standard. Version - 1.5, November 1993. - - PKCS #8: Private-Key Information Syntax Standard. - Version 1.2, November 1993. - - PKCS #9: Selected Attribute Types. Version 1.1, - November 1993. - - PKCS #10: Certification Request Syntax Standard. - Version 1.0, November 1993. - -The following substantive changes were made: - - Section 5: Description of T61String type is added. - - Section 6: Names are changed, consistent with other - PKCS examples. - - -Author's address - -Burton S. Kaliski Jr., Ph.D. -Chief Scientist -RSA Laboratories (415) 595-7703 -100 Marine Parkway (415) 595-4126 (fax) -Redwood City, CA 94065 USA burt@rsa.com diff --git a/doc/devel/guidelines b/doc/devel/guidelines deleted file mode 100644 index 3f81652b0e..0000000000 --- a/doc/devel/guidelines +++ /dev/null @@ -1,110 +0,0 @@ -$OpenLDAP$ - -This document is being replaced with: - http://www.openldap.org/devel/programming.html -and - http://www.openldap.org/devel/contributing.html - -However, some of the info here is still useful. - -Coding guide lines and and hints for OpenLDAP developers. -========================================================= - -Please add to this file when new points come up. - - -C source --------- - -OpenLDAP requires many Standard C features to *build*. This -includes functional prototypes and offsetof macro. It is -possible to *build* OpenLDAP with a number of C translators -which are not fully compliant with Standard C. - -OpenLDAP supports compiling and linking *with* applications -with most C compilers and libraries. The installed headers -are designed to provide K&R C compatiable function declarations -on non-standard compilers. In cases where the compiler does -not define __STDC__ but requires prototypes (ie: MSVC), the -application should define LDAP_NEEDS_PROTOTYPES. In cases -where the compiler does define __STDC__ but does not support -prototypes, the application should define LDAP_NO_PROTOTYPES. - -.c files in the OpenLDAP source tree MUST #include "portable.h" before -any other include file, even system includes. portable.h may control -aspects of system includes, such as whether or not thread-safe library -functions are used. (Separate applications can't use portable.h, since -it is not installed. They can use ldap_features.h, though.) - -.h files that are NOT INSTALLED may depend on features from portable.h. -.h files that *are* installed (from include/) should not depend on it. - -Avoid unnecessary changes, like reindenting code, even if that leaves -the code a little ugly. Often switching your editors tab stops to -4 or 8 may make code easier to read. Unnecessary changes make it -harder to maintain and merge different CVS branches of the source. - -Please follow the style of surrounding code. - -Use feature-specific #if tests (like #ifdef HAVE_LWP) which configure -can figure out, not system-specific test (like #ifdef __SunOS_5_6). - -When available, use include files from ldap/include/ac/ to get system -features or functions. The files try to fix crippled system -includes, and to hide #ifdef messes that portable programs need in order -to find a feature. Note that a file is not necessarily -designed to be equivalent to standard C's file. - -Nonstatic function and variable definitions in .c files should be -preceded by their declarations in .h files. Avoid implicit function -declarations. External declarations with should be avoided. In -.c files, include the appropriate .h file to obtain the declaration. -If the declaration is not available in any system header, add it -to the most appropriate ac/xxx.h header. Do NOT add extern -declarations to .c files. - -When a function returns non-void, it should return a meaningful value. -Avoid implicit int. - -It is recommended that ldap_cdef.h macros LDAP_F and LDAP_P be used -even for non-installed headers. See lber.h and ldap.h for examples. - - -CVS updating ------------- - - describes how to check out --stable. To get the -devel (HEAD) branch, omit `-r OPENLDAP_STABLE'. -You can use 'cvs status -v README' to get a list available CVS tags. - -Core members should subscribe to the -core mailing list. This -list is for private discussions between core team members. The -openldap-devel@openldap.org mailing list is the primary developer -forum for both technical disscusions and coordinating efforts. - -Please test patches before committing. This should include compiling -and linking the system AND running the test suite. - -In general, a patch/bugfix should be applied to -devel and tested. -When the patch is considered stable, then it can be merged into -stable. -Same goes for other release engineering branches (like -OPENLDAP_REL_ENG_1_1). (-stable is rel eng 1.0). -Specific procjects may get their own branches, to be merged later. - -Log messages: Just describe the change and reason. CVS adds your name, -date, etc. - - -Various tips and hints ----------------------- - -How to correct a CVS log message: -Commit the unchanged files again with the `-f' flag and with a log -message stating how the previous log was in error: - cvs commit -f cldap.c os-ip.c -Preferably, prepend a line something like this to the message: -"Forced commit to correct previous log, files were not changed." - -Modify ldapconfig.h instead of ldapconfig.h.edit. Then `cvs commit' -from the include directory won't accidentally commit your private -ldapconfig.h.edit. diff --git a/libraries/liblutil/signal.c b/libraries/liblutil/signal.c index 230a265b95..64084c7eda 100644 --- a/libraries/liblutil/signal.c +++ b/libraries/liblutil/signal.c @@ -8,6 +8,7 @@ #include "portable.h" #ifdef HAVE_SIGACTION +#include #include lutil_sig_t diff --git a/servers/slapd/back-ldbm/attr.c b/servers/slapd/back-ldbm/attr.c index 9eb492000d..fbd8e0d04e 100644 --- a/servers/slapd/back-ldbm/attr.c +++ b/servers/slapd/back-ldbm/attr.c @@ -23,7 +23,7 @@ typedef struct ldbm_attrinfo { #else char *ai_desc; #endif - slap_index ai_indexmask; /* how the attr is indexed */ + slap_mask_t ai_indexmask; /* how the attr is indexed */ } AttrInfo; static int @@ -64,7 +64,7 @@ attr_mask( #else const char *desc, #endif - slap_index *indexmask ) + slap_mask_t *indexmask ) { AttrInfo *a; @@ -84,7 +84,7 @@ attr_index_config( { int rc; int i; - slap_index mask; + slap_mask_t mask; char **attrs; char **indexes = NULL; @@ -115,7 +115,7 @@ attr_index_config( mask = 0; for ( i = 0; indexes[i] != NULL; i++ ) { - slap_index index; + slap_mask_t index; rc = slap_str2index( indexes[i], &index ); if( rc != LDAP_SUCCESS ) { diff --git a/servers/slapd/back-ldbm/back-ldbm.h b/servers/slapd/back-ldbm/back-ldbm.h index 1475042e6c..b1b374b1a7 100644 --- a/servers/slapd/back-ldbm/back-ldbm.h +++ b/servers/slapd/back-ldbm/back-ldbm.h @@ -107,7 +107,7 @@ struct ldbminfo { ldap_pvt_thread_mutex_t li_root_mutex; ldap_pvt_thread_mutex_t li_add_mutex; int li_mode; - slap_index li_defaultmask; + slap_mask_t li_defaultmask; char *li_directory; Cache li_cache; Avlnode *li_attrs; diff --git a/servers/slapd/back-ldbm/filterindex.c b/servers/slapd/back-ldbm/filterindex.c index 674910ddb8..733d011506 100644 --- a/servers/slapd/back-ldbm/filterindex.c +++ b/servers/slapd/back-ldbm/filterindex.c @@ -24,7 +24,7 @@ static ID_BLOCK *approx_candidates( Backend *be, AttributeAssertion *ava ); static ID_BLOCK *substring_candidates( Backend *be, - Filter *f ); + SubstringsAssertion *sub ); static ID_BLOCK *list_candidates( Backend *be, Filter *flist, @@ -69,7 +69,7 @@ filter_candidates( case LDAP_FILTER_SUBSTRINGS: Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 ); - result = substring_candidates( be, f ); + result = substring_candidates( be, f->f_sub ); break; case LDAP_FILTER_GE: @@ -117,7 +117,7 @@ presence_candidates( DBCache *db; int rc; char *dbname; - slap_index mask; + slap_mask_t mask; struct berval *prefix; Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 ); @@ -128,11 +128,17 @@ presence_candidates( &dbname, &mask, &prefix ); if( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, + "<= presence_candidates: index_param failed (%d)\n", + rc, 0, 0 ); return idl; } if( dbname == NULL ) { /* not indexed */ + Debug( LDAP_DEBUG_TRACE, + "<= presense_candidates: not indexed\n", + 0, 0, 0 ); ber_bvfree( prefix ); return idl; } @@ -184,7 +190,7 @@ equality_candidates( int i; int rc; char *dbname; - slap_index mask; + slap_mask_t mask; struct berval *prefix; struct berval **keys = NULL; MatchingRule *mr; @@ -197,11 +203,17 @@ equality_candidates( &dbname, &mask, &prefix ); if( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, + "<= equality_candidates: index_param failed (%d)\n", + rc, 0, 0 ); return idl; } if( dbname == NULL ) { /* not indexed */ + Debug( LDAP_DEBUG_TRACE, + "<= equality_candidates: not indexed\n", + 0, 0, 0 ); ber_bvfree( prefix ); return idl; } @@ -209,7 +221,6 @@ equality_candidates( mr = ava->aa_desc->ad_type->sat_equality; if( !mr ) { ber_bvfree( prefix ); - /* return LDAP_INAPPROPRIATE_MATCHING; */ return idl; } @@ -220,6 +231,7 @@ equality_candidates( rc = (mr->smr_filter)( LDAP_FILTER_EQUALITY, + mask, ava->aa_desc->ad_type->sat_syntax, mr, prefix, @@ -229,6 +241,16 @@ equality_candidates( ber_bvfree( prefix ); if( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, + "<= equality_candidates: (%s%s) MR filter failed (%d)\n", + dbname, LDBM_SUFFIX, rc ); + return idl; + } + + if( keys == NULL ) { + Debug( LDAP_DEBUG_TRACE, + "<= equality_candidates: no keys (%s%s)\n", + dbname, LDBM_SUFFIX, 0 ); return idl; } @@ -294,7 +316,7 @@ approx_candidates( int i; int rc; char *dbname; - slap_index mask; + slap_mask_t mask; struct berval *prefix; struct berval **keys = NULL; MatchingRule *mr; @@ -303,28 +325,33 @@ approx_candidates( idl = idl_allids( be ); - rc = index_param( be, ava->aa_desc, LDAP_FILTER_EQUALITY, + rc = index_param( be, ava->aa_desc, LDAP_FILTER_APPROX, &dbname, &mask, &prefix ); if( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, + "<= approx_candidates: index_param failed (%d)\n", + rc, 0, 0 ); return idl; } if( dbname == NULL ) { /* not indexed */ + Debug( LDAP_DEBUG_ANY, + "<= approx_candidates: not indexed\n", + 0, 0, 0 ); ber_bvfree( prefix ); return idl; } mr = ava->aa_desc->ad_type->sat_approx; - if( mr == NULL ) { + if( !mr ) { /* no approx matching rule, try equality matching rule */ mr = ava->aa_desc->ad_type->sat_equality; } if( !mr ) { ber_bvfree( prefix ); - /* return LDAP_INAPPROPRIATE_MATCHING; */ return idl; } @@ -334,7 +361,8 @@ approx_candidates( } rc = (mr->smr_filter)( - LDAP_FILTER_EQUALITY, + LDAP_FILTER_APPROX, + mask, ava->aa_desc->ad_type->sat_syntax, mr, prefix, @@ -344,6 +372,16 @@ approx_candidates( ber_bvfree( prefix ); if( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, + "<= approx_candidates: (%s%s) MR filter failed (%d)\n", + dbname, LDBM_SUFFIX, rc ); + return idl; + } + + if( keys == NULL ) { + Debug( LDAP_DEBUG_TRACE, + "<= approx_candidates: no keys (%s%s)\n", + dbname, LDBM_SUFFIX, 0 ); return idl; } @@ -438,16 +476,122 @@ list_candidates( static ID_BLOCK * substring_candidates( Backend *be, - Filter *f + SubstringsAssertion *sub ) { ID_BLOCK *idl; + DBCache *db; + int i; + int rc; + char *dbname; + slap_mask_t mask; + struct berval *prefix; + struct berval **keys = NULL; + MatchingRule *mr; - Debug( LDAP_DEBUG_TRACE, "=> substring_candidates\n", 0, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "=> substrings_candidates\n", 0, 0, 0 ); idl = idl_allids( be ); - Debug( LDAP_DEBUG_TRACE, "<= substring_candidates %ld\n", + + rc = index_param( be, sub->sa_desc, LDAP_FILTER_SUBSTRINGS, + &dbname, &mask, &prefix ); + + if( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, + "<= substrings_candidates: index_param failed (%d)\n", + rc, 0, 0 ); + return idl; + } + + if( dbname == NULL ) { + /* not indexed */ + Debug( LDAP_DEBUG_ANY, + "<= substrings_candidates: not indexed\n", + 0, 0, 0 ); + ber_bvfree( prefix ); + return idl; + } + + mr = sub->sa_desc->ad_type->sat_substr; + + if( !mr ) { + ber_bvfree( prefix ); + return idl; + } + + if( !mr->smr_filter ) { + ber_bvfree( prefix ); + return idl; + } + + rc = (mr->smr_filter)( + LDAP_FILTER_SUBSTRINGS, + mask, + sub->sa_desc->ad_type->sat_syntax, + mr, + prefix, + sub, + &keys ); + + ber_bvfree( prefix ); + + if( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, + "<= substrings_candidates: (%s%s) MR filter failed (%d)\n", + dbname, LDBM_SUFFIX, rc ); + return idl; + } + + if( keys == NULL ) { + Debug( LDAP_DEBUG_TRACE, + "<= substrings_candidates: (0x%04lx) no keys (%s%s)\n", + mask, dbname, LDBM_SUFFIX ); + return idl; + } + + db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_READER ); + + if ( db == NULL ) { + Debug( LDAP_DEBUG_ANY, + "<= substrings_candidates db open failed (%s%s)\n", + dbname, LDBM_SUFFIX, 0 ); + return idl; + } + + for ( i= 0; keys[i] != NULL; i++ ) { + ID_BLOCK *save; + ID_BLOCK *tmp; + + rc = key_read( be, db, keys[i], &tmp ); + + if( rc != LDAP_SUCCESS ) { + idl_free( idl ); + idl = NULL; + Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates key read failed (%d)\n", + rc, 0, 0 ); + break; + } + + if( tmp == NULL ) { + idl_free( idl ); + idl = NULL; + Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates NULL\n", + 0, 0, 0 ); + break; + } + + save = idl; + idl = idl_intersection( be, idl, tmp ); + idl_free( save ); + + if( idl == NULL ) break; + } + + ber_bvecfree( keys ); + + ldbm_cache_close( be, db ); + + Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates %ld\n", idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); return( idl ); } - diff --git a/servers/slapd/back-ldbm/index.c b/servers/slapd/back-ldbm/index.c index db9f264fc2..010ca61c6c 100644 --- a/servers/slapd/back-ldbm/index.c +++ b/servers/slapd/back-ldbm/index.c @@ -22,7 +22,7 @@ static index_mask( char **atname ) { AttributeType *at; - slap_index mask = 0; + slap_mask_t mask = 0; /* we do support indexing of binary attributes */ if( slap_ad_is_binary( desc ) ) return 0; @@ -77,10 +77,10 @@ int index_param( AttributeDescription *desc, int ftype, char **dbnamep, - slap_index *maskp, + slap_mask_t *maskp, struct berval **prefixp ) { - slap_index mask; + slap_mask_t mask; char *dbname; char *atname; @@ -135,7 +135,7 @@ static int indexer( struct berval **vals, ID id, int op, - slap_index mask ) + slap_mask_t mask ) { int rc, i; const char *text; @@ -169,6 +169,7 @@ static int indexer( if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) { rc = ad->ad_type->sat_equality->smr_indexer( + LDAP_FILTER_EQUALITY, mask, ad->ad_type->sat_syntax, ad->ad_type->sat_equality, @@ -184,6 +185,7 @@ static int indexer( if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) { rc = ad->ad_type->sat_approx->smr_indexer( + LDAP_FILTER_APPROX, mask, ad->ad_type->sat_syntax, ad->ad_type->sat_approx, @@ -199,6 +201,7 @@ static int indexer( if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) { rc = ad->ad_type->sat_substr->smr_indexer( + LDAP_FILTER_SUBSTRINGS, mask, ad->ad_type->sat_syntax, ad->ad_type->sat_substr, @@ -225,10 +228,10 @@ static int index_at_values( ID id, int op, char ** dbnamep, - slap_index *maskp ) + slap_mask_t *maskp ) { - slap_index mask; - slap_index tmpmask = 0; + slap_mask_t mask; + slap_mask_t tmpmask = 0; int lindex = 0; if( type->sat_sup ) { @@ -291,7 +294,7 @@ int index_values( int op ) { char *dbname = NULL; - slap_index mask; + slap_mask_t mask; if( slap_ad_is_binary( desc ) ) { /* binary attributes have no index capabilities */ diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h index 6cc7d08c2d..280edd5383 100644 --- a/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -35,7 +35,7 @@ Entry *deref_internal_r LDAP_P(( void attr_mask LDAP_P(( struct ldbminfo *li, const char *desc, - slap_index *indexmask )); + slap_mask_t *indexmask )); int attr_index_config LDAP_P(( struct ldbminfo *li, const char *fname, int lineno, @@ -139,7 +139,7 @@ index_param LDAP_P(( AttributeDescription *desc, int ftype, char **dbname, - slap_index *mask, + slap_mask_t *mask, struct berval **prefix )); extern int diff --git a/servers/slapd/index.c b/servers/slapd/index.c index 153cff79a8..8ec5a97997 100644 --- a/servers/slapd/index.c +++ b/servers/slapd/index.c @@ -34,7 +34,7 @@ slap_index2prefix( int indextype ) return( prefix ); } -int slap_str2index( const char *str, slap_index *idx ) +int slap_str2index( const char *str, slap_mask_t *idx ) { if ( strcasecmp( str, "pres" ) == 0 ) { *idx = SLAP_INDEX_PRESENT; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 2c69c2a27e..55927d4d63 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -252,7 +252,7 @@ LDAP_SLAPD_F (int) read_config LDAP_P(( const char *fname )); * index.c */ LDAP_SLAPD_F (int) slap_index2prefix LDAP_P(( int indextype )); -LDAP_SLAPD_F (int) slap_str2index LDAP_P(( const char *str, slap_index *idx )); +LDAP_SLAPD_F (int) slap_str2index LDAP_P(( const char *str, slap_mask_t *idx )); /* * connection.c diff --git a/servers/slapd/schema/core.schema b/servers/slapd/schema/core.schema index 91237cc690..76ba4a3e31 100644 --- a/servers/slapd/schema/core.schema +++ b/servers/slapd/schema/core.schema @@ -546,7 +546,7 @@ objectclass ( 2.16.840.1.113719.2.142.6.1.1 NAME 'LDAPsubEntry' # # OpenLDAProotDSE # likely to change! -objectclass ( 1.3.6.1.4.1.4203.666.3.2 +objectclass ( 1.3.6.1.4.1.4203.1.4.1 NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) DESC 'OpenLDAP Root DSE object' SUP top STRUCTURAL MAY cn ) diff --git a/servers/slapd/schema/openldap.schema b/servers/slapd/schema/openldap.schema index 3d52b7db07..391b86dd9f 100644 --- a/servers/slapd/schema/openldap.schema +++ b/servers/slapd/schema/openldap.schema @@ -8,23 +8,23 @@ # inetorgperson.schema # -objectClass ( 1.3.6.1.4.1.4203.666.3.3 NAME 'OpenLDAPorg' +objectClass ( 1.3.6.1.4.1.4203.1.4.3 NAME 'OpenLDAPorg' DESC 'OpenLDAP Organizational Object' SUP organization MAY ( authPassword $ buildingName $ displayName $ labeledURI ) ) -objectClass ( 1.3.6.1.4.1.4203.666.3.4 NAME 'OpenLDAPou' +objectClass ( 1.3.6.1.4.1.4203.1.4.4 NAME 'OpenLDAPou' DESC 'OpenLDAP Organizational Unit Object' SUP organizationalUnit MAY ( authPassword $ buildingName $ displayName $ labeledURI $ o ) ) -objectClass ( 1.3.6.1.4.1.4203.666.3.5 NAME 'OpenLDAPperson' +objectClass ( 1.3.6.1.4.1.4203.1.4.5 NAME 'OpenLDAPperson' DESC 'OpenLDAP Person' SUP ( pilotPerson $ inetOrgPerson ) MUST ( uid $ cn ) MAY ( authPassword $ givenName $ labeledURI $ o ) ) -objectClass ( 1.3.6.1.4.1.4203.666.3.6 NAME 'OpenLDAPdisplayableObject' +objectClass ( 1.3.6.1.4.1.4203.1.4.6 NAME 'OpenLDAPdisplayableObject' DESC 'OpenLDAP Displayable Object' MAY displayName AUXILIARY ) diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 9ca8ca5826..6c14e783c3 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -88,7 +88,7 @@ static int octetStringMatch( int *matchp, - unsigned flags, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *value, @@ -108,7 +108,8 @@ octetStringMatch( /* Index generation function */ int octetStringIndexer( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, @@ -161,7 +162,8 @@ int octetStringIndexer( /* Index generation function */ int octetStringFilter( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, @@ -254,7 +256,7 @@ dnNormalize( static int dnMatch( int *matchp, - unsigned flags, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *value, @@ -329,7 +331,7 @@ booleanValidate( static int booleanMatch( int *matchp, - unsigned flags, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *value, @@ -628,7 +630,7 @@ IA5StringNormalize( static int caseExactIA5Match( int *matchp, - unsigned flags, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *value, @@ -649,7 +651,7 @@ caseExactIA5Match( static int caseExactIA5SubstringsMatch( int *matchp, - unsigned flags, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *value, @@ -773,7 +775,8 @@ done: /* Index generation function */ int caseExactIA5Indexer( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, @@ -826,7 +829,8 @@ int caseExactIA5Indexer( /* Index generation function */ int caseExactIA5Filter( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, @@ -868,16 +872,18 @@ int caseExactIA5Filter( *keysp = keys; return LDAP_SUCCESS; } + /* Substrings Index generation function */ int caseExactIA5SubstringsIndexer( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, struct berval **values, struct berval ***keysp ) { - int i, nkeys, types; + ber_len_t i, nkeys; size_t slen, mlen; struct berval **keys; lutil_MD5_CTX MD5context; @@ -886,11 +892,6 @@ int caseExactIA5SubstringsIndexer( digest.bv_val = MD5digest; digest.bv_len = sizeof(MD5digest); - types = 0; - if( flags & SLAP_MR_SUBSTR_INITIAL ) types++; - if( flags & SLAP_MR_SUBSTR_FINAL ) types++; - /* no SUBSTR_ANY indexing */ - nkeys=0; for( i=0; values[i] != NULL; i++ ) { /* count number of indices to generate */ @@ -898,10 +899,28 @@ int caseExactIA5SubstringsIndexer( continue; } - if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { - nkeys += SLAP_INDEX_SUBSTR_MAXLEN - ( SLAP_INDEX_SUBSTR_MINLEN - 1); - } else { - nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + if( flags & SLAP_INDEX_SUBSTR_INITIAL ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += SLAP_INDEX_SUBSTR_MAXLEN - + ( SLAP_INDEX_SUBSTR_MINLEN - 1); + } else { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + } + } + + if( flags & SLAP_INDEX_SUBSTR_ANY ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); + } + } + + if( flags & SLAP_INDEX_SUBSTR_FINAL ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += SLAP_INDEX_SUBSTR_MAXLEN - + ( SLAP_INDEX_SUBSTR_MINLEN - 1); + } else { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + } } } assert( i > 0 ); @@ -912,7 +931,6 @@ int caseExactIA5SubstringsIndexer( return LDAP_SUCCESS; } - nkeys *= types; /* We need to generate keys for each type */ keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); slen = strlen( syntax->ssyn_oid ); @@ -920,20 +938,47 @@ int caseExactIA5SubstringsIndexer( nkeys=0; for( i=0; values[i] != NULL; i++ ) { - int j,max; + ber_len_t j,max; struct berval *value; + value = values[i]; if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; + if( ( flags & SLAP_INDEX_SUBSTR_ANY ) && + ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) ) + { + char pre = SLAP_INDEX_SUBSTR_PREFIX; + max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1); + + for( j=0; jbv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + + lutil_MD5Update( &MD5context, + &pre, sizeof( pre ) ); + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + &value->bv_val[j], + SLAP_INDEX_SUBSTR_MAXLEN ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[nkeys++] = ber_bvdup( &digest ); + } + } + max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; - value = values[i]; - for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) { char pre; - if( flags & SLAP_MR_SUBSTR_INITIAL ) { + if( flags & SLAP_INDEX_SUBSTR_INITIAL ) { pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX; lutil_MD5Init( &MD5context ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -953,7 +998,7 @@ int caseExactIA5SubstringsIndexer( keys[nkeys++] = ber_bvdup( &digest ); } - if( flags & SLAP_MR_SUBSTR_FINAL ) { + if( flags & SLAP_INDEX_SUBSTR_FINAL ) { pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX; lutil_MD5Init( &MD5context ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -976,13 +1021,20 @@ int caseExactIA5SubstringsIndexer( } } - keys[nkeys] = NULL; - *keysp = keys; + if( nkeys > 0 ) { + keys[nkeys] = NULL; + *keysp = keys; + } else { + ch_free( keys ); + *keysp = NULL; + } + return LDAP_SUCCESS; } int caseExactIA5SubstringsFilter( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, @@ -991,7 +1043,7 @@ int caseExactIA5SubstringsFilter( { SubstringsAssertion *sa = assertValue; char pre; - int nkeys = 0; + ber_len_t nkeys = 0; size_t slen, mlen, klen; struct berval **keys; lutil_MD5_CTX MD5context; @@ -999,12 +1051,24 @@ int caseExactIA5SubstringsFilter( struct berval *value; struct berval digest; - if( sa->sa_initial != NULL && + if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL && sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { nkeys++; } - if( sa->sa_final != NULL && + + if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) { + ber_len_t i; + for( i=0; sa->sa_any[i] != NULL; i++ ) { + if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + /* don't bother accounting for stepping */ + nkeys += sa->sa_any[i]->bv_len - + ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); + } + } + } + + if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL && sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { nkeys++; @@ -1024,7 +1088,7 @@ int caseExactIA5SubstringsFilter( keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); nkeys = 0; - if( sa->sa_initial != NULL && + if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL && sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX; @@ -1048,11 +1112,46 @@ int caseExactIA5SubstringsFilter( value->bv_val, klen ); lutil_MD5Final( MD5digest, &MD5context ); - ber_bvfree( value ); keys[nkeys++] = ber_bvdup( &digest ); } - if( sa->sa_final != NULL && + if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) { + ber_len_t i, j; + pre = SLAP_INDEX_SUBSTR_PREFIX; + klen = SLAP_INDEX_SUBSTR_MAXLEN; + + for( i=0; sa->sa_any[i] != NULL; i++ ) { + if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) { + continue; + } + + value = sa->sa_any[i]; + + for(j=0; + j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN; + j += SLAP_INDEX_SUBSTR_STEP ) + { + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + &pre, sizeof( pre ) ); + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + &value->bv_val[j], klen ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[nkeys++] = ber_bvdup( &digest ); + } + } + } + + if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL && sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX; @@ -1076,20 +1175,24 @@ int caseExactIA5SubstringsFilter( &value->bv_val[value->bv_len-klen], klen ); lutil_MD5Final( MD5digest, &MD5context ); - ber_bvfree( value ); keys[nkeys++] = ber_bvdup( &digest ); } - keys[nkeys] = NULL; + if( nkeys > 0 ) { + keys[nkeys] = NULL; + *keysp = keys; + } else { + ch_free( keys ); + *keysp = NULL; + } - *keysp = keys; return LDAP_SUCCESS; } static int caseIgnoreIA5Match( int *matchp, - unsigned flags, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *value, @@ -1124,7 +1227,7 @@ static char *strcasechr( const char *str, int c ) static int caseIgnoreIA5SubstringsMatch( int *matchp, - unsigned flags, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *value, @@ -1249,7 +1352,8 @@ done: /* Index generation function */ int caseIgnoreIA5Indexer( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, @@ -1305,7 +1409,8 @@ int caseIgnoreIA5Indexer( /* Index generation function */ int caseIgnoreIA5Filter( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, @@ -1348,19 +1453,21 @@ int caseIgnoreIA5Filter( ber_bvfree( value ); *keysp = keys; + return LDAP_SUCCESS; } /* Substrings Index generation function */ int caseIgnoreIA5SubstringsIndexer( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, struct berval **values, struct berval ***keysp ) { - int i, nkeys, types; + ber_len_t i, nkeys; size_t slen, mlen; struct berval **keys; lutil_MD5_CTX MD5context; @@ -1369,11 +1476,6 @@ int caseIgnoreIA5SubstringsIndexer( digest.bv_val = MD5digest; digest.bv_len = sizeof(MD5digest); - types = 0; - if( flags & SLAP_MR_SUBSTR_INITIAL ) types++; - if( flags & SLAP_MR_SUBSTR_FINAL ) types++; - /* no SUBSTR_ANY indexing */ - nkeys=0; for( i=0; values[i] != NULL; i++ ) { /* count number of indices to generate */ @@ -1381,10 +1483,28 @@ int caseIgnoreIA5SubstringsIndexer( continue; } - if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { - nkeys += SLAP_INDEX_SUBSTR_MAXLEN - ( SLAP_INDEX_SUBSTR_MINLEN - 1); - } else { - nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + if( flags & SLAP_INDEX_SUBSTR_INITIAL ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += SLAP_INDEX_SUBSTR_MAXLEN - + ( SLAP_INDEX_SUBSTR_MINLEN - 1); + } else { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + } + } + + if( flags & SLAP_INDEX_SUBSTR_ANY ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); + } + } + + if( flags & SLAP_INDEX_SUBSTR_FINAL ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += SLAP_INDEX_SUBSTR_MAXLEN - + ( SLAP_INDEX_SUBSTR_MINLEN - 1); + } else { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + } } } assert( i > 0 ); @@ -1395,7 +1515,6 @@ int caseIgnoreIA5SubstringsIndexer( return LDAP_SUCCESS; } - nkeys *= types; /* We need to generate keys for each type */ keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); slen = strlen( syntax->ssyn_oid ); @@ -1408,16 +1527,44 @@ int caseIgnoreIA5SubstringsIndexer( if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; - max = SLAP_INDEX_SUBSTR_MAXLEN < values[i]->bv_len - ? SLAP_INDEX_SUBSTR_MAXLEN : values[i]->bv_len; - value = ber_bvdup( values[i] ); ldap_pvt_str2upper( value->bv_val ); + if( ( flags & SLAP_INDEX_SUBSTR_ANY ) && + ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) ) + { + char pre = SLAP_INDEX_SUBSTR_PREFIX; + max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1); + + for( j=0; jbv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + + lutil_MD5Update( &MD5context, + &pre, sizeof( pre ) ); + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + &value->bv_val[j], + SLAP_INDEX_SUBSTR_MAXLEN ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[nkeys++] = ber_bvdup( &digest ); + } + } + + max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len + ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; + for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) { char pre; - if( flags & SLAP_MR_SUBSTR_INITIAL ) { + if( flags & SLAP_INDEX_SUBSTR_INITIAL ) { pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX; lutil_MD5Init( &MD5context ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -1437,7 +1584,7 @@ int caseIgnoreIA5SubstringsIndexer( keys[nkeys++] = ber_bvdup( &digest ); } - if( flags & SLAP_MR_SUBSTR_FINAL ) { + if( flags & SLAP_INDEX_SUBSTR_FINAL ) { pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX; lutil_MD5Init( &MD5context ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -1462,13 +1609,20 @@ int caseIgnoreIA5SubstringsIndexer( ber_bvfree( value ); } - keys[nkeys] = NULL; - *keysp = keys; + if( nkeys > 0 ) { + keys[nkeys] = NULL; + *keysp = keys; + } else { + ch_free( keys ); + *keysp = NULL; + } + return LDAP_SUCCESS; } int caseIgnoreIA5SubstringsFilter( - unsigned flags, + slap_mask_t use, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, @@ -1477,7 +1631,7 @@ int caseIgnoreIA5SubstringsFilter( { SubstringsAssertion *sa = assertValue; char pre; - int nkeys = 0; + ber_len_t nkeys = 0; size_t slen, mlen, klen; struct berval **keys; lutil_MD5_CTX MD5context; @@ -1485,12 +1639,24 @@ int caseIgnoreIA5SubstringsFilter( struct berval *value; struct berval digest; - if( sa->sa_initial != NULL && + if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL && sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { nkeys++; } - if( sa->sa_final != NULL && + + if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) { + ber_len_t i; + for( i=0; sa->sa_any[i] != NULL; i++ ) { + if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + /* don't bother accounting for stepping */ + nkeys += sa->sa_any[i]->bv_len - + ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); + } + } + } + + if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL && sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { nkeys++; @@ -1510,7 +1676,7 @@ int caseIgnoreIA5SubstringsFilter( keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); nkeys = 0; - if( sa->sa_initial != NULL && + if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL && sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX; @@ -1539,7 +1705,46 @@ int caseIgnoreIA5SubstringsFilter( keys[nkeys++] = ber_bvdup( &digest ); } - if( sa->sa_final != NULL && + if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) { + ber_len_t i, j; + pre = SLAP_INDEX_SUBSTR_PREFIX; + klen = SLAP_INDEX_SUBSTR_MAXLEN; + + for( i=0; sa->sa_any[i] != NULL; i++ ) { + if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) { + continue; + } + + value = ber_bvdup( sa->sa_any[i] ); + ldap_pvt_str2upper( value->bv_val ); + + for(j=0; + j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN; + j += SLAP_INDEX_SUBSTR_STEP ) + { + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + &pre, sizeof( pre ) ); + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + &value->bv_val[j], klen ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[nkeys++] = ber_bvdup( &digest ); + } + + ber_bvfree( value ); + } + } + + if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL && sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX; @@ -1568,9 +1773,14 @@ int caseIgnoreIA5SubstringsFilter( keys[nkeys++] = ber_bvdup( &digest ); } - keys[nkeys] = NULL; + if( nkeys > 0 ) { + keys[nkeys] = NULL; + *keysp = keys; + } else { + ch_free( keys ); + *keysp = NULL; + } - *keysp = keys; return LDAP_SUCCESS; } @@ -1632,7 +1842,7 @@ numericStringNormalize( static int objectIdentifierFirstComponentMatch( int *matchp, - unsigned flags, + slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *value, diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 48e1b5d99b..9c262ec3cb 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -134,11 +134,15 @@ LDAP_SLAPD_F (int) slap_debug; #define SLAP_INDEX_SUBSTR_INITIAL ( SLAP_INDEX_SUBSTR | 0x0100UL ) #define SLAP_INDEX_SUBSTR_ANY ( SLAP_INDEX_SUBSTR | 0x0200UL ) #define SLAP_INDEX_SUBSTR_FINAL ( SLAP_INDEX_SUBSTR | 0x0400UL ) -#define SLAP_INDEX_SUBSTR_DEFAULT ( SLAP_INDEX_SUBSTR \ - | SLAP_INDEX_SUBSTR_INITIAL | SLAP_INDEX_SUBSTR_FINAL ) +#define SLAP_INDEX_SUBSTR_DEFAULT \ + ( SLAP_INDEX_SUBSTR \ + | SLAP_INDEX_SUBSTR_INITIAL \ + | SLAP_INDEX_SUBSTR_ANY \ + | SLAP_INDEX_SUBSTR_FINAL ) #define SLAP_INDEX_SUBSTR_MINLEN 2 #define SLAP_INDEX_SUBSTR_MAXLEN 4 +#define SLAP_INDEX_SUBSTR_STEP 2 #define SLAP_INDEX_FLAGS 0xF000UL #define SLAP_INDEX_SUBTYPES 0x1000UL /* use index with subtypes */ @@ -146,7 +150,7 @@ LDAP_SLAPD_F (int) slap_debug; #define SLAP_INDEX_LANG 0x4000UL /* use index with lang subtypes */ #define SLAP_INDEX_AUTO_LANG 0x8000UL /* use mask with lang subtypes */ -typedef long slap_index; +typedef unsigned long slap_mask_t; /* * there is a single index for each attribute. these prefixes ensure @@ -239,7 +243,7 @@ typedef int slap_mr_convert_func LDAP_P(( /* Normalizer */ typedef int slap_mr_normalize_func LDAP_P(( - unsigned use, + slap_mask_t use, struct slap_syntax *syntax, /* NULL if in is asserted value */ struct slap_matching_rule *mr, struct berval * in, @@ -248,7 +252,7 @@ typedef int slap_mr_normalize_func LDAP_P(( /* Match (compare) function */ typedef int slap_mr_match_func LDAP_P(( int *match, - unsigned flags, + slap_mask_t use, struct slap_syntax *syntax, /* syntax of stored value */ struct slap_matching_rule *mr, struct berval * value, @@ -256,7 +260,8 @@ typedef int slap_mr_match_func LDAP_P(( /* Index generation function */ typedef int slap_mr_indexer_func LDAP_P(( - unsigned flags, + slap_mask_t use, + slap_mask_t mask, struct slap_syntax *syntax, /* syntax of stored value */ struct slap_matching_rule *mr, struct berval *prefix, @@ -265,7 +270,8 @@ typedef int slap_mr_indexer_func LDAP_P(( /* Filter index function */ typedef int slap_mr_filter_func LDAP_P(( - unsigned flags, + slap_mask_t use, + slap_mask_t mask, struct slap_syntax *syntax, /* syntax of stored value */ struct slap_matching_rule *mr, struct berval *prefix, @@ -274,7 +280,7 @@ typedef int slap_mr_filter_func LDAP_P(( typedef struct slap_matching_rule { LDAPMatchingRule smr_mrule; - unsigned smr_usage; + slap_mask_t smr_usage; #define SLAP_MR_TYPE_MASK 0xFF00U #define SLAP_MR_SUBTYPE_MASK 0x00F0U diff --git a/tests/data/slapd.conf b/tests/data/slapd.conf index 0cac379f7f..413b16ec67 100644 --- a/tests/data/slapd.conf +++ b/tests/data/slapd.conf @@ -23,6 +23,7 @@ directory ./test-db rootdn "cn=Manager, o=University of Michigan, c=US" rootpw secret index objectclass eq -index cn,sn,uid pres,eq,sub +index uid pres,eq,sub +index cn,sn pres,eq,sub,subany dbnosync dbnolocking -- 2.39.5