diff --git a/.github/workflows/storage-upgrade-test-tpm.yml b/.github/workflows/storage-upgrade-test-tpm.yml new file mode 100644 index 00000000..d7011d0f --- /dev/null +++ b/.github/workflows/storage-upgrade-test-tpm.yml @@ -0,0 +1,158 @@ +name: wolfPKCS11 Storage Format Upgrade Test (TPM) + +on: + pull_request: + branches: [ '*' ] + +env: + WOLFSSL_VERSION: v5.8.0-stable + +jobs: + storage-upgrade-test-tpm: + runs-on: ubuntu-latest + strategy: + matrix: + base-ref: + - name: master + ref: master + branch-dir: master-branch + - name: v1.3.0 + ref: v1.3.0-stable + branch-dir: v1.3.0-stable-branch + + steps: + # Checkout the PR branch + - name: Checkout PR branch + uses: actions/checkout@v4 + with: + path: pr-branch + + # Checkout base branch/tag separately + - name: Checkout ${{ matrix.base-ref.name }} branch + uses: actions/checkout@v4 + with: + ref: ${{ matrix.base-ref.ref }} + path: ${{ matrix.base-ref.branch-dir }} + + - name: Cache wolfSSL + id: cache-wolfssl + uses: actions/cache@v4 + with: + path: wolfssl + key: wolfssl-${{ env.WOLFSSL_VERSION }} + + # Setup wolfssl (required dependency) + - name: Checkout wolfssl + if: steps.cache-wolfssl.outputs.cache-hit != 'true' + uses: actions/checkout@v4 + with: + repository: wolfssl/wolfssl + path: wolfssl + ref: ${{ env.WOLFSSL_VERSION }} + + - name: Build wolfssl + if: steps.cache-wolfssl.outputs.cache-hit != 'true' + working-directory: ./wolfssl + run: | + ./autogen.sh + ./configure --enable-md5 --enable-cryptocb --enable-aescfb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt \ + C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT" + make + + - name: Install wolfssl + working-directory: ./wolfssl + run: | + sudo make install + sudo ldconfig + + # Setup IBM Software TPM simulator + - name: Setup IBM Software TPM + run: | + git clone https://github.com/kgoldman/ibmswtpm2.git + cd ibmswtpm2/src + make + ./tpm_server & + sleep 2 + cd ../.. + + # Build and install wolfTPM (required for TPM operations) + - name: Build and install wolfTPM + run: | + git clone https://github.com/wolfSSL/wolftpm.git + cd wolftpm + ./autogen.sh + ./configure --enable-swtpm --enable-debug + make -j$(nproc) + sudo make install + sudo ldconfig + cd .. + + # Phase 1: Build and test base branch/tag with TPM + - name: Modify pkcs11test.c for TPM storage generation + working-directory: ./${{ matrix.base-ref.branch-dir }} + run: | + echo "=== Modifying pkcs11test.c for TPM storage generation ===" + # Check if WOLFPKCS11_NO_STORE is used and change it to use token path + if grep -q 'XSETENV("WOLFPKCS11_NO_STORE"' tests/pkcs11test.c; then + echo "Found WOLFPKCS11_NO_STORE, changing to WOLFPKCS11_TOKEN_PATH" + sed -i 's/XSETENV("WOLFPKCS11_NO_STORE", "1", 1);/XSETENV("WOLFPKCS11_TOKEN_PATH", ".\/store\/pkcs11test", 1);/' tests/pkcs11test.c + else + echo "WOLFPKCS11_NO_STORE not found, assuming WOLFPKCS11_TOKEN_PATH is already set" + fi + echo "=== pkcs11test.c modification completed ===" + + - name: Build wolfPKCS11 ${{ matrix.base-ref.name }} with TPM + working-directory: ./${{ matrix.base-ref.branch-dir }} + run: | + echo "=== Building wolfPKCS11 ${{ matrix.base-ref.name }} branch with TPM support ===" + ./autogen.sh + ./configure --enable-singlethreaded --enable-wolftpm --disable-dh C_EXTRA_FLAGS="-DWOLFPKCS11_TPM_STORE" + make + + - name: Run TPM tests on ${{ matrix.base-ref.name }} to generate storage files + working-directory: ./${{ matrix.base-ref.branch-dir }} + run: | + echo "=== Running TPM tests on ${{ matrix.base-ref.name }} branch ===" + # Run specific TPM tests that generate storage files + ./tests/pkcs11test + echo "=== ${{ matrix.base-ref.name }} branch TPM test completed ===" + + # Phase 2: Build PR branch with TPM and copy storage files from base + - name: Build wolfPKCS11 PR branch with TPM + working-directory: ./pr-branch + run: | + echo "=== Building wolfPKCS11 PR branch with TPM support ===" + ./autogen.sh + ./configure --enable-singlethreaded --enable-wolftpm --disable-dh C_EXTRA_FLAGS="-DWOLFPKCS11_TPM_STORE" + make + + - name: Test TPM storage format compatibility (${{ matrix.base-ref.name }} → PR) + working-directory: ./pr-branch + run: | + echo "=== Testing TPM storage format compatibility with PR branch ===" + echo "This tests that the PR can read TPM storage files created by ${{ matrix.base-ref.name }} branch" + + # Run the TPM-specific tests with the copied storage files + echo "=== Running TPM compatibility tests ===" + ./tests/pkcs11test + echo "=== TPM storage format upgrade test (${{ matrix.base-ref.name }} → PR) completed successfully ===" + + # Capture logs on failure with TPM-specific information + - name: Upload TPM failure logs + if: failure() || cancelled() + uses: actions/upload-artifact@v4 + with: + name: tpm-storage-upgrade-test-failure-logs-${{ matrix.base-ref.name }} + path: | + pr-branch/test-suite.log + pr-branch/config.log + ${{ matrix.base-ref.branch-dir }}/test-suite.log + ${{ matrix.base-ref.branch-dir }}/config.log + retention-days: 5 + + # Clean up TPM simulator on exit + - name: Cleanup TPM simulator + if: always() + run: | + echo "=== Cleaning up TPM simulator ===" + pkill -f tpm_server || echo "TPM server was not running" diff --git a/.github/workflows/storage-upgrade-test.yml b/.github/workflows/storage-upgrade-test.yml index 16767b18..3f13702c 100644 --- a/.github/workflows/storage-upgrade-test.yml +++ b/.github/workflows/storage-upgrade-test.yml @@ -16,9 +16,10 @@ jobs: - name: master ref: master branch-dir: master-branch - - name: v1.3.0 - ref: v1.3.0-stable - branch-dir: v1.3.0-stable-branch + # v1.3.0 disk storage is too broken to run + # - name: v1.3.0 + # ref: v1.3.0-stable + # branch-dir: v1.3.0-stable-branch steps: # Checkout the PR branch @@ -68,6 +69,19 @@ jobs: sudo ldconfig # Phase 1: Build and test base branch/tag + - name: Modify pkcs11test.c for storage generation + working-directory: ./${{ matrix.base-ref.branch-dir }} + run: | + echo "=== Modifying pkcs11test.c for storage generation ===" + # Check if WOLFPKCS11_NO_STORE is used and change it to use token path + if grep -q 'XSETENV("WOLFPKCS11_NO_STORE"' tests/pkcs11test.c; then + echo "Found WOLFPKCS11_NO_STORE, changing to WOLFPKCS11_TOKEN_PATH" + sed -i 's/XSETENV("WOLFPKCS11_NO_STORE", "1", 1);/XSETENV("WOLFPKCS11_TOKEN_PATH", ".\/store\/pkcs11test", 1);/' tests/pkcs11test.c + else + echo "WOLFPKCS11_NO_STORE not found, assuming WOLFPKCS11_TOKEN_PATH is already set" + fi + echo "=== pkcs11test.c modification completed ===" + - name: Build wolfPKCS11 ${{ matrix.base-ref.name }} working-directory: ./${{ matrix.base-ref.branch-dir }} run: | @@ -80,7 +94,7 @@ jobs: working-directory: ./${{ matrix.base-ref.branch-dir }} run: | echo "=== Running tests on ${{ matrix.base-ref.name }} branch ===" - make test + ./tests/pkcs11test echo "=== ${{ matrix.base-ref.name }} branch test completed ===" # Phase 2: Build PR branch and copy storage files from base @@ -117,7 +131,7 @@ jobs: ls -la store/* 2>/dev/null || echo "No wp* files in store/" # Run the tests with the copied storage files - make test + ./tests/pkcs11test echo "=== Storage format upgrade test (${{ matrix.base-ref.name }} → PR) completed successfully ===" diff --git a/src/internal.c b/src/internal.c index 7107faa7..a1fbebcc 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3931,6 +3931,11 @@ static void wp11_Object_Unstore(WP11_Object* object, int tokenId, int objId) if (object->objClass == CKO_CERTIFICATE) { storeObjType = WOLFPKCS11_STORE_CERT; } +#ifdef WOLFPKCS11_NSS + else if (object->objClass == CKO_NSS_TRUST) { + storeObjType = WOLFPKCS11_STORE_TRUST; + } +#endif else { /* Open access to symmetric key. */ switch (object->type) { @@ -4159,7 +4164,7 @@ static int wp11_Token_Load(WP11_Slot* slot, int tokenId, WP11_Token* token) } /* If there is no pin, there is no login, so decode now */ - if (WP11_Slot_Has_Empty_Pin(slot)) { + if (WP11_Slot_Has_Empty_Pin(slot) && (ret == 0)) { #ifndef WOLFPKCS11_NO_STORE object = token->object; while (ret == 0 && object != NULL) { diff --git a/tests/pkcs11mtt.c b/tests/pkcs11mtt.c index e3e4c329..fb2ed536 100644 --- a/tests/pkcs11mtt.c +++ b/tests/pkcs11mtt.c @@ -6797,7 +6797,7 @@ int pkcs11test_mtt(int argc, char* argv[]) int i; #ifndef WOLFPKCS11_NO_ENV - XSETENV("WOLFPKCS11_NO_STORE", "1", 1); + XSETENV("WOLFPKCS11_TOKEN_PATH", "./store/pkcs11mtt", 1); #endif argc--; diff --git a/tests/pkcs11test.c b/tests/pkcs11test.c index eeed4914..7536984b 100644 --- a/tests/pkcs11test.c +++ b/tests/pkcs11test.c @@ -410,9 +410,22 @@ static CK_RV test_no_token_init(void* args) CK_FLAGS expFlags = CKF_RNG | CKF_CLOCK_ON_TOKEN | CKF_TOKEN_INITIALIZED; int flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; + ret = funcList->C_GetTokenInfo(slot, &tokenInfo); + CHECK_CKR(ret, "Get Token Info"); + if (ret == CKR_OK) { + /* This will happen if we are re-running the tests */ + if (tokenInfo.flags & CKF_LOGIN_REQUIRED) { + fprintf(stderr, "A test re-run, skipping ... "); + return CKR_SKIPPED; + } + } + session = CK_INVALID_HANDLE; - ret = funcList->C_OpenSession(slot, flags, NULL, NULL, &session); - CHECK_CKR(ret, "Open Session"); + if (ret == CKR_OK) { + ret = funcList->C_OpenSession(slot, flags, NULL, NULL, &session); + CHECK_CKR(ret, "Open Session"); + } + if (ret == CKR_OK) { #ifndef WOLFPKCS11_NSS ret = funcList->C_Login(session, CKU_SO, soPin, soPinLen); @@ -13807,7 +13820,7 @@ static CK_RV pkcs11_test(int slotId, int setPin, int onlySet, int closeDl) { CK_RV ret; int i; - int attempted = 0, passed = 0; + int attempted = 0, passed = 0, skipped = 0; int inited = 0; /* Set it global. */ @@ -13850,7 +13863,10 @@ static CK_RV pkcs11_test(int slotId, int setPin, int onlySet, int closeDl) for (i = 0; i < testFuncCnt; i++) { if (testFunc[i].attempted) { attempted++; - if (testFunc[i].ret != CKR_OK) { + if (testFunc[i].ret == CKR_SKIPPED) { + skipped++; + } + else if (testFunc[i].ret != CKR_OK) { #ifdef DEBUG_WOLFPKCS11 if (ret == CKR_OK) fprintf(stderr, "\nFAILED tests:\n"); @@ -13862,7 +13878,11 @@ static CK_RV pkcs11_test(int slotId, int setPin, int onlySet, int closeDl) passed++; } } - fprintf(stderr, "Result: %d / %d\n", passed, attempted); + fprintf(stderr, "Result: attempted: %d, passed: %d", attempted, passed); + if (skipped != 0) { + fprintf(stderr, ", skipped %d", skipped); + } + fprintf(stderr, "\n"); if (ret == CKR_OK) fprintf(stderr, "Success\n"); else @@ -13944,7 +13964,7 @@ int pkcs11test_test(int argc, char* argv[]) int i; #ifndef WOLFPKCS11_NO_ENV - XSETENV("WOLFPKCS11_NO_STORE", "1", 1); + XSETENV("WOLFPKCS11_TOKEN_PATH", "./store/pkcs11test", 1); #endif argc--; diff --git a/tests/unit.h b/tests/unit.h index 2c719d56..847c4391 100644 --- a/tests/unit.h +++ b/tests/unit.h @@ -117,6 +117,8 @@ { func, #func, CKR_OK, 0, 0, flags, setup, teardown, argsSz } #endif +#define CKR_SKIPPED CKR_VENDOR_DEFINED+77 + typedef struct TEST_FUNC { CK_RV (*func)(void* args); @@ -299,6 +301,9 @@ static CK_RV run_tests(TEST_FUNC* testFunc, int testFuncCnt, int onlySet, testFunc[i].cnt); if (testFunc[i].ret == CKR_OK) fprintf(stderr, "PASSED\n"); + else if (testFunc[i].ret == CKR_SKIPPED) { + fprintf(stderr, "SKIPPED\n"); + } else fprintf(stderr, "FAILED\n"); } @@ -342,6 +347,9 @@ static CK_RV run_tests(TEST_FUNC* testFunc, int testFuncCnt, int onlySet, fprintf(stderr, "%d: %s ... ", i + 1, testFunc[i].name); if (testFunc[i].ret == CKR_OK) fprintf(stderr, "PASSED\n"); + else if (testFunc[i].ret == CKR_SKIPPED) { + fprintf(stderr, "SKIPPED\n"); + } else if (verbose) fprintf(stderr, "FAILED\n");