tryLoadLibCrypto function

DynamicLibrary? tryLoadLibCrypto({
  1. StringBuffer? loadedPath,
})

Try to open libcrypto from the path in _envVar, then from _candidates.

Returns a DynamicLibrary on the first successful load, or null if every candidate fails. Never throws.

at_chops does not call this automatically — consumers decide their own fallback strategy. Pass the returned library to MlKem768FfiAlgo.fromLib or X25519FfiAlgo.fromLib when constructing FFI-backed algorithms.

If loadedPath is provided it will be set to the path that was successfully opened, which callers can use to verify whether the env-var path or a fallback candidate was used.

Implementation

DynamicLibrary? tryLoadLibCrypto({StringBuffer? loadedPath}) {
  final envPath = Platform.environment[_envVar];
  if (envPath != null) {
    final lib = _tryOpen(envPath);
    if (lib != null) {
      loadedPath?.write(envPath);
      return lib;
    }
    // The env var was set but the path failed to open. The most common cause
    // is pointing at a versioned symlink (e.g. libcrypto.so.3): the dynamic
    // linker resolves its baked-in SONAME against system paths and may find an
    // older system OpenSSL instead of the intended one.
    // Fix: set $_envVar to the real .so file — resolve symlinks first:
    //   export $_envVar=$(realpath /your/openssl/lib/libcrypto.so.3)
    stderr.writeln(
      'at_chops warning: $_envVar="$envPath" is set but could not be opened. '
      'Falling back to system candidates. '
      'Tip: if the path is a versioned symlink, point to the real file instead: '
      'export $_envVar=\$(realpath "$envPath")',
    );
  }
  for (final path in _candidates) {
    final lib = _tryOpen(path);
    if (lib != null) {
      loadedPath?.write(path);
      return lib;
    }
  }
  return null;
}