# BST-TIMEOUT: 300 # MEASURED 31s (==BST-SUITE libp11 elapsed=31s cases=182==, # # local-verify on dmi3, 2026-08-18). The scoring forks # # almost nothing -- one probe exec, one awk pass over its # # output, and a bounded 53-name symbol loop -- so the cost # # is dominated by staging the 28 MB probe once. # # # # 31s is UNDER the runner's own 60s default, so this marker # # is not needed to make the suite fit on a quiet host. It is # # declared anyway, at the 300 the ticket gates and the # # nightly already pass, because the margin to 60 is thin for # # a suite whose single exec is 28 MB: staging an image that # # size is exactly what stalls on a loaded guest, and one such # # stall on this suite's first local-verify run cost the whole # # boot. A bound that trips turns a slow run into a red with # # no cases, which is the outcome least worth buying. . "$BST_LIB" # libp11 0.4.12 -- the wrapper that turns a PKCS#11 module's C_* function table # into an OpenSSL-shaped API: contexts, slots, tokens, keys and certificates, # the RSA and EC method objects an application hands to OpenSSL, the PKCS#11 # URI and slot-id parsers, and two error-string tables. What ships under # --disable-shared is /usr/lib/libp11.a, /usr/include/libp11.h and p11_err.h, # and /usr/lib/pkgconfig/libp11.pc. # # --------------------------------------------------------------------------- # THE OPENSSL ENGINE HALF OF THE PACKAGE IS NOT HERE, AND THAT IS THE PORT'S # HEADLINE FACT RATHER THAN AN OMISSION. # # libp11's other output is src/pkcs11.la, the `pkcs11' ENGINE module that lets # `openssl -engine pkcs11' reach a token's keys. This image's OpenSSL is # configured no-engine, beside no-dso and no-module, so # compiles to NOTHING here and the wasm32 libcrypto.a carries no ENGINE_* # symbol at all. eng_front.c and eng_back.c call that API directly and cannot # be compiled; eng_front.c says so itself with `#error did not get engine.h'. # Upstream builds the module unconditionally, so that failure takes the LIBRARY # down with it -- which is why this port carries a patch making the module # conditional on the API being present. # # The engine's absence is therefore asserted below, positively: a pkcs11.so # appearing under /usr/lib/engines* would mean the image's OpenSSL had regained # ENGINE without anyone revisiting this suite. # # --------------------------------------------------------------------------- # NOTHING THAT SHIPS CAN DRIVE A LINE OF THE LIBRARY, WHICH IS WHY THERE IS A # PROBE. # # Upstream's four example programs are noinst_PROGRAMS that `make install' # discards, and each takes a module path on argv and opens it in its first # lines. Nothing else in the rootfs links libp11. So on an image with no # compiler there is no consumer at all, and "the files are present" would have # been the whole of what a self-test could say. The probe is built IN THE # RECIPE against the archive that ships, so it is relinked every build and # cannot go stale against a library that moved under it. # # --------------------------------------------------------------------------- # WHAT CANNOT BE COVERED HERE, STATED ONCE SO THE COUNTS ARE READ CORRECTLY. # # Every PKCS#11 operation proper -- enumerating slots, opening a session, # listing keys and certificates, logging in, signing -- runs through a module # the caller names at RUN TIME and libp11 dlopen()s. Two independent things # stop all of them here, and it is worth separating them because only one is a # platform limit: # # * This image ships NO PKCS#11 module at all. softhsm and p11-kit are not # ported, so there is nothing for a caller to name. # * Nothing in this image is DYNAMICALLY LINKED. The distro is # --disable-shared, so every binary including the probe is static and has # no ld.so; dlopen() in such a process cannot return a handle. This is the # distro's own recorded policy, not a missing kernel feature -- the kernel # implements wasm32_user_dlopen_load with a 64 MiB staging ceiling # (brintos/linux#6, closed) and nothing here is built to use it. # # So not one of those calls can succeed, whatever the port does, and none is # scored as though it could. What the probe drives instead is everything on the # near side of that call, plus the load REFUSAL -- a real assertion about # libp11's error path, and this image's only direct measurement of dlopen. # # --------------------------------------------------------------------------- # THE ORACLE, AND WHY A TARGET-ONLY RUN COULD NOT SUPPLY IT. # # Every value in the ORACLE table below is pinned from a NATIVE x86-64 build of # this same 0.4.12 source against the same OpenSSL 3.5.7 (openssl-native from # this build's own sysroot), running the same probe file. Two properties make # that comparison meaningful: # # * The PKCS#11 return, object, key, mechanism and attribute codes are fixed # by the specification in the same NUMBERS on every host, so the A group # must agree exactly and a disagreement is a real defect in libp11's # private pkcs11.h rather than an expected 32-bit difference. # * The parsers are pure text: given the same bytes in, the same fields must # come out on any architecture. A target-only run could not say that -- # parsing a URI this same code emitted would prove only that its writer and # its reader agree, which is exactly the mistake a port makes when it # decodes wrongly and re-encodes to match. # # The two values that MUST differ are excluded from the table and asserted # against this target directly: sizeof(void*) and sizeof(long) are 8 on the # oracle and must be 4 here. # # --------------------------------------------------------------------------- # THREE UPSTREAM BEHAVIOURS ARE PINNED AS THEY STAND, NOT AS THEY SHOULD BE. # Each reproduces identically on the x86-64 oracle, so each is upstream's and # not wasm32's, and each would otherwise read as a port defect the day someone # looked: # # * A pin read through `pin-source' KEEPS THE FILE'S TRAILING NEWLINE. # read_from_file() uses BIO_gets(), which retains the delimiter, and sets # the length from strlen() with no trim -- so `pin-value=1234' yields four # characters and a pin-source file holding the same four yields five, the # last of them a newline a token would refuse. U40/U41 pin it with the # newline escaped, so a future fix surfaces as one named case. # * PKCS11_CTX_unload() AFTER A FAILED LOAD IS A NULL DEREFERENCE. # pkcs11_CTX_unload() calls cpriv->method->C_Finalize() whenever the forkid # matches -- true in any unforked process -- and cpriv->method is set only # by a SUCCESSFUL PKCS11_CTX_load(). Verified by segfaulting the x86-64 # control. The probe therefore does not call it, and reports L07 as # `not-called' rather than pretending to have exercised it; the reason is # recorded here because a silent omission is indistinguishable from an # untested path. It is not patched: no consumer on this image can reach a # successful load either, so diverging from upstream for an unreachable # path would cost more than it buys. # * hex_to_bin()'s ':' SEPARATOR IS UNREACHABLE from both entry points. The # URI path feeds it exactly two characters at a time, and # parse_slot_id_string()'s own strspn() guards reject a ':' inside a hex # run before hex_to_bin() sees it (S03's `1:aabb' splits on the FIRST colon # only). Dead code; noted rather than fixtured, so nobody re-derives it. R=${BST_LIBP11_ROOT:-} PROBE_SRC=${BST_LIBP11_PROBE:-$R/usr/libexec/libp11-tests/libp11-probe} ARCHIVE=$R/usr/lib/libp11.a PCFILE=$R/usr/lib/pkgconfig/libp11.pc INC=$R/usr/include # Asserted against the .pc rather than assumed: a recipe bumped without # regenerating the ORACLE table below must go red on ONE named case instead of # silently changing the subject of the other hundred and eighty. WANT_VERSION=0.4.12 if [ ! -f "$ARCHIVE" ]; then bst_skip libp11/present "libp11 not installed on this image" exit 0 fi bst_ok libp11/present # --- the installed artifacts ------------------------------------------------ check libp11/staticlib test -s "$ARCHIVE" check libp11/pkgconfig test -s "$PCFILE" check libp11/hdr-main test -s "$INC/libp11.h" check libp11/hdr-err test -s "$INC/p11_err.h" # Shape, not absence: this arm converts to shared libraries per recipe # (BRINTOS-1740), so a .so here is a conversion, not a policy breach. bst_lib_shape libp11/no-shared "$R/usr/lib/libp11.so" "$R/usr/lib/libp11.so.3" # The engine's absence, asserted rather than assumed. If OpenSSL ever regains # ENGINE this goes red and the suite gets revisited, which is the whole point. if [ -e "$R/usr/lib/engines-3/pkcs11.so" ] || [ -e "$R/usr/lib/engines/pkcs11.so" ] || \ [ -e "$R/usr/lib/engines-3/libpkcs11.so" ] || [ -e "$R/usr/lib/engines/libpkcs11.so" ]; then bst_notok libp11/no-engine-module \ "an engine module is installed, but this image's OpenSSL is no-engine -- revisit the port" else bst_ok libp11/no-engine-module fi # The private headers must NOT be installed -- they are noinst_HEADERS, and a # recipe that started shipping them would be shipping libp11's vendored copy of # the RSA Labs pkcs11.h into a namespace another package could collide with. if [ -e "$INC/pkcs11.h" ] || [ -e "$INC/libp11-int.h" ] || [ -e "$INC/engine.h" ]; then bst_notok libp11/no-private-headers "a noinst_HEADER was installed into $INC" else bst_ok libp11/no-private-headers fi # --- pkgconfig -------------------------------------------------------------- pcver=$(sed -n 's/^Version: *//p' "$PCFILE" 2>/dev/null | head -1) check_eq libp11/pkgconfig-version "$WANT_VERSION" "$pcver" check_out libp11/pkgconfig-libs "-lp11" cat "$PCFILE" # libp11.pc names its OpenSSL dependency as `Libs.private: -lcrypto', NOT as # `Requires.private: libcrypto', and both halves of that are pinned because the # distinction bites exactly here. Libs.private is what a static consumer needs # and gets: `pkg-config --static --libs libp11' yields -lp11 -lcrypto, which is # the whole of what an image with no shared objects can link against. What it # does NOT yield is libcrypto's Cflags -- and libp11.h includes , # and , so a consumer whose OpenSSL headers are # not already on the default include path cannot compile against this .pc # alone. Harmless on this image, where they are; pinned as it stands so a # recipe that tightened it shows up as a named case rather than as a silent # change of behaviour. pclibspriv=$(sed -n 's/^Libs.private: *//p' "$PCFILE" 2>/dev/null | head -1) check_eq libp11/pkgconfig-libs-private "-lcrypto" "$pclibspriv" pcreq=$(sed -n 's/^Requires.private: *//p' "$PCFILE" 2>/dev/null | head -1) check_eq libp11/pkgconfig-requires-private-empty "" "$pcreq" # --- the symbol census ------------------------------------------------------ # libp11.exports lists 50 names and ALL FIFTY are enumerated -- exhaustively, # because unlike the larger sibling libraries this surface is small enough to # afford it, and a sample would have to justify what it left out. # # Two of them are easy to leave out wrongly, which is why the count is stated: # PKCS11_get_ecdsa_method and PKCS11_get_ecdh_method are the pre-1.1 ECDSA/ECDH # entry points, superseded by PKCS11_get_ec_key_method on OpenSSL 3. They look # like they should be compiled out here -- and they are NOT. p11_ec.c defines # them unconditionally on a modern OpenSSL as stubs returning NULL, in its own # words "to keep old engines working without ECDSA", so all three are in the # archive and an omission would be a hole in the census rather than a # correctness call. Verified against the x86-64 control archive, not reasoned # from the version guards. # grep -a: the archive is binary and some greps refuse it without it. if echo x | grep -aq x 2>/dev/null; then _grepq="grep -aq"; else _grepq="grep -q"; fi for sym in PKCS11_CTX_new PKCS11_CTX_load PKCS11_CTX_unload PKCS11_CTX_free \ PKCS11_CTX_init_args PKCS11_open_session PKCS11_enumerate_slots \ PKCS11_update_slots PKCS11_release_all_slots PKCS11_find_token \ PKCS11_find_next_token PKCS11_is_logged_in PKCS11_login \ PKCS11_logout PKCS11_enumerate_keys PKCS11_remove_key \ PKCS11_enumerate_public_keys PKCS11_get_key_type \ PKCS11_get_key_size PKCS11_get_key_modulus PKCS11_get_key_exponent \ PKCS11_get_private_key PKCS11_get_public_key \ PKCS11_get_slotid_from_slot PKCS11_find_certificate \ PKCS11_find_key PKCS11_enumerate_certs PKCS11_remove_certificate \ PKCS11_init_token PKCS11_init_pin PKCS11_change_pin \ PKCS11_generate_key PKCS11_store_private_key \ PKCS11_store_public_key PKCS11_store_certificate PKCS11_sign \ PKCS11_private_encrypt PKCS11_private_decrypt PKCS11_verify \ PKCS11_ecdsa_method_free PKCS11_seed_random \ PKCS11_generate_random PKCS11_get_rsa_method \ PKCS11_get_ec_key_method PKCS11_pkey_meths \ PKCS11_get_ecdsa_method PKCS11_get_ecdh_method \ ERR_load_PKCS11_strings PKCS11_set_ui_method ERR_get_CKR_code; do if $_grepq "$sym" "$ARCHIVE" 2>/dev/null; then bst_ok "libp11/sym-$sym" else bst_notok "libp11/sym-$sym" "$sym absent from $ARCHIVE" fi done # The ENGINE half must be absent from the archive too, not merely uninstalled: # these are the engine module's own entry points, and finding one would mean # the conditional in the patch had stopped working and the objects were being # folded into the library. for sym in bind_engine ENGINE_set_id ENGINE_get_static_state; do if $_grepq "$sym" "$ARCHIVE" 2>/dev/null; then bst_notok "libp11/no-engine-sym-$sym" "$sym present in $ARCHIVE -- the engine got built in" else bst_ok "libp11/no-engine-sym-$sym" fi done # --- stage and run the probe ------------------------------------------------ # `test -f' on the shipped payload, never `test -x' on it: the rootfs is # read-only at browser runtime and the payload arrives as the image made it, so # an executable-bit assertion would pass only against a hand-placed copy. tmp=${TMPDIR:-/tmp} probe=$tmp/bst-libp11-probe.$$ got=$tmp/bst-libp11-got.$$ exp=$tmp/bst-libp11-exp.$$ if [ ! -f "$PROBE_SRC" ]; then bst_notok libp11/probe-present "no probe at $PROBE_SRC" exit 0 fi bst_ok libp11/probe-present if cp "$PROBE_SRC" "$probe" 2>/dev/null && chmod +x "$probe" 2>/dev/null; then bst_ok libp11/probe-stage else bst_notok libp11/probe-stage "cannot stage $PROBE_SRC into $tmp" rm -f "$probe" exit 0 fi # stderr carries libp11's own diagnostics -- C_LoadModule() prints dlerror() # itself, and ctx_log() narrates every parser rejection -- so it is dropped # here rather than merged: a `Could not parse string!' line landing in the # scored stream would be read as an unknown tag. "$probe" > "$got" 2>/dev/null prc=$? check_eq libp11/probe-rc 0 "$prc" if [ ! -s "$got" ]; then bst_notok libp11/probe-output "the probe produced no output (rc=$prc)" rm -f "$probe" "$got" exit 0 fi bst_ok libp11/probe-output # --- the oracle ------------------------------------------------------------- # Format: . The slug is what a reader sees in # the report; the tag is what the probe printed. Written to a file rather than # embedded in the awk program so that backslashes in the expected values (U40, # U41) are data and not awk string escapes. cat > "$exp" <<'ORACLE' A01 version 0.4.12 A10 ckr-ok 0 A11 ckr-cancel 1 A12 ckr-slot-id-invalid 3 A13 ckr-general-error 5 A14 ckr-arguments-bad 7 A15 ckr-pin-incorrect 160 A16 ckr-token-not-present 224 A17 ckr-user-not-logged-in 257 A18 ckr-function-not-supported 84 A19 ckr-vendor-defined 2147483648 A20 ckf-os-locking-ok 2 A21 cko-private-key 3 A22 cko-certificate 1 A23 ckk-rsa 0 A24 ckk-ec 3 A25 ckm-rsa-pkcs 1 A26 ckm-ecdsa 4161 A27 cka-id 258 A28 cka-label 3 A29 cka-key-type 256 U01 uri-empty rv=1|model=~|manu=~|token=~|serial=~|object=~|id=-|idlen=0|pin=-|pinlen=0 U02 uri-token rv=1|model=~|manu=~|token=MyToken|serial=~|object=~|id=-|idlen=0|pin=-|pinlen=0 U03 uri-model rv=1|model=SmartCard-HSM|manu=~|token=~|serial=~|object=~|id=-|idlen=0|pin=-|pinlen=0 U04 uri-manufacturer rv=1|model=~|manu=Acme Corp|token=~|serial=~|object=~|id=-|idlen=0|pin=-|pinlen=0 U05 uri-serial rv=1|model=~|manu=~|token=~|serial=0123456789ABCDEF|object=~|id=-|idlen=0|pin=-|pinlen=0 U06 uri-object rv=1|model=~|manu=~|token=~|serial=~|object=my-key|id=-|idlen=0|pin=-|pinlen=0 U07 uri-id-hex rv=1|model=~|manu=~|token=~|serial=~|object=~|id=010203|idlen=3|pin=-|pinlen=0 U08 uri-pin-value rv=1|model=~|manu=~|token=~|serial=~|object=~|id=-|idlen=0|pin=1234|pinlen=4 U09 uri-all-attrs rv=1|model=M1|manu=Acme|token=T1|serial=S1|object=K1|id=aabb|idlen=2|pin=-|pinlen=0 U10 uri-sep-question rv=1|model=~|manu=~|token=T1|serial=~|object=~|id=-|idlen=0|pin=4321|pinlen=4 U11 uri-sep-amp rv=1|model=~|manu=~|token=T1|serial=~|object=K1|id=-|idlen=0|pin=-|pinlen=0 U12 uri-sep-mixed rv=1|model=~|manu=~|token=T1|serial=~|object=K1|id=0f|idlen=1|pin=-|pinlen=0 U13 uri-pct-space rv=1|model=~|manu=~|token=~|serial=~|object=my key|id=-|idlen=0|pin=-|pinlen=0 U14 uri-pct-utf8 rv=1|model=~|manu=~|token=café|serial=~|object=~|id=-|idlen=0|pin=-|pinlen=0 U15 uri-pct-percent rv=1|model=~|manu=~|token=~|serial=~|object=100%|id=-|idlen=0|pin=-|pinlen=0 U16 uri-type-cert rv=1|model=~|manu=~|token=~|serial=~|object=K1|id=-|idlen=0|pin=-|pinlen=0 U17 uri-type-public rv=1|model=~|manu=~|token=~|serial=~|object=K1|id=-|idlen=0|pin=-|pinlen=0 U18 uri-type-private rv=1|model=~|manu=~|token=~|serial=~|object=K1|id=-|idlen=0|pin=-|pinlen=0 U19 uri-object-type rv=1|model=~|manu=~|token=~|serial=~|object=K1|id=-|idlen=0|pin=-|pinlen=0 U20 uri-id-ascii rv=1|model=~|manu=~|token=~|serial=~|object=~|id=3031|idlen=2|pin=-|pinlen=0 U21 uri-object-empty rv=1|model=~|manu=~|token=~|serial=~|object=|id=-|idlen=0|pin=-|pinlen=0 U22 uri-token-empty rv=1|model=~|manu=~|token=|serial=~|object=~|id=-|idlen=0|pin=-|pinlen=0 U23 uri-id-empty rv=1|model=~|manu=~|token=~|serial=~|object=~|id=-|idlen=0|pin=-|pinlen=0 U30 uri-reject-unknown-attr rv=0 U31 uri-reject-bad-type rv=0 U32 uri-reject-bad-object-type rv=0 U33 uri-reject-two-pin-values rv=0 U34 uri-reject-pin-value-and-source rv=0 U35 uri-reject-pct-bad-nybble rv=0 U36 uri-reject-pct-truncated rv=0 U37 uri-reject-id-bad-hex rv=0 U38 uri-reject-attr-no-equals rv=0 U39 uri-reject-prefix-not-name rv=0 U40 uri-pin-source-path rv=1|model=~|manu=~|token=T1|serial=~|object=~|id=-|idlen=0|pin=secret42\n|pinlen=9 U41 uri-pin-source-file-scheme rv=1|model=~|manu=~|token=T1|serial=~|object=~|id=-|idlen=0|pin=secret42\n|pinlen=9 U42 uri-reject-pin-source-missing rv=0 U43 uri-reject-pin-source-pipe rv=0 S01 slot-bare-hex rv=1|slot=-1|id=abcd|idlen=2|label=~ S02 slot-bare-hex-digits rv=1|slot=-1|id=0102|idlen=2|label=~ S03 slot-colon-id rv=1|slot=1|id=aabb|idlen=2|label=~ S04 slot-colon-only rv=1|slot=3|id=-|idlen=0|label=~ S05 slot-id-prefix rv=1|slot=-1|id=cafe|idlen=2|label=~ S06 slot-label-prefix rv=1|slot=-1|id=-|idlen=0|label=my-key S07 slot-slot-prefix rv=1|slot=2|id=-|idlen=0|label=~ S08 slot-slot-id rv=1|slot=2|id=00ff|idlen=2|label=~ S09 slot-slot-label rv=1|slot=2|id=-|idlen=0|label=key S10 slot-label-empty rv=1|slot=-1|id=-|idlen=0|label= S11 slot-reject-nonsense rv=0 S12 slot-reject-colon-bad-hex rv=0 S13 slot-reject-id-bad-hex rv=0 S14 slot-reject-slot-not-number rv=0 S15 slot-reject-slot-bad-suffix rv=0 S16 slot-reject-dash-not-colon rv=0 L01 ctx-new ctx L02 ctx-init-args ok L03 ctx-load-missing-module -1 L04 ctx-load-error-reason Unable to load PKCS#11 module L05 ctx-load-empty-path -1 L06 ctx-load-not-a-module -1 L07 ctx-unload-not-called not-called L08 ctx-free ok M01 rsa-method method M02 rsa-method-name libp11 RSA method M03 rsa-method-flags 0 M04 rsa-method-priv-enc set M05 rsa-method-priv-dec set M06 ec-key-method method M07 pkey-meths-count 2 M08 pkey-meths-list list M09 pkey-meths-first-nid 6 M10 pkey-meths-first-sn rsaEncryption E01 ckr-errlib lib E02 p11-errlib lib E03 p11-reason-load-module Unable to load PKCS#11 module E04 p11-reason-not-supported Not supported E05 p11-reason-no-session No session open E06 p11-reason-keygen-failed Key generation failed E07 p11-reason-ui-failed UI request failed E08 p11-reason-bad-padding Unsupported padding type E10 ckr-reason-cancel Cancel E11 ckr-reason-slot-id Invalid slot ID E12 ckr-reason-general General Error E13 ckr-reason-arguments Invalid arguments E14 ckr-reason-pin PIN incorrect E15 ckr-reason-no-token No PKCS#11 token present E16 ckr-reason-not-logged-in User not logged in E17 ckr-reason-not-supported Function not supported E18 ckr-reason-device Device error E19 ckr-reason-key-type Key type inconsistent D01 dlopen-missing-refused null ORACLE # One awk pass emits the BST lines directly. Doing this in the shell would be # two forks per case and ~350 across the table, which on a guest whose memory # is not returned on process exit is the difference between a suite that runs # and one that is killed part-way through. awk ' NR == FNR { tag = $1; slug = $2 line = $0 sub(/^[^ ]+ +[^ ]+ +/, "", line) ord[++n] = tag; sl[tag] = slug; e[tag] = line next } { tag = $1 line = $0 sub(/^[^ ]+ +/, "", line) a[tag] = line; seen[tag] = 1 } END { for (i = 1; i <= n; i++) { t = ord[i] id = "libp11/" sl[t] if (!seen[t]) printf "BST not ok %s : the probe emitted no %s line\n", id, t else if (a[t] == e[t]) printf "BST ok %s\n", id else printf "BST not ok %s : want [%s] got [%s]\n", id, e[t], a[t] } } ' "$exp" "$got" # --- the two values that MUST differ from the oracle ------------------------- # Asserted against this target directly rather than compared: wasm32 is ILP32 # and the oracle is LP64, so agreement here would mean the probe had not been # built for this arch at all. a02=$(awk '$1=="A02"{print $2}' "$got") a03=$(awk '$1=="A03"{print $2}' "$got") check_eq libp11/target-pointer-width 4 "$a02" check_eq libp11/target-long-width 4 "$a03" # --- the loader, asserted in the direction the distro actually guarantees ---- # # D01 -- a module that is not there must not open -- is in the ORACLE table # because it must hold on every platform, and it does. # # D02/D03 ask a different question: does THIS PROCESS have a runtime loader at # all? `dlopen(NULL)' is the one call that needs no file, so its answer is the # process's link model rather than the kernel's capability. This distro is # --disable-shared (brintos.conf: "Static-only world until dlopen substrate # (HWJS-5) is exercised end-to-end"), so the probe is a static binary with no # ld.so and the answer must be NULL. That is correct glibc behaviour for a # static link, not a defect, and NOT the same thing as the platform lacking a # loader -- the kernel does implement wasm32_user_dlopen_load, with a 64 MiB # staging ceiling (brintos/linux#6, closed). Nothing in this image is built to # use it. # # So the assertion runs the other way, exactly like libp11/no-shared and # libp11/no-engine-module above: a HANDLE here would mean the image had grown a # dynamic-linking path this distro says it does not have, and this port -- whose # whole PKCS#11 half is gated on loading a module at run time -- would need # revisiting. The oracle's own answer is `self', because the control build links # libcrypto.so; that is why these two are asserted against the target directly # rather than compared, the same treatment as the pointer width above. # # THIS IS ALSO THE WHOLE REASON THE PKCS#11 OPERATIONS ARE OUT OF SCOPE, stated # where it can be measured rather than only asserted in a comment: with no # loader in the process there is no way to reach a module, so slots, sessions, # keys and signing are unreachable by construction and not by absent hardware. d02=$(awk '$1=="D02"{print $2}' "$got") d03=$(awk '$1=="D03"{print $2}' "$got") if [ "$d02" = "null" ]; then bst_ok libp11/static-no-loader else bst_notok libp11/static-no-loader \ "dlopen(NULL) returned $d02 on a --disable-shared image -- a dynamic-linking path appeared; revisit whether libp11 can now load a PKCS#11 module" fi if [ "$d03" = "~" ]; then bst_ok libp11/static-no-loader-dlsym else bst_notok libp11/static-no-loader-dlsym \ "dlsym on a self handle answered $d03 -- see libp11/static-no-loader; the probe found a loader where this distro guarantees none" fi rm -f "$probe" "$got" "$exp"