490 lines
22 KiB
Text
490 lines
22 KiB
Text
=pod
|
|
|
|
=head1 NAME
|
|
|
|
X509_verify_cert,
|
|
X509_STORE_CTX_verify,
|
|
X509_build_chain - build and verify X509 certificate chain
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
#include <openssl/x509_vfy.h>
|
|
|
|
int X509_verify_cert(X509_STORE_CTX *ctx);
|
|
int X509_STORE_CTX_verify(X509_STORE_CTX *ctx);
|
|
STACK_OF(X509) *X509_build_chain(X509 *target, STACK_OF(X509) *certs,
|
|
X509_STORE *store, int with_self_signed,
|
|
OSSL_LIB_CTX *libctx, const char *propq);
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
=head2 X509_verify_cert and X509_STORE_CTX_verify
|
|
|
|
X509_verify_cert() attempts to build and validate a certificate chain for the
|
|
target certificate set in I<ctx>. The verification context, of type
|
|
B<X509_STORE_CTX>, must first be constructed with L<X509_STORE_CTX_new(3)> and
|
|
initialised with L<X509_STORE_CTX_init(3)>. It carries the target certificate,
|
|
the trust store, an optional stack of untrusted certificates that may assist
|
|
chain construction, verification parameters such as flags and a verification
|
|
purpose, an optional verification callback, and, after a call, the verification
|
|
outcome.
|
|
|
|
A B<X509_STORE_CTX> can be used for only one verification. Calling
|
|
X509_verify_cert() a second time on the same context without reinitialising it
|
|
fails with a negative return value, and L<X509_STORE_CTX_get_error(3)>
|
|
subsequently returns B<X509_V_ERR_INVALID_CALL>.
|
|
|
|
When the target is a certificate, the function performs the following steps in
|
|
order. The first step that fails aborts verification, except where a
|
|
verification callback explicitly waives the error (see
|
|
L</THE VERIFICATION CALLBACK> below):
|
|
|
|
=over 4
|
|
|
|
=item 1.
|
|
|
|
B<Chain construction.> Starting from the target certificate, the verification
|
|
machinery seeks an issuer for the certificate currently at the top of the
|
|
chain, drawing candidates from I<ctx>'s untrusted stack and from the trust
|
|
store. By default the search is untrusted-first: the untrusted stack is
|
|
examined before the trust store. Setting B<X509_V_FLAG_TRUSTED_FIRST> on
|
|
I<ctx>'s verification parameters reverses this. When an untrusted-first
|
|
search fails to reach a trust anchor and B<X509_V_FLAG_NO_ALT_CHAINS> is not
|
|
set, the search is retried with progressively shorter untrusted prefixes in
|
|
an attempt to find an alternative trusted path. The chain length is bounded
|
|
by the configured depth limit (see L<X509_VERIFY_PARAM_set_depth(3)>);
|
|
exceeding it yields B<X509_V_ERR_CERT_CHAIN_TOO_LONG>. If more than one
|
|
chain is possible, only one is taken.
|
|
|
|
Failure to build a chain to a trust anchor yields an error such as
|
|
B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT>,
|
|
B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY>,
|
|
B<X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN>,
|
|
B<X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT>, or
|
|
B<X509_V_ERR_CERT_CHAIN_TOO_LONG>.
|
|
|
|
=item 2.
|
|
|
|
B<Certificate extension validation> per RFC 5280, including basic constraints,
|
|
key usage and the verification purpose set via
|
|
L<X509_VERIFY_PARAM_set_purpose(3)>.
|
|
|
|
=item 3.
|
|
|
|
B<Security level checks> against the configured authentication level, covering
|
|
issuer key sizes (B<X509_V_ERR_CA_KEY_TOO_SMALL>) and signature algorithm
|
|
strength (B<X509_V_ERR_CA_MD_TOO_WEAK>). The leaf key is checked separately
|
|
before chain construction begins (B<X509_V_ERR_EE_KEY_TOO_SMALL>).
|
|
|
|
=item 4.
|
|
|
|
B<Identity checks> against any hostnames, email addresses or IP addresses
|
|
configured on the verification parameters
|
|
(L<X509_VERIFY_PARAM_set1_host(3)> and related).
|
|
|
|
=item 5.
|
|
|
|
B<Revocation checks> via CRLs and, when configured, OCSP. The set of checks
|
|
performed is controlled by flags such as B<X509_V_FLAG_CRL_CHECK> and
|
|
B<X509_V_FLAG_CRL_CHECK_ALL>.
|
|
|
|
=item 6.
|
|
|
|
B<Signature and validity period checks> on every certificate in the chain,
|
|
walking from the trust anchor down to the target. The signature on the
|
|
chain's terminating certificate is not verified: trust is taken from its
|
|
presence in the trust store rather than from its signature. This applies
|
|
both to a conventional self-signed trust anchor and, when
|
|
B<X509_V_FLAG_PARTIAL_CHAIN> is in effect, to a non-self-signed
|
|
intermediate promoted to anchor status. B<X509_V_FLAG_CHECK_SS_SIGNATURE>
|
|
requests that the self-signature on a self-signed terminator be verified;
|
|
it has no effect when the terminator is a non-self-signed certificate.
|
|
Validity periods are checked on every certificate, including the
|
|
terminator.
|
|
|
|
=item 7.
|
|
|
|
B<Name constraint validation> per RFC 5280 section 4.2.1.10; see
|
|
L<NAME_CONSTRAINTS_check(3)> for details of the matching primitive and
|
|
the general-name types it covers.
|
|
|
|
=item 8.
|
|
|
|
B<RFC 3779 path validation> of AS-number and IP-address delegation
|
|
extensions, performed by default unless OpenSSL was built with
|
|
B<no-rfc3779>.
|
|
|
|
=item 9.
|
|
|
|
B<Certificate policy validation>, performed only when
|
|
B<X509_V_FLAG_POLICY_CHECK> is set.
|
|
|
|
=back
|
|
|
|
Several B<X509_V_FLAG_*> values modify the behaviour of these checks;
|
|
representative ones are named at the relevant step above, but the list there
|
|
is not exhaustive. The complete set of verification flags, the effect each
|
|
one has, and the functions used to query and modify them are documented in
|
|
L<X509_VERIFY_PARAM_set_flags(3)>.
|
|
|
|
Applications rarely call X509_verify_cert() directly. It is invoked internally
|
|
by OpenSSL during S/MIME and CMS verification and during the TLS handshake.
|
|
|
|
X509_STORE_CTX_verify() behaves identically to X509_verify_cert() except for
|
|
the selection of the target certificate: if no target has been set on I<ctx>
|
|
(see L<X509_STORE_CTX_set_cert(3)>) and the untrusted stack is nonempty, the
|
|
first certificate in the untrusted stack is adopted as the target before
|
|
verification begins. If a target was set explicitly, X509_STORE_CTX_verify()
|
|
uses it and does not consult the untrusted stack for this purpose.
|
|
|
|
=head2 Raw public key targets
|
|
|
|
When the verification target is a raw public key rather than a certificate
|
|
(set via L<X509_STORE_CTX_init_rpk(3)>), both functions validate the raw public
|
|
key instead of a certificate chain. The set of possible checks is significantly
|
|
reduced: there are no extensions, names, CRLs or signatures to verify. The raw
|
|
public key can be authenticated only via DANE TLSA records, either locally
|
|
synthesised or obtained by the application from DNS. Raw public key DANE TLSA
|
|
records may be added via L<SSL_add_expected_rpk(3)> or L<SSL_dane_tlsa_add(3)>.
|
|
|
|
=head2 X509_build_chain
|
|
|
|
X509_build_chain() builds a certificate chain starting from I<target>, using
|
|
the same chain-construction algorithm as X509_verify_cert() (see
|
|
L</X509_verify_cert and X509_STORE_CTX_verify> above). It internally uses a
|
|
B<X509_STORE_CTX> structure associated with the library context I<libctx>
|
|
and property query string I<propq>, both of which may be NULL. The role of
|
|
I<certs> depends on I<store>:
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
If I<store> is non-NULL, I<certs> is treated as an optional list of
|
|
B<untrusted> intermediate certificates that may help complete the chain, and
|
|
the chain must reach a trust anchor contained in I<store>. If no chain to a
|
|
trust anchor can be built, the function fails and returns NULL.
|
|
|
|
=item *
|
|
|
|
If I<store> is NULL, I<certs> is installed as the B<trusted> stack for the
|
|
internal context (see L<X509_STORE_CTX_set0_trusted_stack(3)>). In this mode
|
|
the function builds the chain as far as it can but does not require it to
|
|
reach an anchor: if chain construction fails partway, the partial chain built
|
|
so far is still returned.
|
|
|
|
=back
|
|
|
|
Because the internal B<X509_STORE_CTX> is allocated and freed inside
|
|
X509_build_chain(), search-policy flags such as B<X509_V_FLAG_TRUSTED_FIRST>
|
|
and B<X509_V_FLAG_NO_ALT_CHAINS> and the configured depth limit always take
|
|
their default values, and the specific B<X509_V_ERR_*> code that caused
|
|
chain construction to fail is not reported back: the function signals only
|
|
success or failure through its return value (and, when I<store> is NULL, may
|
|
also return a partial chain).
|
|
|
|
On success the returned stack starts with a newly up-referenced I<target>
|
|
followed by the issuer certificates that were found. A self-signed certificate
|
|
at the top of the chain is included in the returned stack when either
|
|
I<with_self_signed> is 1, or the chain consists solely of I<target> (for
|
|
example because I<target> itself is self-signed or no further issuer could
|
|
be found). When the chain has more than one element and I<with_self_signed>
|
|
is 0, the self-signed top is omitted from the result.
|
|
|
|
The caller is responsible for freeing the returned stack.
|
|
|
|
=head1 THE VERIFICATION CALLBACK
|
|
|
|
Each B<X509_STORE_CTX> carries a I<verification callback> with the signature
|
|
|
|
int (*verify_cb)(int ok, X509_STORE_CTX *ctx);
|
|
|
|
This callback is invoked by X509_verify_cert() and X509_STORE_CTX_verify()
|
|
at multiple points during verification, both to B<report errors> and to
|
|
B<notify of progress>. It is installed by L<X509_STORE_CTX_set_verify_cb(3)>
|
|
on the context, or it is inherited at L<X509_STORE_CTX_init(3)> time from
|
|
the B<X509_STORE> (see L<X509_STORE_set_verify_cb_func(3)>). If neither has
|
|
been set, a default callback is used which simply returns its I<ok> argument
|
|
unchanged, causing every error to abort verification.
|
|
|
|
=head2 When the callback is called
|
|
|
|
There are two distinct invocation patterns:
|
|
|
|
=over 4
|
|
|
|
=item B<Error notification> (I<ok> = 0)
|
|
|
|
The callback is called with I<ok> set to 0 each time a check fails. Before the
|
|
call, the verification machinery records the B<X509_V_ERR_*> code describing
|
|
the failure on I<ctx>, and for certificate-level errors also records the
|
|
depth at which the error was detected and the certificate in question. The
|
|
callback inspects these via L<X509_STORE_CTX_get_error(3)>,
|
|
L<X509_STORE_CTX_get_error_depth(3)>, and L<X509_STORE_CTX_get_current_cert(3)>.
|
|
CRL- and OCSP-related errors update only the error code; the depth and
|
|
current certificate retain their values from a preceding context.
|
|
|
|
=item B<Per-certificate success notification> (I<ok> = 1)
|
|
|
|
During the signature-and-validity pass, after each certificate in the chain
|
|
has been checked successfully, the callback is called with I<ok> set to 1.
|
|
The current certificate, current issuer, and error depth (queryable
|
|
respectively via L<X509_STORE_CTX_get_current_cert(3)>,
|
|
L<X509_STORE_CTX_get0_current_issuer(3)>, and
|
|
L<X509_STORE_CTX_get_error_depth(3)>) describe the certificate that has just
|
|
been accepted. The callback may use this to log progress, but B<must> return
|
|
a nonzero value, otherwise verification is aborted.
|
|
|
|
=back
|
|
|
|
The callback's return value controls subsequent verification:
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
A nonzero return value causes verification to B<continue>. For an error
|
|
notification this constitutes B<waiving> the error.
|
|
|
|
=item *
|
|
|
|
A zero return value causes verification to B<abort> immediately. The function
|
|
returns 0 to its caller in this case, regardless of whether the callback was
|
|
invoked with I<ok> = 0 or I<ok> = 1.
|
|
|
|
=back
|
|
|
|
=head2 Sticky errors
|
|
|
|
When the callback waives an error by returning nonzero, the underlying check is
|
|
treated as passed for control-flow purposes, but the error code recorded on
|
|
I<ctx> is B<not> reset to B<X509_V_OK>. A subsequent successful return from
|
|
X509_verify_cert() therefore does B<not> imply that
|
|
L<X509_STORE_CTX_get_error(3)> will return B<X509_V_OK>: it may still hold
|
|
the last error code that was waived. This is intentional. Only the callback
|
|
itself is permitted to overwrite the error code, via
|
|
L<X509_STORE_CTX_set_error(3)>, and only at its own risk.
|
|
|
|
=head2 Dangers
|
|
|
|
A verification callback that returns nonzero on an error notification has, by
|
|
definition, suppressed an authentication check that OpenSSL considered
|
|
necessary. Callers should treat installing a callback that waives errors as a
|
|
deliberate weakening of the security guarantees of X509_verify_cert(), to be
|
|
done only for specific, well-understood error codes. The following pitfalls are
|
|
common:
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
B<Blanket waivers>. A callback that returns 1 unconditionally turns
|
|
X509_verify_cert() into "accept anything" and is almost always wrong outside of
|
|
diagnostics. Inspect the error code via L<X509_STORE_CTX_get_error(3)> and
|
|
waive only the specific codes you intend to.
|
|
|
|
=item *
|
|
|
|
B<Failing a success notification>. Because the callback is also called with
|
|
I<ok> = 1, a callback that mistakenly returns 0 in that case causes
|
|
verification to fail even though every check passed. The caller cannot
|
|
distinguish this from a genuine failure based on the return value alone.
|
|
|
|
=item *
|
|
|
|
B<Clearing the error code>. The sticky-error rule exists so that a waived
|
|
error remains visible to the caller after verification returns. A callback
|
|
that calls L<X509_STORE_CTX_set_error(3)> with B<X509_V_OK> hides this
|
|
information and can also mask a later error if the callback is invoked again
|
|
before verification completes.
|
|
|
|
=item *
|
|
|
|
B<Mutating the verification context>. The B<X509_STORE_CTX> is live during
|
|
the callback: the verification routines are actively reading its chain,
|
|
parameters, and other state. Calling context-mutating functions from within
|
|
the callback -- for example, replacing the verified chain via
|
|
L<X509_STORE_CTX_set0_verified_chain(3)>, swapping the trust store or
|
|
untrusted stack, or changing verification flags, depth, purpose, or target
|
|
-- can corrupt the in-progress verification, produce inconsistent behaviour
|
|
between later steps of the pipeline, or, in the case of the verified chain,
|
|
cause use-after-free. The only mutators reasonable from within a callback
|
|
are the error-related setters (L<X509_STORE_CTX_set_error(3)>,
|
|
L<X509_STORE_CTX_set_error_depth(3)>, L<X509_STORE_CTX_set_current_cert(3)>),
|
|
and even those should be used sparingly (see L</Sticky errors>).
|
|
|
|
=item *
|
|
|
|
B<Heavy work in the callback>. The callback is on the hot path of every
|
|
certificate check; expensive work performed there will slow every TLS handshake
|
|
or S/MIME verification that uses the surrounding context.
|
|
|
|
=item *
|
|
|
|
B<Trusting the depth alone>. The error depth, from
|
|
L<X509_STORE_CTX_get_error_depth(3)>, records where an error was detected
|
|
during chain processing, not the position of the certificate in the final
|
|
chain. Always consult L<X509_STORE_CTX_get_current_cert(3)> in addition to
|
|
the depth when deciding whether to waive.
|
|
|
|
=item *
|
|
|
|
B<Fragility with respect to check order>. The set of errors the callback
|
|
observes, and the order in which it observes them, depends on the internal
|
|
order in which verification checks are performed. When a certificate has more
|
|
than one problem, only the first check to detect a problem causes the
|
|
callback to be invoked for that certificate; later checks are not reached
|
|
unless the callback waives the earlier error. This ordering is an
|
|
implementation detail and is not part of the stable API: a refactor that
|
|
reorders internal checks without altering the binary success/failure contract
|
|
of X509_verify_cert() may still change which B<X509_V_ERR_*> code the
|
|
callback sees, or whether a given code is reported at all. Callbacks that
|
|
branch on a specific error code being reported, or that assume earlier checks
|
|
have already filtered out certain conditions, can therefore change behaviour
|
|
silently across OpenSSL releases. Write callbacks defensively: re-fetch the
|
|
error code and the current certificate via L<X509_STORE_CTX_get_error(3)>
|
|
and L<X509_STORE_CTX_get_current_cert(3)> afresh on each invocation, and
|
|
treat "this error code never appears" as an assumption that may be
|
|
invalidated. More fundamentally, because the set and order of error
|
|
notifications is not a stable contract, the callback cannot be relied upon to
|
|
observe any particular condition or sequence of conditions; that makes it an
|
|
unsound mechanism for enforcing or modifying security policy. Use of the
|
|
verification callback to alter verification outcomes -- to waive errors, to
|
|
inject conditional acceptance, or to gate behaviour on a specific
|
|
B<X509_V_ERR_*> code being reported -- is therefore discouraged in production
|
|
code. Reserve the callback for diagnostic and logging purposes, where future
|
|
changes in which errors appear, or in what order, are not security-relevant.
|
|
|
|
=back
|
|
|
|
The default callback waives nothing and is the safe choice; it is the right
|
|
behaviour for almost all production uses.
|
|
|
|
=head1 RETURN VALUES
|
|
|
|
X509_verify_cert() and X509_STORE_CTX_verify() return:
|
|
|
|
=over 4
|
|
|
|
=item B<1>
|
|
|
|
if a complete chain has been built and every check either succeeded or was
|
|
waived by the verification callback. Note that the latter case does not
|
|
guarantee that L<X509_STORE_CTX_get_error(3)> returns B<X509_V_OK>; see
|
|
L</Sticky errors>. The return value is the authoritative success/failure
|
|
signal: callers do not need to additionally check that
|
|
L<X509_STORE_CTX_get_error(3)> returns B<X509_V_OK> to consider verification
|
|
successful. They may consult it to learn whether, and which, errors were
|
|
waived by the verification callback.
|
|
|
|
=item B<0>
|
|
|
|
if verification was rejected. This occurs when a check failed and the callback
|
|
did not waive the error, when a trust decision actively rejected the chain, or
|
|
when the verification callback returned 0 from a success notification (see
|
|
L</THE VERIFICATION CALLBACK>). When a certificate would have failed more
|
|
than one check, the specific B<X509_V_ERR_*> code returned by
|
|
L<X509_STORE_CTX_get_error(3)> reflects whichever check fired first; this
|
|
ordering is an implementation detail and is not stable across releases.
|
|
Callers must therefore treat the return value as the authoritative
|
|
success/failure signal, and treat the specific error code as diagnostic
|
|
information that may shift over time.
|
|
|
|
=item A B<negative> value
|
|
|
|
on a hard error that prevented verification from running to completion. The
|
|
documented cases are: I<ctx> is NULL; I<ctx> has no target certificate set;
|
|
I<ctx> has already been used for a previous verification; memory allocation
|
|
failed; the trust store lookup function returned an error; or an internal
|
|
invariant was violated. In these cases L<X509_STORE_CTX_get_error(3)>
|
|
returns an appropriate B<X509_V_ERR_*> value (B<X509_V_ERR_INVALID_CALL>,
|
|
B<X509_V_ERR_OUT_OF_MEM>, B<X509_V_ERR_STORE_LOOKUP> or
|
|
B<X509_V_ERR_UNSPECIFIED>).
|
|
|
|
=back
|
|
|
|
In all failure modes, additional information can be obtained from
|
|
L<X509_STORE_CTX_get_error(3)> and the related accessors. Applications must
|
|
treat any return value E<lt>= 0 as verification not having succeeded.
|
|
|
|
X509_build_chain() returns NULL on error. Otherwise it returns a newly
|
|
allocated stack of certificates that the caller must free; the stack may
|
|
represent only a partial chain when I<store> is NULL.
|
|
|
|
=head1 BUGS
|
|
|
|
Several aspects of chain construction depart from the recommendations of
|
|
RFC 4158 (Certification Path Building) and from strict RFC 5280 path
|
|
validation. Callers should be aware of the following:
|
|
|
|
The chain search is not optimised in the manner described by RFC 4158
|
|
sections 3.1 to 3.5. Candidate issuers are not scored against the set of
|
|
heuristics RFC 4158 recommends; at each step the first viable candidate
|
|
is committed to, with the only preference being for a candidate whose
|
|
validity period covers the current time. There is no tree-traversal
|
|
backtracking: when an initial chain does not reach a trust anchor, the
|
|
search is retried with progressively shorter untrusted prefixes (unless
|
|
B<X509_V_FLAG_NO_ALT_CHAINS> is set), but different candidate issuers at
|
|
intermediate positions of the same chain are not tried. In simple
|
|
hierarchical PKIs this is rarely an issue. In cross-certified or bridged
|
|
PKI environments X509_verify_cert() may fail to find a valid certification
|
|
path even when one demonstrably exists in the available certificate set.
|
|
|
|
Issuer key usage is not enforced during chain construction. RFC 5280
|
|
section 6.1.4(n) and RFC 4158 section 3.5.3 call for verifying that an
|
|
issuer candidate's keyUsage extension permits certificate signing
|
|
(B<keyCertSign>) before that candidate is selected. OpenSSL defers this
|
|
check to the later extension-validation pass: if two candidate issuers
|
|
exist for a certificate, and the one lacking B<keyCertSign> happens to be
|
|
selected first, verification fails on the extension check rather than
|
|
backing off and trying the other candidate. The misuse is ultimately
|
|
caught, but a chain that would have validated through the alternative
|
|
issuer is not built.
|
|
|
|
B<X509_V_FLAG_PARTIAL_CHAIN> relaxes the trust-anchor requirement from
|
|
the one defined by RFC 5280 section 6.1.1(d). With the flag set, any
|
|
certificate in the trust store is acceptable as the terminator of the
|
|
chain, even if it is not a self-signed root. This is an intentional and
|
|
now-common deviation that supports modern practices such as pinning trust
|
|
to a specific intermediate, or shortening chains by treating a
|
|
sufficiently-trusted intermediate as the trust point and eliding the root
|
|
above it. Callers should nevertheless be aware that the chain returned in
|
|
this mode does not necessarily terminate at an RFC 5280-style trust
|
|
anchor.
|
|
|
|
L<NAME_CONSTRAINTS_check(3)> caps each per-pair check at 2**20
|
|
comparisons, but the chain orchestrator issues B<N>(B<N>-1)/2 such
|
|
checks for an B<N>-certificate chain. An adversary submitting a
|
|
maximally constructed chain can therefore force up to approximately
|
|
6.3 million name-constraint comparisons in a four-certificate chain
|
|
(one leaf and three name-constrained signers), or approximately 5.2
|
|
billion at the default chain-depth limit of 100.
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<NAME_CONSTRAINTS_check(3)>,
|
|
L<SSL_add_expected_rpk(3)>,
|
|
L<SSL_CTX_dane_enable(3)>,
|
|
L<SSL_dane_tlsa_add(3)>,
|
|
L<X509_STORE_CTX_new(3)>,
|
|
L<X509_STORE_CTX_init(3)>,
|
|
L<X509_STORE_CTX_init_rpk(3)>,
|
|
L<X509_STORE_CTX_get_error(3)>,
|
|
L<X509_STORE_CTX_set_verify_cb(3)>,
|
|
L<X509_STORE_set_verify_cb_func(3)>,
|
|
L<X509_VERIFY_PARAM_set_flags(3)>
|
|
|
|
=head1 HISTORY
|
|
|
|
X509_build_chain() and X509_STORE_CTX_verify() were added in OpenSSL 3.0.
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved.
|
|
|
|
Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
this file except in compliance with the License. You can obtain a copy
|
|
in the file LICENSE in the source distribution or at
|
|
L<https://www.openssl.org/source/license.html>.
|
|
|
|
=cut
|