# BST-TIMEOUT: 1200 # 114 cases, 284s measured locally; the nightly's browser run still exceeds 300s . "$BST_LIB" # openssl 3.5.7 (poky recipes-connectivity) -- libcrypto/libssl plus the openssl # CLI, on the wasm32-hwjs glibc arm. # # WHAT THIS SUITE IS FOR, and why it is not payload-shaped like its neighbours in # the 76- band. The sibling library ports (gmp, libmxml, libdaemon, onig) can only # weigh payload, because nothing on this image links them. openssl is different in # two ways that between them decide the whole shape: # # 1. THE CLI SHIPS, so this library HAS a consumer on the image -- 59.57 MiB of # whole-program-coroutinized libcrypto+libssl that has to exec, and then has # to compute the right answers. That is a claim no header check can make, and # openssl is precisely the package where "the files are present" is worth # least: a crypto library that links and returns wrong bytes is worse than one # that does not link. Every digest, cipher and signature below is asserted # against a value computed on x86_64 with the same openssl release. # # 2. THE CONFIGURATION IS THE PORT. The recipe's Configure line was reconciled # with the platform's own reference port (packages/modified/openssl@wasm32 in # the superproject) and four knobs were turned OFF for substrate reasons -- # no-async, no-threads, no-engine, no-dso. The cfg-* cases below assert each # one out of the installed configuration.h. They are not decoration: poky # appends no-async ":libc-musl" ONLY, so on THIS arm the ucontext fibre # machinery is one distro upgrade away from silently coming back, and it comes # back as a suspension shape the coroutinize pass does not enumerate. A # regression there produces a library that still builds and still packages. # # Three things here were measured rather than assumed, each of which a suite copied # from a neighbour would state backwards: # # * rand-* IS THE ENTROPY PROBE, and it is a real question on this target, not a # formality. The recipe configures --with-rand-seed=os, i.e. getrandom(2) and # nothing else -- no /dev/urandom fallback to quietly cover for it. If the # syscall is not wired, `openssl rand` fails outright and every keygen below # fails with it. That is the intended behaviour: one honest red, not a silent # downgrade to a weak seed. # * genrsa IS THE COROUTINIZE REGRESSION GUARD. RSA keygen is what reaches # bn_mod_exp_mont_fixed_top, the function whose alloca-escape made the # coroutinize pass refuse this library under BRINTOS-21 (linux-in-the-browser # #64) and forced a force-malloc source edit. That edit is NOT in the recipe # any more -- it was dropped after the current toolchain pin linked the CLI # clean without it -- so this case is what will notice if the refusal ever # comes back as a wrong answer rather than a link failure. # * NO libcrypto.so, NO engines-3/, NO ossl-modules/. Under no-shared/no-dso/ # no-module/no-engine all four are absent BY CONFIGURATION, so their absence is # asserted positively -- if any of them reappears the image has grown a dlopen # path this kernel cannot serve (brintos/linux#6 caps a dlopen'd .so anyway). # $BST_ROOT is empty on target and points at a staged payload tree when the # static half is validated host-side before shipping (the 76-onig.test shape). root=${BST_ROOT:-} inc=$root/usr/include/openssl lib=$root/usr/lib pc=$root/usr/lib/pkgconfig tmp=${TMPDIR:-/tmp}/bst-ossl.$$ mkdir -p "$tmp" 2>/dev/null # ----------------------------------------------------------------- headers ---- check openssl/hdr-dir test -d "$inc" for h in ssl.h crypto.h evp.h opensslv.h configuration.h bn.h rsa.h ec.h \ x509.h rand.h err.h hmac.h aes.h sha.h pem.h; do check "openssl/hdr-$h" test -f "$inc/$h" done # Version, as the three forms a consumer actually compares against. check_out openssl/ver-str '# define OPENSSL_VERSION_STR "3.5.7"' cat "$inc/opensslv.h" check_out openssl/ver-major '# define OPENSSL_VERSION_MAJOR 3' cat "$inc/opensslv.h" check_out openssl/ver-minor '# define OPENSSL_VERSION_MINOR 5' cat "$inc/opensslv.h" check_out openssl/ver-patch '# define OPENSSL_VERSION_PATCH 7' cat "$inc/opensslv.h" # ---------------------------------------------- the reconciled configuration ---- # configuration.h is a multilib shim on this recipe (oe_multilib_header), so the # real content is configuration-32.h; assert both exist and read the 32 one. cfg=$inc/configuration-32.h check openssl/cfg-multilib-shim test -f "$inc/configuration.h" check openssl/cfg-32-present test -f "$cfg" # See note 2 above: these four are the port, and each is off for its own reason. check_out openssl/cfg-no-async "define OPENSSL_NO_ASYNC" cat "$cfg" check_out openssl/cfg-no-engine "define OPENSSL_NO_ENGINE" cat "$cfg" check_out openssl/cfg-no-dso "define OPENSSL_NO_DSO" cat "$cfg" check_out openssl/cfg-no-asm "define OPENSSL_NO_ASM" cat "$cfg" # no-threads is the ABSENCE of a define, so it needs the inverse check: grep -q # must FAIL. Stated as its own case because a copied check_out would silently # assert nothing. check openssl/cfg-no-threads sh -c '! grep -q "define OPENSSL_THREADS" "$1"' _ "$cfg" # -------------------------------------------------------------- pkg-config ---- for f in libcrypto.pc libssl.pc openssl.pc; do check "openssl/pc-$f" test -f "$pc/$f" done check_out openssl/pc-crypto-name "Name: OpenSSL-libcrypto" cat "$pc/libcrypto.pc" check_out openssl/pc-crypto-version "Version: 3.5.7" cat "$pc/libcrypto.pc" check_out openssl/pc-ssl-version "Version: 3.5.7" cat "$pc/libssl.pc" # libssl requires libcrypto -- a consumer that links only -lssl gets an # unresolved link, so the Requires chain is load-bearing here. check_out openssl/pc-ssl-requires "libcrypto" cat "$pc/libssl.pc" if [ -n "$root" ]; then # Host validation: the host's pkg-config would answer out of the HOST's .pc # files, not the staged payload, so the answer would be about the wrong # openssl. Skipped rather than asserted against a value that means nothing. bst_skip openssl/pkgconf "host validation run (BST_ROOT set)" elif command -v pkg-config >/dev/null 2>&1; then check_out openssl/pkgconf-modversion "3.5.7" pkg-config --modversion libcrypto # Filtered by default (-I/usr/include, -L/usr/lib are system paths), restored # with --keep-system-*. Both directions, so a pc file that never populated the # fields cannot pass by looking identical. check_eq openssl/pkgconf-libs-filtered "-lcrypto" \ "$(pkg-config --libs libcrypto 2>/dev/null)" check_out openssl/pkgconf-libs-kept "-L/usr/lib" \ pkg-config --keep-system-libs --libs libcrypto else bst_skip openssl/pkgconf "pkg-config absent" fi # ---------------------------------------------------------------- archives ---- for a in libcrypto.a libssl.a; do check "openssl/lib-$a-present" test -f "$lib/$a" check_out "openssl/lib-$a-archive" "!" head -c 8 "$lib/$a" done # Size windows. libcrypto is ~26 MiB and libssl ~8 MiB of BITCODE members (the # coro arm emits LLVM bitcode from -c and merges at the consumer's final link), # which is why they are an order of magnitude larger than a native build's. The # windows are wide enough to survive a point release and narrow enough to notice # an empty or a native-object archive. sz_crypto=$(wc -c < "$lib/libcrypto.a") sz_ssl=$(wc -c < "$lib/libssl.a") check openssl/lib-crypto-size sh -c '[ "$1" -gt 15000000 ] && [ "$1" -lt 45000000 ]' _ "$sz_crypto" check openssl/lib-ssl-size sh -c '[ "$1" -gt 3000000 ] && [ "$1" -lt 15000000 ]' _ "$sz_ssl" # Member names live in the archive's long-name table at the head, so a bounded # read finds them without flattening 26 MiB -- which is what makes the # neighbouring archive suites lose results under load. 1 MiB is the measured # figure, not a guess: the table stores full paths, so 256 KiB reaches only 596 # of the ~1200 names and stops in the r's, which is exactly how rsa_gen.o and # rand_lib.o came back missing on the first host validation. names=$tmp/names head -c 1048576 "$lib/libcrypto.a" | tr -c '\40-\176\n' '\n' > "$names" 2>/dev/null for m in bn_exp.o evp_enc.o sha256.o rsa_gen.o rand_lib.o aes_core.o err.o; do check_out "openssl/ar-$m" "$m" cat "$names" done # --------------------------------------------------- static-only packaging ---- # All four absences are BY CONFIGURATION -- see note 3 above. nsh=$(ls "$lib"/libcrypto.so* "$lib"/libssl.so* 2>/dev/null | wc -l | tr -d ' ') check_eq openssl/no-shared-libs 0 "$nsh" # The two loadable-object DIRECTORIES are asserted EMPTY, not absent, and the # difference was measured rather than assumed: openssl's install_sw creates # MODULESDIR unconditionally, so /usr/lib/ossl-modules ships as an empty # directory in the main package whatever no-module says. Asserting its absence # would have been a permanent false red; asserting that nothing loadable is IN # it is the invariant that actually matters. nmod=$(ls "$lib"/ossl-modules/*.so 2>/dev/null | wc -l | tr -d ' ') neng=$(ls "$lib"/engines-3/*.so 2>/dev/null | wc -l | tr -d ' ') check_eq openssl/no-provider-modules 0 "$nmod" check_eq openssl/no-engines 0 "$neng" # --------------------------------------------------------------- ssl config ---- # The recipe moves openssl.cnf/certs/private to /etc/ssl and symlinks them back # under the OPENSSLDIR, so both ends of that pair are asserted. check openssl/cnf-present test -f "$root/etc/ssl/openssl.cnf" check_out openssl/cnf-content "openssl_conf" cat "$root/etc/ssl/openssl.cnf" check openssl/cnf-link test -e "$root/usr/lib/ssl-3/openssl.cnf" check openssl/certs-dir test -d "$root/etc/ssl/certs" # ====================================================== runtime: the probe ==== # data/openssl-probe is 29.3 MiB, cross-linked with wasmcc-glibc against THIS # image's /usr/lib/libcrypto.a. That size is measured and is most of a minimal # libcrypto consumer: EVP_get_digestbyname pulls in the whole default provider. # It exists because the openssl CLI is a 59.57 MiB exec image that SPANS both # 32 MiB staging slots, so a second concurrent large exec can be refused -- # while the probe fits ONE slot with ~2.7 MiB to spare. Whether LIBCRYPTO # computes correctly is the actual deliverable, and the probe answers that # without depending on the CLI. # Every value it prints is deterministic and was cross-checked against an # independent oracle before shipping: the digests against coreutils, the HMAC # against `openssl dgst -hmac`, the modexp against Python's pow(), and the RSA # signature against `openssl dgst -sha256 -sign` on the same fixed key. probe=${TMPDIR:-/tmp}/bst-ossl-probe.$$ if [ -n "$root" ]; then # Host validation: the probe is a wasm32 module and cannot execute here. The # whole runtime half below is the same, so it is skipped as one case rather # than reported as ~40 failures that mean nothing about the port. bst_skip openssl/runtime "host validation run (BST_ROOT set) -- wasm32 payload" rm -rf "$tmp" exit 0 fi if cp "$BST_DATA/openssl-probe" "$probe" 2>/dev/null && chmod +x "$probe" 2>/dev/null; then pout=$("$probe" 2>&1); prc=$? case "$pout" in *OSSLP-END*) pdone=1 ;; *) pdone=0 ;; esac if [ "$prc" -eq 0 ] && [ "$pdone" -eq 1 ]; then bst_ok openssl/probe-run else bst_notok openssl/probe-run "rc=$prc $(_bst_1line "$pout")" fi pv() { printf '%s\n' "$pout" | awk -v k="OSSLP-$1" '$1==k{print $2; exit}'; } check_eq openssl/probe-version "OpenSSL" "$(pv version)" check_eq openssl/probe-vernum "30500070" "$(pv vernum)" check_eq openssl/probe-sha256 \ "5714fd83b16c93c526916cc4d2f51526ae93039d5473042bd910b6a149a51d52" "$(pv sha256)" check_eq openssl/probe-sha1 \ "c922342319ef3ead8a9616fe10c2317d67b979c1" "$(pv sha1)" check_eq openssl/probe-sha512 \ "83b333b8d96414e7e1a4ffbc591535435dad88b1cc51001b84c840654b17debace195ec31a927e42c375e00f49901d387be65cb8585855c47a2245c1467b6296" \ "$(pv sha512)" check_eq openssl/probe-md5 \ "4a34d54a2f23d14075cc7371b582dddd" "$(pv md5)" check_eq openssl/probe-hmac \ "d71543820f713b9b6162f80d325c2da8b296ebdc40d056d8cdc928a88337bc8d" "$(pv hmac)" check_eq openssl/probe-aes-ct \ "5b68e8d8680d1656de9ed54d0826d733ef49c7a0cba18d1524354a8b9c717b34" "$(pv aes-ct)" check_eq openssl/probe-aes-roundtrip "OK" "$(pv aes-roundtrip)" # The modexp is the direct exercise of the bn_mod_exp_mont_fixed_top family -- # the function whose alloca escape made the coroutinize pass refuse this # library under BRINTOS-21. Its expected value comes from Python's pow(), not # from openssl, so a library that is wrong in the same way as its own oracle # cannot pass. check_eq openssl/probe-bn-modexp \ "ae03c090c6b11af2158e2f14de4ea4234fc91433c5df7fbb" "$(pv bn-modexp)" check_eq openssl/probe-rsa-bits "2048" "$(pv rsa-bits)" check_eq openssl/probe-rsa-siglen "256" "$(pv rsa-siglen)" check_eq openssl/probe-rsa-sig16 \ "06a086ff762610874dd8bf2d9c2f14a8" "$(pv rsa-sig16)" check_eq openssl/probe-rsa-verify "OK" "$(pv rsa-verify)" check_eq openssl/probe-ec-signverify "OK" "$(pv ec-signverify)" # Entropy. RAND_status()==1 means openssl considers the DRBG seeded; the two # draws must differ, because a stuck or zero-filled seed passes every other # check here. Note what this is and is not: a LIVENESS check, not a quality # one -- a counter would pass it. It catches a dead source, a stuck source and # a zero seed, which is what a package port can honestly claim. check_eq openssl/probe-rand-status "1" "$(pv rand-status)" pr1=$(pv rand1); pr2=$(pv rand2) check openssl/probe-rand1-hex sh -c 'echo "$1" | grep -qE "^[0-9a-f]{32}$"' _ "$pr1" check openssl/probe-rand-distinct sh -c '[ -n "$1" ] && [ "$1" != "$2" ]' _ "$pr1" "$pr2" rm -f "$probe" # ---- the entropy surface, characterised rather than inferred ---------- # data/rand-probe is a 2.0 MiB PACKAGE-FREE binary (no libcrypto) that calls # every path openssl's seed source can take and prints the raw return value and # errno for each: getentropy(3) first, then the getrandom(2) syscall in # blocking / GRND_NONBLOCK / GRND_RANDOM / zero-length forms, then /dev/urandom # as the control, then entropy_avail. It exists because openssl's own message # ("seed_get_seed: entropy source strength too weak") names a verdict but not a # mechanism, and the mechanism is what an upstream report needs. rp=${TMPDIR:-/tmp}/bst-rand-probe.$$ if cp "$BST_DATA/rand-probe" "$rp" 2>/dev/null && chmod +x "$rp" 2>/dev/null; then rout=$("$rp" 2>&1) case "$rout" in *RP-END*) bst_ok openssl/randprobe-run ;; *) bst_notok openssl/randprobe-run "$(_bst_1line "$rout")" ;; esac rv() { printf '%s\n' "$rout" | awk -v k="RP-$1" '$1==k{$1=""; sub(/^ /,""); print; exit}'; } # The probe's whole value is its MEASURED VALUES, and the BST protocol has # nowhere to carry a value on a passing case -- so echo the raw output to the # console, where the browser-verify/local-verify dump keeps it verbatim. Not a # BST line, deliberately: it is evidence for an upstream report, not a result. printf '%s\n' "$rout" | sed 's/^/RANDPROBE| /' # Reported, not asserted green/red: these are measurements whose value is the # VALUE. Each is emitted as its own case so the browser-verify report carries # the numbers, and only the /dev/urandom control is asserted, because that is # the one this port actually depends on. for k in getentropy32 sys32 sys256 sysnonblock32 sysrandom32 syszero entropyavail; do v=$(rv "$k") if [ -n "$v" ]; then bst_ok "openssl/randprobe-$k" else bst_notok "openssl/randprobe-$k" "no RP-$k line"; fi done check openssl/randprobe-devurandom sh -c 'echo "$1" | grep -q "rc=32 got=32/32"' _ "$(rv devurandom32)" rm -f "$rp" else bst_notok openssl/randprobe-run "cannot stage $BST_DATA/rand-probe" fi # /dev/urandom is NOT the configured seed source -- the recipe sets # --with-rand-seed=os, i.e. getrandom(2) alone. It is asserted anyway, and # deliberately, because the reason `os` alone is safe here is that this kernel # credits a crypto.getRandomValues seed to the CRNG before userspace # (arch/wasm32/kernel/setup.c, add_bootloader_randomness, litb#99) -- and # /dev/urandom draws from that SAME pool. So these two cases are the standing # evidence that re-enabling the devrandom fallback would be safe if getrandom # ever regressed, which is exactly the question a later reader would otherwise # have to re-investigate from source. check openssl/devurandom-present test -c /dev/urandom u1=$(od -An -tx1 -N16 /dev/urandom 2>/dev/null | tr -d ' \n') u2=$(od -An -tx1 -N16 /dev/urandom 2>/dev/null | tr -d ' \n') check openssl/devurandom-live sh -c '[ -n "$1" ] && [ "$1" != "$2" ]' _ "$u1" "$u2" else bst_notok openssl/probe-run "cannot stage $BST_DATA/openssl-probe" for c in probe-version probe-vernum probe-sha256 probe-sha1 probe-sha512 \ probe-md5 probe-hmac probe-aes-ct probe-aes-roundtrip \ probe-bn-modexp probe-rsa-bits probe-rsa-siglen probe-rsa-sig16 \ probe-rsa-verify probe-ec-signverify probe-rand-status \ probe-rand1-hex probe-rand-distinct devurandom-present \ devurandom-live; do bst_notok "openssl/$c" "probe not staged" done fi # ========================================================= runtime: the CLI ==== # Everything below runs the 59.57 MiB CLI. On a kernel whose exec staging reserves # 64 MiB in two slots, this image SPANS both -- so it stages, but a concurrent # large exec gets a transient -ENOMEM while it does, and it still has to FIT the # per-process user memory once staged. `require` is the right verb for a CLI that # is not on the image; a CLI that is present and cannot exec is a `not ok`, which # is what the cases below produce. require openssl openssl/present check_out openssl/run-version "OpenSSL 3.5.7" openssl version check_out openssl/run-dir "/usr/lib/ssl-3" openssl version -d check_out openssl/run-platform "linux-generic32" openssl version -p fix=$tmp/fixture.txt printf 'brintOS wasm32-hwjs\n' > "$fix" # Digests, against values computed with the same release on x86_64. check_out openssl/dgst-sha256 \ "5714fd83b16c93c526916cc4d2f51526ae93039d5473042bd910b6a149a51d52" \ openssl dgst -sha256 -r "$fix" check_out openssl/dgst-sha1 \ "c922342319ef3ead8a9616fe10c2317d67b979c1" \ openssl dgst -sha1 -r "$fix" check_out openssl/dgst-md5 \ "4a34d54a2f23d14075cc7371b582dddd" \ openssl dgst -md5 -r "$fix" check_out openssl/dgst-sha512 \ "83b333b8d96414e7e1a4ffbc591535435dad88b1cc51001b84c840654b17deba" \ openssl dgst -sha512 -r "$fix" # base64 both ways -- the decode leg is what proves it is a codec and not a # one-way formatter. check_eq openssl/b64-encode "YnJpbnRPUyB3YXNtMzItaHdqcwo=" \ "$(openssl base64 -in "$fix" 2>/dev/null)" # Decode leg via a FILE, not a pipe -- see the next case for why. Two sequential # execs prove base64 is a codec and not a one-way formatter. b64f=$tmp/b64.txt openssl base64 -in "$fix" -out "$b64f" 2>/dev/null check_eq openssl/b64-roundtrip "brintOS wasm32-hwjs" \ "$(openssl base64 -d -in "$b64f" 2>/dev/null)" # THE PIPE IS OBSERVED, NOT ASSERTED, and that took three runs to get right. # A 59.57 MiB exec claims a contiguous run of BOTH 32 MiB staging slots # (binfmt_wasm.c slot spanning), so `openssl X | openssl Y` can get a POSIX-legal # transient -ENOMEM on the second exec -- and it DOES, but only sometimes: # measured twice as `Cannot allocate memory` and once as a clean success, because # the two processes overlap logically while their STAGING windows may not. The # kernel comment calls it transient and it means it. So neither outcome is a # stable assertion: asserting success would flake, asserting the refusal would # flake the other way, and a permanent red would mean "broken" for something that # is designed behaviour. Reported as a diagnostic line instead -- the codec itself # is already covered by the file-based roundtrip above, which needs no # concurrency. b64err=$(openssl base64 -in "$fix" 2>/dev/null | openssl base64 -d 2>&1 >/dev/null) case "$b64err" in "") printf 'PIPEPROBE| two-exec pipe SUCCEEDED (staging windows did not overlap)\n' ;; *"Cannot allocate memory"*) printf 'PIPEPROBE| two-exec pipe refused ENOMEM (both-slot span, expected)\n' ;; *) printf 'PIPEPROBE| two-exec pipe refused, NOT ENOMEM: %s\n' "$(_bst_1line "$b64err")" ;; esac # The algorithm inventory a consumer queries at run time. Under no-engine/no-dso # these come from the built-in default provider only. check_out openssl/list-digests "SHA2-256" openssl list -digest-algorithms check_out openssl/list-ciphers "AES-256-CBC" openssl list -cipher-algorithms check_out openssl/list-provider "default" openssl list -providers # ----------------------------------------------------------------- entropy ---- # See note 1: --with-rand-seed=os means getrandom(2) and nothing else. r1=$(openssl rand -hex 16 2>&1); rc1=$? if [ "$rc1" -eq 0 ]; then bst_ok openssl/rand-rc check_eq openssl/rand-len 32 "$(printf '%s' "$r1" | wc -c | tr -d ' ')" check openssl/rand-hex sh -c 'echo "$1" | grep -qE "^[0-9a-f]{32}$"' _ "$r1" # Two draws must differ. A stuck or zero-filled seed is the failure mode that # a length check alone would pass. r2=$(openssl rand -hex 16 2>/dev/null) check openssl/rand-distinct sh -c '[ "$1" != "$2" ]' _ "$r1" "$r2" else bst_notok openssl/rand-rc "rc=$rc1 $(_bst_1line "$r1")" bst_notok openssl/rand-len "no output to measure" bst_notok openssl/rand-hex "no output to measure" bst_notok openssl/rand-distinct "no output to compare" fi # ------------------------------------------------------- asymmetric crypto ---- # See note 2: genrsa is what reaches bn_mod_exp_mont_fixed_top. key=$tmp/rsa.pem if openssl genrsa -out "$key" 2048 >/dev/null 2>&1 && [ -s "$key" ]; then bst_ok openssl/genrsa-2048 check_out openssl/rsa-check "RSA key ok" openssl rsa -in "$key" -check -noout check_out openssl/rsa-modulus-bits "2048 bit" openssl rsa -in "$key" -text -noout # Sign/verify over the fixture: the round trip is the only assertion that shows # the modular exponentiation produced a mathematically correct signature rather # than merely a well-formed blob. sig=$tmp/sig.bin pub=$tmp/rsa-pub.pem openssl rsa -in "$key" -pubout -out "$pub" >/dev/null 2>&1 if [ -s "$pub" ] && openssl dgst -sha256 -sign "$key" -out "$sig" "$fix" 2>/dev/null; then bst_ok openssl/rsa-sign # Verified with the extracted PUBLIC key, not the private one: that is what # makes this a signature check rather than a re-run of the signer. check_out openssl/rsa-verify "Verified OK" \ openssl dgst -sha256 -verify "$pub" -signature "$sig" "$fix" else bst_notok openssl/rsa-sign "openssl dgst -sign failed" bst_notok openssl/rsa-verify "sign leg failed, nothing to verify" fi # A self-signed certificate exercises ASN.1 encoding + the signature path # end to end, and x509 -subject reads it back through the parser. crt=$tmp/cert.pem if openssl req -x509 -new -key "$key" -sha256 -days 1 -subj /CN=brintos \ -out "$crt" >/dev/null 2>&1; then bst_ok openssl/x509-selfsign # openssl 3.x prints `subject=CN=brintos`; the spaced `CN = brintos` form is # 1.1.1's and was what this case first (wrongly) expected. check_out openssl/x509-subject "subject=CN=brintos" openssl x509 -in "$crt" -noout -subject check_out openssl/x509-verify "$crt: OK" openssl verify -CAfile "$crt" "$crt" else bst_notok openssl/x509-selfsign "openssl req -x509 failed" bst_notok openssl/x509-subject "no certificate to read" bst_notok openssl/x509-verify "no certificate to verify" fi else bst_notok openssl/genrsa-2048 "openssl genrsa 2048 failed" for c in rsa-check rsa-modulus-bits rsa-sign rsa-verify x509-selfsign \ x509-subject x509-verify; do bst_notok "openssl/$c" "no RSA key was generated" done fi # EC, a different bignum path from RSA (curve arithmetic rather than modexp). eckey=$tmp/ec.pem if openssl ecparam -name prime256v1 -genkey -noout -out "$eckey" 2>/dev/null && [ -s "$eckey" ]; then bst_ok openssl/ec-genkey check_out openssl/ec-check "EC Key valid" openssl ec -in "$eckey" -check -noout ecsig=$tmp/ec.sig if openssl dgst -sha256 -sign "$eckey" -out "$ecsig" "$fix" 2>/dev/null; then bst_ok openssl/ec-sign else bst_notok openssl/ec-sign "openssl dgst -sign with an EC key failed" fi else bst_notok openssl/ec-genkey "openssl ecparam -genkey prime256v1 failed" bst_notok openssl/ec-check "no EC key was generated" bst_notok openssl/ec-sign "no EC key was generated" fi rm -rf "$tmp"