Smart card integration in macOS Sierra: CryptoTokenKit plugin

Crypto Token Kit

In macOS Sierra (v10.12) Apple introduced the CryptoTokenKit plugin mechanism. This new mechanism is used to replace the tokend mechanism that was deprecated since OS X Lion (v10.7) in 2011.

The CryptoTokenKit API was introduced in OS X Yosemite (v10.10). What is new with macOS Sierra is that a smart card manufacturer can provide a plugin to use the smart card through the Crypto Token Kit API.

By default, macOS provides a Crypto Token Kit plugin to use a PIV card.

Implementation of a CryptoTokenKit plugin

I will not document here how to write a CryptoTokenKit plugin. Refer to Apple documentation for that and in particular the PIVtoken source code. See my article "macOS Sierra and PIVToken source code".

OpenSC plugin

The OpenSC project provides a PKCS#11 library for different smart cards.

OpenSCToken: Use OpenSC in CryptoTokenKit by Frank Morgner is a CryptoTokenKit plugin that works with OpenSC.

Fetch OpenSCToken-1.0.dmg, open the .dmg image, copy the application OpenSCTokenApp.app in your /Applications/ directory.
You need to start the OpenSCTokenApp application at least one time to register the CryptoTokenKit plugin provided by the application. The application does nothing and you can quit it now.

Comparison with OpenSC.tokend

From the website project:
  • OpenSCToken supports multiple certificates, keys and PINs
  • OpenSCToken has proper support for PIN pad on reader or token
  • OpenSCToken offers easy login with smart card and automatically unlocks the login keychain
  • Tokens are not visible in Keychain Access any more (use sc_auth/security from command line instead)
  • Most non-Apple applications do not yet support CryptoTokenKit. If OpenSCToken is used together with OpenSC.tokend, your token will appear twice in Safari and other Apple-apps.

Check installation

To check if the plugin is installed you can use the pluginkit command line tool.

Before installation:
$ pluginkit -m -p com.apple.ctk-tokens
     com.apple.CryptoTokenKit.setoken(1.0)
     com.apple.CryptoTokenKit.pivtoken(1.0)

After installation:
$ pluginkit -m -p com.apple.ctk-tokens
     org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken(1.0)
     com.apple.CryptoTokenKit.pivtoken(1.0)
     com.apple.CryptoTokenKit.setoken(1.0)

Verbose

You can have more verbose output.

Before installation:
$ pluginkit -v -m -p com.apple.ctk-tokens
     com.apple.CryptoTokenKit.setoken(1.0) 4D0E5BB3-D45E-42A1-A0AE-24E0D71A6149 2018-07-12 16:37:44 +0000 /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/setoken.appex
     com.apple.CryptoTokenKit.pivtoken(1.0) A0B7E31C-443B-4B89-9D57-98D6A3736B86 2018-07-12 16:37:44 +0000 /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex
 (2 plug-ins)

After installation:
$ pluginkit -v -m -p com.apple.ctk-tokens
     org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken(1.0) 327C0A2C-4A43-4BB6-B858-73594115DCFA 2018-09-09 14:58:30 +0000 /Applications/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex
     com.apple.CryptoTokenKit.pivtoken(1.0) A0B7E31C-443B-4B89-9D57-98D6A3736B86 2018-07-12 16:37:44 +0000 /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex
     com.apple.CryptoTokenKit.setoken(1.0) 4D0E5BB3-D45E-42A1-A0AE-24E0D71A6149 2018-07-12 16:37:44 +0000 /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/setoken.appex
 (3 plug-ins)

This more verbose output allows you to know where on disk the plugin is found.
To remove/uninstall the plugin you just have to delete the application containing/providing the plugin.

Verbose + +

Or an even more verbose output:

Before installation:
$ pluginkit -vv -m -p com.apple.ctk-tokens
     com.apple.CryptoTokenKit.setoken(1.0)
             Path = /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/setoken.appex
             UUID = 4D0E5BB3-D45E-42A1-A0AE-24E0D71A6149
        Timestamp = 2018-07-12 16:37:44 +0000
              SDK = com.apple.ctk-tokens
     Display Name = Secure Enclave Private Key Storage
       Short Name = setoken

     com.apple.CryptoTokenKit.pivtoken(1.0)
             Path = /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex
             UUID = A0B7E31C-443B-4B89-9D57-98D6A3736B86
        Timestamp = 2018-07-12 16:37:44 +0000
              SDK = com.apple.ctk-tokens
     Display Name = Personal Identity Verification token driver
       Short Name = pivtoken

 (2 plug-ins)

After installation:
$ pluginkit -vv -m -p com.apple.ctk-tokens
     org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken(1.0)
             Path = /Applications/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex
             UUID = 327C0A2C-4A43-4BB6-B858-73594115DCFA
        Timestamp = 2018-09-09 14:58:30 +0000
              SDK = com.apple.ctk-tokens
    Parent Bundle = /Applications/OpenSCTokenApp.app
     Display Name = OpenSC token driver
       Short Name = OpenSCToken
      Parent Name = OpenSCTokenApp

     com.apple.CryptoTokenKit.pivtoken(1.0)
             Path = /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex
             UUID = A0B7E31C-443B-4B89-9D57-98D6A3736B86
        Timestamp = 2018-07-12 16:37:44 +0000
              SDK = com.apple.ctk-tokens
     Display Name = Personal Identity Verification token driver
       Short Name = pivtoken

     com.apple.CryptoTokenKit.setoken(1.0)
             Path = /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/setoken.appex
             UUID = 4D0E5BB3-D45E-42A1-A0AE-24E0D71A6149
        Timestamp = 2018-07-12 16:37:44 +0000
              SDK = com.apple.ctk-tokens
     Display Name = Secure Enclave Private Key Storage
       Short Name = setoken

 (3 plug-ins)

List inserted token

If your smart card is supported by one of the installed CryptoTokenKit plugin you will see it using the command "security list-smartcards".

$ security list-smartcards
org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310

Card content

There is different ways to display the content of the card.

system_profiler SPSmartCardsDataType

$ system_profiler SPSmartCardsDataType

    Readers:

      #01: Cherry KC 1000 SC Z (ATR:<3b9f9581 00000081="" 300671df="" 31fe9f00="" 6112c4="" 65465305="">)

    Reader Drivers:

      #01: org.debian.alioth.pcsclite.smartcardccid:1.4.27 (/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle)

    Tokend Drivers:

      #01: com.apple.tokend.opensc:1.0 (/Library/Security/tokend/OpenSC.tokend)

    SmartCard Drivers:

      #01: org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:1.0 (/Applications/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex)
      #02: com.apple.CryptoTokenKit.pivtoken:1.0 (/System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex)

    Available SmartCards (keychain):

        org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310:

          #01: Kind: private RSA 2048-bit, Certificate: <0b1bea81 4ee563aa="" ab26c4c8="" c7f82472="" d70c33d5="">, Usage: Sign Decrypt Unwrap 
Valid from: 2018-09-09 19:50:20 +0000 to: 2019-03-08 19:50:20 +0000, SSL trust: NO, X509 trust: YES 

-----BEGIN CERTIFICATE-----
MIIFlTCCA32gAwIBAgIDE8gaMA0GCSqGSIb3DQEBCwUAMHkxEDAOBgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBjYWNlcnQub3JnMB4XDTE4MDkwOTE5NTAyMFoXDTE5MDMwODE5NTAyMFowTDEYMBYGA1UEAxMPQ0FjZXJ0IFdvVCBVc2VyMTAwLgYJKoZIhvcNAQkBFiFsdWRvdmljLnJvdXNzZWF1K2NhY2VydEBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcW791p4I7wPdDTpHFzSNQwGvDlbOT5zYqSGTU1EeUNMewgj0KaGGcA9tEPD5B6U089/28QpJDU7LJb1bZygasl5VJxznXofZYP4GLerw8SMKfGPB5M3Yq9Wtxq8A282uzzfH9evvpQDoPxc03FZTyESeF1pr2y1oCNO4tvyd6hQc90zPdmzuXY2I/JwfhF6lJR/NaIFtpUqLJoRgN+pNwWjxvtQx5sjdWnFHW7R1/x+enp2eLTPTt2FRaSOdnCZVx9CNJw0BGTrzjHewp9kbdvLS3/A23ZPa4z+WUxNj4p3AgxJ3vh/VoRD3EhPpyvcfEgS7PWPHWHhKV5Z1CNFz5AgMBAAGjggFRMIIBTTAMBgNVHRMBAf8EAjAAMFYGCWCGSAGG+EIBDQRJFkdUbyBnZXQgeW91ciBvd24gY2VydGlmaWNhdGUgZm9yIEZSRUUgaGVhZCBvdmVyIHRvIGh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZzAOBgNVHQ8BAf8EBAMCA6gwQAYDVR0lBDkwNwYIKwYBBQUHAwQGCCsGAQUFBwMCBgorBgEEAYI3CgMEBgorBgEEAYI3CgMDBglghkgBhvhCBAEwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC5jYWNlcnQub3JnMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwuY2FjZXJ0Lm9yZy9yZXZva2UuY3JsMCwGA1UdEQQlMCOBIWx1ZG92aWMucm91c3NlYXUrY2FjZXJ0QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAAsGk23KL8OmpUmnS+rAQOEuHhcJ2gBNgR8Au83QmJKlpmyJD190UIJARd0QPp7583bt3c0iOMw2qtXSDkiFmo/ngyed02UYFSxWRUsoi8RmF8Rjv/xw797vVlO1zbiMcra91Ftf53ylCtGhhoNxyso4lkwXKCJuKUD4+8f02QvpNgG/WE3YtZ2WWiTa2RaXtoTWY3gU1TZVuW1CV7aHbA/xx+Gv/YK/WtMZYvHNmcppfuRsmw4hIGWyibZ073Nsn7DglictRTrNGI4+yJSR8MV53mkhBJHmXRtOJNvLV9vEcnF6qpxd5kMJiTFr6RzQJb86lIebhXlb6RjtbhNZSR0WESnRYzxjgNIkVtwUBamm94JoY1SUJDqS/totB147oRGzD+ha3scq+ZbM5MMniZM2qUbk6nnbiswPBFYo45nQcMGx++q9WoYGsf0euDzhVMKC7uHaIUHcaI1xlJpSoxR6GIOqqcoNRvPSJQy6DSosewBqhnRps6eSUTuqAD5cen9o16zba1T8iiIch5PeI/GbteokSpwSCH/21wjzMdCc8Q2/WHPWfrbyPuB5ymVmXbYZAD3sGcNh0ukzeEFJ2tuTGavtDil3Yka3C0EfLqKdykDPZtwXg9maCV8i6IQUBW3ty10ms5HRc/U2UaG0j+xx53dMxjl3idZmJN/FVOOM=
-----END CERTIFICATE-----


    Available SmartCards (token):

        org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310:

          #01: Kind: private RSA 2048-bit, Certificate: <0b1bea81 4ee563aa="" ab26c4c8="" c7f82472="" d70c33d5="">, Usage: Sign Decrypt Unwrap 
Valid from: 2018-09-09 19:50:20 +0000 to: 2019-03-08 19:50:20 +0000, SSL trust: NO, X509 trust: YES 

-----BEGIN CERTIFICATE-----
MIIFlTCCA32gAwIBAgIDE8gaMA0GCSqGSIb3DQEBCwUAMHkxEDAOBgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBjYWNlcnQub3JnMB4XDTE4MDkwOTE5NTAyMFoXDTE5MDMwODE5NTAyMFowTDEYMBYGA1UEAxMPQ0FjZXJ0IFdvVCBVc2VyMTAwLgYJKoZIhvcNAQkBFiFsdWRvdmljLnJvdXNzZWF1K2NhY2VydEBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcW791p4I7wPdDTpHFzSNQwGvDlbOT5zYqSGTU1EeUNMewgj0KaGGcA9tEPD5B6U089/28QpJDU7LJb1bZygasl5VJxznXofZYP4GLerw8SMKfGPB5M3Yq9Wtxq8A282uzzfH9evvpQDoPxc03FZTyESeF1pr2y1oCNO4tvyd6hQc90zPdmzuXY2I/JwfhF6lJR/NaIFtpUqLJoRgN+pNwWjxvtQx5sjdWnFHW7R1/x+enp2eLTPTt2FRaSOdnCZVx9CNJw0BGTrzjHewp9kbdvLS3/A23ZPa4z+WUxNj4p3AgxJ3vh/VoRD3EhPpyvcfEgS7PWPHWHhKV5Z1CNFz5AgMBAAGjggFRMIIBTTAMBgNVHRMBAf8EAjAAMFYGCWCGSAGG+EIBDQRJFkdUbyBnZXQgeW91ciBvd24gY2VydGlmaWNhdGUgZm9yIEZSRUUgaGVhZCBvdmVyIHRvIGh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZzAOBgNVHQ8BAf8EBAMCA6gwQAYDVR0lBDkwNwYIKwYBBQUHAwQGCCsGAQUFBwMCBgorBgEEAYI3CgMEBgorBgEEAYI3CgMDBglghkgBhvhCBAEwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC5jYWNlcnQub3JnMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwuY2FjZXJ0Lm9yZy9yZXZva2UuY3JsMCwGA1UdEQQlMCOBIWx1ZG92aWMucm91c3NlYXUrY2FjZXJ0QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAAsGk23KL8OmpUmnS+rAQOEuHhcJ2gBNgR8Au83QmJKlpmyJD190UIJARd0QPp7583bt3c0iOMw2qtXSDkiFmo/ngyed02UYFSxWRUsoi8RmF8Rjv/xw797vVlO1zbiMcra91Ftf53ylCtGhhoNxyso4lkwXKCJuKUD4+8f02QvpNgG/WE3YtZ2WWiTa2RaXtoTWY3gU1TZVuW1CV7aHbA/xx+Gv/YK/WtMZYvHNmcppfuRsmw4hIGWyibZ073Nsn7DglictRTrNGI4+yJSR8MV53mkhBJHmXRtOJNvLV9vEcnF6qpxd5kMJiTFr6RzQJb86lIebhXlb6RjtbhNZSR0WESnRYzxjgNIkVtwUBamm94JoY1SUJDqS/totB147oRGzD+ha3scq+ZbM5MMniZM2qUbk6nnbiswPBFYo45nQcMGx++q9WoYGsf0euDzhVMKC7uHaIUHcaI1xlJpSoxR6GIOqqcoNRvPSJQy6DSosewBqhnRps6eSUTuqAD5cen9o16zba1T8iiIch5PeI/GbteokSpwSCH/21wjzMdCc8Q2/WHPWfrbyPuB5ymVmXbYZAD3sGcNh0ukzeEFJ2tuTGavtDil3Yka3C0EfLqKdykDPZtwXg9maCV8i6IQUBW3ty10ms5HRc/U2UaG0j+xx53dMxjl3idZmJN/FVOOM=
-----END CERTIFICATE-----

I also installed the OpenSC_0.18.dmg package so the OpenSC tokend (using the deprecated API) is also installed.

security export-smartcard

$ security export-smartcard

==== certificate #1
 class : "cert"
 subj : <31 18 30 16 06 03 55 04 03 13 0f 43 41 43 45 52 54 20 57 4f 54 20 55 53 45 52 31 30 30 2e 06 09 2a 86 48 86 f7 0d 01 09 01 16 21 6c 75 64 6f 76 69 63 2e 72 6f 75 73 73 65 61 75 2b 63 61 63 65 72 74 40 67 6d 61 69 6c 2e 63 6f 6d>
 cenc : 3
 ctyp : 3
 pkhh : <0b 1b ea 81 4e e5 63 aa d7 0c 33 d5 c7 f8 24 72 ab 26 c4 c8>
 persistref : <>
 agrp : "com.apple.token"
 pdmn : "dk"
 labl : "User PIN (Ludovic Rousseau):ID Root CA de CAcert WoT User (CAcert WoT User)"
 UUID : "B997A93B-052E-4DB0-80B8-46A23A455085"
 mdat : 2018-09-09 19:55:07 +0000
 slnr : <13 c8 1a>
 sync : 0
 sha1 : <04 df f6 71 9e ad 56 97 96 81 6c b5 8b 46 a4 08 cd e0 65 35>
 tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
 musr : <>
 cdat : 2018-09-09 19:55:07 +0000
 tomb : 0
 issr : <31 10 30 0e 06 03 55 04 0a 13 07 52 4f 4f 54 20 43 41 31 1e 30 1c 06 03 55 04 0b 13 15 48 54 54 50 3a 2f 2f 57 57 57 2e 43 41 43 45 52 54 2e 4f 52 47 31 22 30 20 06 03 55 04 03 13 19 43 41 20 43 45 52 54 20 53 49 47 4e 49 4e 47 20 41 55 54 48 4f 52 49 54 59 31 21 30 1f 06 09 2a 86 48 86 f7 0d 01 09 01 16 12 73 75 70 70 6f 72 74 40 63 61 63 65 72 74 2e 6f 72 67>
 accc : constraints: {
   ord : true
  }
  protection: {
   tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
  }
====

==== private key #1
 crtr : 0
 esiz : 0
 decr : 1
 persistref : <>
 atag : ""
 kcls : 1
 agrp : "com.apple.token"
 pdmn : "dk"
 bsiz : 2 048
 type : 42
 klbl : <0b 1b ea 81 4e e5 63 aa d7 0c 33 d5 c7 f8 24 72 ab 26 c4 c8>
 edat : 2001-01-01 00:00:00 +0000
 sign : 1
 mdat : 2018-09-09 19:55:07 +0000
 drve : 0
 labl : "User PIN (Ludovic Rousseau):ID Root CA de CAcert WoT User (CAcert WoT User)"
 sync : 0
 musr : <>
 sha1 : <ed 9c 0f 96 fd e3 e0 ee 30 b9 d3 b1 23 13 8b 3c b0 8e 9c ad>
 cdat : 2018-09-09 19:55:07 +0000
 tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
 sdat : 2001-01-01 00:00:00 +0000
 tomb : 0
 priv : 1
 accc : constraints: {
   od : <ff>,
   osgn : <ff>
  }
  protection: {
   tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
  }
 unwp : 1
====

==== identity #1
 class : "idnt"
 slnr : <13 c8 1a>
 certdata : <CFData 0x7fdbb2007c00 [0x7fffa8c23af0]>{length = 1433, capacity = 1433, bytes = 0x308205953082037da003020102020313 ... 75998937f15538e3}
 certtkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
 priv : 1
 ctyp : 3
 mdat : 2018-09-09 19:55:07 +0000
 sdat : 2001-01-01 00:00:00 +0000
 bsiz : 2 048
 type : 42
 sha1 : <04 df f6 71 9e ad 56 97 96 81 6c b5 8b 46 a4 08 cd e0 65 35>
 pkhh : <0b 1b ea 81 4e e5 63 aa d7 0c 33 d5 c7 f8 24 72 ab 26 c4 c8>
 cdat : 2018-09-09 19:55:07 +0000
 tomb : 0
 UUID : "B997A93B-052E-4DB0-80B8-46A23A455085"
 persistref : <>
 accc : constraints: {
   od : <ff>,
   osgn : <ff>
  }
  protection: {
   tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
  }
 sync : 0
 tkid : "org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:3015061316010310"
 subj : <31 18 30 16 06 03 55 04 03 13 0f 43 41 43 45 52 54 20 57 4f 54 20 55 53 45 52 31 30 30 2e 06 09 2a 86 48 86 f7 0d 01 09 01 16 21 6c 75 64 6f 76 69 63 2e 72 6f 75 73 73 65 61 75 2b 63 61 63 65 72 74 40 67 6d 61 69 6c 2e 63 6f 6d>
 pdmn : "dk"
 musr : <>
 sign : 1
 esiz : 0
 decr : 1
 atag : ""
 edat : 2001-01-01 00:00:00 +0000
 klbl : <0b 1b ea 81 4e e5 63 aa d7 0c 33 d5 c7 f8 24 72 ab 26 c4 c8>
 crtr : 0
 unwp : 1
 issr : <31 10 30 0e 06 03 55 04 0a 13 07 52 4f 4f 54 20 43 41 31 1e 30 1c 06 03 55 04 0b 13 15 48 54 54 50 3a 2f 2f 57 57 57 2e 43 41 43 45 52 54 2e 4f 52 47 31 22 30 20 06 03 55 04 03 13 19 43 41 20 43 45 52 54 20 53 49 47 4e 49 4e 47 20 41 55 54 48 4f 52 49 54 59 31 21 30 1f 06 09 2a 86 48 86 f7 0d 01 09 01 16 12 73 75 70 70 6f 72 74 40 63 61 63 65 72 74 2e 6f 72 67>
 cenc : 3
 kcls : 1
 agrp : "com.apple.token"
 labl : "User PIN (Ludovic Rousseau):ID Root CA de CAcert WoT User (CAcert WoT User)"
 drve : 0
====

Keychain Access application

The Keychain Access application displays objects returned by the tokend.

If you install only the CryptoTokenKit plugin then you will not see a new keychain in Keychain Access. For me it is a regression. The graphical application was a good tool to display the content of a smart card.

Pairing a card to a user account


After inserting the card you should see a dialog window like the one bellow.



Click on "Pair" to associate the card private key to the user account.

You will need to enter your account password:


Then enter the card PIN code:


And the user account again:


The pairing is now done.

Untrusted Certification Authority

Note that you can pair a card certificate to a user even if the certificate is not trusted. In my case the certificate is issued and signed by CAcert. This Certification Authority is not trusted by macOS (you can see that in the Keychain Access screen copy) but you can still use the untrusted certificate to login.

Check pairing

You can now check that your account is paired to card
$ sc_auth list
Hash: 0B1BEA814EE563AAD70C33D5C7F82472AB26C4C8

You can note that the hash 0B1BEA814EE563AAD70C33D5C7F82472AB26C4C8 correspond to the "certificate #1" "pkhh", the "private key #1" "klbl", the "identity #1" "pkhh" and "klbl" fields from the security export-smartcard output.

Unparing a user

You can unpair a user

$ sc_auth unpair
$ sc_auth list
$

You will get the pairing dialog again after removing and inserting the card again. So it is easy to play with the pairing process.

Pairing dialog status

Disable

If you click on the "Do not show again" on the pairing dialog box the dialog will not be displayed again. You can check the pairing dialog status using:

$ sc_auth pairing_ui -s status
SmartCard Pairing dialog is disabled.

Enable

You can re-enable the pairing dialog using:
$ sc_auth pairing_ui -s enable

$ sc_auth pairing_ui -s status 
SmartCard Pairing dialog is enabled.

Usage


Screen unlock

You can lock your screen and unlock it using your smart card and PIN.


sudo(8)

As already seen in "macOS Sierra and pam_smartcard" some services are configured to use a PAM module for smart card.
In macOS Sierra only authorization_ctk and screensaver_ctk were configred to use the pam_smartcard.so module.

In macOS High Sierra the sudo command is also configured to use smart card authentication.

$ sudo id
Enter PIN for 'User PIN (Ludovic Rousseau):ID Root CA de CAcert WoT User (CAcert WoT User)': 
uid=0(root) gid=0(wheel) groups=0(wheel),1(daemon),2(kmem),3(sys),4(tty),5(operator),8(procview),9(procmod),12(everyone),20(staff),29(certusers),61(localaccounts),80(admin),702(2),705(5),703(3),701(1),33(_appstore),98(_lpadmin),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),704(4)

User login

The CryptoTokenKit plugin is enabled only for the user that has started the OpenSCTokenApp application.
Since the login screen is not executed as my user (I am not yet logged) so the plugin is not available at this step.

The OpenSCToken web site indicates a way to enable smart card use for the login screen. But this involves to disable the System Integrity Protection (SIP) and I think that is a bad idea.

There is a way (maybe more) to enable a CryptoTokenKit plugin for the login screen without disabling SIP. I may write about it in another blog article.

Conclusion

I wanted to write about CryptoTokenKit plugin since a long time. There is still a lot to write regarding the development and use of a CryptoTokenKit plugin.

If implemented and integrated correctly a CryptoTokenKit plugin should be very easy to use.