Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor card #20

Merged
merged 12 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ linters-settings:
sections:
- standard
- default
- prefix(cunicu.li/skeleton)
- prefix(cunicu.li/go-piv)
- blank
- dot

Expand Down
2 changes: 1 addition & 1 deletion .reuse/dep5
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ Upstream-Name: skeleton
Upstream-Contact: Steffen Vogel <[email protected]>
Source: https://github.com/stv0g/skeleton

Files: go.sum *.crt
Files: go.sum *.crt *.key mockdata/*/*
Copyright: 2023 Steffen Vogel <[email protected]>
License: Apache-2.0
40 changes: 20 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@ if err != nil {
}

// Find a YubiKey and open the reader.
var yk *piv.YubiKey
var c *piv.Card
for _, card := range cards {
if strings.Contains(strings.ToLower(card), "yubikey") {
if yk, err = piv.Open(card); err != nil {
if c, err = piv.Open(card); err != nil {
// ...
}
break
}
}

if yk == nil {
if c == nil {
// ...
}

Expand All @@ -74,13 +74,13 @@ key := piv.Key{
TouchPolicy: piv.TouchPolicyAlways,
}

pub, err := yk.GenerateKey(piv.DefaultManagementKey, piv.SlotAuthentication, key)
pub, err := c.GenerateKey(piv.DefaultManagementKey, piv.SlotAuthentication, key)
if err != nil {
// ...
}

auth := piv.KeyAuth{PIN: piv.DefaultPIN}
priv, err := yk.PrivateKey(piv.SlotAuthentication, pub, auth)
priv, err := c.PrivateKey(piv.SlotAuthentication, pub, auth)
if err != nil {
// ...
}
Expand Down Expand Up @@ -113,7 +113,7 @@ if err != nil {
// ...
}

var newKey [24]byte
var newKey ManagementKey
if _, err := io.ReadFull(rand.Reader, newKey[:]); err != nil {
// ...
}
Expand All @@ -123,21 +123,21 @@ newPIN := fmt.Sprintf("%06d", newPINInt)
newPUK := fmt.Sprintf("%08d", newPUKInt)

// Set all values to a new value.
if err := yk.SetManagementKey(piv.DefaultManagementKey, newKey); err != nil {
if err := c.SetManagementKey(piv.DefaultManagementKey, newKey); err != nil {
// ...
}

if err := yk.SetPUK(piv.DefaultPUK, newPUK); err != nil {
if err := c.SetPUK(piv.DefaultPUK, newPUK); err != nil {
// ...
}

if err := yk.SetPIN(piv.DefaultPIN, newPIN); err != nil {
if err := c.SetPIN(piv.DefaultPIN, newPIN); err != nil {
// ...
}

// Store management key on the YubiKey.
m := piv.Metadata{ManagementKey: &newKey}
if err := yk.SetMetadata(newKey, m); err != nil {
if err := c.SetMetadata(newKey, m); err != nil {
// ...
}

Expand All @@ -147,7 +147,7 @@ fmt.Println("Credentials set. Your PIN is: %s", newPIN)
The user can use the PIN later to fetch the management key:

```go
m, err := yk.Metadata(pin)
m, err := c.Metadata(pin)
if err != nil {
// ...
}
Expand All @@ -169,7 +169,7 @@ if err != nil {
// ...
}

if err := yk.SetCertificate(managementKey, piv.SlotAuthentication, cert); err != nil {
if err := c.SetCertificate(managementKey, piv.SlotAuthentication, cert); err != nil {
// ...
}
```
Expand All @@ -178,12 +178,12 @@ The certificate can later be used in combination with the private key. For
example, to serve TLS traffic:

```go
cert, err := yk.Certificate(piv.SlotAuthentication)
cert, err := c.Certificate(piv.SlotAuthentication)
if err != nil {
// ...
}

priv, err := yk.PrivateKey(piv.SlotAuthentication, cert.PublicKey, auth)
priv, err := c.PrivateKey(piv.SlotAuthentication, cert.PublicKey, auth)
if err != nil {
// ...
}
Expand All @@ -209,7 +209,7 @@ key, then asks the YubiKey to sign an attestation certificate:

```go
// Get the YubiKey's attestation certificate, which is signed by Yubico.
yubiKeyAttestationCert, err := yk.AttestationCertificate()
yubiKeyAttestationCert, err := c.AttestationCertificate()
if err != nil {
// ...
}
Expand All @@ -221,10 +221,10 @@ key := piv.Key{
PINPolicy: piv.PINPolicyAlways,
TouchPolicy: piv.TouchPolicyAlways,
}
if _, err := yk.GenerateKey(managementKey, piv.SlotAuthentication, key); err != nil {
if _, err := c.GenerateKey(managementKey, piv.SlotAuthentication, key); err != nil {
// ...
}
slotAttestationCertificate, err := yk.Attest(piv.SlotAuthentication)
slotAttestationCertificate, err := c.Attest(piv.SlotAuthentication)
if err != nil {
// ...
}
Expand Down Expand Up @@ -294,17 +294,17 @@ Non-YubiKey smart cards that implement the PIV standard are not officially suppo
## Testing

Tests automatically find connected available YubiKeys, but won't modify the
smart card without the `--reset-yubikey` flag. To let the tests modify your
smart card without the `TEST_DANGEROUS_WIPE_REAL_CARD=1` environment variable is set. To let the tests modify your
YubiKey's PIV applet, run:

```shell
go test -v ./piv --reset-yubikey
TEST_DANGEROUS_WIPE_REAL_CARD=1 go test -v ./piv
```

Longer tests can be skipped with the `--test.short` flag.

```shell
go test -v --short ./piv --reset-yubikey
TEST_DANGEROUS_WIPE_REAL_CARD=1 go test -v --short ./piv
```

## Why?
Expand Down
70 changes: 48 additions & 22 deletions algorithm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,17 @@

package piv

//nolint:gochecknoglobals
var (
algorithmsMap = map[Algorithm]byte{
AlgorithmEC256: algECCP256,
AlgorithmEC384: algECCP384,
AlgorithmEd25519: algEd25519,
AlgorithmRSA1024: algRSA1024,
AlgorithmRSA2048: algRSA2048,
}
type algorithmType byte

algorithmsMapInv = map[byte]Algorithm{
algECCP256: AlgorithmEC256,
algECCP384: AlgorithmEC384,
algEd25519: AlgorithmEd25519,
algRSA1024: AlgorithmRSA1024,
algRSA2048: AlgorithmRSA2048,
}
const (
AlgTypeRSA algorithmType = iota + 1
AlgTypeECCP
AlgTypeEd25519
)

// Algorithm represents a specific algorithm and bit size supported by the PIV
// specification.
type Algorithm int
type Algorithm byte

// Algorithms supported by this package. Note that not all cards will support
// every algorithm.
Expand All @@ -33,9 +22,46 @@ type Algorithm int
//
// For algorithm discovery, see: https://github.com/ericchiang/piv-go/issues/1
const (
AlgorithmEC256 Algorithm = iota + 1
AlgorithmEC384
AlgorithmEd25519
AlgorithmRSA1024
AlgorithmRSA2048
Alg3DES Algorithm = 0x03
AlgRSA1024 Algorithm = 0x06
AlgRSA2048 Algorithm = 0x07
AlgECCP256 Algorithm = 0x11
AlgECCP384 Algorithm = 0x14

// Non-standard; as implemented by SoloKeys. Chosen for low probability of eventual
// clashes, if and when PIV standard adds Ed25519 support
AlgEd25519 Algorithm = 0x22
)

func (a Algorithm) algType() algorithmType {
switch a {
case AlgRSA1024, AlgRSA2048:
return AlgTypeRSA

case AlgECCP256, AlgECCP384:
return AlgTypeECCP

case AlgEd25519:
return AlgTypeEd25519

default:
return 0
}
}

func (a Algorithm) bits() int {
switch a {
case AlgRSA1024:
return 1024
case AlgRSA2048:
return 2048

case AlgECCP256:
return 256
case AlgECCP384:
return 384

default:
return 0
}
}
44 changes: 0 additions & 44 deletions asn1.go

This file was deleted.

Loading