14. Property Queries as Selection Policy

The property mechanism is how a deployment states which implementation it will accept. This chapter treats it as what it is — a policy language — and addresses requirements F5 and F10.

14.1 The language

A property query is a comma-separated sequence of clauses. A clause may require a property to have a value, require it to be absent, or express a preference rather than a requirement. A query is evaluated against the properties each implementation declares in its OSSL_ALGORITHM entry (§3.3).

QueryMeaning
provider=tlsextOnly implementations from that provider are acceptable
provider!=defaultThe default provider's implementations are excluded
?provider=tlsextPrefer that provider, but accept another
provider=tlsext,fips=yesBoth conditions required

The distinction between the first form and the third is the distinction between a requirement and a wish, and it is the whole of §6.4 expressed in one character.

14.2 Mandatory versus preferred, and why it matters

A deployment introduces a particular algorithm for a reason — a regulatory obligation, an internal standard, a migration. If that reason is genuine, then a connection that does not use the algorithm has not satisfied it, and should not be established.

Expressing the requirement as a preference produces the opposite behaviour: when the provider fails to load, when the configuration names the wrong path, when the module is present but activated in a different library context, the fetch quietly resolves to the default implementation and the connection succeeds. The deployment believes it is compliant. Nothing in the connection indicates otherwise.

The failure is silent and it is the common case. Every mechanism in this chapter works correctly; the deployment simply asked the wrong question. This is why requirement F10 exists and why Chapter 19 makes the negative test — deactivate the provider, assert the handshake fails — a required test rather than a thorough one.

14.3 Properties a provider should declare

The design declares, on each algorithm:

The design specifically does not declare fips=yes. The provider is not a validated module (§6.5), and declaring the property would allow it to be selected by a query intended to restrict selection to validated implementations — defeating the control entirely. A property is an assertion, and asserting something untrue in a selection language is a vulnerability, not a configuration choice.

14.4 Where the query is set

A property query may be supplied per fetch, or set as a default for a library context. For the TLS case the application does not perform the fetches — libssl does — so the per-fetch route is unavailable to a deployment that is not modifying the application. The context-wide default is therefore the mechanism in practice, set programmatically or through configuration.

This has a consequence that deserves care. A context-wide default applies to every fetch in that context, including fetches by code with no relation to TLS. A default of provider=tlsext in a context where the provider offers only three algorithms will cause every other fetch in that context to fail. The usable form is one that constrains only what the deployment means to constrain, which in practice means naming the algorithms distinctively (§9.5) and configuring TLS to ask for them by name, rather than imposing a broad property default.

14.5 Diagnosis

When selection does not behave as expected, the questions in order are: is the provider loaded; does it advertise the algorithm under the name being fetched; does the property query admit it; and is the fetch happening in the context where it is activated. Each has a direct observation, and taking them in order is faster than reasoning about the outcome.

openssl list -providers                        # loaded?
openssl list -digest-algorithms -provider tlsext  # advertised, under what name?
openssl list -digest-algorithms -propquery 'provider=tlsext'   # admitted by query?

The fourth question — the context — has no command-line observation, because the command-line tool uses the default context. It is answerable only by inspecting the application, which is why §13.3 treats it as a deployment hazard rather than a diagnostic step.