Using SCSH3 from within Docker Container (decrypting keyblob)

In order to build OpenSC with custom flags and not interfere with my current installation, I’ve prepared a Docker image with scsh3 installed that can access the Nitrokey HSM and use OpenSSL with the keys. When I’m in the container, however, using scripts in the smart card shell FAIL. SCSH3 scripts only work on my desktop (non-container) using the GUI.

Are there more requirements for the smartcard shell scripts to work properly?

The Dockerfile:

FROM ubuntu

RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get -y install pcscd libccid libpcsclite-dev \
    libssl-dev libreadline-dev autoconf automake build-essential \
    docbook-xsl xsltproc libtool pkg-config wget usbutils gnutls-bin unzip \
    openjdk-8-jdk ant ca-certificates-java && \
    update-ca-certificates -f;

# Setup JAVA_HOME -- useful for docker commandline
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/

# install and build OpenSC -
RUN wget -q && \
    tar xfvz opensc-0.20.0.tar.gz && \
    cd opensc-0.20.0 && \
    ./bootstrap && \
    ./configure CPPFLAGS=-DPRINT_DKEK_SHARE --prefix=/usr --sysconfdir=/etc/opensc && \
    make && \
    make install

# install and build libp11 -
RUN wget -q && \
    tar xfvz libp11-0.4.10.tar.gz && \
    cd libp11-0.4.10 && \
    ./configure --with-pkcs11-module=/usr/lib/ && \
    make && \
    make install

RUN wget -q && \
    unzip && \
    chmod +x /scsh3.16.426/scsh3

WORKDIR /scsh3.16.426

Running ./scsh3 and trying load('decrypt_keyblob.js') from within the docker container OR from the desktop results in this eror:

org.mozilla.javascript.EcmaError: ReferenceError: "print" is not defined. (/home/jared/dev/smartcards/smartcard-hsm/scsh3.15.388/scsh/sc-hsm/DKEK.js#474)
    at /home/jared/dev/smartcards/smartcard-hsm/scsh3.15.388/scsh/sc-hsm/DKEK.js#474
    at /home/jared/dev/smartcards/smartcard-hsm/scsh3.15.388/decrypt_keyblob.js#55

The only way I can successfully use SCSH3 scripts is from the gui on desktop using ./scsh3gui. Then there are no errors. Is there a way to use the scsh3 tool in a headless environment? Does de.cardcontact.scdp.engine.CommandProcessor not allow print(), and if not, is there a workaround?

There is indeed an issue with the print() statement in modules, when you run a script via scsh3. The reason for that is, that the print() statement is in a different scope than the modules. print() is in the Shell scope, while modules are imported into the top-level shared scope. In the UI variant, the Shell scope is the top-level scope into which print() and he modules are imported. So module “see” the print() statement.

The scsh3 variant is not really meant to execute scripts automatically. It’s more an interactive tool to do some quick checks on headless machines.

For running scripts we have a different startup script, which is unfortunately missing from the distributed package. The script is

echo $0
INSTALLDIR=$(dirname $0)
java -classpath 'lib/*' -Dorg.bouncycastle.asn1.allow_unsafe_integer=true -Djava.library.path=./lib -Dscdp.workspace=${WORKSPACE} de.cardcontact.scdp.engine.ScriptRunner $*
exit ${RC}

The script makes sure that the current working is considered as workspace from which module references are resolved. See Locating Files for details.

We’ve released an updated 3.17.452 that contains the script.


Thanks for the quick solution! This works great with the newer version and script. I do however get these warnings:

log4j:WARN No appenders could be found for logger (opencard.core.service.SmartCard).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See for more info.

It doesn’t seem to interfere with the scripts. Should I add a custom, or is there a better way to suppress the warning so I can process the script output easier?

Does not have an impact and should be fixed in 3.17.453.

1 Like

I am successfully using the included ./scriptrunner in the 3.17.453 package to run scripts in the container, such as decrypt_keyblob.js.

Is it possible to either pass variables into the bash script with positional arguments, or is there a way to access environment variables from the Rhino scripts? Now I have a decrypted raw DKEK, SO PIN, and User PIN hard coded in the decrypt_keyblob.js file, and I’m looking for alternatives.

There is no formal way to pass arguments to a JavaScript program, but you could pass arguments using environment variables.

As you can script all Java APIs, a simple

var path = java.lang.System.getenv("PATH");

would return the current value of the PATH environment variable.

Thanks for your help again, this works great!