Skip to content

minidriver: correct where cardmod.h comes from - #3818

Open
spurglegooge wants to merge 1 commit into
OpenSC:masterfrom
spurglegooge:cardmod-h-comment
Open

spurglegooge wants to merge 1 commit into
OpenSC:masterfrom
spurglegooge:cardmod-h-comment

Conversation

@spurglegooge

@spurglegooge spurglegooge commented Sep 4, 2026

Copy link
Copy Markdown

In #3814 you mentioned:

We didn't find a reliable source for cardmod.h. Maybe WSL with an original
cardmod.h could be a possibility.

We went looking for the same thing and found a chain that works on plain Linux with no
Windows machine involved, which should suit CI better than WSL. The one-line comment fix in this PR
records the source; the full procedure is below in case it is useful for CI.

What this PR changes

minidriver.c said the header comes "from CNG SDK or platform SDK". That is not correct
and it costs time, so this corrects it to name the CPDK and point at the
CPDK_INCL_DIR line in win32/Make.rules.mak that already encodes the real location.

Where it is not

Not in the Windows SDK, the WDK, the EWDK, or the Microsoft.Windows.SDK.CPP /
Microsoft.Windows.WDK.* nuget packages. We downloaded and searched all four, including a
1.8 GB EWDK ISO with a complete 1,612-header Kits tree. We couldn't find it.

win32/Make.rules.mak already points CPDK_INCL_DIR at the right directory, so the build
system knows even if the comment did not.

Where it is

Only in the Cryptographic Provider Development Kit (CPDK). The installer is a WiX Burn
bundle, so the payload has to be extracted rather than run. Tools on Debian:
p7zip-full cabextract msitools.

  1. Landing page (check for a newer version first):
    https://www.microsoft.com/en-us/download/details.aspx?id=30688

  2. Bootstrapper:

    https://download.microsoft.com/download/1/7/6/176909b0-50f2-4df3-b29b-830a17ea7e38/CPDK_RELEASE_UPDATE/cpdksetup.exe
    sha256 76d6f7580fce9bb1045b5f0871718342443ec5d99c316489ef8c7bc83d4dd6ed  (1,281,504 bytes)
    
  3. List the Burn payloads (7z treats the bundle as an archive; file 0 is the manifest):

    7z x cpdksetup.exe -oburn
    grep -oE 'FilePath="Installers\\[^"]+"' burn/0
  4. Payloads sit beside the bootstrapper under .../CPDK_RELEASE_UPDATE/Installers/
    (URL-encode the spaces):

    Installers/Windows%20Cryptographic%20Provider%20Development%20Kit-x86_en-us.msi
    sha256 b401010d60c5cb0e4f6e3e12e938f78e159331f83843405d8b9a5bebba803a22  (409,600 bytes)
    
    Installers/4c9acdde8c6aed110d8dac9ace60b90a.cab
    sha256 84549b70cc6fe2911f936478b546c6fc0766019605d43da8cfc54f660af2296a  (65,929 bytes)
    
  5. Cab entries have hashed names, so map them through the MSI File table:

    cabextract -d cab 4c9acdde8c6aed110d8dac9ace60b90a.cab
    msiinfo export cpdk.msi File | grep -i cardmod
    # fild99c8486373dedc4d3327c73db2af022 ... cardmod.h  66008
    cp cab/fild99c8486373dedc4d3327c73db2af022 cardmod.h

Result:

cardmod.h  66,008 bytes
sha256     a6222ef5ac63d0db989a85810d5b73d96990122db371c9f0cc50a36d4dcdb598

The same cab also carries bcrypt.h, bcrypt_provider.h, cspdk.h, msclmd.h,
ncrypt.h, ncrypt_provider.h and sslprovider.h.

One trap worth documenting

mingw-w64 ships its own cardmod.h at /usr/share/mingw-w64/include/cardmod.h. It is an
older partial subset, roughly 10 KB, and the minidriver fails against it with 103
undefined identifiers. Because a header of the right name is present, this reads as a
source problem rather than a missing dependency. A quick discriminator:

grep -c "CARD_DATA_VERSION_SEVEN\|CONTAINER_MAP_RECORD\|PIN_ID\|CARD_CACHE_FILE_FORMAT" cardmod.h
# real CPDK header: non-zero (26 in our copy).  mingw-w64 subset: 0

On WSL

To be clear about scope: the above is only about obtaining the header. It does not
compete with using WSL in a GitHub Actions job to run the MinGW build — the two fit
together, since a runner still needs the header from somewhere before it can compile.

What we are not attaching

We are deliberately not attaching the header. Our own reading of the CPDK licence terms is
that internal use is unlimited but redistribution is not, so we are sharing the procedure
and the hashes rather than the file. That is our reading of our own obligations only —
whether OpenSC can vendor or ship it is a question for the project.

 The header ships only in the Cryptographic Provider Development Kit, not
 in the Windows SDK or WDK. win32/Make.rules.mak already points at the
 CPDK include directory.
@metsma

metsma commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

@frankmorgner frankmorgner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My hint regarding WSL was not a suggestion for a general fix, but rather a suggestion on how to test building a cross compiled minidriver in CI. via GH actions, we have the option to copy cardmod.h into WSL, and then to compile here with MINGW.

Anyway, codewise the change looks good. Improvements for CI may be suggested in a seperate PR.

@spurglegooge

Copy link
Copy Markdown
Author

Thanks both.

@metsma — useful link, the wiki Build requirements page is a better landing spot for this
than the source comment was. The in-tree comment was still naming the wrong SDK, which is
what this changes.

@frankmorgner — I misread the WSL hint, and I will correct the "On WSL" section of the
description. Copying cardmod.h into WSL and building with MinGW inside a GH Actions job
is a different proposition from sourcing the header, and my note was answering a question
you had not asked. The extraction procedure is about getting the header onto the runner in
the first place, so the two fit together rather than competing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants