go-piv / piv-go Goto Github PK
View Code? Open in Web Editor NEWKeys and certificates for YubiKeys, written in Go
License: Apache License 2.0
Keys and certificates for YubiKeys, written in Go
License: Apache License 2.0
The PIV spec says this about the TouchPolicy stored as byte 2 in the KeyPolicy OID:
1.3.6.1.4.1.41482.3.8: Two bytes, the first encoding pin policy and the second touch policy
Pin policy: 01 - never, 02 - once per session, 03 - always
Touch policy: 01 - never, 02 - always, 03 - cached for 15s
in key.go
the const's are out of order:
// Touch policies supported by this package.
const (
TouchPolicyNever TouchPolicy = iota + 1
TouchPolicyCached
TouchPolicyAlways
)
๐ Cached (2) and Always (3) are reversed. Should be Always=2 and Cached=3
The other spots where touchpolicy parsing/mapping is implemented have the correct values:
var touchPolicyMap = map[TouchPolicy]byte{
TouchPolicyNever: 0x01,
TouchPolicyAlways: 0x02,
TouchPolicyCached: 0x03,
}
case 0x01:
a.TouchPolicy = TouchPolicyNever
case 0x02:
a.TouchPolicy = TouchPolicyAlways
case 0x03:
a.TouchPolicy = TouchPolicyCached
go-ykpiv's CGo wrapper of libykpiv has this:
https://godoc.org/github.com/go-piv/go-ykpiv#Slot.Decrypt
f the slot holds an EC key, then we will perform ECDH and return the shared secret. In this case, msg must be the peer's public key in octet form, as specified in section 4.3.6 of ANSI X9.62.
I've tested that to work. I would, however, like to use pure-Go libraries.
I couldn't figure out how to get ECDH working with piv-go. For the CGo version, sign and decrypt look very similar:
https://github.com/go-piv/go-ykpiv/blob/32315ce599d8e21e91880e6ecdce55a98420ddc0/decrypt.go#L68
https://github.com/go-piv/go-ykpiv/blob/32315ce599d8e21e91880e6ecdce55a98420ddc0/sign.go#L166
and so do libykpiv's two functions, they both call the same function:
https://github.com/Yubico/yubico-piv-tool/blob/0b27308560ab4f3df4bc29a179e1c91649ce0629/lib/ykpiv.c#L1144
https://github.com/Yubico/yubico-piv-tool/blob/0b27308560ab4f3df4bc29a179e1c91649ce0629/lib/ykpiv.c#L1126
go-ykpiv has a helpful test case here:
https://github.com/go-piv/go-ykpiv/blob/32315ce599d8e21e91880e6ecdce55a98420ddc0/ykpiv_test.go#L522
But I can't see where exactly signing and decrypting are different to make ECDH work with go-piv. Any thoughts?
Hi, in PR #101 support for OpenBSD was added. I made this change in preparation for smallstep/certificates#990 , would it be possible to get a new piv-go tag cut to include this?
As noted here, upstream would prefer to use the non-auto-gen'd tag: smallstep/certificates#990 (comment) .
Thanks!
If I managed to get the APDU commands working for yubikeys to import their private key, would you accept a PR for that functionality?
Currently we're assuming > 4.3.0 since I only have a v4.3.7 and v3.4.9 key to test with
Lines 137 to 152 in 2184bb6
If someone can confirm that that test passes with an older version of a YubiKey (e.g. 4.2.X), we can support PIN caching and PINPolicyOnce for those versions.
To test against a YubiKey, comment out the version and run (this will destroy all data on your PIV applet but leave GPG and U2F/WebAuthN data unaffected):
go test -v -run=^TestYubiKeyReset$ . -wipe-yubikey
go test -v -run=^TestYubiKeyLoginNeeded$ . -wipe-yubikey
Hi! I am writing a PIV application for SoloKeys, and found some idiosyncrasies in this repository (which is named piv-go
and not yubico-piv-go
๐ผ).
This is the start of the "handshake" when I run @FiloSottile's https://github.com/FiloSottile/yubikey-agent:
10055575 APDU: 00 A4 04 00 05 A0 00 00 03 08
00001734 SW: 61 11 4F 06 00 00 10 00 01 00 79 07 4F 05 A0 00 00 03 08 90 00
00001345 APDU: 00 FD 00 00 00
00004496 SW: 04 03 04 90 00
00000965 APDU: 00 A4 04 00 08 A0 00 00 05 27 20 01 01
00002205 SW: 04 03 04 01 05 00 05 0F 00 00 90 00
00000661 APDU: 00 01 10 00 00
00000929 SW: 00 52 F7 43 90 00
For one, you send instruction 0xFD
(getVersion) against the PIV app, I guess because Yubico implements it there. Secondly, instruction 0x01
is used, is this also an idiosyncrasy? As ISO 7816-4 does not contain it. I can "fake" responses here, but it would be neat if answering these commands for non-Yubikeys would not be mandatory.
Also, the "AID" in
Line 336 in 564f246
[0x00, 0x00, 0x10, 0x00]
or additionally its version [0x01, 0x00]
.Currently this library doesn't support AES management keys as described in https://docs.yubico.com/hardware/yubikey/yk-5/tech-manual/yk5-piv-tech-desc.html#piv-aes-management-key
Inspired by the last stream of @FiloSottile I've digged into piv-go and windows and created a port for windows. Are the maintainers willing to merge windows patches into this repo? If it's fine I would put together a PR and would be willing to work with everyone involved.
Thanks in advance and thanks for this nice library.
https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf#page=30 (in agreement with https://developers.yubico.com/PIV/Introduction/Certificate_slots.html) says:
Purpose | Key Reference | BER-TLV Tag |
---|---|---|
PIV Authentication | 9A |
5FC105 |
Digital Signature | 9C |
5FC10A |
Key Management | 9D |
5FC10B |
Card Authentication | 9E |
5FC101 |
Lines 224 to 226 in 4cd4b28
Purpose | Slot | Tag | |
---|---|---|---|
SlotAuthentication | 0x9a |
0x5fc101 |
seems to be using object for card auth? |
SlotSignature | 0x9c |
0x5fc10a |
ok |
SlotCardAuthentication | 0x9e |
0x5fc10b |
seems to be using object for key management? |
When inspecting the card through pkcs11-tool
it does look like the wrong slots are being manipulated.
Also should there be a variable for the Key Management slot?
Hi! Trying to get a go-piv client working on Windows.
I've started 'smart card' in services.msc, however a call to GetCards()
will always error with connecting to pscs: the Smart card resource manager is not running
.
Any idea?
As reported in #42 (comment)
These were explicitly left out of the API since hardware bound keys are a much stronger security assertion if they never leave the key and you can prove that they're actually bound to hardware. They also make things harder because of they won't have an attestation certificate for us to get hints about PIN policy.
Consider documenting that imported keys aren't supported or explicitly handling them. Either way it's unlikely we'll provide an API to import keys.
For KeyAuth, the API to handle imported keys might look like:
type KeyAuth struct {
PIN string
PINPrompt func() (string, error)
// ImportedKeyPINPolicy is required for interacting with other tools that import
// keys that take a PIN.
//
// If a key was generated by this package, this value doesn't need to be set.
ImportedKeyPINPolicy PINPolicy
}
This a question not an issue, my question is I recently came across the library go-libpcsclite which is implemented completely in go, I tried to test it (not intensive) but it worked for me (signing and verifying).
So I ran a complete test using (go test -v ./... --wipe-yubikey) and it was 80% successful, if took the time to fix the other issues would you merge the change into the main repository.
--- PASS: TestYubiKeySignECDSA (4.44s)
=== RUN TestYubiKeyECDSASharedKey
=== RUN TestYubiKeyECDSASharedKey/good
=== RUN TestYubiKeyECDSASharedKey/bad
=== RUN TestYubiKeyECDSASharedKey/bad/size
--- PASS: TestYubiKeyECDSASharedKey (0.18s)
--- PASS: TestYubiKeyECDSASharedKey/good (0.06s)
--- PASS: TestYubiKeyECDSASharedKey/bad (0.01s)
--- PASS: TestYubiKeyECDSASharedKey/bad/size (0.01s)
=== RUN TestPINPrompt
=== RUN TestPINPrompt/Never
=== RUN TestPINPrompt/Once
=== RUN TestPINPrompt/Always
--- PASS: TestPINPrompt (1.15s)
--- PASS: TestPINPrompt/Never (0.38s)
--- PASS: TestPINPrompt/Once (0.38s)
--- PASS: TestPINPrompt/Always (0.39s)
=== RUN TestSlots
=== RUN TestSlots/Authentication
=== RUN TestSlots/CardAuthentication
=== RUN TestSlots/KeyManagement
=== RUN TestSlots/Signature
--- PASS: TestSlots (2.74s)
--- PASS: TestSlots/Authentication (0.47s)
--- PASS: TestSlots/CardAuthentication (0.46s)
--- PASS: TestSlots/KeyManagement (0.46s)
--- PASS: TestSlots/Signature (0.47s)
=== RUN TestYubiKeySignRSA
=== RUN TestYubiKeySignRSA/rsa1024
=== RUN TestYubiKeySignRSA/rsa2048
--- PASS: TestYubiKeySignRSA (2.31s)
--- PASS: TestYubiKeySignRSA/rsa1024 (0.71s)
--- PASS: TestYubiKeySignRSA/rsa2048 (1.59s)
=== RUN TestYubiKeyDecryptRSA
=== RUN TestYubiKeyDecryptRSA/rsa1024
=== RUN TestYubiKeyDecryptRSA/rsa2048
--- PASS: TestYubiKeyDecryptRSA (7.79s)
--- PASS: TestYubiKeyDecryptRSA/rsa1024 (0.71s)
--- PASS: TestYubiKeyDecryptRSA/rsa2048 (7.08s)
=== RUN TestYubiKeyAttestation
--- PASS: TestYubiKeyAttestation (0.24s)
=== RUN TestYubiKeyStoreCertificate
--- PASS: TestYubiKeyStoreCertificate (0.18s)
=== RUN TestYubiKeyGenerateKey
=== RUN TestYubiKeyGenerateKey/ec_256
=== RUN TestYubiKeyGenerateKey/ec_384
=== RUN TestYubiKeyGenerateKey/rsa_1024
=== RUN TestYubiKeyGenerateKey/rsa_2048
--- PASS: TestYubiKeyGenerateKey (9.69s)
--- PASS: TestYubiKeyGenerateKey/ec_256 (0.10s)
--- PASS: TestYubiKeyGenerateKey/ec_384 (0.14s)
--- PASS: TestYubiKeyGenerateKey/rsa_1024 (0.65s)
--- PASS: TestYubiKeyGenerateKey/rsa_2048 (8.79s)
=== RUN TestYubiKeyPrivateKey
--- PASS: TestYubiKeyPrivateKey (0.31s)
=== RUN TestYubiKeyPrivateKeyPINError
--- PASS: TestYubiKeyPrivateKeyPINError (0.24s)
=== RUN TestRetiredKeyManagementSlot
=== RUN TestRetiredKeyManagementSlot/Non-existent_slot,_before_range
=== RUN TestRetiredKeyManagementSlot/Non-existent_slot,_after_range
=== RUN TestRetiredKeyManagementSlot/First_retired_slot_key
=== RUN TestRetiredKeyManagementSlot/Last_retired_slot_key
--- PASS: TestRetiredKeyManagementSlot (0.00s)
--- PASS: TestRetiredKeyManagementSlot/Non-existent_slot,_before_range (0.00s)
--- PASS: TestRetiredKeyManagementSlot/Non-existent_slot,_after_range (0.00s)
--- PASS: TestRetiredKeyManagementSlot/First_retired_slot_key (0.00s)
--- PASS: TestRetiredKeyManagementSlot/Last_retired_slot_key (0.00s)
=== RUN TestContextClose
--- PASS: TestContextClose (0.00s)
=== RUN TestContextListReaders
--- PASS: TestContextListReaders (0.00s)
=== RUN TestHandle
--- PASS: TestHandle (0.00s)
=== RUN TestTransaction
pcsc_test.go:72: disconnecting from handle: EOF
pcsc_test.go:30: closing context: write unix @->/run/pcscd/pcscd.comm: write: broken pipe
--- FAIL: TestTransaction (2.00s)
=== RUN TestErrors
--- PASS: TestErrors (0.00s)
=== RUN TestGetVersion
pcsc_test.go:72: disconnecting from handle: EOF
pcsc_test.go:30: closing context: write unix @->/run/pcscd/pcscd.comm: write: broken pipe
--- FAIL: TestGetVersion (2.00s)
=== RUN TestCards
--- PASS: TestCards (0.00s)
=== RUN TestNewYubiKey
--- PASS: TestNewYubiKey (0.00s)
=== RUN TestMultipleConnections
piv_test.go:136: expected scErr, got connecting to smart card: invalid return code: 8010000b (sharing violation)
--- FAIL: TestMultipleConnections (0.00s)
=== RUN TestYubiKeySerial
--- PASS: TestYubiKeySerial (0.00s)
=== RUN TestYubiKeyLoginNeeded
--- PASS: TestYubiKeyLoginNeeded (0.06s)
=== RUN TestYubiKeyPINRetries
piv_test.go:177: getting retries: expected error code from empty pin
--- FAIL: TestYubiKeyPINRetries (0.00s)
=== RUN TestYubiKeyReset
--- PASS: TestYubiKeyReset (0.97s)
=== RUN TestYubiKeyLogin
--- PASS: TestYubiKeyLogin (0.01s)
=== RUN TestYubiKeyAuthenticate
--- PASS: TestYubiKeyAuthenticate (0.00s)
=== RUN TestYubiKeySetManagementKey
--- PASS: TestYubiKeySetManagementKey (0.02s)
=== RUN TestYubiKeyUnblockPIN
--- PASS: TestYubiKeyUnblockPIN (0.04s)
=== RUN TestYubiKeyChangePIN
--- PASS: TestYubiKeyChangePIN (0.03s)
=== RUN TestYubiKeyChangePUK
--- PASS: TestYubiKeyChangePUK (0.03s)
=== RUN TestChangeManagementKey
--- PASS: TestChangeManagementKey (0.01s)
=== RUN TestMetadata
--- PASS: TestMetadata (0.92s)
=== RUN TestMetadataUnmarshal
--- PASS: TestMetadataUnmarshal (0.00s)
=== RUN TestMetadataMarshal
--- PASS: TestMetadataMarshal (0.00s)
=== RUN TestMetadataUpdate
--- PASS: TestMetadataUpdate (0.00s)
=== RUN TestMetadataAdditoinalFields
--- PASS: TestMetadataAdditoinalFields (0.00s)
FAIL
FAIL github.com/go-piv/piv-go/piv 35.396s
FAIL
I want to build this project to linux armv7 device
cmd: env GOOS=linux GOARCH=arm GOARM=7 go build
got errors:
.../github.com/go-piv/[email protected]/piv/piv.go:103:7: undefined: scContext
.../github.com/go-piv/[email protected]/piv/piv.go:104:7: undefined: scHandle
.../github.com/go-piv/[email protected]/piv/piv.go:105:7: undefined: scTx
.../github.com/go-piv/[email protected]/piv/key.go:521:19: undefined: scTx
.../github.com/go-piv/[email protected]/piv/key.go:614:29: undefined: scTx
.../github.com/go-piv/[email protected]/piv/key.go:668:24: undefined: scTx
.../github.com/go-piv/[email protected]/piv/key.go:773:59: undefined: scTx
.../github.com/go-piv/[email protected]/piv/key.go:929:22: undefined: scTx
.../github.com/go-piv/[email protected]/piv/key.go:1085:22: undefined: scTx
.../github.com/go-piv/[email protected]/piv/key.go:1130:24: undefined: scTx
.../github.com/go-piv/[email protected]/piv/key.go:1130:24: too many errors
I am trying to build yubikey-agent on macOS (Apple M1 chip) and I see:
# github.com/go-piv/piv-go/piv
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/piv.go:103:7: undefined: scContext
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/piv.go:104:7: undefined: scHandle
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/piv.go:105:7: undefined: scTx
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:521:19: undefined: scTx
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:614:29: undefined: scTx
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:668:24: undefined: scTx
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:773:59: undefined: scTx
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:929:22: undefined: scTx
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:1085:22: undefined: scTx
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:1130:24: undefined: scTx
../../go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:1130:24: too many errors
Google search brought me here, and I saw that some work (#114, #94, #71) already went into supporting builds on ARM cpus. I am aware that yubikey-agent
is available via homebrew (on Apple M1 chips), however I am not sure how they achieved that. The homebrew formulas did not reveal anything special (I admit my ruby skills are not great, so I might have missed something).
My build environment is miniconda with native compilers, etc. I was able to build pcsc-lite
(this is what they do in homebrew, however it does not seem to have any effect - which would confirm what yubikey-agent says "nothing extra is needed to build the package").
Any help with supporting a native build on macOS would be greatly appreciated.
Thanks in advance!
OS: macOS 13.1
Consider the following code:
package main
import (
"log"
"github.com/go-piv/piv-go/piv"
)
func main() {
log.SetFlags(0)
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
cards, err := piv.Cards()
if err != nil {
return err
}
log.Print(cards)
return nil
}
When run with go version go1.20rc1 darwin/arm64, it fails with
connecting to pscs: the Smart card resource manager is not running
With go version go1.19.4 darwin/arm64 however, it works as expected, printing [Yubico YubiKey OTP+FIDO+CCID]
.
I get the below error when trying to build the piv-go project to run on arm. Apologies if I am simply missing a dependency.
ubuntu@tmc:~/go/src/github.com/filosottile/yubikey-agent$ GOOS=linux GOARCH=arm GOARM=5 go build
# github.com/go-piv/piv-go/piv
../../../../pkg/mod/github.com/go-piv/[email protected]/piv/piv.go:100:7: undefined: scContext
../../../../pkg/mod/github.com/go-piv/[email protected]/piv/piv.go:101:7: undefined: scHandle
../../../../pkg/mod/github.com/go-piv/[email protected]/piv/piv.go:102:7: undefined: scTx
ubuntu@tmc:~/go/pkg/mod/github.com/go-piv/[email protected]/piv$ GOOS=linux GOARCH=arm GOARM=5 go build
# github.com/go-piv/piv-go/piv
./piv.go:100:7: undefined: scContext
./piv.go:101:7: undefined: scHandle
./piv.go:102:7: undefined: scTx
Attestation is implemented by creating a X.509 certificate for the key that is to be attested, this is only done if the key has been generated on device. This certificate should only be used for the purpose of verifying that the key was generated in device, not for any other purposes.
https://developers.yubico.com/PIV/Introduction/PIV_attestation.html
Based off my testing, releasing the transaction wipes the PIN.
It seems that OSX (at least on 10.14.6) will not accept smartcards without a CHUID resulting in the following error:
failed to read CHUID record (Error Domain=CryptoTokenKit Code=-6 "(null)")
and the yubikey is not showing in
security list-smartcards
The card works for pkcs11 use cases, but is not recognized.
Values for yubikey CHUID and CCC are available here:
https://github.com/Yubico/yubico-piv-tool/blob/ebee7f63b85fe4373efc4d8d44cbe5fe321c158c/lib/util.c#L44
Hello
I'm able to build a program with this library that allows me to successfully interact with my YubiKey. However under some conditions, e.g. after some idle period, I'm getting the aforementioned erorr:
Error: Unable to open the Yubikey card: connecting to smart card: the smart card cannot be accessed because of other connections outstanding
I'm not sure if there is anything wrong with piv-go. But I'm quite puzzled since I make thorough use of the Close()
method and additionally I don't get this error with other tools e.g. libykcs11.so.
Yubico Yubikey NEO OTP+U2F+CCID
Applet version: piv.version{major:0x1, minor:0x0, patch:0x4}
Logs
=== RUN TestYubiKeySignECDSA
TestYubiKeySignECDSA: key_test.go:64: signing failed: command failed: smart card error 6982: security status not satisfied
--- FAIL: TestYubiKeySignECDSA (0.94s)
=== RUN TestPINPrompt
=== RUN TestPINPrompt/Never
TestPINPrompt/Never: key_test.go:110: building private key: get attestation cert: command failed: smart card error 6d00
=== RUN TestPINPrompt/Once
TestPINPrompt/Once: key_test.go:110: building private key: get attestation cert: command failed: smart card error 6d00
=== RUN TestPINPrompt/Always
TestPINPrompt/Always: key_test.go:110: building private key: get attestation cert: command failed: smart card error 6d00
--- FAIL: TestPINPrompt (2.01s)
--- FAIL: TestPINPrompt/Never (0.67s)
--- FAIL: TestPINPrompt/Once (0.67s)
--- FAIL: TestPINPrompt/Always (0.67s)
=== RUN TestSlots
=== RUN TestSlots/Authentication
TestSlots/Authentication: key_test.go:153: attest: got err=command failed: smart card error 6d00, want=ErrNotFound
TestSlots/Authentication: key_test.go:166: attest: command failed: smart card error 6d00
TestSlots/Authentication: key_test.go:171: private key: get attestation cert: command failed: smart card error 6d00
=== RUN TestSlots/CardAuthentication
TestSlots/CardAuthentication: key_test.go:153: attest: got err=command failed: smart card error 6d00, want=ErrNotFound
TestSlots/CardAuthentication: key_test.go:166: attest: command failed: smart card error 6d00
TestSlots/CardAuthentication: key_test.go:171: private key: get attestation cert: command failed: smart card error 6d00
=== RUN TestSlots/KeyManagement
TestSlots/KeyManagement: key_test.go:153: attest: got err=command failed: smart card error 6d00, want=ErrNotFound
TestSlots/KeyManagement: key_test.go:166: attest: command failed: smart card error 6d00
TestSlots/KeyManagement: key_test.go:171: private key: get attestation cert: command failed: smart card error 6d00
=== RUN TestSlots/Signature
TestSlots/Signature: key_test.go:153: attest: got err=command failed: smart card error 6d00, want=ErrNotFound
TestSlots/Signature: key_test.go:166: attest: command failed: smart card error 6d00
TestSlots/Signature: key_test.go:171: private key: get attestation cert: command failed: smart card error 6d00
--- FAIL: TestSlots (6.84s)
--- FAIL: TestSlots/Authentication (0.93s)
--- FAIL: TestSlots/CardAuthentication (0.91s)
--- FAIL: TestSlots/KeyManagement (0.91s)
--- FAIL: TestSlots/Signature (0.91s)
=== RUN TestYubiKeySignRSA
=== RUN TestYubiKeySignRSA/rsa1024
TestYubiKeySignRSA/rsa1024: key_test.go:249: signing failed: command failed: smart card error 6982: security status not satisfied
=== RUN TestYubiKeySignRSA/rsa2048
TestYubiKeySignRSA/rsa2048: key_test.go:249: signing failed: command failed: smart card error 6982: security status not satisfied
--- FAIL: TestYubiKeySignRSA (19.47s)
--- FAIL: TestYubiKeySignRSA/rsa1024 (4.92s)
--- FAIL: TestYubiKeySignRSA/rsa2048 (14.54s)
=== RUN TestYubiKeyDecryptRSA
=== RUN TestYubiKeyDecryptRSA/rsa1024
TestYubiKeyDecryptRSA/rsa1024: key_test.go:305: decryption failed: command failed: smart card error 6982: security status not satisfied
=== RUN TestYubiKeyDecryptRSA/rsa2048
TestYubiKeyDecryptRSA/rsa2048: key_test.go:305: decryption failed: command failed: smart card error 6982: security status not satisfied
--- FAIL: TestYubiKeyDecryptRSA (36.03s)
--- FAIL: TestYubiKeyDecryptRSA/rsa1024 (4.67s)
--- FAIL: TestYubiKeyDecryptRSA/rsa2048 (31.36s)
=== RUN TestYubiKeyAttestation
TestYubiKeyAttestation: key_test.go:325: getting attestation certificate: command failed: smart card error 6a82: data object or application not found
--- FAIL: TestYubiKeyAttestation (0.03s)
=== RUN TestYubiKeyStoreCertificate
--- PASS: TestYubiKeyStoreCertificate (3.54s)
=== RUN TestYubiKeyGenerateKey
=== RUN TestYubiKeyGenerateKey/ec_256
=== RUN TestYubiKeyGenerateKey/ec_384
TestYubiKeyGenerateKey/ec_384: key_test.go:462: generating key: command failed: smart card error 6a80: incorrect parameter in command data field
=== RUN TestYubiKeyGenerateKey/rsa_1024
=== RUN TestYubiKeyGenerateKey/rsa_2048
--- FAIL: TestYubiKeyGenerateKey (20.94s)
--- PASS: TestYubiKeyGenerateKey/ec_256 (0.67s)
--- FAIL: TestYubiKeyGenerateKey/ec_384 (0.07s)
--- PASS: TestYubiKeyGenerateKey/rsa_1024 (5.02s)
--- PASS: TestYubiKeyGenerateKey/rsa_2048 (15.18s)
=== RUN TestYubiKeyPrivateKey
TestYubiKeyPrivateKey: key_test.go:492: getting private key: get attestation cert: command failed: smart card error 6d00
--- FAIL: TestYubiKeyPrivateKey (3.36s)
=== RUN TestYubiKeyPrivateKeyPINError
TestYubiKeyPrivateKeyPINError: key_test.go:542: getting private key: get attestation cert: command failed: smart card error 6d00
--- FAIL: TestYubiKeyPrivateKeyPINError (0.67s)
=== RUN TestContextClose
--- PASS: TestContextClose (0.00s)
=== RUN TestContextListReaders
--- PASS: TestContextListReaders (0.00s)
=== RUN TestHandle
--- PASS: TestHandle (0.00s)
=== RUN TestTransaction
--- PASS: TestTransaction (0.00s)
=== RUN TestErrors
--- PASS: TestErrors (0.00s)
=== RUN TestGetVersion
--- PASS: TestGetVersion (0.02s)
=== RUN TestCards
--- PASS: TestCards (0.00s)
=== RUN TestNewYubiKey
--- PASS: TestNewYubiKey (0.02s)
=== RUN TestMultipleConnections
--- PASS: TestMultipleConnections (0.02s)
=== RUN TestYubiKeySerial
--- PASS: TestYubiKeySerial (0.05s)
=== RUN TestYubiKeyLoginNeeded
TestYubiKeyLoginNeeded: piv_test.go:140: expected no login needed
--- FAIL: TestYubiKeyLoginNeeded (0.07s)
=== RUN TestYubiKeyPINRetries
--- PASS: TestYubiKeyPINRetries (0.03s)
=== RUN TestYubiKeyReset
--- PASS: TestYubiKeyReset (3.26s)
=== RUN TestYubiKeyLogin
--- PASS: TestYubiKeyLogin (0.05s)
=== RUN TestYubiKeyAuthenticate
--- PASS: TestYubiKeyAuthenticate (0.07s)
=== RUN TestYubiKeySetManagementKey
--- PASS: TestYubiKeySetManagementKey (0.19s)
=== RUN TestYubiKeyUnblockPIN
--- PASS: TestYubiKeyUnblockPIN (0.20s)
=== RUN TestYubiKeyChangePIN
--- PASS: TestYubiKeyChangePIN (0.15s)
=== RUN TestYubiKeyChangePUK
--- PASS: TestYubiKeyChangePUK (0.14s)
=== RUN TestChangeManagementKey
--- PASS: TestChangeManagementKey (0.18s)
=== RUN TestMetadata
--- PASS: TestMetadata (3.43s)
=== RUN TestMetadataUnmarshal
--- PASS: TestMetadataUnmarshal (0.00s)
=== RUN TestMetadataMarshal
--- PASS: TestMetadataMarshal (0.00s)
=== RUN TestMetadataUpdate
--- PASS: TestMetadataUpdate (0.00s)
=== RUN TestMetadataAdditoinalFields
--- PASS: TestMetadataAdditoinalFields (0.00s)
FAIL
FAIL github.com/go-piv/piv-go/piv 102.041s
FAIL
Hello,
I'm trying to use piv-go
. No problem on OSX, but on my Arch Linux I've this error:
verify pin: smart card error 6983: authentication method blocked
Same error with good or bad PIN.
libpcsclite-dev
has been installed.
I'm using the piv-go library via yubikey-agent with a YubiKey 5Ci. I was getting errors when trying to sign which looked like:
agent 13: failed to prepare private key: parse attestation cert: parsing extension: unrecognized formfactor: 0x5
I patched the library with the following patch and everything seems to work as expected now.
diff --git a/piv/key.go b/piv/key.go
index f8679b1..fc1eff3 100644
--- a/piv/key.go
+++ b/piv/key.go
@@ -66,6 +66,7 @@ const (
FormfactorUSBANano
FormfactorUSBCKeychain
FormfactorUSBCNano
+ FormfactorUSBCLightning
)
// Attestation returns additional information about a key attested to be on a
@@ -142,6 +143,8 @@ func (a *Attestation) addExt(e pkix.Extension) error {
a.Formfactor = FormfactorUSBCKeychain
case 0x04:
a.Formfactor = FormfactorUSBCNano
+ case 0x05:
+ a.Formfactor = FormfactorUSBCLightning
default:
return fmt.Errorf("unrecognized formfactor: 0x%x", e.Value[0])
}
Would you accept a pull request to add this form factor to the library?
Thanks!
Hey, thank you so much for landing these changes so fast, without me even asking!
I tried v1.4.0 with yubikey-agent, and it doesn't quite work =(
No idea what's going on with (2), but for (1) I think you can learn about the policy from the attestation certificate, and behave accordingly.
Hello,
I'm trying to use an x.509 certificate to serve TLS traffic;
The certificate has been generated in the same way as key_test.go.
I defined the http serve like this:
mux := http.NewServeMux()
mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(200)
writer.Write([]byte("hello world"))
})
logger := log.New(os.Stdout, "http: ", log.LstdFlags)
s := &http.Server{
Addr: ":1443",
ErrorLog: logger,
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{
{
Certificate: [][]byte{cert.Raw},
PrivateKey: priv,
},
},
},
Handler: mux,
}
When I try to access to https://localhost:1443 I have this error with the curl command:
โ ~ curl -vvv https://localhost:1443/
* Trying ::1:1443...
* Connected to localhost (::1) port 1443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* error:1408F10B:SSL routines:ssl3_get_record:wrong version number
* Closing connection 0
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
I've created a repository:
https://github.com/shenron/try-piv-go
I've some difficulty to understand if the problem come from the combination with the private key. Or if it's something else.
Hi!
I think that keyRSA
and keyEd25519
type should be exposed otherwise golang is not able to use purpose-specific interfaces such as Signer and Decrypter of that type.
For example:
priv, err := yk.PrivateKey(...) // using a RSA pub key
// cannot cast to *piv.keyRSA like: "priv.(*piv.keyRSA)" since the type is not exposed
priv.Decrypt(....) // will not work, golang is not able to convert crypto.PrivateKey, to piv.keyRSA since is not exposed
Let me know if I am wrong, thanks!
When the YubiKey is busy I get an error like unknown pcsc return code 0x-7feffff5
on macOS.
0x-7feffff5
is the negative of 0x8010000B
, which would be correctly mapped to "the smart card cannot be accessed because of other connections outstanding".
The build fails as follows on arm FreeBSD:
# github.com/go-piv/piv-go/piv
vendor/github.com/go-piv/piv-go/piv/pcsc_freebsd.go:29:15: 0x8010002E (untyped int constant 2148532270) overflows int32
golang.org/x/crypto/ssh/agent
*** Error code 2
Please check and possible add a cast to make the number negative.
Got this report downstream, looks like piv-go is not obtaining and passing the PIN for the subsequent signature operations when the policy is ALWAYS.
With the current implementation, it doesn't seem practical detect whether we're dealing with a yubikey via NFC, as the only way we can really do so is by looking at the reader name. But that doesn't work if it's over an NFC reader, which will have a different name under PCSC. I think the ideal way to do this would be to look at the card's ATR, which the current PCSC code doesn't support. I've added Windows support for that, (here: https://github.com/1Dragoon/piv-go) though I don't have a means of easily testing any support I add for other platforms.
Once the ATR is obtained, based on this:
http://ludovic.rousseau.free.fr/softwares/pcsc-tools/smartcard_list.txt
It looks like all yubikeys will have some variation of the word "yubikey" in the historical bytes field, sometimes with the first or last y omitted.
Line 97 in 4b80d66
Multiple processes cannot acquire YubiKey if I am using go-piv.
but if we pass C.SCARD_SHARE_SHARED
in place of C.SCARD_SHARE_EXCLUSIVE
this will solve the problem without any side effects.
When trying to build this on a 32 bit machine, the 0x8010002E
constant overflowsC.long
:
Building subPackage ./.
github.com/go-piv/piv-go/piv
# github.com/go-piv/piv-go/piv
vendor/github.com/go-piv/piv-go/piv/pcsc_linux.go:29:12: constant 2148532270 overflows _Ctype_long
github.com/pkg/errors
github.com/gopasspw/gopass/pkg/pinentry
golang.org/x/crypto/internal/subtle
golang.org/x/crypto/chacha20
golang.org/x/crypto/curve25519
golang.org/x/crypto/ed25519
golang.org/x/crypto/poly1305
golang.org/x/crypto/blowfish
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
golang.org/x/crypto/ssh
golang.org/x/crypto/ssh/agent
golang.org/x/sys/unix
golang.org/x/crypto/ssh/terminal
builder for '/nix/store/7v5l6inyjav2hw79hann01xrdabv20x5-yubikey-agent-0.1.3.drv' failed with exit code 1
TouchPolicyAlways is "stricter" than TouchPolicyCached, however it is "less than" TouchPolicyCached in the code due to #74. This makes it hard to verify a minimum strictness. Compare to PINPolicy:
if cond.PINPolicy > attestation.PINPolicy {
return fmt.Errorf("Key's PINPolicy %v is less strict than the minimum %v", attestation.PINPolicy, cond.PINPolicy)
}
Because TouchPolicy isn't ordered by strictness, checking it is much harder. It seems a bit silly to make the (once written) parsing code simpler at the expense of use of the values. What do you think?
Hello,
Thank you very much for this project.
On my Yubikey I imported RSA keys to be able to sign/encrypt/authenticate. I use OpenPGP for this. I'm wondering if I can use this project to do the same.
My PublicKeyAlgorithm
is ECDSA
, so I guess it's the "internal" certificat of my Yubikey not my imported keys.
Thanks.
Older YubiKeys require this to get the serial which un-caches the PIN. Document this or see if there's a less intrusive way of getting the data.
Hi! Thank you for the library.
I'm trying to fetch the public key for generated keypair but this always returns in command failed: smart card error 6a82: data object or application not found
.
Code:
key := piv.Key{
Algorithm: piv.AlgorithmRSA2048,
PINPolicy: piv.PINPolicyOnce,
TouchPolicy: piv.TouchPolicyNever,
}
newPubKey, err := yubi.GenerateKey(piv.DefaultManagementKey, piv.SlotAuthentication, key)
if err != nil {
logger.WithError(err).Fatal("could not generate new public key on the security device")
}
cert, err := yubi.Certificate(piv.SlotAuthentication)
if err != nil {
// ERROR HERE
return nil, errors.Wrap(err, "could not get certificate from yubikey")
}
Any ideas?
This logic would likely be:
Could I prompt you to bump the go.mod version, it's currently 1.16
.
Per the Go release policy, they only support two prior major releases.
Also this is not just a cosmetic issue, per the gomod-ref , this value affects (a) use of new language features (b) behaviour of go command. Bumping the go.mod version has a positive effect on both.
Hey folks, I've been beating my head against a wall trying to cross compile this library using cgo on a amd64 linux system to be used on a amd64 mac using zig
which is using gcc
under the covers but continually get <angled> include; use "quotes" instead
errors. Does anyone know a way/flag around this?
root@115867f33658:/tmp/project# CC="${ZIG_HOME}/zig cc -target x86_64-macos -isystem /usr/include/ -L/usr/lib/ -Wno-macro-redefined -Wno-error-implicit-function-declaration"\
GOOS=darwin GOARCH=amd64 \
go build -o project
# github.com/go-piv/piv-go/piv
In file included from /go/pkg/mod/github.com/go-piv/[email protected]/piv/pcsc_unix.go:32:
/usr/include/PCSC/winscard.h:41:10: error: 'pcsclite.h' file not found with <angled> include; use "quotes" instead
#include <pcsclite.h>
^
In file included from /go/pkg/mod/github.com/go-piv/[email protected]/piv/pcsc_unix.go:32:
In file included from /usr/include/PCSC/winscard.h:41:
/usr/include/PCSC/pcsclite.h:45:10: error: 'wintypes.h' file not found with <angled> include; use "quotes" instead
#include <wintypes.h>
^
2 errors generated.
Hi!
Curious what packages I'd need (next to libpcsclite-dev
) for cross-compiling?
Error: ../../pkg/ui/open_linux.go:4:9: undefined: exec
66
# github.com/go-piv/piv-go/piv
67
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:448:19: undefined: scTx
68
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:541:29: undefined: scTx
69
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:595:24: undefined: scTx
70
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:708:59: undefined: scTx
71
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:864:22: undefined: scTx
72
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:1020:22: undefined: scTx
73
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:1065:24: undefined: scTx
74
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/piv.go:103:7: undefined: scContext
75
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/piv.go:104:7: undefined: scHandle
76
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/piv.go:105:7: undefined: scTx
77
Error: /home/runner/go/pkg/mod/github.com/go-piv/[email protected]/piv/key.go:1065:24: too many errors
78
https://www.eftlab.com/knowledge-base/complete-list-of-apdu-responses/
Common ones:
sw1=0x6a, sw2=0x80 - incorrect input or unsupported algorithm
sw1=0x69, sw2=0x82 - unauthenticated
sw1=0x69, sw2=0x83 - authentication method blocked
Different smart cards can implement different algorithm sets. See if YubiKey's PIV implementation supports algorithm discovery:
https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf#page=61
I'm using a certificate stored on a Yubikey to authenticate with a server. After enabling TLS 1.3, the flow broke because the TLS handshake attempts to use rsassa-pss and this library prevents that here:
if _, ok := opts.(*rsa.PSSOptions); ok {
return nil, fmt.Errorf("rsassa-pss signatures not supported")
}
Disabling rsassa-pss is not possible, unfortunately.
Interestingly, if I comment out the code above, the Yubikey seems to support this just fine, and the authentication succeeds.
What was the historical reason for introducing the check above? Was it related to the issues that golang had introducing support for rsassa-pss? Or maybe older Yubikeys did not support it?
Could removing this check be an option?
Both seemed to be cached, so it might take a while to figure this out.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.