ssh-add -s: Could not add card: agent refused operation

Problem

I wanted to use ssh-agent with a PKCS#11 library on macOS. So I tried adding the smart card using the command ssh-add -s but I received the following error:

 $ ssh-add -s /Library/Frameworks/xyz.framework/Versions/A/libxyz.dylib
 Enter passphrase for PKCS#11:
 Could not add card "/Library/Frameworks/xyz.framework/Versions/A/libxyz.dylib": agent refused operation

The error agent refused operation is not very informative. From the logs of the PKCS#11 library, I can see that the library is not being used at all. The problem does not come from the library, which would have returned an error.

Analysis

In order to analyse the problem, I tried debugging the version of OpenSSH provided by Apple. However, I encountered another issue. See my previous article Apple and OpenSSH modified source code.

To find out exactly what is happening, we need to obtain the logs from ssh-agent command, rather than the ssh-add command. So I restart ssh-agent in debug mode and I re-run the ssh-add command.

 $ ssh-agent -d
 [...]
 debug1: new_socket: type = CONNECTION
 debug2: fd 4 setting O_NONBLOCK
 debug1: process_message: socket 1 (fd=4) type 20
 debug2: process_add_smartcard_key: entering
 refusing PKCS#11 add of "/Library/Frameworks/xyz.framework/Versions/A/libxyz.dylib": provider not allowed

The error here is different: provider not allowed.

The ssh-agent manpage indicates an option [-P allowed_providers].

-P allowed_providers
        Specify  a pattern-list of acceptable paths for PKCS#11 provider
        and FIDO authenticator middleware shared libraries that  may  be
        used with the -S or -s options to ssh-add(1).  Libraries that do
        not match the pattern list will be refused.  The default list is
        "/usr/lib*/*,/usr/local/lib*/*".

The problem is clear. The PKCS#11 library is located in /Library/Frameworks/, which is not included in the default list of allowed directories.

Solutions

Update the way ssh-agent is started by adding the -P '/Library/Frameworks/*' option.

Alternatively, copy or install the PKCS#11 library somewhere in the /usr/local/lib/ directory.

Conclusion

I wrote this blog article to ensure that it is indexed by web search engines, so that other people can find it when searching for the ssh-add error agent refused operation message.

Using Free Software is really helpful when you need to debug an issue. You can read (and modify) the source code to identify the problem.

I should sometimes read a program's manpage before looking at its source code 😀.