diff --git a/algorithm.go b/algorithm.go index 2e38684..0990c27 100644 --- a/algorithm.go +++ b/algorithm.go @@ -31,6 +31,9 @@ const ( // Non-standard; as implemented by SoloKeys. Chosen for low probability of eventual // clashes, if and when PIV standard adds Ed25519 support AlgEd25519 Algorithm = 0x22 + + // Non-standard extensions + AlgPIN Algorithm = 0xFF ) func (a Algorithm) algType() algorithmType { diff --git a/auth.go b/auth.go index 0e87676..30fa97e 100644 --- a/auth.go +++ b/auth.go @@ -314,3 +314,23 @@ func (c *Card) Retries() (int, error) { return 0, fmt.Errorf("invalid response: %w", err) } + +// SetRetries sets the number of attempts for PIN and PUK. +// +// Both PIN and PUK will be reset to default values when this is executed. +// Requires authentication with management key and PIN verification. +func (c *Card) SetRetries(key ManagementKey, pin string, pinAttempts, pukAttempts int) error { + if err := login(c.tx, pin); err != nil { + return fmt.Errorf("PIN verification failed: %w", err) + } + + if err := c.authenticate(key); err != nil { + return fmt.Errorf("failed to authenticate with management key: %w", err) + } + + if _, err := send(c.tx, insSetPINRetries, byte(pinAttempts), byte(pukAttempts), nil); err != nil { + return fmt.Errorf("failed to execute command: %w", err) + } + + return nil +} diff --git a/auth_test.go b/auth_test.go index a2e80e1..35626bc 100644 --- a/auth_test.go +++ b/auth_test.go @@ -144,3 +144,64 @@ func TestChangeManagementKey(t *testing.T) { require.NoError(t, err, "Failed to reset management key") }) } + +func TestSetRetries(t *testing.T) { + withCard(t, true, false, nil, func(t *testing.T, c *Card) { + // Check default attempt counters + for _, key := range []byte{keyPIN, keyPUK} { + meta, err := c.Metadata(Slot{Key: key}) + require.NoError(t, err) + require.Equal(t, 3, meta.RetriesRemaining) + require.Equal(t, 3, meta.RetriesTotal) + require.True(t, meta.IsDefault) + } + + retries := map[byte]int{keyPIN: 5, keyPUK: 10} + + // Modify retry counter + err := c.SetRetries(DefaultManagementKey, DefaultPIN, retries[keyPIN], retries[keyPUK]) + require.NoError(t, err) + + for key, cnt := range retries { + meta, err := c.Metadata(Slot{Key: key}) + require.NoError(t, err) + require.Equal(t, cnt, meta.RetriesRemaining) + require.Equal(t, cnt, meta.RetriesTotal) + require.True(t, meta.IsDefault) + } + + // Update remaining retries + var aErr AuthError + + err = c.VerifyPIN("92837492") + require.ErrorAs(t, err, &aErr) + require.Equal(t, retries[keyPIN]-1, aErr.Retries) + + err = c.Unblock("92837492", "12345678") + require.ErrorAs(t, err, &aErr) + require.Equal(t, retries[keyPUK]-1, aErr.Retries) + + for key, cnt := range retries { + meta, err := c.Metadata(Slot{Key: key}) + require.NoError(t, err) + require.Equal(t, cnt-1, meta.RetriesRemaining) + require.Equal(t, cnt, meta.RetriesTotal) + require.True(t, meta.IsDefault) + } + + // Modify PIN/PUK + err = c.SetPIN(DefaultPIN, "981211") + require.NoError(t, err) + + err = c.SetPUK(DefaultPUK, "981211") + require.NoError(t, err) + + for key, cnt := range retries { + meta, err := c.Metadata(Slot{Key: key}) + require.NoError(t, err) + require.Equal(t, cnt, meta.RetriesRemaining) + require.Equal(t, cnt, meta.RetriesTotal) + require.False(t, meta.IsDefault) + } + }) +} diff --git a/metadata.go b/metadata.go index bf2658d..96fc05b 100644 --- a/metadata.go +++ b/metadata.go @@ -12,43 +12,48 @@ import ( // Metadata holds unprotected metadata about a key slot. type Metadata struct { - Algorithm Algorithm - PINPolicy PINPolicy - TouchPolicy TouchPolicy - Origin Origin - PublicKey crypto.PublicKey + Algorithm Algorithm + PINPolicy PINPolicy + TouchPolicy TouchPolicy + Origin Origin + PublicKey crypto.PublicKey + RetriesTotal int + RetriesRemaining int + IsDefault bool } //nolint:gocognit func (ki *Metadata) unmarshal(tvs tlv.TagValues) (err error) { // Algorithm - if v, _, ok := tvs.Get(0x01); ok { - if len(v) != 1 { - return fmt.Errorf("%w for algorithm", errUnexpectedLength) + if v, _, ok := tvs.Get(tagMetadataAlgo); ok { + if l := len(v); l != 1 { + return fmt.Errorf("%w for algorithm: %d", errUnexpectedLength, l) } ki.Algorithm = Algorithm(v[0]) } // PIN & Touch Policy - if v, _, ok := tvs.Get(0x02); ok { - if len(v) != 2 { - return fmt.Errorf("%w for PIN and touch policy", errUnexpectedLength) + if v, _, ok := tvs.Get(tagMetadataPolicy); ok { + if l := len(v); l != 2 { + return fmt.Errorf("%w for PIN and touch policy: %d", errUnexpectedLength, l) } if ki.PINPolicy, ok = pinPolicyMapInv[v[0]]; !ok { - return errUnsupportedPinPolicy + if v[0] > 0 { // SlotCardManagement has no PIN policy + return fmt.Errorf("%w: %x", errUnsupportedPinPolicy, v[0]) + } } if ki.TouchPolicy, ok = touchPolicyMapInv[v[1]]; !ok { - return errUnsupportedTouchPolicy + return fmt.Errorf("%w: %x", errUnsupportedTouchPolicy, v[1]) } } // Origin - if v, _, ok := tvs.Get(0x03); ok { - if len(v) != 1 { - return fmt.Errorf("%w for origin", errUnexpectedLength) + if v, _, ok := tvs.Get(tagMetadataOrigin); ok { + if l := len(v); l != 1 { + return fmt.Errorf("%w for origin: %d", errUnexpectedLength, l) } if ki.Origin, ok = originMapInv[v[0]]; !ok { @@ -57,30 +62,31 @@ func (ki *Metadata) unmarshal(tvs tlv.TagValues) (err error) { } // Public Key - if v, _, ok := tvs.Get(0x04); ok { + if v, _, ok := tvs.Get(tagMetadataPublicKey); ok { ki.PublicKey, err = decodePublic(v, ki.Algorithm) if err != nil { return fmt.Errorf("failed to parse public key: %w", err) } } - // TODO: According to the Yubico website, we get two more fields, - // if we pass 0x80 or 0x81 as slots: - // 1. Default value (for PIN/PUK and management key): Whether the - // default value is used. - // 2. Retries (for PIN/PUK): The number of retries remaining - // However, it seems the reference implementation does not expect - // these and can not parse them out: - // https://github.com/Yubico/yubico-piv-tool/blob/yubico-piv-tool-2.3.1/lib/util.c#L1529 - // For now, we just ignore them. - - // Default Value - // if _, v, ok := tvs.Get(0x05); ok { - // } - - // Retries - // if _, v, ok := tvs.Get(0x06); ok { - // } + // Has default value + if v, _, ok := tvs.Get(tagMetadataIsDefault); ok { + if l := len(v); l != 1 { + return fmt.Errorf("%w for default value: %d", errUnexpectedLength, l) + } + + ki.IsDefault = v[0] != 0 + } + + // Number of retries left + if v, _, ok := tvs.Get(tagMetadataRetries); ok { + if l := len(v); l != 2 { + return fmt.Errorf("%w for retries: %d", errUnexpectedLength, l) + } + + ki.RetriesTotal = int(v[0]) + ki.RetriesRemaining = int(v[1]) + } return nil } diff --git a/metadata_test.go b/metadata_test.go index 8b4b98d..bd178b2 100644 --- a/metadata_test.go +++ b/metadata_test.go @@ -14,7 +14,7 @@ func TestMetadata(t *testing.T) { tests := []struct { name string slot Slot - policy Key + key Key importKey bool }{ { @@ -113,21 +113,22 @@ func TestMetadata(t *testing.T) { t.Run(test.name, func(t *testing.T) { withCard(t, true, false, SupportsMetadata, func(t *testing.T, c *Card) { want := &Metadata{ - Algorithm: test.policy.Algorithm, - PINPolicy: test.policy.PINPolicy, - TouchPolicy: test.policy.TouchPolicy, + Algorithm: test.key.Algorithm, + PINPolicy: test.key.PINPolicy, + TouchPolicy: test.key.TouchPolicy, + IsDefault: false, } if test.importKey { - key := testKey(t, test.policy.Algorithm.algType(), test.policy.Algorithm.bits()) + key := testKey(t, test.key.Algorithm.algType(), test.key.Algorithm.bits()) - err := c.SetPrivateKeyInsecure(DefaultManagementKey, test.slot, key, test.policy) + err := c.SetPrivateKeyInsecure(DefaultManagementKey, test.slot, key, test.key) require.NoError(t, err, "importing key") want.Origin = OriginImported want.PublicKey = key.Public() } else { - pub, err := c.GenerateKey(DefaultManagementKey, test.slot, test.policy) + pub, err := c.GenerateKey(DefaultManagementKey, test.slot, test.key) require.NoError(t, err, "Failed to generate key") want.Origin = OriginGenerated @@ -141,3 +142,40 @@ func TestMetadata(t *testing.T) { }) } } + +func TestMetadataPINPUK(t *testing.T) { + for typ, slot := range map[string]Slot{ + "PIN": SlotPIN, + "PUK": SlotPUK, + } { + t.Run(typ, func(t *testing.T) { + withCard(t, true, false, SupportsMetadata, func(t *testing.T, c *Card) { + want := &Metadata{ + Algorithm: AlgPIN, + RetriesTotal: 3, + RetriesRemaining: 3, + IsDefault: true, + } + + // Get default metadata + got, err := c.Metadata(slot) + require.NoError(t, err) + require.Equal(t, want, got) + }) + }) + } +} + +func TestMetadataCardManagement(t *testing.T) { + withCard(t, true, false, SupportsMetadata, func(t *testing.T, c *Card) { + want := &Metadata{ + Algorithm: Alg3DES, + TouchPolicy: TouchPolicyNever, + IsDefault: true, + } + + got, err := c.Metadata(SlotCardManagement) + require.NoError(t, err) + require.Equal(t, want, got) + }) +} diff --git a/mockdata/TestMetadataCardManagement/yk-5.4.3 b/mockdata/TestMetadataCardManagement/yk-5.4.3 new file mode 100644 index 0000000..2c00325 --- /dev/null +++ b/mockdata/TestMetadataCardManagement/yk-5.4.3 @@ -0,0 +1,26 @@ +mockfile + +file.version v2 +file.created 2024-06-05T20:59:51+02:00 +file.creator stv0g@cam + +meta status.active_protocol t1,any +meta status.atr 3bfd1300008131fe158073c021c057597562694b657940 +meta status.reader Yubico YubiKey OTP+FIDO+CCID +meta status.state specific,present,powered +meta yubikey.serial 23852774 +meta yubikey.version 5.4.3 + +# start end method +on 0.000 0.000 BeginTransaction +on 0.104 0.104 Transmit 00a4040009a00000030800001000 61114f0600001000010079074f05a0000003089000 +on 1.686 1.686 Transmit 00fd0000 0504039000 +on 2.345 2.345 Transmit 00200080083631353832323531 63c2 +on 7.555 7.555 Transmit 00200080083631353832323531 63c1 +on 12.772 12.772 Transmit 00200080083631353832323531 6983 +on 17.929 17.929 Transmit 002400811036313538323235313631353832323531 63c2 +on 22.935 22.935 Transmit 002400811036313538323235313631353832323531 63c1 +on 28.034 28.034 Transmit 002400811036313538323235313631353832323531 6983 +on 33.120 33.120 Transmit 00fb0000 9000 +on 536.242 536.242 Transmit 00f7009b 010103020200010501019000 +on 537.918 537.918 EndTransaction diff --git a/mockdata/TestMetadataCardManagement/yk-5.7.1 b/mockdata/TestMetadataCardManagement/yk-5.7.1 new file mode 100644 index 0000000..f569316 --- /dev/null +++ b/mockdata/TestMetadataCardManagement/yk-5.7.1 @@ -0,0 +1,26 @@ +mockfile + +file.version v2 +file.created 2024-06-05T20:59:35+02:00 +file.creator stv0g@cam + +meta status.active_protocol t1,any +meta status.atr 3bfd1300008131fe158073c021c057597562694b657940 +meta status.reader Yubico YubiKey OTP+FIDO+CCID +meta status.state present,powered,specific +meta yubikey.serial 29173673 +meta yubikey.version 5.7.1 + +# start end method +on 0.000 0.000 BeginTransaction +on 0.107 0.107 Transmit 00a4040009a00000030800001000 61114f0600001000010079074f05a0000003089000 +on 1.726 1.726 Transmit 00fd0000 0507019000 +on 2.945 2.945 Transmit 00200080083631353832323531 63c2 +on 8.894 8.894 Transmit 00200080083631353832323531 63c1 +on 14.725 14.725 Transmit 00200080083631353832323531 6983 +on 20.569 20.569 Transmit 002400811036313538323235313631353832323531 63c2 +on 26.485 26.485 Transmit 002400811036313538323235313631353832323531 63c1 +on 32.367 32.367 Transmit 002400811036313538323235313631353832323531 6983 +on 38.001 38.001 Transmit 00fb0000 9000 +on 965.039 965.039 Transmit 00f7009b 01010a020200010501019000 +on 967.124 967.124 EndTransaction diff --git a/mockdata/TestMetadataPINPUK/PIN/yk-5.4.3 b/mockdata/TestMetadataPINPUK/PIN/yk-5.4.3 new file mode 100644 index 0000000..8056809 --- /dev/null +++ b/mockdata/TestMetadataPINPUK/PIN/yk-5.4.3 @@ -0,0 +1,26 @@ +mockfile + +file.version v2 +file.created 2024-06-05T21:00:13+02:00 +file.creator stv0g@cam + +meta status.active_protocol any,t1 +meta status.atr 3bfd1300008131fe158073c021c057597562694b657940 +meta status.reader Yubico YubiKey OTP+FIDO+CCID +meta status.state specific,present,powered +meta yubikey.serial 23852774 +meta yubikey.version 5.4.3 + +# start end method +on 0.000 0.000 BeginTransaction +on 0.099 0.099 Transmit 00a4040009a00000030800001000 61114f0600001000010079074f05a0000003089000 +on 1.698 1.698 Transmit 00fd0000 0504039000 +on 2.446 2.446 Transmit 00200080083631353832323531 63c2 +on 7.753 7.753 Transmit 00200080083631353832323531 63c1 +on 13.116 13.116 Transmit 00200080083631353832323531 6983 +on 18.448 18.448 Transmit 002400811036313538323235313631353832323531 63c2 +on 23.587 23.587 Transmit 002400811036313538323235313631353832323531 63c1 +on 28.791 28.791 Transmit 002400811036313538323235313631353832323531 6983 +on 33.888 33.888 Transmit 00fb0000 9000 +on 547.578 547.578 Transmit 00f70080 0101ff050101060203039000 +on 552.110 552.110 EndTransaction diff --git a/mockdata/TestMetadataPINPUK/PIN/yk-5.7.1 b/mockdata/TestMetadataPINPUK/PIN/yk-5.7.1 new file mode 100644 index 0000000..e202a48 --- /dev/null +++ b/mockdata/TestMetadataPINPUK/PIN/yk-5.7.1 @@ -0,0 +1,35 @@ +mockfile + +file.version v2 +file.created 2024-06-05T20:47:04+02:00 +file.creator stv0g@cam + +meta status.active_protocol t1,any +meta status.atr 3bfd1300008131fe158073c021c057597562694b657940 +meta status.reader Yubico YubiKey OTP+FIDO+CCID +meta status.state specific,present,powered +meta yubikey.serial 29173673 +meta yubikey.version 5.7.1 + +# start end method +on 0.000 0.000 BeginTransaction +on 0.137 0.137 Transmit 00a4040009a00000030800001000 61114f0600001000010079074f05a0000003089000 +on 1.787 1.787 Transmit 00fd0000 0507019000 +on 3.105 3.105 Transmit 00200080083631353832323531 63c4 +on 8.824 8.824 Transmit 00200080083631353832323531 63c3 +on 14.604 14.604 Transmit 00200080083631353832323531 63c2 +on 20.176 20.176 Transmit 00200080083631353832323531 63c1 +on 25.909 25.909 Transmit 00200080083631353832323531 6983 +on 31.836 31.836 Transmit 002400811036313538323235313631353832323531 63c9 +on 37.629 37.629 Transmit 002400811036313538323235313631353832323531 63c8 +on 43.501 43.501 Transmit 002400811036313538323235313631353832323531 63c7 +on 49.511 49.511 Transmit 002400811036313538323235313631353832323531 63c6 +on 55.350 55.350 Transmit 002400811036313538323235313631353832323531 63c5 +on 61.131 61.131 Transmit 002400811036313538323235313631353832323531 63c4 +on 66.893 66.893 Transmit 002400811036313538323235313631353832323531 63c3 +on 72.509 72.509 Transmit 002400811036313538323235313631353832323531 63c2 +on 78.147 78.147 Transmit 002400811036313538323235313631353832323531 63c1 +on 83.847 83.847 Transmit 002400811036313538323235313631353832323531 6983 +on 89.512 89.512 Transmit 00fb0000 9000 +on 1042.079 1042.079 Transmit 00f70080 0101ff050101060203039000 +on 1043.592 1043.592 EndTransaction diff --git a/mockdata/TestMetadataPINPUK/PUK/yk-5.4.3 b/mockdata/TestMetadataPINPUK/PUK/yk-5.4.3 new file mode 100644 index 0000000..d7da756 --- /dev/null +++ b/mockdata/TestMetadataPINPUK/PUK/yk-5.4.3 @@ -0,0 +1,26 @@ +mockfile + +file.version v2 +file.created 2024-06-05T21:00:14+02:00 +file.creator stv0g@cam + +meta status.active_protocol any,t1 +meta status.atr 3bfd1300008131fe158073c021c057597562694b657940 +meta status.reader Yubico YubiKey OTP+FIDO+CCID +meta status.state present,powered,specific +meta yubikey.serial 23852774 +meta yubikey.version 5.4.3 + +# start end method +on 0.000 0.000 BeginTransaction +on 0.183 0.183 Transmit 00a4040009a00000030800001000 61114f0600001000010079074f05a0000003089000 +on 1.801 1.801 Transmit 00fd0000 0504039000 +on 2.529 2.529 Transmit 00200080083631353832323531 63c2 +on 7.799 7.799 Transmit 00200080083631353832323531 63c1 +on 13.404 13.404 Transmit 00200080083631353832323531 6983 +on 18.622 18.622 Transmit 002400811036313538323235313631353832323531 63c2 +on 23.767 23.767 Transmit 002400811036313538323235313631353832323531 63c1 +on 28.997 28.997 Transmit 002400811036313538323235313631353832323531 6983 +on 34.348 34.348 Transmit 00fb0000 9000 +on 537.019 537.019 Transmit 00f70081 0101ff050101060203039000 +on 537.847 537.847 EndTransaction diff --git a/mockdata/TestMetadataPINPUK/PUK/yk-5.7.1 b/mockdata/TestMetadataPINPUK/PUK/yk-5.7.1 new file mode 100644 index 0000000..91ba5c1 --- /dev/null +++ b/mockdata/TestMetadataPINPUK/PUK/yk-5.7.1 @@ -0,0 +1,26 @@ +mockfile + +file.version v2 +file.created 2024-06-05T20:47:05+02:00 +file.creator stv0g@cam + +meta status.active_protocol t1,any +meta status.atr 3bfd1300008131fe158073c021c057597562694b657940 +meta status.reader Yubico YubiKey OTP+FIDO+CCID +meta status.state specific,present,powered +meta yubikey.serial 29173673 +meta yubikey.version 5.7.1 + +# start end method +on 0.000 0.000 BeginTransaction +on 0.126 0.126 Transmit 00a4040009a00000030800001000 61114f0600001000010079074f05a0000003089000 +on 1.698 1.698 Transmit 00fd0000 0507019000 +on 2.766 2.766 Transmit 00200080083631353832323531 63c2 +on 8.338 8.338 Transmit 00200080083631353832323531 63c1 +on 14.359 14.359 Transmit 00200080083631353832323531 6983 +on 20.374 20.374 Transmit 002400811036313538323235313631353832323531 63c2 +on 26.235 26.235 Transmit 002400811036313538323235313631353832323531 63c1 +on 31.936 31.936 Transmit 002400811036313538323235313631353832323531 6983 +on 37.806 37.806 Transmit 00fb0000 9000 +on 954.327 954.327 Transmit 00f70081 0101ff050101060203039000 +on 955.805 955.805 EndTransaction diff --git a/mockdata/TestSetRetries/yk-5.4.3 b/mockdata/TestSetRetries/yk-5.4.3 new file mode 100644 index 0000000..f038067 --- /dev/null +++ b/mockdata/TestSetRetries/yk-5.4.3 @@ -0,0 +1,42 @@ +mockfile + +file.version v2 +file.created 2024-06-05T21:00:27+02:00 +file.creator stv0g@cam + +meta status.active_protocol t1,any +meta status.atr 3bfd1300008131fe158073c021c057597562694b657940 +meta status.reader Yubico YubiKey OTP+FIDO+CCID +meta status.state present,powered,specific +meta yubikey.serial 23852774 +meta yubikey.version 5.4.3 + +# start end method +on 0.000 0.000 BeginTransaction +on 0.138 0.138 Transmit 00a4040009a0000003080000100000 61114f0600001000010079074f05a0000003089000 +on 1.579 1.579 Transmit 00fd0000 0504039000 +on 2.256 2.256 Transmit 00200080083631353832323531 63c2 +on 7.382 7.382 Transmit 00200080083631353832323531 63c1 +on 12.788 12.788 Transmit 00200080083631353832323531 6983 +on 17.968 17.968 Transmit 002400811036313538323235313631353832323531 63c2 +on 22.955 22.955 Transmit 002400811036313538323235313631353832323531 63c1 +on 27.945 27.945 Transmit 002400811036313538323235313631353832323531 6983 +on 33.177 33.177 Transmit 00fb0000 9000 +on 537.346 537.346 Transmit 00f70080 0101ff050101060203039000 +on 539.340 539.340 Transmit 00f70081 0101ff050101060203039000 +on 540.795 540.795 Transmit 0020008008313233343536ffff 9000 +on 550.234 550.234 Transmit 00f7009b 010103020200010501019000 +on 551.240 551.240 Transmit 0087039b047c028000 7c0a80082be171482013eb049000 +on 552.804 552.804 Transmit 0087039b167c1480083b8d1e42d99399af8108abababababababab 7c0a8208b4e0e48bf8e2d06a9000 +on 554.008 554.008 Transmit 00fa050a 9000 +on 570.621 570.621 Transmit 00f70080 0101ff050101060205059000 +on 571.442 571.442 Transmit 00f70081 0101ff05010106020a0a9000 +on 572.211 572.211 Transmit 00200080083932383337343932 63c4 +on 577.762 577.762 Transmit 002c00801039323833373439323132333435363738 63c9 +on 583.199 583.199 Transmit 00f70080 0101ff050101060205049000 +on 584.605 584.605 Transmit 00f70081 0101ff05010106020a099000 +on 586.216 586.216 Transmit 0024008010313233343536ffff393831323131ffff 9000 +on 600.259 600.259 Transmit 00240081103132333435363738393831323131ffff 9000 +on 613.619 613.619 Transmit 00f70080 0101ff050100060205059000 +on 614.708 614.708 Transmit 00f70081 0101ff05010006020a0a9000 +on 616.149 616.149 EndTransaction diff --git a/mockdata/TestSetRetries/yk-5.7.1 b/mockdata/TestSetRetries/yk-5.7.1 new file mode 100644 index 0000000..d2bf5bf --- /dev/null +++ b/mockdata/TestSetRetries/yk-5.7.1 @@ -0,0 +1,51 @@ +mockfile + +file.version v2 +file.created 2024-06-05T20:46:29+02:00 +file.creator stv0g@cam + +meta status.active_protocol t1,any +meta status.atr 3bfd1300008131fe158073c021c057597562694b657940 +meta status.reader Yubico YubiKey OTP+FIDO+CCID +meta status.state powered,specific,present +meta yubikey.serial 29173673 +meta yubikey.version 5.7.1 + +# start end method +on 0.000 0.000 BeginTransaction +on 0.101 0.101 Transmit 00a4040009a0000003080000100000 61114f0600001000010079074f05a0000003089000 +on 0.880 0.880 Transmit 00fd0000 0507019000 +on 2.110 2.110 Transmit 00200080083631353832323531 63c4 +on 7.662 7.662 Transmit 00200080083631353832323531 63c3 +on 13.536 13.536 Transmit 00200080083631353832323531 63c2 +on 19.349 19.349 Transmit 00200080083631353832323531 63c1 +on 25.356 25.356 Transmit 00200080083631353832323531 6983 +on 31.124 31.124 Transmit 002400811036313538323235313631353832323531 63c9 +on 36.895 36.895 Transmit 002400811036313538323235313631353832323531 63c8 +on 42.633 42.633 Transmit 002400811036313538323235313631353832323531 63c7 +on 48.149 48.149 Transmit 002400811036313538323235313631353832323531 63c6 +on 53.760 53.760 Transmit 002400811036313538323235313631353832323531 63c5 +on 59.723 59.723 Transmit 002400811036313538323235313631353832323531 63c4 +on 65.379 65.379 Transmit 002400811036313538323235313631353832323531 63c3 +on 70.992 70.992 Transmit 002400811036313538323235313631353832323531 63c2 +on 76.681 76.681 Transmit 002400811036313538323235313631353832323531 63c1 +on 82.493 82.493 Transmit 002400811036313538323235313631353832323531 6983 +on 88.398 88.398 Transmit 00fb0000 9000 +on 1030.660 1030.660 Transmit 00f70080 0101ff050101060203039000 +on 1034.466 1034.466 Transmit 00f70081 0101ff050101060203039000 +on 1036.969 1036.969 Transmit 0020008008313233343536ffff 9000 +on 1047.988 1047.988 Transmit 00f7009b 01010a020200010501019000 +on 1050.016 1050.016 Transmit 00870a9b047c028000 7c1280102714235f1b780dd47f344bab623b48679000 +on 1052.464 1052.464 Transmit 00870a9b267c248010bb65ef29ca9ea3ba4610871d53b61cda8110abababababababababababababababab 7c12821040e0910c0a9420eb12ba9efcb51c48829000 +on 1054.864 1054.864 Transmit 00fa050a 9000 +on 1072.623 1072.623 Transmit 00f70080 0101ff050101060205059000 +on 1074.353 1074.353 Transmit 00f70081 0101ff05010106020a0a9000 +on 1076.041 1076.041 Transmit 00200080083932383337343932 63c4 +on 1082.120 1082.120 Transmit 002c00801039323833373439323132333435363738 63c9 +on 1088.074 1088.074 Transmit 00f70080 0101ff050101060205049000 +on 1089.594 1089.594 Transmit 00f70081 0101ff05010106020a099000 +on 1090.845 1090.845 Transmit 0024008010313233343536ffff393831323131ffff 9000 +on 1116.500 1116.500 Transmit 00240081103132333435363738393831323131ffff 9000 +on 1142.079 1142.079 Transmit 00f70080 0101ff050100060205059000 +on 1143.534 1143.534 Transmit 00f70081 0101ff05010006020a0a9000 +on 1144.840 1144.840 EndTransaction diff --git a/piv.go b/piv.go index ca4ea11..41cd284 100644 --- a/piv.go +++ b/piv.go @@ -54,6 +54,8 @@ const ( tagAlg = 0x80 // https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-78-4.pdf#page=16 + keyPIN = 0x80 + keyPUK = 0x81 keyAuthentication = 0x9a keyCardManagement = 0x9b keySignature = 0x9c diff --git a/slot.go b/slot.go index 4d3bc8e..41f2b7e 100644 --- a/slot.go +++ b/slot.go @@ -65,8 +65,11 @@ var ( SlotKeyManagement = Slot{keyKeyManagement, doCertKeyManagement} // YubiKey specific - SlotAttestation = Slot{keyAttestation, doCertAttestation} - SlotGraveyard = Slot{Key: 0xff} // Moving a key to this slot will destroy it + SlotAttestation = Slot{keyAttestation, doCertAttestation} + SlotPIN = Slot{Key: keyPIN} + SlotPUK = Slot{Key: keyPUK} + SlotCardManagement = Slot{Key: keyCardManagement} + SlotGraveyard = Slot{Key: 0xff} // Moving a key to this slot will destroy it ) // SlotRetiredKeyManagement provides access to "retired" slots. Slots meant for old Key Management diff --git a/tag.go b/tag.go index b61c6dd..5ae159d 100644 --- a/tag.go +++ b/tag.go @@ -91,4 +91,15 @@ const ( tagPINPolicy = 0xaa tagTouchPolicy = 0xab tagErrorDetectionCode = 0xfe + + // Yubikey extensions + + tagMetadataAlgo = 0x01 + tagMetadataPolicy = 0x02 + tagMetadataOrigin = 0x03 + tagMetadataPublicKey = 0x04 + tagMetadataIsDefault = 0x05 + tagMetadataRetries = 0x06 + tagMetadataBioConfigured = 0x07 + tagMetadataTemporaryPin = 0x08 )