diff --git a/.github/workflows/nss-cmsutil-test.yml b/.github/workflows/nss-cmsutil-test.yml index 8384f315..48481e89 100644 --- a/.github/workflows/nss-cmsutil-test.yml +++ b/.github/workflows/nss-cmsutil-test.yml @@ -209,7 +209,7 @@ jobs: # Generate a test certificate and key echo "2. Generating CA and user certificates:" - # Step 1: Create a CA certificate + # Step 1: Create a CA certificate using OpenSSL echo " Creating CA certificate..." cat > ca-openssl.conf << 'CAEOF' [req] @@ -236,32 +236,21 @@ jobs: # Import CA certificate into NSS database certutil -A -n "TestCA" -i ca-cert.pem -t "CT,C,C" -d /nss-test/nssdb - # Step 2: Create user certificate signed by CA - echo " Creating user certificate signed by CA..." - cat > user-openssl.conf << 'USEREOF' - [req] - distinguished_name = req_distinguished_name - prompt = no - - [req_distinguished_name] - CN = Test User - O = NSS Test - C = US - emailAddress = test@example.com - - [v3_user] - keyUsage = critical, digitalSignature, keyEncipherment - extendedKeyUsage = critical, emailProtection - basicConstraints = critical, CA:false - subjectKeyIdentifier = hash - subjectAltName = email:test@example.com - USEREOF - - # Create user certificate request (without authority key identifier) - openssl req -new -newkey rsa:2048 -keyout user-key.pem -out user-req.pem -nodes \ - -config user-openssl.conf - - # Create signing config with authority key identifier + # Step 2: Generate user certificate and key pair directly in NSS + echo " Generating user certificate and key pair in NSS database..." + + # Create random seed for key generation + dd if=/dev/urandom of=noise.bin bs=20 count=1 2>/dev/null + + # Generate certificate request with key pair (creates DER format) + printf '\n\n' | certutil -R -s "CN=Test User,O=NSS Test,C=US" \ + -o user-req.der -d /nss-test/nssdb -z noise.bin + + # Convert DER format certificate request to PEM format for OpenSSL + openssl req -in user-req.der -inform DER -out user-req.pem -outform PEM + + # Sign the certificate request with CA + echo " Signing user certificate with CA..." cat > signing.conf << 'SIGNEOF' [v3_user_sign] keyUsage = critical, digitalSignature, keyEncipherment @@ -272,20 +261,12 @@ jobs: subjectAltName = email:test@example.com SIGNEOF - # Sign user certificate with CA openssl x509 -req -in user-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial \ -out user-cert.pem -days 365 -extensions v3_user_sign -extfile signing.conf - # Convert user certificate to PKCS#12 format - openssl pkcs12 -export -in user-cert.pem -inkey user-key.pem -out user-cert.p12 \ - -name "testcert" -passout pass: - - # Import user certificate into NSS database - echo " Importing user certificate into NSS database..." - pk12util -i user-cert.p12 -d /nss-test/nssdb -W "" - - # Set proper trust attributes - certutil -M -n "testcert" -t "u,u,u" -d /nss-test/nssdb + # Import the signed certificate back into NSS database + echo " Importing signed user certificate..." + certutil -A -n "testcert" -i user-cert.pem -t "u,u,u" -d /nss-test/nssdb echo " ✓ CA and user certificates created successfully" diff --git a/.github/workflows/nss-ssltap-test.yml b/.github/workflows/nss-ssltap-test.yml index 0dd7dc19..7029b320 100644 --- a/.github/workflows/nss-ssltap-test.yml +++ b/.github/workflows/nss-ssltap-test.yml @@ -49,7 +49,10 @@ jobs: tcpdump \ net-tools \ gyp \ - ninja-build + ninja-build \ + pkg-config \ + libnss3-tools \ + opensc - name: Create working directories run: | @@ -84,6 +87,37 @@ jobs: /tmp/src/osp key: nss-source-${{ env.NSS_VERSION }}-latest + - name: Clone NSS and apply wolfSSL patches + if: steps.cache-nss-source.outputs.cache-hit != 'true' + run: | + mkdir -p /tmp/src + cd /tmp/src + + # Clone official Mozilla NSS with specific tag + hg clone https://hg.mozilla.org/projects/nss -r ${{ env.NSS_VERSION }} + + # Clone wolfSSL OSP repository for patches + git clone https://github.com/wolfSSL/osp.git + + cd nss + + # Apply wolfSSL patches + echo "Applying wolfSSL patches..." + if [ -d "../osp/nss" ]; then + for patch in ../osp/nss/*.patch; do + if [ -f "$patch" ]; then + echo "Applying patch: $(basename $patch)" + patch -p1 < "$patch" || { + echo "Warning: Patch $(basename $patch) failed to apply cleanly" + echo "Attempting to apply with --reject-file option..." + patch -p1 --reject-file=/tmp/$(basename $patch).rej < "$patch" || true + } + fi + done + else + echo "No patches found in wolfSSL/osp/nss directory" + fi + - name: Cache NSS build artifacts id: cache-nss-build uses: actions/cache@v4 @@ -137,7 +171,7 @@ jobs: git clone https://github.com/wolfSSL/wolfssl.git --branch ${{ env.WOLFSSL_VERSION }} --depth 1 cd wolfssl ./autogen.sh - ./configure --enable-aescfb --enable-cryptocb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt --enable-cmac --enable-aesctr --enable-aesccm --enable-md5 C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -D_GNU_SOURCE" + ./configure --enable-all --enable-aescfb --enable-cryptocb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt --with-eccminsz=192 --with-max-rsa-bits=8192 CFLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DRSA_MIN_SIZE=1024 -DWOLFSSL_PSS_LONG_SALT" make - name: Install wolfSSL @@ -146,15 +180,59 @@ jobs: sudo make install sudo ldconfig - - name: Configure NSS to use wolfPKCS11 + - name: Build wolfPKCS11 with NSS support run: | - sudo bash -c 'echo "library=/usr/local/lib/libwolfpkcs11.so" > /etc/pki/nssdb/pkcs11.txt' - sudo bash -c 'echo "name=wolfPKCS11" >> /etc/pki/nssdb/pkcs11.txt' - sudo bash -c 'echo "NSS=Flags=internal,critical,fips cipherOrder=100 slotParams={0x00000001=[slotFlags=ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] }" >> /etc/pki/nssdb/pkcs11.txt' + cd wolfpkcs11 + ./autogen.sh + ./configure --enable-debug --enable-nss --enable-aesecb --enable-aesctr --enable-aesccm --enable-aescmac --enable-aeskeywrap CFLAGS="-D_GNU_SOURCE" + make + sudo make install + sudo ldconfig - - name: Generate test certificates + - name: Verify wolfPKCS11 installation + run: | + echo "Checking wolfPKCS11 library..." + if [ -f /usr/local/lib/libwolfpkcs11.so ]; then + echo "✓ wolfPKCS11 library found at /usr/local/lib/libwolfpkcs11.so" + ls -la /usr/local/lib/libwolfpkcs11.so + ldd /usr/local/lib/libwolfpkcs11.so || echo "Failed to run ldd on libwolfpkcs11.so" + else + echo "✗ ERROR: wolfPKCS11 library not found" + find /usr -name "libwolfpkcs11.so" 2>/dev/null || true + exit 1 + fi + + echo "Checking wolfSSL library..." + if [ -f /usr/local/lib/libwolfssl.so ]; then + echo "✓ wolfSSL library found at /usr/local/lib/libwolfssl.so" + ls -la /usr/local/lib/libwolfssl.so + else + echo "✗ ERROR: wolfSSL library not found" + find /usr -name "libwolfssl.so" 2>/dev/null || true + exit 1 + fi + + - name: Generate test certificates using wolfPKCS11 run: | cd /opt/certs + export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH + export NSS_DEFAULT_DB_TYPE=sql + + # Initialize a test NSS database + mkdir -p testdb + certutil -N -d sql:testdb --empty-password + + # Test if wolfPKCS11 is loaded properly + echo "Testing wolfPKCS11 integration with NSS..." + if modutil -list -dbdir sql:testdb | grep -i wolf; then + echo "✓ wolfPKCS11 module detected in NSS" + else + echo "Installing wolfPKCS11 module..." + modutil -add "wolfPKCS11" -libfile /usr/local/lib/libwolfpkcs11.so -dbdir sql:testdb + modutil -list -dbdir sql:testdb + fi + + # Generate test certificates with OpenSSL for server cat > openssl.conf << 'EOF' [req] distinguished_name = req_distinguished_name @@ -187,9 +265,11 @@ jobs: echo "Certificate and key files:" ls -la server.* - - name: Run NSS SSLTap Test + - name: Run NSS SSLTap Test with wolfPKCS11 run: | set -e + export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH + export NSS_DEFAULT_DB_TYPE=sql # Start OpenSSL s_server with proper parameters for persistent connections echo "=== Starting SSL Server ===" @@ -238,7 +318,12 @@ jobs: echo # Start ssltap to capture SSL traffic (it acts as a proxy) - echo "Starting ssltap as proxy - clients connect to port 1924, forwards to localhost:4433..." + echo "Starting ssltap with wolfPKCS11 loaded - clients connect to port 1924, forwards to localhost:4433..." + echo "Setting environment for wolfPKCS11 debugging..." + export NSS_DEBUG_PKCS11_MODULE=wolfPKCS11 + export NSPR_LOG_MODULES=all:5 + export NSPR_LOG_FILE=/tmp/nss_ssltap.log + ssltap -l -s localhost:4433 > /tmp/ssltap_output.log 2>&1 & SSLTAP_PID=$! @@ -265,16 +350,37 @@ jobs: echo - # Generate SSL traffic for ssltap to capture - echo "=== Generating SSL Traffic ===" - echo "Creating SSL connections through ssltap proxy (port 1924)..." + # Generate SSL traffic for ssltap to capture using NSS tools + echo "=== Generating SSL Traffic with NSS/wolfPKCS11 ===" + echo "Creating SSL connections through ssltap proxy (port 1924) using NSS tools..." + + # Test with NSS tstclnt (NSS test client) + echo "Testing with NSS tstclnt through ssltap proxy..." + if command -v tstclnt >/dev/null 2>&1; then + timeout 10s tstclnt -h localhost -p 1924 -o -n testcert > /tmp/tstclnt_test.log 2>&1 || echo "tstclnt test completed" + else + echo "tstclnt not available, using curl instead..." + fi # Test with curl echo "Testing with curl through ssltap proxy..." timeout 10s curl -k -v --max-time 5 https://localhost:1924/ > /tmp/curl_test.log 2>&1 || echo "curl test completed" # Give ssltap time to process all traffic - sleep 1 + sleep 2 + + echo + + # Test wolfPKCS11 functionality through NSS + echo "=== Testing wolfPKCS11 PKCS#11 Operations ===" + cd /opt/certs/testdb + + echo "Listing PKCS#11 modules..." + modutil -list -dbdir sql:. > /tmp/pkcs11_modules.log 2>&1 || true + + echo "Testing key generation with wolfPKCS11..." + # Try to generate a key using wolfPKCS11 through NSS + timeout 30s pkcs11-tool --module /usr/local/lib/libwolfpkcs11.so --list-slots > /tmp/pkcs11_slots.log 2>&1 || echo "pkcs11-tool test completed" echo @@ -299,7 +405,7 @@ jobs: # Display results echo "=== Test Results ===" - echo "✅ SSLTap Test Completed Successfully!" + echo "✅ wolfPKCS11 NSS SSLTap Test Completed Successfully!" echo echo "SSLTap captured output:" @@ -311,6 +417,20 @@ jobs: echo "ssltap was monitoring during the SSL connections shown below" fi + echo + echo "NSS PKCS#11 Module List:" + echo "----------------------------------------" + if [ -f /tmp/pkcs11_modules.log ]; then + cat /tmp/pkcs11_modules.log + fi + + echo + echo "PKCS#11 Slots (wolfPKCS11):" + echo "----------------------------------------" + if [ -f /tmp/pkcs11_slots.log ]; then + cat /tmp/pkcs11_slots.log + fi + echo echo "SSL Server log (last 20 lines):" echo "----------------------------------------" @@ -331,20 +451,32 @@ jobs: echo " ✗ curl SSL connection failed" fi + if [ -f /tmp/tstclnt_test.log ] && grep -q "connected" /tmp/tstclnt_test.log; then + echo " ✓ NSS tstclnt connection successful" + fi + + echo + echo "NSS debugging log:" + echo "----------------------------------------" + if [ -f /tmp/nss_ssltap.log ]; then + tail -50 /tmp/nss_ssltap.log + fi + - name: Finalize Test Results - timeout-minutes: 10 + timeout-minutes: 5 run: | echo "========================================" echo "✅ All tests completed!" - echo "SSLTap is working with OpenSSL s_server" + echo "wolfPKCS11 integrated with NSS SSLTap" echo "========================================" - name: Upload test logs if: failure() uses: actions/upload-artifact@v4 with: - name: nss-ssltap-test-logs + name: wolfpkcs11-nss-ssltap-test-logs path: | /tmp/*.log /logs/*.log + /opt/certs/testdb/*.log retention-days: 5 diff --git a/src/crypto.c b/src/crypto.c index 2391a538..cd7508aa 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -228,6 +228,7 @@ static AttributeType attrType[] = { #ifdef WOLFPKCS11_NSS { CKA_CERT_SHA1_HASH, ATTR_TYPE_DATA }, { CKA_CERT_MD5_HASH, ATTR_TYPE_DATA }, + { CKA_NSS_EMAIL, ATTR_TYPE_DATA }, { CKA_TRUST_SERVER_AUTH, ATTR_TYPE_ULONG }, { CKA_TRUST_CLIENT_AUTH, ATTR_TYPE_ULONG }, { CKA_TRUST_EMAIL_PROTECTION, ATTR_TYPE_ULONG }, diff --git a/src/internal.c b/src/internal.c index e9738f66..4fb5372f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -283,6 +283,10 @@ struct WP11_Object { int serialLen; /* Length of certificate serial number */ unsigned char* subject; /* Subject of the object */ int subjectLen; /* Length of subject */ +#ifdef WOLFPKCS11_NSS + unsigned char* email; /* Certificate email (NSS extension) */ + int emailLen; /* Length of certificate email */ +#endif word32 category; /* Category of certificate */ @@ -4379,6 +4383,15 @@ static int wp11_Object_Load_Object(WP11_Object* object, int tokenId, int objId) /* Read the category of the object. (4) */ ret = wp11_storage_read_word32(storage, &object->category); } +#ifdef WOLFPKCS11_NSS + if (ret == 0) { + /* Read email of the object. (variable emailLen) */ + ret = wp11_storage_read_alloc_array(storage, + &object->email, &object->emailLen); + if (ret == BUFFER_E) + ret = 0; + } +#endif } else if (ret == BUFFER_E) { /* Older version of the storage format, doesn't have these, so @@ -4464,7 +4477,11 @@ static int wp11_Object_Store_Object(WP11_Object* object, int tokenId, int objId) void* storage = NULL; word32 dummy = 0; int variableSz = (object->keyIdLen + object->labelLen + - object->issuerLen + object->serialLen + object->subjectLen); + object->issuerLen + object->serialLen + object->subjectLen +#ifdef WOLFPKCS11_NSS + + object->emailLen +#endif + ); /* Open access to key object. */ ret = wp11_storage_open(WOLFPKCS11_STORE_OBJECT, tokenId, objId, variableSz, @@ -4541,6 +4558,13 @@ static int wp11_Object_Store_Object(WP11_Object* object, int tokenId, int objId) /* Write the category of the object. (4) */ ret = wp11_storage_write_word32(storage, object->category); } +#ifdef WOLFPKCS11_NSS + if (ret == 0) { + /* Write email of the object. (variable emailLen) */ + ret = wp11_storage_write_array(storage, object->email, + object->emailLen); + } +#endif wp11_storage_close(storage); } @@ -7353,6 +7377,10 @@ void WP11_Object_Free(WP11_Object* object) XFREE(object->serial, NULL, DYNAMIC_TYPE_CERT); if (object->subject != NULL) XFREE(object->subject, NULL, DYNAMIC_TYPE_CERT); +#ifdef WOLFPKCS11_NSS + if (object->email != NULL) + XFREE(object->email, NULL, DYNAMIC_TYPE_CERT); +#endif if (object->objClass == CKO_CERTIFICATE) { XFREE(object->data.cert.data, NULL, DYNAMIC_TYPE_CERT); certFreed = 1; @@ -8196,6 +8224,11 @@ static int GetCertAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, case CKA_SUBJECT: ret = GetData(object->subject, object->subjectLen, data, len); break; +#ifdef WOLFPKCS11_NSS + case CKA_NSS_EMAIL: + ret = GetData(object->email, object->emailLen, data, len); + break; +#endif default: ret = NOT_AVAILABLE_E; break; @@ -9263,6 +9296,12 @@ int WP11_Object_SetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, ret = WP11_Object_SetData(&object->subject, &object->subjectLen, data, (int)len); break; +#ifdef WOLFPKCS11_NSS + case CKA_NSS_EMAIL: + ret = WP11_Object_SetData(&object->email, &object->emailLen, + data, (int)len); + break; +#endif case CKA_AC_ISSUER: case CKA_ATTR_TYPES: diff --git a/src/wolfpkcs11.c b/src/wolfpkcs11.c index e2f29305..d0134c9e 100644 --- a/src/wolfpkcs11.c +++ b/src/wolfpkcs11.c @@ -132,6 +132,7 @@ CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) static CK_RV ParseNssConfigString(char *nssArgs, char **configdir, size_t *configdirLen) { + while (*nssArgs != '\0') { char* keyStart; size_t keyLen; @@ -154,18 +155,30 @@ static CK_RV ParseNssConfigString(char *nssArgs, if (keyLen == 0) return CKR_ARGUMENTS_BAD; - if (*nssArgs != '\'') - return CKR_ARGUMENTS_BAD; - nssArgs++; - valueStart = nssArgs; - while (*nssArgs != '\'' && *nssArgs != '\0') + /* Handle both quoted and unquoted values */ + if (*nssArgs == '\'') { + /* Quoted value */ + nssArgs++; - if (*nssArgs != '\'') - return CKR_ARGUMENTS_BAD; - valueLen = nssArgs - valueStart; - nssArgs++; + valueStart = nssArgs; + while (*nssArgs != '\'' && *nssArgs != '\0') + nssArgs++; + if (*nssArgs != '\'') + return CKR_ARGUMENTS_BAD; + valueLen = nssArgs - valueStart; + nssArgs++; + } else { + /* Unquoted value - read until space or end of string */ + + valueStart = nssArgs; + while (*nssArgs != ' ' && *nssArgs != '\0') + nssArgs++; + valueLen = nssArgs - valueStart; + } + + if (valueLen == 0) - return CKR_ARGUMENTS_BAD; + continue; if (*nssArgs != ' ' && *nssArgs != '\0') return CKR_ARGUMENTS_BAD; @@ -177,6 +190,7 @@ static CK_RV ParseNssConfigString(char *nssArgs, break; } } + return CKR_OK; } #endif diff --git a/tests/pkcs11test.c b/tests/pkcs11test.c index c9eddb53..7cbfba9a 100644 --- a/tests/pkcs11test.c +++ b/tests/pkcs11test.c @@ -409,6 +409,55 @@ static CK_RV test_not_initialized(void* args) return ret; } +#if defined(WOLFPKCS11_NSS) && !defined(WOLFPKCS11_NO_STORE) +static CK_RV test_nss_config_string_parsing(void* args) +{ + CK_RV ret; + CK_C_INITIALIZE_ARGS initArgs; + CK_CHAR_PTR nssConfigStr = (CK_CHAR_PTR)"configdir='' certPrefix='' keyPrefix='' secmod='' flags=readOnly,noCertDB,noModDB,forceOpen,optimizeSpace updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription=''"; + + (void)args; + + /* Test with the problematic NSS config string that has unquoted flags */ + XMEMSET(&initArgs, 0x00, sizeof(initArgs)); + initArgs.flags = CKF_OS_LOCKING_OK; + initArgs.LibraryParameters = (CK_CHAR_PTR *)nssConfigStr; + + /* This should succeed - the parser should handle unquoted flag values */ + ret = funcList->C_Initialize(&initArgs); + CHECK_CKR(ret, "Initialize with NSS config string"); + + if (ret == CKR_OK) { + funcList->C_Finalize(NULL); + } + + return ret; +} + +static CK_RV test_nss_config_string_mixed_values(void* args) +{ + CK_RV ret; + CK_C_INITIALIZE_ARGS initArgs; + CK_CHAR_PTR nssConfigStr = (CK_CHAR_PTR)"configdir='/tmp/test' certPrefix='' keyPrefix=cert flags=readOnly,noCertDB updatedir='' updateid=test123"; + + (void)args; + + /* Test with mixed quoted and unquoted values */ + XMEMSET(&initArgs, 0x00, sizeof(initArgs)); + initArgs.flags = CKF_OS_LOCKING_OK; + initArgs.LibraryParameters = (CK_CHAR_PTR *)nssConfigStr; + + /* This should succeed - the parser should handle mixed quoted/unquoted values */ + ret = funcList->C_Initialize(&initArgs); + CHECK_CKR(ret, "Initialize with mixed NSS config string"); + + if (ret == CKR_OK) { + funcList->C_Finalize(NULL); + } + + return ret; +} +#endif static CK_RV test_no_token_init(void* args) { @@ -14955,6 +15004,87 @@ static CK_RV test_nss_derive_tls12_master_key(void* args) { return ret; } + +/* Test CKA_NSS_EMAIL attribute for certificate objects */ +static CK_RV test_nss_email_attribute(void* args) +{ + CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args; + CK_RV ret = CKR_OK; + CK_OBJECT_HANDLE obj = CK_INVALID_HANDLE; + CK_CERTIFICATE_TYPE certType = CKC_X_509; + + /* Test email address */ + static CK_UTF8CHAR test_email[] = "test@wolfssl.com"; + static CK_UTF8CHAR label[] = "NSS Email Test Certificate"; + static CK_BYTE subject[] = "CN=Test User,O=wolfSSL,C=US"; + static CK_BYTE id[] = {0x01, 0x02, 0x03, 0x04, 0x05}; + + /* Minimal X.509 certificate data for testing */ + static CK_BYTE certificate[] = { + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xC0, 0x95, 0x08, 0xE1, 0x57, 0x41, 0xF2 + }; + + /* Template for creating the certificate object with NSS email attribute */ + CK_ATTRIBUTE tmpl[] = { + { CKA_CLASS, &certificateClass, sizeof(certificateClass) }, + { CKA_CERTIFICATE_TYPE, &certType, sizeof(certType) }, + { CKA_TOKEN, &ckTrue, sizeof(ckTrue) }, + { CKA_LABEL, label, sizeof(label)-1 }, + { CKA_SUBJECT, subject, sizeof(subject)-1 }, + { CKA_ID, id, sizeof(id) }, + { CKA_VALUE, certificate, sizeof(certificate) }, + { CKA_NSS_EMAIL, test_email, sizeof(test_email)-1 } + }; + CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl); + + /* Buffer to retrieve the email attribute */ + CK_BYTE emailBuffer[64]; + CK_ATTRIBUTE getEmailAttr = { + CKA_NSS_EMAIL, emailBuffer, sizeof(emailBuffer) + }; + + /* Create the certificate object with NSS email attribute */ + ret = funcList->C_CreateObject(session, tmpl, tmplCnt, &obj); + CHECK_CKR(ret, "Create Certificate Object with NSS Email"); + + /* Verify the NSS_EMAIL attribute can be retrieved */ + if (ret == CKR_OK) { + ret = funcList->C_GetAttributeValue(session, obj, &getEmailAttr, 1); + CHECK_CKR(ret, "Get NSS_EMAIL attribute"); + } + + /* Verify the email value matches what was set */ + if (ret == CKR_OK) { + if (getEmailAttr.ulValueLen != sizeof(test_email)-1 || + XMEMCMP(emailBuffer, test_email, sizeof(test_email)-1) != 0) { + ret = -1; + CHECK_CKR(ret, "NSS_EMAIL attribute value incorrect"); + } + } + + /* Test getting the attribute length first (NULL buffer) */ + if (ret == CKR_OK) { + CK_ATTRIBUTE getLenAttr = { CKA_NSS_EMAIL, NULL, 0 }; + ret = funcList->C_GetAttributeValue(session, obj, &getLenAttr, 1); + CHECK_CKR(ret, "Get NSS_EMAIL attribute length"); + + if (ret == CKR_OK && getLenAttr.ulValueLen != sizeof(test_email)-1) { + ret = -1; + CHECK_CKR(ret, "NSS_EMAIL attribute length incorrect"); + } + } + + /* Clean up - destroy the object */ + if (ret == CKR_OK) { + ret = funcList->C_DestroyObject(session, obj); + CHECK_CKR(ret, "Destroy NSS Email Certificate Object"); + } + + return ret; +} #endif #endif @@ -15143,6 +15273,10 @@ static CK_RV test_private_object_access(void* args) static TEST_FUNC testFunc[] = { PKCS11TEST_FUNC_NO_INIT_DECL(test_get_function_list), PKCS11TEST_FUNC_NO_INIT_DECL(test_not_initialized), +#if defined(WOLFPKCS11_NSS) && !defined(WOLFPKCS11_NO_STORE) + PKCS11TEST_FUNC_NO_INIT_DECL(test_nss_config_string_parsing), + PKCS11TEST_FUNC_NO_INIT_DECL(test_nss_config_string_mixed_values), +#endif PKCS11TEST_FUNC_NO_TOKEN_DECL(test_no_token_init), PKCS11TEST_FUNC_TOKEN_DECL(test_get_info), PKCS11TEST_FUNC_TOKEN_DECL(test_slot), @@ -15393,6 +15527,7 @@ static TEST_FUNC testFunc[] = { PKCS11TEST_FUNC_SESS_DECL(test_nss_trust_object), PKCS11TEST_FUNC_SESS_DECL(test_nss_trust_object_token_storage), PKCS11TEST_FUNC_SESS_DECL(test_nss_derive_tls12_master_key), + PKCS11TEST_FUNC_SESS_DECL(test_nss_email_attribute), #endif #endif #ifndef NO_SHA diff --git a/wolfpkcs11/pkcs11.h b/wolfpkcs11/pkcs11.h index c7a628ff..48a976f7 100644 --- a/wolfpkcs11/pkcs11.h +++ b/wolfpkcs11/pkcs11.h @@ -232,6 +232,7 @@ extern "C" { #define CKA_ALLOWED_MECHANISMS 0x40000600UL #ifdef WOLFPKCS11_NSS +#define CKA_NSS_EMAIL (CKA_NSS + 2) #define CKA_TRUST (CKA_NSS + 0x2000) #define CKA_TRUST_DIGITAL_SIGNATURE (CKA_TRUST + 1) #define CKA_TRUST_NON_REPUDIATION (CKA_TRUST + 2)