Commit Graph
198 Commits
Author SHA1 Message Date
Yu Watanabe 661ab8b6fd tree-wide: drop DLOPEN_FOO() macros
Since 4c0d8d9673, most dlopen notes are
set at the beginning of the executables. Let's manage all dlopen notes
there, rather than setting them where dlopen is called.

Note that the only exceptions are the LIBBPF_NOTE for networkd and
nsresource. Since dlopen_bpf() is wrapped in an `#if` guard, the notes
are instead set within the corresponding functionality.

As a result, the DLOPEN_FOO() wrapper macros are no longer needed and
can be dropped completely.
2026-07-18 04:56:32 +09:00
Yu Watanabe a74b3e1778 dlopen-note: move all dlopen notes to dlopen-note.h
This also switches all these notes to be defined via SD_ELF_NOTE_DLOPEN_ANCHORED().
Consequently, any notes added within unreachable or unused functions will be
automatically garbage-collected by the linker (--gc-sections) instead of
bloating the final binary.

E.g. unused p11-kit library dependency is now dropped from
systemd-repart.standalone binary.

Before:
```
$ systemd-analyze dlopen-metadata build/systemd-repart.standalone
FEATURE    DESCRIPTION                                                SONAME                        PRIORITY
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           recommended
blkid      Support for block device identification                    libblkid.so.1                 required
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 recommended
mount      Support for mount enumeration                              libmount.so.1                 required
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 required
blkid      Support for block device identification                    libblkid.so.1                 recommended
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 suggested
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           suggested
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 suggested
idn        Support for internationalized domain names                 libidn2.so.0                  suggested
mount      Support for mount enumeration                              libmount.so.1                 recommended
selinux    Support for SELinux                                        libselinux.so.1               recommended
tpm        Support for TPM                                            libtss2-esys.so.0             suggested
tpm        Support for TPM                                            libtss2-rc.so.0               suggested
tpm        Support for TPM                                            libtss2-mu.so.0               suggested
tpm        Support for TPM                                            libtss2-tcti-device.so.0      suggested
p11-kit    Support for PKCS11 hardware tokens                         libp11-kit.so.0               suggested
```

After:
```
$ systemd-analyze dlopen-metadata build/systemd-repart.standalone
FEATURE    DESCRIPTION                                                SONAME                        PRIORITY
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           recommended
blkid      Support for block device identification                    libblkid.so.1                 required
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 recommended
mount      Support for mount enumeration                              libmount.so.1                 required
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 required
blkid      Support for block device identification                    libblkid.so.1                 recommended
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 suggested
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           suggested
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 suggested
mount      Support for mount enumeration                              libmount.so.1                 recommended
selinux    Support for SELinux                                        libselinux.so.1               recommended
tpm        Support for TPM                                            libtss2-esys.so.0             suggested
tpm        Support for TPM                                            libtss2-rc.so.0               suggested
tpm        Support for TPM                                            libtss2-mu.so.0               suggested
tpm        Support for TPM                                            libtss2-tcti-device.so.0      suggested
```
2026-07-10 16:34:26 +09:00
dongshengyuan ccae5c7a4f dns-rr: invalidate wire format after changing ttl
dns_resource_record_clamp_ttl() may patch the TTL in place when the
record has a single reference. dnssec_fix_rrset_ttl() also updates TTLs
after canonical wire-format data may have been cached.

If a record already has cached wire-format data, that cache still
contains the old TTL and dns_resource_record_to_wire_format() will keep
reusing it.

Add a small helper to clear the cached wire-format state, and use it
whenever the TTL changes. This makes subsequent serialization match the
record fields.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-09 08:35:03 +08:00
Yu Watanabe c18ee628a5 resolved: migrate ECDSA verification to OpenSSL 3 EVP API
OpenSSL 3.0 deprecated low-level Elliptic Curve (EC) key manipulation
functions (EC_KEY, EC_POINT, EC_GROUP) and direct signature verification
functions like ECDSA_do_verify().

This commit modernizes dnssec_ecdsa_verify_raw() by transitioning to the
provider-aware EVP API:
* Uses OSSL_PARAM arrays and EVP_PKEY_fromdata() to construct the EC
  public key directly from the raw octet string and curve name, avoiding
  deprecated EC_POINT parsing.
* Converts the raw R and S signature components into a DER-encoded ASN.1
  signature using i2d_ECDSA_SIG(), as required by the modern EVP API.
* Uses EVP_PKEY_verify() for the actual signature validation.

Additionally, this drops an outdated TODO comment waiting for raw ECDSA
support in the EVP API, as well as the deprecated warning suppression
macros and fallback code blocks. Unit tests for ECDSA are now run
unconditionally.
2026-07-03 03:02:56 +09:00
Yu Watanabe 13be553507 resolve: make dnssec_ecdsa_verify_raw() take struct iovec
This also
- adds missing assertions,
- moves variable declarations,
- rename variables.

No functional change, just refactoring.
2026-07-03 03:02:56 +09:00
Yu Watanabe 59fa4dd142 resolve: add unit test for dnssec_ecdsa_verify_raw() 2026-07-03 03:02:56 +09:00
Yu Watanabe cd3c0859b2 resolved: migrate RSA key construction to OpenSSL 3 EVP API
OpenSSL 3.0 deprecated low-level key manipulation functions and direct
access to RSA structures (such as RSA_new(), RSA_set0_key(), and
RSA_size()).

This commit modernizes dnssec_rsa_verify_raw() by replacing these
deprecated functions with the provider-aware EVP API:
* Uses OSSL_PARAM_BLD and EVP_PKEY_fromdata() to construct the RSA
  public key directly from the modulus and exponent BIGNUMs.
* Replaces RSA_size() with EVP_PKEY_get_size().

Consequently, the workaround macros suppressing deprecated warnings
(DISABLE_WARNING_DEPRECATED_DECLARATIONS) and the conditional fallback
blocks (#if !defined(OPENSSL_NO_DEPRECATED_3_0)) are no longer needed
and have been dropped. Unit tests are also updated to run unconditionally.
2026-07-03 03:02:56 +09:00
Yu Watanabe 918193b438 resolve: make dnssec_rsa_verify_raw() take struct iovec
This also
- adds missing assertions,
- moves variable declarations.

No functional change, just refactoring.
2026-07-03 03:02:56 +09:00
Yu Watanabe 6bf0540e93 resolve: add unit test for dnssec_rsa_verify_raw() 2026-07-03 03:02:56 +09:00
Yu Watanabe 6268b094eb resolve: fix segfault when built with OPENSSL_NO_DEPRECATED_3_0
In that case, deprecated funcdions are not loaded from libcrypto.so,
and calling them causes segfault.
2026-07-03 03:02:56 +09:00
Luca Boccassi c8c83bde01 resolved: load libcrypto/libssl lazily on first use and make them optional
Currently they are marked as required, as resolved aborts on startup if
dns-over-tls is built in, even if it is not enabled in the config.
Change initialization to be done lazily on first use, so that if the
config is not enabled, it never runs, and the libraries are never
dlopened, so they can be downgraded to recommends.
2026-06-22 10:56:10 +01:00
Daan De Meyer 6b158b72f5 tree-wide: Beef up openssl logging
Let's translate openssl's errors to proper errnos 
where we can instead of returning EIO for everything.
Let's also make log_openssl_errors() public so we can
use it everywhere and migrate the rest of the codebase
to use it.
2026-06-22 11:40:57 +02:00
Antonio Alvarez Feijoo 7b2c004345 resolve: only write one ELF note for libcrypto
systemd-resolved has 2 contradictory ELF notes for libcrypto:

```
$ systemd-analyze dlopen-metadata /usr/lib/systemd/systemd-resolved
FEATURE   DESCRIPTION                                SONAME         PRIORITY
libcrypto Support for cryptographic operations       libcrypto.so.3 recommended
idn       Support for internationalized domain names libidn2.so.0   recommended
libcrypto Support for cryptographic operations       libcrypto.so.3 required
libssl    Support for TLS                            libssl.so.3    required
```

In order to have a single note, condition its priority based on whether
DNS-over-TLS is enabled.
2026-06-04 18:33:19 +01:00
Luca Boccassi b0ede9f9ee tree-wide: convert dlopen_*() callers to DLOPEN_* wrapper macros
Switch the executable-owned call sites from the plain dlopen_<lib>()
helpers to the new DLOPEN_<LIB>() macros, so that each binary that loads
an optional library at runtime now carries its own .note.dlopen note
instead of relying solely on libsystemd-shared. Each call site passes a
priority reflecting whether it hard-depends on the library (required) or
degrades gracefully without it (recommended).

Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 18:46:24 +01:00
Luca Boccassi 004401fd06 resolve: validate short RSA DNSKEY blobs
Reject malformed RSA DNSKEY data before reading the extended exponent
header, and add a regression test.

Co-developed-by: GitHub Copilot (GPT 5.5) <copilot@github.com>
2026-05-28 15:00:51 +09:00
Daan De Meyer 8c3f64e61f tree-wide: Load libcrypto and libssl via dlopen()
Until now OpenSSL was linked into every binary and library that needed
cryptography, pulling libcrypto (and, for resolved, libssl) into the
address space of services that never touch them at runtime. This commit
moves all OpenSSL usage behind the same dlopen helper pattern that we
already use for other optional libraries (libpam, libseccomp, libxz, …)
so libcrypto/libssl are only loaded on demand.

The bulk of the work lives in src/shared/crypto-util.{c,h} (libcrypto)
and src/shared/ssl-util.{c,h} (libssl), which replace the previous
src/shared/openssl-util.{c,h}:

 - crypto-util.{c,h} declares every libcrypto function we call via
   DLSYM_PROTOTYPE() and resolves them inside dlopen_libcrypto().

 - ssl-util.{c,h} holds the libssl-specific DLSYM_PROTOTYPEs,
   dlopen_libssl(), and the SSL_freep cleanup helper, so translation
   units that only need libcrypto do not pull in libssl declarations.

 - Callers refer to the symbols through sym_* aliases rather than the
   original names.

 - Convenience macros that used to be provided by the OpenSSL headers
   (OPENSSL_free, BN_num_bytes, the sk_TYPE_* helpers, …) are
   reimplemented as sym_* wrappers so no code path needs to fall back
   to the linker-resolved symbols.

 - All _cleanup_ helpers are redefined in terms of the sym_* variants
   (EVP_PKEY_freep, X509_freep, BIO_freep, …) so cleanup attributes
   keep working without pulling in libcrypto symbols at link time.

 - The public crypto-util.c entry points (openssl_pubkey_from_pem,
   openssl_digest_many, openssl_hmac_many, openssl_cipher_many,
   kdf_ss_derive, kdf_kb_hmac_derive, rsa_* / ecc_* helpers,
   pubkey_fingerprint, digest_and_sign, pkcs7_new, x509_fingerprint,
   openssl_extract_public_key, pkey_generate_volume_keys, the load_*
   helpers, …) now call dlopen_libcrypto() at entry before touching any
   sym_* pointer.

The call sites across the tree have been converted to call
dlopen_libcrypto()/dlopen_libssl() at the appropriate entry point
before their first sym_* use, and to use sym_* variants throughout:

 - bootctl, sbsign, measure, pcrlock, pcrextend, tpm2-setup, repart,
   cryptsetup, cryptenroll, homectl, homed, homework, keyutil,
   sysupdate, creds, import, dissect-image, pe-binary, pkcs11-util,
   pkcs7-util, tpm2-util, creds-util. resolved additionally dlopens
   libssl for DoT.

The meson build files are updated to depend on libopenssl_cflags (a
new partial dependency that exposes include paths and compile flags
only, not the linker flags) instead of libopenssl for every target that
previously linked against OpenSSL. Nothing links against libcrypto or
libssl directly anymore.

A new src/sbsign/authenticode.c hosts the Authenticode ASN.1 type
definitions that used to live inline in sbsign.c. The OpenSSL
ASN1_SEQUENCE / ASN1_CHOICE / IMPLEMENT_ASN1_FUNCTIONS macros expand to
code that references libcrypto symbols directly, so to keep this
translation unit unlinked from libcrypto we redirect ASN1_item_* to
the sym_* variants via #define and wrap the ASN1_*_it() getters (which
appear as constant function pointers in static initializers) in small
trampoline functions that forward to the sym_* pointers at runtime.

test-dlopen-so gains assertions for dlopen_libcrypto and dlopen_libssl
so the dlopen contract is exercised in CI, and the openssl-specific
test was renamed from test-openssl.c to test-crypto-util.c to match
the new header naming.
2026-04-24 06:32:42 +02:00
Michael Vogt bd141bd818 many: fix remaining check-pointer-deref issues
The updated parsing_hacks.h file uncovered a bunch of extra
things that the check-pointer-deref coccinelle script flags.

This commit fixes them to make the tree check-pointer-deref clean.
2026-04-12 15:27:15 +02:00
Milan Kyselica dd80e5a348 resolved: replace assert() with error return in DNSSEC verify functions
dnssec_rsa_verify_raw() asserts that RSA_size(key) matches the RRSIG
signature size, and dnssec_ecdsa_verify_raw() asserts that
EC_KEY_check_key() succeeds. Both conditions depend on parsed DNS
record content. Replace with proper error returns.

The actual crypto verify calls (EVP_PKEY_verify / ECDSA_do_verify)
handle mismatches fine on their own, so the asserts were also redundant.

While at it, fix the misleading "EC_POINT_bn2point failed" log message
that actually refers to an EC_KEY_set_public_key() failure.

Fixes: https://github.com/systemd/systemd/issues/41569
2026-04-10 10:29:37 +01:00
Michael Vogt 39ef41e388 resolved: make check-pointer-deref clean
Add the needed assert changes to make the code clean
for the new check-pointer-deref script.
2026-03-27 11:24:38 +01:00
Ronan Pigott 3ddb73317e resolved: also validate unsupported dnssec digest algs 2026-03-23 13:06:19 -07:00
Ronan Pigott 053f4f1dbc resolved: resolve insecure answers with unsupported sig algorithms
sd-resolved does not support all the permissible DNSSEC signature
algorithms, and some are intentionally unsupported as a matter of
policy. Answers that can only be validated via unsupported algorithms
should be treated as if they were unsigned, per RFC4035§5.2.

Previously, sd-resolved tried to properly record insecure answers for
unsupported algortihms, but did not record this status for each of the
auxilliary DNSSEC transactions, so the primary transaction had no way to
know if there was a plausible DNSKEY with an unsupported signature
algorithm in the chain of trust.

This commit adds the insecure DNSKEYs that use unsupported algorithms to
the list of validated keys for each transaction, so that dependent
transactions can learn that a plausible chain of trust exists, even if
no authenticated one does, and report the insecure answer.
2026-03-23 13:06:19 -07:00
Yu Watanabe 99d0a9fdb0 Bump required minimum version of OpenSSL to 3.0.0
All major distributions have switched to OpenSSL version 3.x.
Let's drop support of OpenSSL version 1.x.

Note, OpenSSL 3.0 was released on 2021-09-07 (and will be EOL on 2026-09-07).

See also #38608.
2026-01-02 11:09:52 +09:00
Lennart Poettering 5751b236a5 resolved: move DNS RR/key/answer/question/packet tools to shared/
We want to reuse these generic DNS concepts in resolved hook
implementations, hence move them to shared code.

(This also enables us to immediately remove som SVCB record handling
duplicate definitions.)

No real code changes, just some moving around of things.
2025-10-20 10:35:23 +02:00
Daan De Meyer 284d76414e resolve: Clean up includes
Split out of #37344.
2025-05-21 23:50:31 +09:00
Daan De Meyer 68527d3051 resolved: Remove circular header dependencies 2025-04-23 10:33:37 +02:00
Daan De Meyer 3bb398c299 resolve,import: always use openssl (#36937) 2025-04-18 15:30:33 +02:00
Daan De Meyer 93a1f7921a basic: Stop including log.h in macro.h
Now that the necessary functions from log.h have been moved to macro.h,
we can stop including log.h in macro.h. This requires modifying source
files all over the tree to include log.h instead.
2025-04-18 14:19:15 +02:00
Yu Watanabe e9d4b88b81 resolve,import: always use openssl
This deprecate cryptolib meson option.
2025-04-02 05:47:47 +09:00
Fabian Möller cac3b43eee resolved: fix DNSSEC missing-key error
Skip unsupport/invalid `DS` and `DNSKEY` combinations during verification.

Fixes: #12545
2025-02-05 22:11:55 +01:00
Lennart Poettering 1d5f0a88e0 fundamental: unify gcc warning pragmas at one place
This also drops HAVE_WSTRINGOP_TRUNCATION as the corresponding option
was introduced in GCC 8, and our baseline is GCC 8.4.
2025-01-17 04:08:58 +09:00
Yu Watanabe cdf006973d resolve: fix typo
Follow-up for 67d0ce8843.
2024-09-03 14:00:18 +09:00
Luca Boccassi 8707c9b244 gcrypt: dlopenify for libsystemd
gcrypt is used only for journal sealing operations in libsystemd, so it
can be made into a dlopen dependency that is used only on demand. This
allows to reduce the footprint of libsystemd in the most common cases.

Keep systemd-pull and systemd-resolved with normal linking, as they are
executables, and usually built with OpenSSL support anyway.
2024-04-03 11:50:25 +01:00
Luca Boccassi 72270f29e4 resolve: avoid reusing 'r' for encoded packet size
This is a footgun, as using r between the encoded length being
taken and it being used risks it being overwritten accidentally
2024-04-02 20:28:11 +01:00
Ronan Pigott eba291124b resolved: reduce the maximum nsec3 iterations to 100
According to RFC9267, the 2500 value is not helpful, and in fact it can
be harmful to permit a large number of iterations. Combined with limits
on the number of signature validations, I expect this will mitigate the
impact of maliciously crafted domains designed to cause excessive
cryptographic work.
2024-02-26 01:55:57 -07:00
Ronan Pigott 67d0ce8843 resolved: limit the number of signature validations in a transaction
It has been demonstrated that tolerating an unbounded number of dnssec
signature validations is a bad idea. It is easy for a maliciously
crafted DNS reply to contain as many keytag collisions as desired,
causing us to iterate every dnskey and signature combination in vain.

The solution is to impose a maximum number of validations we will
tolerate. While collisions are not hard to craft, I still expect they
are unlikely in the wild so it should be safe to pick fairly small
values.

Here two limits are imposed: one on the maximum number of invalid
signatures encountered per rrset, and another on the total number of
validations performed per transaction.
2024-02-26 01:55:57 -07:00
Yu Watanabe a72cf22d06 resolve: introduce DNSSEC_UPSTREAM_FAILURE
and include EDE code and message in the error messages.

This replaces 9ca133e97a, and implements
originally suggested at
https://github.com/systemd/systemd/pull/30513#discussion_r1433823737
2024-01-11 02:10:32 +09:00
Lennart Poettering fd7e988700 resolved: increase most label buffers to fit a trailing NUL byte
This is just paranoia. In all these cases we don't really care about the
trailing NUL byte. But if there's space for it dns_label_unescape() is
going to insert it, and that's a good safety strategy.

This is a follow-up to c29c3adefa8cd859f8cb87d9ad62f3d77b7cd102 which
fixed an actual bug, unlike this commit, which is just paranoia.
2023-12-18 10:27:27 +01:00
Dan Streetman dcec950ca1 openssl: add rsa_pkey_new(), rsa_pkey_from_n_e(), rsa_pkey_to_n_e()
Add function to generate an EVP_PKEY for a specific 'n' and 'e', and function
to get 'n' and 'e' values from existing RSA public key. Also add a function to
generate a new RSA key with a specified number of bits.
2023-08-04 10:57:07 -04:00
Yu Watanabe 2485b7e2b8 tree-wide: use memstream-util 2023-06-01 06:48:47 +09:00
Frantisek Sumsal f392dfb5a1 tree-wide: check memstream buffer after closing the handle
When closing the FILE handle attached to a memstream, it may attempt to
do a realloc() that may fail during OOM situations, in which case we are
left with the buffer pointer pointing to NULL and buffer size > 0. For
example:

```
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>

    void *realloc(void *ptr, size_t size) {
        return NULL;
    }

    int main(int argc, char *argv[])
    {
        FILE *f;
        char *buf;
        size_t sz = 0;

        f = open_memstream(&buf, &sz);
        if (!f)
            return -ENOMEM;

        fputs("Hello", f);

        fflush(f);
        printf("buf: 0x%lx, sz: %lu, errno: %d\n",
                    (unsigned long) buf, sz, errno);
        fclose(f);
        printf("buf: 0x%lx, sz: %lu, errno: %d\n",
                    (unsigned long) buf, sz, errno);

        return 0;
    }
```

```
$ gcc -o main main.c
$ ./main
buf: 0x74d4a0, sz: 5, errno: 0
buf: 0x0, sz: 5, errno: 0
```

This might do unexpected things if the underlying code expects a valid
pointer to the memstream buffer after closing the handle.

Found by Nallocfuzz.
2023-05-24 21:59:10 +02:00
Dmitry V. Levin 30fd9a2dab treewide: fix a few typos in NEWS, docs and comments 2023-02-15 10:41:03 +00:00
Zbigniew Jędrzejewski-Szmek 80c48dd3a2 Merge pull request #23114 from yuwata/resolve-dnssec
resolve: always request additional record to verify negative answer
2022-05-17 16:53:09 +02:00
Yu Watanabe d1b8e56a62 resolve: fix false maybe-uninitialized warning 2022-05-07 15:14:41 +09:00
Yu Watanabe 6edf21dba7 resolve: use dns_answer_isempty() at one more place 2022-05-07 15:14:41 +09:00
Yu Watanabe cd2cdba2fe resolve: drop unused argument 2022-04-18 23:21:12 +09:00
Yu Watanabe e28df39269 resolve: add missing initialization of libgcrypt
Fixes #21951.
2022-01-05 12:12:54 +01:00
Zbigniew Jędrzejewski-Szmek acfdfb8620 openssl: supress warnings about functions deprecated by openssl 3.0
We get warnings for RSA_free(), EC_KEY_free(), EC_KEY_new(), etc. Those
functions are now deprecated and we're supposed to use the new "EVP API" that
is all the rage in openssl 3.0.

With some effort I converted dnssec_rsa_verify_raw() to use the new API.  The
code is significantly longer and, if anything, less readable. The EC code is
more complicated and I assume that the EVP API version will be even more
complex. It is possiblet that I'm missing some way to call the new functions in
a better way, but the documentation is abysmal, so it's really hard to figure
out the best way. Of course there are almost no examples, and the ones that are
there are not terribly useful and are also stubs that don't do interesting
things, don't implement error handling, or memory cleanup. I'll submit my
conversion draft as a separate PR. Maybe somebody who knows openssl better
will pick it up and write a proper solution.

For now, let's just use the existing code, but suppress the warnings. The
new version just came out, so it's unlikely that the deprecated functions will
be removed any time soon.

Fixes #21666.
2021-12-09 10:27:18 +01:00
Zbigniew Jędrzejewski-Szmek 6e7323137a resolved: do not use BN_dup() unnecessarilly
Suggested in https://github.com/systemd/systemd/pull/21170#discussion_r738696794
2021-12-01 12:36:57 +01:00
Kevin KuehlerandZbigniew Jędrzejewski-Szmek 1736344e9e resolve: Port nsec3 code to openssl^gcrypt
Co-authored-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
2021-12-01 12:36:45 +01:00
Kevin KuehlerandZbigniew Jędrzejewski-Szmek 1cd7a2c172 resolve: Port dnskey verification by ds to openssl^gcrypt
Co-authored-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
2021-11-30 23:00:21 +01:00