GnuTLS | PKCS#11 Auto-Initialization Not Working (#1798)

Read-only notification of GnuTLS library development activities <[email protected]>
Newsgroups gmane.comp.encryption.gpg.gnutls.devel
Message-ID <[email protected]>

Claudio Ferreira created an issue: https://gitlab.com/gnutls/gnutls/-/issues/1798



## Context

This issue was discovered while investigating OpenConnect VPN client authentication failures with PKCS#11 tokens.

**OpenConnect issue #835**: "GnuTLS backend does not initialize PKCS#11 modules"
- URL: https://gitlab.com/openconnect/openconnect/-/issues/835
- OpenConnect maintainer (Dimitri Papadopoulos) suggested this is a GnuTLS bug
- OpenConnect calls multiple `gnutls_pkcs11_*()` functions but auto-init doesn't trigger
- Workaround being implemented in OpenConnect pending GnuTLS fix

## Summary

GnuTLS 3.8.12 does not automatically initialize PKCS#11 modules when applications call `gnutls_pkcs11_*()` functions, despite documentation stating that `gnutls_pkcs11_init()` is called automatically since version 3.3.0.

## Environment

- **GnuTLS**: 3.8.12-2
- **p11-kit**: 0.25.10
- **OS**: Debian GNU/Linux Sid
- **Application**: OpenConnect 9.12
- **Token**: G&D StarSign CUT S (SafeSign IC driver)
- **Certificate**: ICP-Brasil A3

## Expected Behavior

According to GnuTLS documentation:

> Since GnuTLS 3.3.0 this function is no longer necessary to be explicitly called. It is being called during the first request PKCS 11 operation.

When an application calls `gnutls_pkcs11_*()` functions (e.g., when processing a PKCS#11 URI), GnuTLS should automatically initialize PKCS#11 modules.

## Actual Behavior

PKCS#11 modules are **not** initialized automatically. Applications must explicitly call `gnutls_pkcs11_init()` or PKCS#11 operations fail silently.

## Reproduction

### Test Case 1: OpenConnect (Real-World Application)

OpenConnect calls multiple `gnutls_pkcs11_*()` functions when processing PKCS#11 URIs, but PKCS#11 modules are never initialized.

**Command:**
```bash
export GNUTLS_DEBUG_LEVEL=3
openconnect --protocol=gp -c "pkcs11:token=MyToken" vpn.example.com
```

**Result WITHOUT explicit `gnutls_pkcs11_init()`:**
```
gnutls[2]: Enabled GnuTLS 3.8.12 logging...
gnutls[2]: getrandom random generator was selected
...
(zero PKCS#11-related messages)
...
Valid client certificate is required
Failed to complete authentication
```

No PKCS#11 initialization occurs, even though OpenConnect calls `gnutls_pkcs11_*()` functions.

**Result WITH explicit `gnutls_pkcs11_init()`:**
```
gnutls[2]: Enabled GnuTLS 3.8.12 logging...
gnutls[2]: Initializing all PKCS #11 modules
gnutls[2]: p11: Initializing module: p11-kit-trust
gnutls[2]: p11: Initializing module: safesign
gnutls[2]: p11: Module safesign is initialized in a thread-safe mode
PIN required for MyToken
Enter PIN:
```

PKCS#11 modules are loaded and authentication succeeds.

### Test Case 2: Minimal Reproduction (Suggested)

```c
#include <gnutls/gnutls.h>
#include <gnutls/pkcs11.h>
#include <stdio.h>

int main(void) {
    int ret;
    
    // Initialize GnuTLS (but NOT PKCS#11)
    gnutls_global_init();
    
    // Try to use PKCS#11 - should trigger auto-init according to docs
    gnutls_pkcs11_token_get_info(
        "pkcs11:token=MyToken",
        GNUTLS_PKCS11_TOKEN_LABEL,
        NULL, NULL
    );
    
    // Check if PKCS#11 was initialized
    // Expected: modules loaded automatically
    // Actual: no initialization occurs
    
    gnutls_global_deinit();
    return 0;
}
```

**Expected**: First `gnutls_pkcs11_*()` call triggers automatic initialization.  
**Actual**: No initialization occurs, PKCS#11 operations fail.

## Analysis

### Code Flow in OpenConnect

1. `openconnect_init_ssl()` calls `gnutls_global_init()` only
2. Later, certificate loading code calls various `gnutls_pkcs11_*()` functions
3. These functions should trigger auto-initialization per documentation
4. But they don't - no PKCS#11 modules are loaded

### Which Functions Are Called

OpenConnect calls (at minimum):
- `gnutls_pkcs11_obj_*()` functions for certificate operations
- `gnutls_pkcs11_privkey_*()` functions for private key operations
- Other PKCS#11-related GnuTLS APIs

These should qualify as "PKCS 11 operations" that trigger auto-init.

## Impact

This affects any application that:
1. Calls `gnutls_global_init()` but not `gnutls_pkcs11_init()`
2. Relies on documented automatic PKCS#11 initialization
3. Uses PKCS#11 tokens for authentication

Real-world affected applications:
- OpenConnect VPN client
- Potentially other VPN clients using GnuTLS
- Any application following GnuTLS documentation

## Workaround

Applications must explicitly call `gnutls_pkcs11_init()`:

```c
int openconnect_init_ssl(void)
{
    if (gnutls_global_init())
        return -EIO;
    
    // Workaround for GnuTLS auto-init not working
    #if defined(HAVE_P11KIT)
    if (gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO, NULL) < 0) {
        // Handle error
    }
    #endif
    
    return 0;
}
```

## Questions

1. Is automatic PKCS#11 initialization still supposed to work in GnuTLS 3.8.x?
2. Which specific GnuTLS functions should trigger auto-initialization?
3. Is there a specific initialization order or condition required?
4. Should this be considered a regression or documentation issue?

## References

- GnuTLS PKCS#11 docs: https://gnutls.org/manual/html_node/PKCS11-Initialization.html
- OpenConnect issue #835: https://gitlab.com/openconnect/openconnect/-/issues/835
- RFC 7512 (PKCS#11 URI): https://tools.ietf.org/html/rfc7512

## Related Issues

- **GnuTLS #1784** - "SafeSign token compatibility: CKR_ARGUMENTS_BAD with threading flags" (January 2026)
  - URL: https://gitlab.com/gnutls/gnutls/-/issues/1784
  - Our previous report about SafeSign driver rejecting PKCS#11 threading flags
  - Patch submitted to add fallback for `CKR_ARGUMENTS_BAD` with `flags=0`
  - This current issue is different but related: auto-initialization not working

- **GnuTLS #1060** - "Uninitialized lock when using pkcs11 private key for signing" (August 2020)
  - URL: https://gitlab.com/gnutls/gnutls/-/issues/1060
  - Similar symptom: "Thread locking error" in single-threaded application
  - Context: Lock not initialized when using PKCS#11 private key
  - May be related to PKCS#11 initialization issues

## Additional Information

I can provide:
- Complete debug logs (with `GNUTLS_DEBUG_LEVEL=9`)
- Minimal test case if needed
- Testing on different GnuTLS versions
- p11-kit configuration details

-- 
Reply to this email directly or view it on GitLab: https://gitlab.com/gnutls/gnutls/-/issues/1798
You're receiving this email because of your account on gitlab.com.

_______________________________________________
Gnutls-devel mailing list
[email protected]
http://lists.gnupg.org/mailman/listinfo/gnutls-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.