Skip to content

Instantly share code, notes, and snippets.

@witalisoft
Created December 12, 2021 09:49
Show Gist options
  • Save witalisoft/02618e6f79630c7dca3ab8511d95cbda to your computer and use it in GitHub Desktop.
Save witalisoft/02618e6f79630c7dca3ab8511d95cbda to your computer and use it in GitHub Desktop.
yubikey attestation server
package main
import (
"bufio"
"crypto/x509"
"encoding/asn1"
"encoding/base64"
"fmt"
"log"
"os"
"github.com/go-piv/piv-go/piv"
)
var (
extIDSerialNumber = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 4, 1, 41482, 3, 7})
dbSerialAttestCert = map[uint32]string{
// use ie. yubico-piv-tool to get those data
// cert as base64
1234567: "<your_attestation certificate>",
}
)
func main() {
reader := bufio.NewReader(os.Stdin)
rcvdAttestCertBase64, err := reader.ReadString('\n')
if err != nil {
log.Fatalf("cannot read from stdin, err: %+v", err)
}
rcvdAttestCertDecoded, err := base64.StdEncoding.DecodeString(rcvdAttestCertBase64)
if err != nil {
log.Fatalf("cannot decode received base64, err: %+v", err)
}
rcvdAttestCert, err := x509.ParseCertificate([]byte(rcvdAttestCertDecoded))
if err != nil {
log.Fatalf("cannot parse received attest certificate, err: %+v", err)
}
deviceSerial, err := getDeviceSerial(rcvdAttestCert)
if err != nil {
log.Fatal(err)
}
if dbAttestCertBase64, ok := dbSerialAttestCert[deviceSerial]; ok {
dbAttestCertDecoded, _ := base64.StdEncoding.DecodeString(dbAttestCertBase64)
dbAttestCert, err := x509.ParseCertificate([]byte(dbAttestCertDecoded))
if err != nil {
log.Fatalf("cannot parse db attest certificate, err: %+v", err)
}
_, err = piv.Verify(dbAttestCert, rcvdAttestCert)
if err != nil {
log.Fatalf("cannot verify attestation, err: %+v", err)
}
log.Printf("verified device with serial number: %d", deviceSerial)
} else {
log.Printf("could find attestation certificate for device with serial number: %d", deviceSerial)
}
}
func getDeviceSerial(cert *x509.Certificate) (uint32, error) {
var serial int64
for _, ext := range cert.Extensions {
if ext.Id.Equal(extIDSerialNumber) {
if _, err := asn1.Unmarshal(ext.Value, &serial); err != nil {
return 0, fmt.Errorf("parsing serial number: %v", err)
}
if serial < 0 {
return 0, fmt.Errorf("serial number was negative: %d", serial)
}
return uint32(serial), nil
}
}
return uint32(serial), fmt.Errorf("couldn't find serial number")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment